Blame view
drivers/regulator/tps65910-regulator.c
31.9 KB
518fb721d TPS65910: Add tps... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/* * tps65910.c -- TI tps65910 * * Copyright 2010 Texas Instruments Inc. * * Author: Graeme Gregory <gg@slimlogic.co.uk> * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/err.h> #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> |
518fb721d TPS65910: Add tps... |
23 24 25 |
#include <linux/slab.h> #include <linux/gpio.h> #include <linux/mfd/tps65910.h> |
6790178f5 regulator: tps659... |
26 |
#include <linux/regulator/of_regulator.h> |
518fb721d TPS65910: Add tps... |
27 |
|
518fb721d TPS65910: Add tps... |
28 |
#define TPS65910_SUPPLY_STATE_ENABLED 0x1 |
1e0c66f49 regulator: tps659... |
29 30 |
#define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \ TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \ |
f30b0716f regulator: tps659... |
31 32 |
TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 | \ TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) |
518fb721d TPS65910: Add tps... |
33 |
|
d9fe28f96 regulator: tps659... |
34 35 36 |
/* supported VIO voltages in microvolts */ static const unsigned int VIO_VSEL_table[] = { 1500000, 1800000, 2500000, 3300000, |
518fb721d TPS65910: Add tps... |
37 |
}; |
a320e3c3d regulator: tps659... |
38 |
/* VSEL tables for TPS65910 specific LDOs and dcdc's */ |
d9fe28f96 regulator: tps659... |
39 40 41 |
/* supported VDD3 voltages in microvolts */ static const unsigned int VDD3_VSEL_table[] = { 5000000, |
518fb721d TPS65910: Add tps... |
42 |
}; |
d9fe28f96 regulator: tps659... |
43 44 45 |
/* supported VDIG1 voltages in microvolts */ static const unsigned int VDIG1_VSEL_table[] = { 1200000, 1500000, 1800000, 2700000, |
518fb721d TPS65910: Add tps... |
46 |
}; |
d9fe28f96 regulator: tps659... |
47 48 49 |
/* supported VDIG2 voltages in microvolts */ static const unsigned int VDIG2_VSEL_table[] = { 1000000, 1100000, 1200000, 1800000, |
518fb721d TPS65910: Add tps... |
50 |
}; |
d9fe28f96 regulator: tps659... |
51 52 53 |
/* supported VPLL voltages in microvolts */ static const unsigned int VPLL_VSEL_table[] = { 1000000, 1100000, 1800000, 2500000, |
518fb721d TPS65910: Add tps... |
54 |
}; |
d9fe28f96 regulator: tps659... |
55 56 57 |
/* supported VDAC voltages in microvolts */ static const unsigned int VDAC_VSEL_table[] = { 1800000, 2600000, 2800000, 2850000, |
518fb721d TPS65910: Add tps... |
58 |
}; |
d9fe28f96 regulator: tps659... |
59 60 61 |
/* supported VAUX1 voltages in microvolts */ static const unsigned int VAUX1_VSEL_table[] = { 1800000, 2500000, 2800000, 2850000, |
518fb721d TPS65910: Add tps... |
62 |
}; |
d9fe28f96 regulator: tps659... |
63 64 65 |
/* supported VAUX2 voltages in microvolts */ static const unsigned int VAUX2_VSEL_table[] = { 1800000, 2800000, 2900000, 3300000, |
518fb721d TPS65910: Add tps... |
66 |
}; |
d9fe28f96 regulator: tps659... |
67 68 69 |
/* supported VAUX33 voltages in microvolts */ static const unsigned int VAUX33_VSEL_table[] = { 1800000, 2000000, 2800000, 3300000, |
518fb721d TPS65910: Add tps... |
70 |
}; |
d9fe28f96 regulator: tps659... |
71 72 73 |
/* supported VMMC voltages in microvolts */ static const unsigned int VMMC_VSEL_table[] = { 1800000, 2800000, 3000000, 3300000, |
518fb721d TPS65910: Add tps... |
74 75 76 77 |
}; struct tps_info { const char *name; |
19228a6a5 regulator: tps659... |
78 |
const char *vin_name; |
7d38a3cb9 regulator: tps659... |
79 |
u8 n_voltages; |
d9fe28f96 regulator: tps659... |
80 |
const unsigned int *voltage_table; |
0651eed5e regulator: tps659... |
81 |
int enable_time_us; |
518fb721d TPS65910: Add tps... |
82 83 84 85 |
}; static struct tps_info tps65910_regs[] = { { |
33a6943d2 regulator: tps659... |
86 |
.name = "vrtc", |
19228a6a5 regulator: tps659... |
87 |
.vin_name = "vcc7", |
0651eed5e regulator: tps659... |
88 |
.enable_time_us = 2200, |
518fb721d TPS65910: Add tps... |
89 90 |
}, { |
33a6943d2 regulator: tps659... |
91 |
.name = "vio", |
19228a6a5 regulator: tps659... |
92 |
.vin_name = "vccio", |
7d38a3cb9 regulator: tps659... |
93 94 |
.n_voltages = ARRAY_SIZE(VIO_VSEL_table), .voltage_table = VIO_VSEL_table, |
0651eed5e regulator: tps659... |
95 |
.enable_time_us = 350, |
518fb721d TPS65910: Add tps... |
96 97 |
}, { |
33a6943d2 regulator: tps659... |
98 |
.name = "vdd1", |
19228a6a5 regulator: tps659... |
99 |
.vin_name = "vcc1", |
0651eed5e regulator: tps659... |
100 |
.enable_time_us = 350, |
518fb721d TPS65910: Add tps... |
101 102 |
}, { |
33a6943d2 regulator: tps659... |
103 |
.name = "vdd2", |
19228a6a5 regulator: tps659... |
104 |
.vin_name = "vcc2", |
0651eed5e regulator: tps659... |
105 |
.enable_time_us = 350, |
518fb721d TPS65910: Add tps... |
106 107 |
}, { |
33a6943d2 regulator: tps659... |
108 |
.name = "vdd3", |
7d38a3cb9 regulator: tps659... |
109 110 |
.n_voltages = ARRAY_SIZE(VDD3_VSEL_table), .voltage_table = VDD3_VSEL_table, |
0651eed5e regulator: tps659... |
111 |
.enable_time_us = 200, |
518fb721d TPS65910: Add tps... |
112 113 |
}, { |
33a6943d2 regulator: tps659... |
114 |
.name = "vdig1", |
19228a6a5 regulator: tps659... |
115 |
.vin_name = "vcc6", |
7d38a3cb9 regulator: tps659... |
116 117 |
.n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), .voltage_table = VDIG1_VSEL_table, |
0651eed5e regulator: tps659... |
118 |
.enable_time_us = 100, |
518fb721d TPS65910: Add tps... |
119 120 |
}, { |
33a6943d2 regulator: tps659... |
121 |
.name = "vdig2", |
19228a6a5 regulator: tps659... |
122 |
.vin_name = "vcc6", |
7d38a3cb9 regulator: tps659... |
123 124 |
.n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), .voltage_table = VDIG2_VSEL_table, |
0651eed5e regulator: tps659... |
125 |
.enable_time_us = 100, |
518fb721d TPS65910: Add tps... |
126 127 |
}, { |
33a6943d2 regulator: tps659... |
128 |
.name = "vpll", |
19228a6a5 regulator: tps659... |
129 |
.vin_name = "vcc5", |
7d38a3cb9 regulator: tps659... |
130 131 |
.n_voltages = ARRAY_SIZE(VPLL_VSEL_table), .voltage_table = VPLL_VSEL_table, |
0651eed5e regulator: tps659... |
132 |
.enable_time_us = 100, |
518fb721d TPS65910: Add tps... |
133 134 |
}, { |
33a6943d2 regulator: tps659... |
135 |
.name = "vdac", |
19228a6a5 regulator: tps659... |
136 |
.vin_name = "vcc5", |
7d38a3cb9 regulator: tps659... |
137 138 |
.n_voltages = ARRAY_SIZE(VDAC_VSEL_table), .voltage_table = VDAC_VSEL_table, |
0651eed5e regulator: tps659... |
139 |
.enable_time_us = 100, |
518fb721d TPS65910: Add tps... |
140 141 |
}, { |
33a6943d2 regulator: tps659... |
142 |
.name = "vaux1", |
19228a6a5 regulator: tps659... |
143 |
.vin_name = "vcc4", |
7d38a3cb9 regulator: tps659... |
144 145 |
.n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), .voltage_table = VAUX1_VSEL_table, |
0651eed5e regulator: tps659... |
146 |
.enable_time_us = 100, |
518fb721d TPS65910: Add tps... |
147 148 |
}, { |
33a6943d2 regulator: tps659... |
149 |
.name = "vaux2", |
19228a6a5 regulator: tps659... |
150 |
.vin_name = "vcc4", |
7d38a3cb9 regulator: tps659... |
151 152 |
.n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), .voltage_table = VAUX2_VSEL_table, |
0651eed5e regulator: tps659... |
153 |
.enable_time_us = 100, |
518fb721d TPS65910: Add tps... |
154 155 |
}, { |
33a6943d2 regulator: tps659... |
156 |
.name = "vaux33", |
19228a6a5 regulator: tps659... |
157 |
.vin_name = "vcc3", |
7d38a3cb9 regulator: tps659... |
158 159 |
.n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), .voltage_table = VAUX33_VSEL_table, |
0651eed5e regulator: tps659... |
160 |
.enable_time_us = 100, |
518fb721d TPS65910: Add tps... |
161 162 |
}, { |
33a6943d2 regulator: tps659... |
163 |
.name = "vmmc", |
19228a6a5 regulator: tps659... |
164 |
.vin_name = "vcc3", |
7d38a3cb9 regulator: tps659... |
165 166 |
.n_voltages = ARRAY_SIZE(VMMC_VSEL_table), .voltage_table = VMMC_VSEL_table, |
0651eed5e regulator: tps659... |
167 |
.enable_time_us = 100, |
518fb721d TPS65910: Add tps... |
168 169 |
}, }; |
a320e3c3d regulator: tps659... |
170 171 |
static struct tps_info tps65911_regs[] = { { |
33a6943d2 regulator: tps659... |
172 |
.name = "vrtc", |
19228a6a5 regulator: tps659... |
173 |
.vin_name = "vcc7", |
0651eed5e regulator: tps659... |
174 |
.enable_time_us = 2200, |
c2f8efd76 regulator: tps659... |
175 176 |
}, { |
33a6943d2 regulator: tps659... |
177 |
.name = "vio", |
19228a6a5 regulator: tps659... |
178 |
.vin_name = "vccio", |
7d38a3cb9 regulator: tps659... |
179 180 |
.n_voltages = ARRAY_SIZE(VIO_VSEL_table), .voltage_table = VIO_VSEL_table, |
0651eed5e regulator: tps659... |
181 |
.enable_time_us = 350, |
a320e3c3d regulator: tps659... |
182 183 |
}, { |
33a6943d2 regulator: tps659... |
184 |
.name = "vdd1", |
19228a6a5 regulator: tps659... |
185 |
.vin_name = "vcc1", |
7be531883 regulator: tps659... |
186 |
.n_voltages = 0x4C, |
0651eed5e regulator: tps659... |
187 |
.enable_time_us = 350, |
a320e3c3d regulator: tps659... |
188 189 |
}, { |
33a6943d2 regulator: tps659... |
190 |
.name = "vdd2", |
19228a6a5 regulator: tps659... |
191 |
.vin_name = "vcc2", |
7be531883 regulator: tps659... |
192 |
.n_voltages = 0x4C, |
0651eed5e regulator: tps659... |
193 |
.enable_time_us = 350, |
a320e3c3d regulator: tps659... |
194 195 |
}, { |
33a6943d2 regulator: tps659... |
196 |
.name = "vddctrl", |
7be531883 regulator: tps659... |
197 |
.n_voltages = 0x44, |
0651eed5e regulator: tps659... |
198 |
.enable_time_us = 900, |
a320e3c3d regulator: tps659... |
199 200 |
}, { |
33a6943d2 regulator: tps659... |
201 |
.name = "ldo1", |
19228a6a5 regulator: tps659... |
202 |
.vin_name = "vcc6", |
7be531883 regulator: tps659... |
203 |
.n_voltages = 0x33, |
0651eed5e regulator: tps659... |
204 |
.enable_time_us = 420, |
a320e3c3d regulator: tps659... |
205 206 |
}, { |
33a6943d2 regulator: tps659... |
207 |
.name = "ldo2", |
19228a6a5 regulator: tps659... |
208 |
.vin_name = "vcc6", |
7be531883 regulator: tps659... |
209 |
.n_voltages = 0x33, |
0651eed5e regulator: tps659... |
210 |
.enable_time_us = 420, |
a320e3c3d regulator: tps659... |
211 212 |
}, { |
33a6943d2 regulator: tps659... |
213 |
.name = "ldo3", |
19228a6a5 regulator: tps659... |
214 |
.vin_name = "vcc5", |
7be531883 regulator: tps659... |
215 |
.n_voltages = 0x1A, |
0651eed5e regulator: tps659... |
216 |
.enable_time_us = 230, |
a320e3c3d regulator: tps659... |
217 218 |
}, { |
33a6943d2 regulator: tps659... |
219 |
.name = "ldo4", |
19228a6a5 regulator: tps659... |
220 |
.vin_name = "vcc5", |
7be531883 regulator: tps659... |
221 |
.n_voltages = 0x33, |
0651eed5e regulator: tps659... |
222 |
.enable_time_us = 230, |
a320e3c3d regulator: tps659... |
223 224 |
}, { |
33a6943d2 regulator: tps659... |
225 |
.name = "ldo5", |
19228a6a5 regulator: tps659... |
226 |
.vin_name = "vcc4", |
7be531883 regulator: tps659... |
227 |
.n_voltages = 0x1A, |
0651eed5e regulator: tps659... |
228 |
.enable_time_us = 230, |
a320e3c3d regulator: tps659... |
229 230 |
}, { |
33a6943d2 regulator: tps659... |
231 |
.name = "ldo6", |
19228a6a5 regulator: tps659... |
232 |
.vin_name = "vcc3", |
7be531883 regulator: tps659... |
233 |
.n_voltages = 0x1A, |
0651eed5e regulator: tps659... |
234 |
.enable_time_us = 230, |
a320e3c3d regulator: tps659... |
235 236 |
}, { |
33a6943d2 regulator: tps659... |
237 |
.name = "ldo7", |
19228a6a5 regulator: tps659... |
238 |
.vin_name = "vcc3", |
7be531883 regulator: tps659... |
239 |
.n_voltages = 0x1A, |
0651eed5e regulator: tps659... |
240 |
.enable_time_us = 230, |
a320e3c3d regulator: tps659... |
241 242 |
}, { |
33a6943d2 regulator: tps659... |
243 |
.name = "ldo8", |
19228a6a5 regulator: tps659... |
244 |
.vin_name = "vcc3", |
7be531883 regulator: tps659... |
245 |
.n_voltages = 0x1A, |
0651eed5e regulator: tps659... |
246 |
.enable_time_us = 230, |
a320e3c3d regulator: tps659... |
247 248 |
}, }; |
1e0c66f49 regulator: tps659... |
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
#define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits)) static unsigned int tps65910_ext_sleep_control[] = { 0, EXT_CONTROL_REG_BITS(VIO, 1, 0), EXT_CONTROL_REG_BITS(VDD1, 1, 1), EXT_CONTROL_REG_BITS(VDD2, 1, 2), EXT_CONTROL_REG_BITS(VDD3, 1, 3), EXT_CONTROL_REG_BITS(VDIG1, 0, 1), EXT_CONTROL_REG_BITS(VDIG2, 0, 2), EXT_CONTROL_REG_BITS(VPLL, 0, 6), EXT_CONTROL_REG_BITS(VDAC, 0, 7), EXT_CONTROL_REG_BITS(VAUX1, 0, 3), EXT_CONTROL_REG_BITS(VAUX2, 0, 4), EXT_CONTROL_REG_BITS(VAUX33, 0, 5), EXT_CONTROL_REG_BITS(VMMC, 0, 0), }; static unsigned int tps65911_ext_sleep_control[] = { 0, EXT_CONTROL_REG_BITS(VIO, 1, 0), EXT_CONTROL_REG_BITS(VDD1, 1, 1), EXT_CONTROL_REG_BITS(VDD2, 1, 2), EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3), EXT_CONTROL_REG_BITS(LDO1, 0, 1), EXT_CONTROL_REG_BITS(LDO2, 0, 2), EXT_CONTROL_REG_BITS(LDO3, 0, 7), EXT_CONTROL_REG_BITS(LDO4, 0, 6), EXT_CONTROL_REG_BITS(LDO5, 0, 3), EXT_CONTROL_REG_BITS(LDO6, 0, 0), EXT_CONTROL_REG_BITS(LDO7, 0, 5), EXT_CONTROL_REG_BITS(LDO8, 0, 4), }; |
518fb721d TPS65910: Add tps... |
281 |
struct tps65910_reg { |
39aa9b6e3 regulator: tps659... |
282 |
struct regulator_desc *desc; |
518fb721d TPS65910: Add tps... |
283 |
struct tps65910 *mfd; |
39aa9b6e3 regulator: tps659... |
284 285 |
struct regulator_dev **rdev; struct tps_info **info; |
39aa9b6e3 regulator: tps659... |
286 |
int num_regulators; |
518fb721d TPS65910: Add tps... |
287 |
int mode; |
a320e3c3d regulator: tps659... |
288 |
int (*get_ctrl_reg)(int); |
1e0c66f49 regulator: tps659... |
289 290 |
unsigned int *ext_sleep_control; unsigned int board_ext_control[TPS65910_NUM_REGS]; |
518fb721d TPS65910: Add tps... |
291 |
}; |
518fb721d TPS65910: Add tps... |
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
static int tps65910_get_ctrl_register(int id) { switch (id) { case TPS65910_REG_VRTC: return TPS65910_VRTC; case TPS65910_REG_VIO: return TPS65910_VIO; case TPS65910_REG_VDD1: return TPS65910_VDD1; case TPS65910_REG_VDD2: return TPS65910_VDD2; case TPS65910_REG_VDD3: return TPS65910_VDD3; case TPS65910_REG_VDIG1: return TPS65910_VDIG1; case TPS65910_REG_VDIG2: return TPS65910_VDIG2; case TPS65910_REG_VPLL: return TPS65910_VPLL; case TPS65910_REG_VDAC: return TPS65910_VDAC; case TPS65910_REG_VAUX1: return TPS65910_VAUX1; case TPS65910_REG_VAUX2: return TPS65910_VAUX2; case TPS65910_REG_VAUX33: return TPS65910_VAUX33; case TPS65910_REG_VMMC: return TPS65910_VMMC; default: return -EINVAL; } } |
a320e3c3d regulator: tps659... |
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
static int tps65911_get_ctrl_register(int id) { switch (id) { case TPS65910_REG_VRTC: return TPS65910_VRTC; case TPS65910_REG_VIO: return TPS65910_VIO; case TPS65910_REG_VDD1: return TPS65910_VDD1; case TPS65910_REG_VDD2: return TPS65910_VDD2; case TPS65911_REG_VDDCTRL: return TPS65911_VDDCTRL; case TPS65911_REG_LDO1: return TPS65911_LDO1; case TPS65911_REG_LDO2: return TPS65911_LDO2; case TPS65911_REG_LDO3: return TPS65911_LDO3; case TPS65911_REG_LDO4: return TPS65911_LDO4; case TPS65911_REG_LDO5: return TPS65911_LDO5; case TPS65911_REG_LDO6: return TPS65911_LDO6; case TPS65911_REG_LDO7: return TPS65911_LDO7; case TPS65911_REG_LDO8: return TPS65911_LDO8; default: return -EINVAL; } } |
518fb721d TPS65910: Add tps... |
358 359 360 361 362 |
static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); struct tps65910 *mfd = pmic->mfd; int reg, value, id = rdev_get_id(dev); |
a320e3c3d regulator: tps659... |
363 364 |
reg = pmic->get_ctrl_reg(id); |
518fb721d TPS65910: Add tps... |
365 366 367 368 369 |
if (reg < 0) return reg; switch (mode) { case REGULATOR_MODE_NORMAL: |
faa95fde4 regulator: tps659... |
370 371 372 |
return tps65910_reg_update_bits(pmic->mfd, reg, LDO_ST_MODE_BIT | LDO_ST_ON_BIT, LDO_ST_ON_BIT); |
518fb721d TPS65910: Add tps... |
373 374 |
case REGULATOR_MODE_IDLE: value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT; |
3f7e82759 mfd: Commonize tp... |
375 |
return tps65910_reg_set_bits(mfd, reg, value); |
518fb721d TPS65910: Add tps... |
376 |
case REGULATOR_MODE_STANDBY: |
3f7e82759 mfd: Commonize tp... |
377 |
return tps65910_reg_clear_bits(mfd, reg, LDO_ST_ON_BIT); |
518fb721d TPS65910: Add tps... |
378 379 380 381 382 383 384 385 |
} return -EINVAL; } static unsigned int tps65910_get_mode(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
faa95fde4 regulator: tps659... |
386 |
int ret, reg, value, id = rdev_get_id(dev); |
518fb721d TPS65910: Add tps... |
387 |
|
a320e3c3d regulator: tps659... |
388 |
reg = pmic->get_ctrl_reg(id); |
518fb721d TPS65910: Add tps... |
389 390 |
if (reg < 0) return reg; |
faa95fde4 regulator: tps659... |
391 392 393 |
ret = tps65910_reg_read(pmic->mfd, reg, &value); if (ret < 0) return ret; |
518fb721d TPS65910: Add tps... |
394 |
|
585993932 regulator: Fix th... |
395 |
if (!(value & LDO_ST_ON_BIT)) |
518fb721d TPS65910: Add tps... |
396 397 398 399 400 401 |
return REGULATOR_MODE_STANDBY; else if (value & LDO_ST_MODE_BIT) return REGULATOR_MODE_IDLE; else return REGULATOR_MODE_NORMAL; } |
18039e0f1 regulator: tps659... |
402 |
static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) |
518fb721d TPS65910: Add tps... |
403 404 |
{ struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
faa95fde4 regulator: tps659... |
405 |
int ret, id = rdev_get_id(dev); |
a320e3c3d regulator: tps659... |
406 |
int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; |
518fb721d TPS65910: Add tps... |
407 408 409 |
switch (id) { case TPS65910_REG_VDD1: |
faa95fde4 regulator: tps659... |
410 411 412 413 414 415 |
ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_OP, &opvsel); if (ret < 0) return ret; ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1, &mult); if (ret < 0) return ret; |
518fb721d TPS65910: Add tps... |
416 |
mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT; |
faa95fde4 regulator: tps659... |
417 418 419 |
ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_SR, &srvsel); if (ret < 0) return ret; |
518fb721d TPS65910: Add tps... |
420 421 422 |
sr = opvsel & VDD1_OP_CMD_MASK; opvsel &= VDD1_OP_SEL_MASK; srvsel &= VDD1_SR_SEL_MASK; |
a320e3c3d regulator: tps659... |
423 |
vselmax = 75; |
518fb721d TPS65910: Add tps... |
424 425 |
break; case TPS65910_REG_VDD2: |
faa95fde4 regulator: tps659... |
426 427 428 429 430 431 |
ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_OP, &opvsel); if (ret < 0) return ret; ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2, &mult); if (ret < 0) return ret; |
518fb721d TPS65910: Add tps... |
432 |
mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT; |
faa95fde4 regulator: tps659... |
433 434 435 |
ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_SR, &srvsel); if (ret < 0) return ret; |
518fb721d TPS65910: Add tps... |
436 437 438 |
sr = opvsel & VDD2_OP_CMD_MASK; opvsel &= VDD2_OP_SEL_MASK; srvsel &= VDD2_SR_SEL_MASK; |
a320e3c3d regulator: tps659... |
439 440 441 |
vselmax = 75; break; case TPS65911_REG_VDDCTRL: |
faa95fde4 regulator: tps659... |
442 443 444 445 446 447 448 449 |
ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_OP, &opvsel); if (ret < 0) return ret; ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_SR, &srvsel); if (ret < 0) return ret; |
a320e3c3d regulator: tps659... |
450 451 452 453 |
sr = opvsel & VDDCTRL_OP_CMD_MASK; opvsel &= VDDCTRL_OP_SEL_MASK; srvsel &= VDDCTRL_SR_SEL_MASK; vselmax = 64; |
518fb721d TPS65910: Add tps... |
454 455 456 457 458 459 460 461 |
break; } /* multiplier 0 == 1 but 2,3 normal */ if (!mult) mult=1; if (sr) { |
a320e3c3d regulator: tps659... |
462 463 464 465 466 |
/* normalise to valid range */ if (srvsel < 3) srvsel = 3; if (srvsel > vselmax) srvsel = vselmax; |
18039e0f1 regulator: tps659... |
467 |
return srvsel - 3; |
518fb721d TPS65910: Add tps... |
468 |
} else { |
a320e3c3d regulator: tps659... |
469 470 471 472 473 |
/* normalise to valid range*/ if (opvsel < 3) opvsel = 3; if (opvsel > vselmax) opvsel = vselmax; |
18039e0f1 regulator: tps659... |
474 |
return opvsel - 3; |
518fb721d TPS65910: Add tps... |
475 |
} |
18039e0f1 regulator: tps659... |
476 |
return -EINVAL; |
518fb721d TPS65910: Add tps... |
477 |
} |
1f904fd1c regulator: tps659... |
478 |
static int tps65910_get_voltage_sel(struct regulator_dev *dev) |
518fb721d TPS65910: Add tps... |
479 480 |
{ struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
faa95fde4 regulator: tps659... |
481 |
int ret, reg, value, id = rdev_get_id(dev); |
518fb721d TPS65910: Add tps... |
482 |
|
a320e3c3d regulator: tps659... |
483 |
reg = pmic->get_ctrl_reg(id); |
518fb721d TPS65910: Add tps... |
484 485 |
if (reg < 0) return reg; |
faa95fde4 regulator: tps659... |
486 487 488 |
ret = tps65910_reg_read(pmic->mfd, reg, &value); if (ret < 0) return ret; |
518fb721d TPS65910: Add tps... |
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
switch (id) { case TPS65910_REG_VIO: case TPS65910_REG_VDIG1: case TPS65910_REG_VDIG2: case TPS65910_REG_VPLL: case TPS65910_REG_VDAC: case TPS65910_REG_VAUX1: case TPS65910_REG_VAUX2: case TPS65910_REG_VAUX33: case TPS65910_REG_VMMC: value &= LDO_SEL_MASK; value >>= LDO_SEL_SHIFT; break; default: return -EINVAL; } |
1f904fd1c regulator: tps659... |
506 |
return value; |
518fb721d TPS65910: Add tps... |
507 508 509 510 |
} static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) { |
d9fe28f96 regulator: tps659... |
511 |
return dev->desc->volt_table[0]; |
518fb721d TPS65910: Add tps... |
512 |
} |
1f904fd1c regulator: tps659... |
513 |
static int tps65911_get_voltage_sel(struct regulator_dev *dev) |
a320e3c3d regulator: tps659... |
514 515 |
{ struct tps65910_reg *pmic = rdev_get_drvdata(dev); |
faa95fde4 regulator: tps659... |
516 517 |
int ret, id = rdev_get_id(dev); unsigned int value, reg; |
a320e3c3d regulator: tps659... |
518 519 |
reg = pmic->get_ctrl_reg(id); |
faa95fde4 regulator: tps659... |
520 521 522 |
ret = tps65910_reg_read(pmic->mfd, reg, &value); if (ret < 0) return ret; |
a320e3c3d regulator: tps659... |
523 524 525 526 527 528 529 |
switch (id) { case TPS65911_REG_LDO1: case TPS65911_REG_LDO2: case TPS65911_REG_LDO4: value &= LDO1_SEL_MASK; value >>= LDO_SEL_SHIFT; |
a320e3c3d regulator: tps659... |
530 531 532 533 534 535 536 537 |
break; case TPS65911_REG_LDO3: case TPS65911_REG_LDO5: case TPS65911_REG_LDO6: case TPS65911_REG_LDO7: case TPS65911_REG_LDO8: value &= LDO3_SEL_MASK; value >>= LDO_SEL_SHIFT; |
a320e3c3d regulator: tps659... |
538 539 |
break; case TPS65910_REG_VIO: |
e882eae80 regulator: tps659... |
540 541 |
value &= LDO_SEL_MASK; value >>= LDO_SEL_SHIFT; |
1f904fd1c regulator: tps659... |
542 |
break; |
a320e3c3d regulator: tps659... |
543 544 545 |
default: return -EINVAL; } |
1f904fd1c regulator: tps659... |
546 |
return value; |
a320e3c3d regulator: tps659... |
547 |
} |
94732b97c regulator: Rename... |
548 549 |
static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, unsigned selector) |
518fb721d TPS65910: Add tps... |
550 551 552 |
{ struct tps65910_reg *pmic = rdev_get_drvdata(dev); int id = rdev_get_id(dev), vsel; |
a320e3c3d regulator: tps659... |
553 |
int dcdc_mult = 0; |
518fb721d TPS65910: Add tps... |
554 |
|
a320e3c3d regulator: tps659... |
555 556 |
switch (id) { case TPS65910_REG_VDD1: |
780dc9ba4 regulator: TPS659... |
557 |
dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; |
a320e3c3d regulator: tps659... |
558 559 |
if (dcdc_mult == 1) dcdc_mult--; |
780dc9ba4 regulator: TPS659... |
560 |
vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; |
518fb721d TPS65910: Add tps... |
561 |
|
faa95fde4 regulator: tps659... |
562 563 564 565 |
tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD1, VDD1_VGAIN_SEL_MASK, dcdc_mult << VDD1_VGAIN_SEL_SHIFT); tps65910_reg_write(pmic->mfd, TPS65910_VDD1_OP, vsel); |
a320e3c3d regulator: tps659... |
566 567 |
break; case TPS65910_REG_VDD2: |
780dc9ba4 regulator: TPS659... |
568 |
dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; |
a320e3c3d regulator: tps659... |
569 570 |
if (dcdc_mult == 1) dcdc_mult--; |
780dc9ba4 regulator: TPS659... |
571 |
vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; |
a320e3c3d regulator: tps659... |
572 |
|
faa95fde4 regulator: tps659... |
573 574 575 576 |
tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD2, VDD1_VGAIN_SEL_MASK, dcdc_mult << VDD2_VGAIN_SEL_SHIFT); tps65910_reg_write(pmic->mfd, TPS65910_VDD2_OP, vsel); |
a320e3c3d regulator: tps659... |
577 578 |
break; case TPS65911_REG_VDDCTRL: |
c4632aed3 regulator: tps659... |
579 |
vsel = selector + 3; |
faa95fde4 regulator: tps659... |
580 |
tps65910_reg_write(pmic->mfd, TPS65911_VDDCTRL_OP, vsel); |
518fb721d TPS65910: Add tps... |
581 582 583 584 |
} return 0; } |
94732b97c regulator: Rename... |
585 586 |
static int tps65910_set_voltage_sel(struct regulator_dev *dev, unsigned selector) |
518fb721d TPS65910: Add tps... |
587 588 589 |
{ struct tps65910_reg *pmic = rdev_get_drvdata(dev); int reg, id = rdev_get_id(dev); |
a320e3c3d regulator: tps659... |
590 |
reg = pmic->get_ctrl_reg(id); |
518fb721d TPS65910: Add tps... |
591 592 593 594 595 596 597 598 599 600 601 602 603 |
if (reg < 0) return reg; switch (id) { case TPS65910_REG_VIO: case TPS65910_REG_VDIG1: case TPS65910_REG_VDIG2: case TPS65910_REG_VPLL: case TPS65910_REG_VDAC: case TPS65910_REG_VAUX1: case TPS65910_REG_VAUX2: case TPS65910_REG_VAUX33: case TPS65910_REG_VMMC: |
faa95fde4 regulator: tps659... |
604 605 |
return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK, selector << LDO_SEL_SHIFT); |
518fb721d TPS65910: Add tps... |
606 607 608 609 |
} return -EINVAL; } |
94732b97c regulator: Rename... |
610 611 |
static int tps65911_set_voltage_sel(struct regulator_dev *dev, unsigned selector) |
a320e3c3d regulator: tps659... |
612 613 614 615 616 617 618 619 620 621 622 623 |
{ struct tps65910_reg *pmic = rdev_get_drvdata(dev); int reg, id = rdev_get_id(dev); reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; switch (id) { case TPS65911_REG_LDO1: case TPS65911_REG_LDO2: case TPS65911_REG_LDO4: |
faa95fde4 regulator: tps659... |
624 625 |
return tps65910_reg_update_bits(pmic->mfd, reg, LDO1_SEL_MASK, selector << LDO_SEL_SHIFT); |
a320e3c3d regulator: tps659... |
626 627 628 629 630 |
case TPS65911_REG_LDO3: case TPS65911_REG_LDO5: case TPS65911_REG_LDO6: case TPS65911_REG_LDO7: case TPS65911_REG_LDO8: |
faa95fde4 regulator: tps659... |
631 632 |
return tps65910_reg_update_bits(pmic->mfd, reg, LDO3_SEL_MASK, selector << LDO_SEL_SHIFT); |
e882eae80 regulator: tps659... |
633 |
case TPS65910_REG_VIO: |
faa95fde4 regulator: tps659... |
634 635 |
return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK, selector << LDO_SEL_SHIFT); |
a320e3c3d regulator: tps659... |
636 637 638 639 |
} return -EINVAL; } |
518fb721d TPS65910: Add tps... |
640 641 642 |
static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, unsigned selector) { |
a320e3c3d regulator: tps659... |
643 |
int volt, mult = 1, id = rdev_get_id(dev); |
518fb721d TPS65910: Add tps... |
644 |
|
a320e3c3d regulator: tps659... |
645 646 647 |
switch (id) { case TPS65910_REG_VDD1: case TPS65910_REG_VDD2: |
780dc9ba4 regulator: TPS659... |
648 |
mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; |
a320e3c3d regulator: tps659... |
649 |
volt = VDD1_2_MIN_VOLT + |
780dc9ba4 regulator: TPS659... |
650 |
(selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET; |
d04156bca regulator: tps659... |
651 |
break; |
a320e3c3d regulator: tps659... |
652 653 |
case TPS65911_REG_VDDCTRL: volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); |
d04156bca regulator: tps659... |
654 655 656 657 |
break; default: BUG(); return -EINVAL; |
a320e3c3d regulator: tps659... |
658 |
} |
518fb721d TPS65910: Add tps... |
659 660 661 |
return volt * 100 * mult; } |
a320e3c3d regulator: tps659... |
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 |
static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); int step_mv = 0, id = rdev_get_id(dev); switch(id) { case TPS65911_REG_LDO1: case TPS65911_REG_LDO2: case TPS65911_REG_LDO4: /* The first 5 values of the selector correspond to 1V */ if (selector < 5) selector = 0; else selector -= 4; step_mv = 50; break; case TPS65911_REG_LDO3: case TPS65911_REG_LDO5: case TPS65911_REG_LDO6: case TPS65911_REG_LDO7: case TPS65911_REG_LDO8: /* The first 3 values of the selector correspond to 1V */ if (selector < 3) selector = 0; else selector -= 2; step_mv = 100; break; case TPS65910_REG_VIO: |
d9fe28f96 regulator: tps659... |
693 |
return pmic->info[id]->voltage_table[selector]; |
a320e3c3d regulator: tps659... |
694 695 696 697 698 699 |
default: return -EINVAL; } return (LDO_MIN_VOLT + selector * step_mv) * 1000; } |
518fb721d TPS65910: Add tps... |
700 701 |
/* Regulator ops (except VRTC) */ static struct regulator_ops tps65910_ops_dcdc = { |
a40a9c436 regulator: tps659... |
702 703 704 |
.is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, |
518fb721d TPS65910: Add tps... |
705 706 |
.set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, |
18039e0f1 regulator: tps659... |
707 |
.get_voltage_sel = tps65910_get_voltage_dcdc_sel, |
94732b97c regulator: Rename... |
708 |
.set_voltage_sel = tps65910_set_voltage_dcdc_sel, |
01bc3a140 regulator: tps659... |
709 |
.set_voltage_time_sel = regulator_set_voltage_time_sel, |
518fb721d TPS65910: Add tps... |
710 711 712 713 |
.list_voltage = tps65910_list_voltage_dcdc, }; static struct regulator_ops tps65910_ops_vdd3 = { |
a40a9c436 regulator: tps659... |
714 715 716 |
.is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, |
518fb721d TPS65910: Add tps... |
717 718 719 |
.set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, .get_voltage = tps65910_get_voltage_vdd3, |
d9fe28f96 regulator: tps659... |
720 |
.list_voltage = regulator_list_voltage_table, |
518fb721d TPS65910: Add tps... |
721 722 723 |
}; static struct regulator_ops tps65910_ops = { |
a40a9c436 regulator: tps659... |
724 725 726 |
.is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, |
518fb721d TPS65910: Add tps... |
727 728 |
.set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, |
1f904fd1c regulator: tps659... |
729 |
.get_voltage_sel = tps65910_get_voltage_sel, |
94732b97c regulator: Rename... |
730 |
.set_voltage_sel = tps65910_set_voltage_sel, |
d9fe28f96 regulator: tps659... |
731 |
.list_voltage = regulator_list_voltage_table, |
518fb721d TPS65910: Add tps... |
732 |
}; |
a320e3c3d regulator: tps659... |
733 |
static struct regulator_ops tps65911_ops = { |
a40a9c436 regulator: tps659... |
734 735 736 |
.is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, |
a320e3c3d regulator: tps659... |
737 738 |
.set_mode = tps65910_set_mode, .get_mode = tps65910_get_mode, |
1f904fd1c regulator: tps659... |
739 |
.get_voltage_sel = tps65911_get_voltage_sel, |
94732b97c regulator: Rename... |
740 |
.set_voltage_sel = tps65911_set_voltage_sel, |
a320e3c3d regulator: tps659... |
741 742 |
.list_voltage = tps65911_list_voltage, }; |
1e0c66f49 regulator: tps659... |
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 |
static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, int id, int ext_sleep_config) { struct tps65910 *mfd = pmic->mfd; u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF; u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF); int ret; /* * Regulator can not be control from multiple external input EN1, EN2 * and EN3 together. */ if (ext_sleep_config & EXT_SLEEP_CONTROL) { int en_count; en_count = ((ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0); en_count += ((ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0); en_count += ((ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0); |
f30b0716f regulator: tps659... |
763 764 |
en_count += ((ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) != 0); |
1e0c66f49 regulator: tps659... |
765 766 767 768 769 770 771 772 773 774 775 776 |
if (en_count > 1) { dev_err(mfd->dev, "External sleep control flag is not proper "); return -EINVAL; } } pmic->board_ext_control[id] = ext_sleep_config; /* External EN1 control */ if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) |
3f7e82759 mfd: Commonize tp... |
777 |
ret = tps65910_reg_set_bits(mfd, |
1e0c66f49 regulator: tps659... |
778 779 |
TPS65910_EN1_LDO_ASS + regoffs, bit_pos); else |
3f7e82759 mfd: Commonize tp... |
780 |
ret = tps65910_reg_clear_bits(mfd, |
1e0c66f49 regulator: tps659... |
781 782 783 784 785 786 787 788 789 790 |
TPS65910_EN1_LDO_ASS + regoffs, bit_pos); if (ret < 0) { dev_err(mfd->dev, "Error in configuring external control EN1 "); return ret; } /* External EN2 control */ if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) |
3f7e82759 mfd: Commonize tp... |
791 |
ret = tps65910_reg_set_bits(mfd, |
1e0c66f49 regulator: tps659... |
792 793 |
TPS65910_EN2_LDO_ASS + regoffs, bit_pos); else |
3f7e82759 mfd: Commonize tp... |
794 |
ret = tps65910_reg_clear_bits(mfd, |
1e0c66f49 regulator: tps659... |
795 796 797 798 799 800 801 802 803 804 805 806 |
TPS65910_EN2_LDO_ASS + regoffs, bit_pos); if (ret < 0) { dev_err(mfd->dev, "Error in configuring external control EN2 "); return ret; } /* External EN3 control for TPS65910 LDO only */ if ((tps65910_chip_id(mfd) == TPS65910) && (id >= TPS65910_REG_VDIG1)) { if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) |
3f7e82759 mfd: Commonize tp... |
807 |
ret = tps65910_reg_set_bits(mfd, |
1e0c66f49 regulator: tps659... |
808 809 |
TPS65910_EN3_LDO_ASS + regoffs, bit_pos); else |
3f7e82759 mfd: Commonize tp... |
810 |
ret = tps65910_reg_clear_bits(mfd, |
1e0c66f49 regulator: tps659... |
811 812 813 814 815 816 817 818 819 820 821 822 |
TPS65910_EN3_LDO_ASS + regoffs, bit_pos); if (ret < 0) { dev_err(mfd->dev, "Error in configuring external control EN3 "); return ret; } } /* Return if no external control is selected */ if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) { /* Clear all sleep controls */ |
3f7e82759 mfd: Commonize tp... |
823 |
ret = tps65910_reg_clear_bits(mfd, |
1e0c66f49 regulator: tps659... |
824 825 |
TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); if (!ret) |
3f7e82759 mfd: Commonize tp... |
826 |
ret = tps65910_reg_clear_bits(mfd, |
1e0c66f49 regulator: tps659... |
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 |
TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); if (ret < 0) dev_err(mfd->dev, "Error in configuring SLEEP register "); return ret; } /* * For regulator that has separate operational and sleep register make * sure that operational is used and clear sleep register to turn * regulator off when external control is inactive */ if ((id == TPS65910_REG_VDD1) || (id == TPS65910_REG_VDD2) || ((id == TPS65911_REG_VDDCTRL) && (tps65910_chip_id(mfd) == TPS65911))) { int op_reg_add = pmic->get_ctrl_reg(id) + 1; int sr_reg_add = pmic->get_ctrl_reg(id) + 2; |
faa95fde4 regulator: tps659... |
846 847 848 849 850 851 852 853 |
int opvsel, srvsel; ret = tps65910_reg_read(pmic->mfd, op_reg_add, &opvsel); if (ret < 0) return ret; ret = tps65910_reg_read(pmic->mfd, sr_reg_add, &srvsel); if (ret < 0) return ret; |
1e0c66f49 regulator: tps659... |
854 855 |
if (opvsel & VDD1_OP_CMD_MASK) { u8 reg_val = srvsel & VDD1_OP_SEL_MASK; |
faa95fde4 regulator: tps659... |
856 857 858 |
ret = tps65910_reg_write(pmic->mfd, op_reg_add, reg_val); |
1e0c66f49 regulator: tps659... |
859 860 861 862 863 864 865 |
if (ret < 0) { dev_err(mfd->dev, "Error in configuring op register "); return ret; } } |
faa95fde4 regulator: tps659... |
866 |
ret = tps65910_reg_write(pmic->mfd, sr_reg_add, 0); |
1e0c66f49 regulator: tps659... |
867 868 869 870 871 872 |
if (ret < 0) { dev_err(mfd->dev, "Error in settting sr register "); return ret; } } |
3f7e82759 mfd: Commonize tp... |
873 |
ret = tps65910_reg_clear_bits(mfd, |
1e0c66f49 regulator: tps659... |
874 |
TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); |
f30b0716f regulator: tps659... |
875 876 |
if (!ret) { if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) |
3f7e82759 mfd: Commonize tp... |
877 |
ret = tps65910_reg_set_bits(mfd, |
f30b0716f regulator: tps659... |
878 879 |
TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); else |
3f7e82759 mfd: Commonize tp... |
880 |
ret = tps65910_reg_clear_bits(mfd, |
f30b0716f regulator: tps659... |
881 882 |
TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); } |
1e0c66f49 regulator: tps659... |
883 884 885 886 |
if (ret < 0) dev_err(mfd->dev, "Error in configuring SLEEP register "); |
f30b0716f regulator: tps659... |
887 |
|
1e0c66f49 regulator: tps659... |
888 889 |
return ret; } |
6790178f5 regulator: tps659... |
890 891 892 |
#ifdef CONFIG_OF static struct of_regulator_match tps65910_matches[] = { |
33a6943d2 regulator: tps659... |
893 894 895 896 897 898 899 900 901 902 903 904 905 |
{ .name = "vrtc", .driver_data = (void *) &tps65910_regs[0] }, { .name = "vio", .driver_data = (void *) &tps65910_regs[1] }, { .name = "vdd1", .driver_data = (void *) &tps65910_regs[2] }, { .name = "vdd2", .driver_data = (void *) &tps65910_regs[3] }, { .name = "vdd3", .driver_data = (void *) &tps65910_regs[4] }, { .name = "vdig1", .driver_data = (void *) &tps65910_regs[5] }, { .name = "vdig2", .driver_data = (void *) &tps65910_regs[6] }, { .name = "vpll", .driver_data = (void *) &tps65910_regs[7] }, { .name = "vdac", .driver_data = (void *) &tps65910_regs[8] }, { .name = "vaux1", .driver_data = (void *) &tps65910_regs[9] }, { .name = "vaux2", .driver_data = (void *) &tps65910_regs[10] }, { .name = "vaux33", .driver_data = (void *) &tps65910_regs[11] }, { .name = "vmmc", .driver_data = (void *) &tps65910_regs[12] }, |
6790178f5 regulator: tps659... |
906 907 908 |
}; static struct of_regulator_match tps65911_matches[] = { |
33a6943d2 regulator: tps659... |
909 910 911 912 913 914 915 916 917 918 919 920 921 |
{ .name = "vrtc", .driver_data = (void *) &tps65911_regs[0] }, { .name = "vio", .driver_data = (void *) &tps65911_regs[1] }, { .name = "vdd1", .driver_data = (void *) &tps65911_regs[2] }, { .name = "vdd2", .driver_data = (void *) &tps65911_regs[3] }, { .name = "vddctrl", .driver_data = (void *) &tps65911_regs[4] }, { .name = "ldo1", .driver_data = (void *) &tps65911_regs[5] }, { .name = "ldo2", .driver_data = (void *) &tps65911_regs[6] }, { .name = "ldo3", .driver_data = (void *) &tps65911_regs[7] }, { .name = "ldo4", .driver_data = (void *) &tps65911_regs[8] }, { .name = "ldo5", .driver_data = (void *) &tps65911_regs[9] }, { .name = "ldo6", .driver_data = (void *) &tps65911_regs[10] }, { .name = "ldo7", .driver_data = (void *) &tps65911_regs[11] }, { .name = "ldo8", .driver_data = (void *) &tps65911_regs[12] }, |
6790178f5 regulator: tps659... |
922 923 924 |
}; static struct tps65910_board *tps65910_parse_dt_reg_data( |
84df8c124 regulator: tps659... |
925 926 |
struct platform_device *pdev, struct of_regulator_match **tps65910_reg_matches) |
6790178f5 regulator: tps659... |
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 |
{ struct tps65910_board *pmic_plat_data; struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); struct device_node *np = pdev->dev.parent->of_node; struct device_node *regulators; struct of_regulator_match *matches; unsigned int prop; int idx = 0, ret, count; pmic_plat_data = devm_kzalloc(&pdev->dev, sizeof(*pmic_plat_data), GFP_KERNEL); if (!pmic_plat_data) { dev_err(&pdev->dev, "Failure to alloc pdata for regulators. "); return NULL; } regulators = of_find_node_by_name(np, "regulators"); |
92ab953bd regulator: tps659... |
946 947 948 949 950 |
if (!regulators) { dev_err(&pdev->dev, "regulator node not found "); return NULL; } |
6790178f5 regulator: tps659... |
951 952 953 954 955 956 957 958 959 960 961 |
switch (tps65910_chip_id(tps65910)) { case TPS65910: count = ARRAY_SIZE(tps65910_matches); matches = tps65910_matches; break; case TPS65911: count = ARRAY_SIZE(tps65911_matches); matches = tps65911_matches; break; default: |
7e9a57e62 regulator: tps659... |
962 963 |
dev_err(&pdev->dev, "Invalid tps chip version "); |
6790178f5 regulator: tps659... |
964 965 966 967 968 969 970 971 972 973 |
return NULL; } ret = of_regulator_match(pdev->dev.parent, regulators, matches, count); if (ret < 0) { dev_err(&pdev->dev, "Error parsing regulator init data: %d ", ret); return NULL; } |
84df8c124 regulator: tps659... |
974 |
*tps65910_reg_matches = matches; |
6790178f5 regulator: tps659... |
975 976 977 978 979 980 981 982 983 984 985 |
for (idx = 0; idx < count; idx++) { if (!matches[idx].init_data || !matches[idx].of_node) continue; pmic_plat_data->tps65910_pmic_init_data[idx] = matches[idx].init_data; ret = of_property_read_u32(matches[idx].of_node, "ti,regulator-ext-sleep-control", &prop); if (!ret) pmic_plat_data->regulator_ext_sleep_control[idx] = prop; |
19228a6a5 regulator: tps659... |
986 |
|
6790178f5 regulator: tps659... |
987 988 989 990 991 992 |
} return pmic_plat_data; } #else static inline struct tps65910_board *tps65910_parse_dt_reg_data( |
84df8c124 regulator: tps659... |
993 994 |
struct platform_device *pdev, struct of_regulator_match **tps65910_reg_matches) |
6790178f5 regulator: tps659... |
995 |
{ |
84df8c124 regulator: tps659... |
996 |
*tps65910_reg_matches = NULL; |
74ea0e599 regulator: tps659... |
997 |
return NULL; |
6790178f5 regulator: tps659... |
998 999 |
} #endif |
518fb721d TPS65910: Add tps... |
1000 1001 1002 |
static __devinit int tps65910_probe(struct platform_device *pdev) { struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); |
c172708d3 regulator: core: ... |
1003 |
struct regulator_config config = { }; |
a320e3c3d regulator: tps659... |
1004 |
struct tps_info *info; |
518fb721d TPS65910: Add tps... |
1005 1006 1007 1008 |
struct regulator_init_data *reg_data; struct regulator_dev *rdev; struct tps65910_reg *pmic; struct tps65910_board *pmic_plat_data; |
84df8c124 regulator: tps659... |
1009 |
struct of_regulator_match *tps65910_reg_matches = NULL; |
518fb721d TPS65910: Add tps... |
1010 1011 1012 |
int i, err; pmic_plat_data = dev_get_platdata(tps65910->dev); |
6790178f5 regulator: tps659... |
1013 |
if (!pmic_plat_data && tps65910->dev->of_node) |
84df8c124 regulator: tps659... |
1014 1015 |
pmic_plat_data = tps65910_parse_dt_reg_data(pdev, &tps65910_reg_matches); |
6790178f5 regulator: tps659... |
1016 |
|
7e9a57e62 regulator: tps659... |
1017 1018 1019 |
if (!pmic_plat_data) { dev_err(&pdev->dev, "Platform data not found "); |
518fb721d TPS65910: Add tps... |
1020 |
return -EINVAL; |
7e9a57e62 regulator: tps659... |
1021 |
} |
518fb721d TPS65910: Add tps... |
1022 |
|
9eb0c4218 regulator: Conver... |
1023 |
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); |
7e9a57e62 regulator: tps659... |
1024 1025 1026 |
if (!pmic) { dev_err(&pdev->dev, "Memory allocation failed for pmic "); |
518fb721d TPS65910: Add tps... |
1027 |
return -ENOMEM; |
7e9a57e62 regulator: tps659... |
1028 |
} |
518fb721d TPS65910: Add tps... |
1029 |
|
518fb721d TPS65910: Add tps... |
1030 1031 1032 1033 |
pmic->mfd = tps65910; platform_set_drvdata(pdev, pmic); /* Give control of all register to control port */ |
3f7e82759 mfd: Commonize tp... |
1034 |
tps65910_reg_set_bits(pmic->mfd, TPS65910_DEVCTRL, |
518fb721d TPS65910: Add tps... |
1035 |
DEVCTRL_SR_CTL_I2C_SEL_MASK); |
a320e3c3d regulator: tps659... |
1036 1037 1038 |
switch(tps65910_chip_id(tps65910)) { case TPS65910: pmic->get_ctrl_reg = &tps65910_get_ctrl_register; |
39aa9b6e3 regulator: tps659... |
1039 |
pmic->num_regulators = ARRAY_SIZE(tps65910_regs); |
1e0c66f49 regulator: tps659... |
1040 |
pmic->ext_sleep_control = tps65910_ext_sleep_control; |
a320e3c3d regulator: tps659... |
1041 |
info = tps65910_regs; |
d04156bca regulator: tps659... |
1042 |
break; |
a320e3c3d regulator: tps659... |
1043 1044 |
case TPS65911: pmic->get_ctrl_reg = &tps65911_get_ctrl_register; |
39aa9b6e3 regulator: tps659... |
1045 |
pmic->num_regulators = ARRAY_SIZE(tps65911_regs); |
1e0c66f49 regulator: tps659... |
1046 |
pmic->ext_sleep_control = tps65911_ext_sleep_control; |
a320e3c3d regulator: tps659... |
1047 |
info = tps65911_regs; |
d04156bca regulator: tps659... |
1048 |
break; |
a320e3c3d regulator: tps659... |
1049 |
default: |
7e9a57e62 regulator: tps659... |
1050 1051 |
dev_err(&pdev->dev, "Invalid tps chip version "); |
a320e3c3d regulator: tps659... |
1052 1053 |
return -ENODEV; } |
68d8c1cd5 regulator: tps659... |
1054 |
pmic->desc = devm_kzalloc(&pdev->dev, pmic->num_regulators * |
39aa9b6e3 regulator: tps659... |
1055 1056 |
sizeof(struct regulator_desc), GFP_KERNEL); if (!pmic->desc) { |
68d8c1cd5 regulator: tps659... |
1057 1058 1059 |
dev_err(&pdev->dev, "Memory alloc fails for desc "); return -ENOMEM; |
39aa9b6e3 regulator: tps659... |
1060 |
} |
68d8c1cd5 regulator: tps659... |
1061 |
pmic->info = devm_kzalloc(&pdev->dev, pmic->num_regulators * |
39aa9b6e3 regulator: tps659... |
1062 1063 |
sizeof(struct tps_info *), GFP_KERNEL); if (!pmic->info) { |
68d8c1cd5 regulator: tps659... |
1064 1065 1066 |
dev_err(&pdev->dev, "Memory alloc fails for info "); return -ENOMEM; |
39aa9b6e3 regulator: tps659... |
1067 |
} |
68d8c1cd5 regulator: tps659... |
1068 |
pmic->rdev = devm_kzalloc(&pdev->dev, pmic->num_regulators * |
39aa9b6e3 regulator: tps659... |
1069 1070 |
sizeof(struct regulator_dev *), GFP_KERNEL); if (!pmic->rdev) { |
68d8c1cd5 regulator: tps659... |
1071 1072 1073 |
dev_err(&pdev->dev, "Memory alloc fails for rdev "); return -ENOMEM; |
39aa9b6e3 regulator: tps659... |
1074 |
} |
c1fc14802 regulator: TPS659... |
1075 1076 1077 1078 1079 1080 1081 1082 1083 |
for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS; i++, info++) { reg_data = pmic_plat_data->tps65910_pmic_init_data[i]; /* Regulator API handles empty constraints but not NULL * constraints */ if (!reg_data) continue; |
518fb721d TPS65910: Add tps... |
1084 1085 1086 1087 |
/* Register the regulators */ pmic->info[i] = info; pmic->desc[i].name = info->name; |
d2cfdb055 regulator: tps659... |
1088 |
pmic->desc[i].supply_name = info->vin_name; |
77fa44d0e regulator: Fix de... |
1089 |
pmic->desc[i].id = i; |
7d38a3cb9 regulator: tps659... |
1090 |
pmic->desc[i].n_voltages = info->n_voltages; |
94f48ab32 regulator: tps659... |
1091 |
pmic->desc[i].enable_time = info->enable_time_us; |
518fb721d TPS65910: Add tps... |
1092 |
|
a320e3c3d regulator: tps659... |
1093 |
if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { |
518fb721d TPS65910: Add tps... |
1094 |
pmic->desc[i].ops = &tps65910_ops_dcdc; |
780dc9ba4 regulator: TPS659... |
1095 1096 |
pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE * VDD1_2_NUM_VOLT_COARSE; |
01bc3a140 regulator: tps659... |
1097 |
pmic->desc[i].ramp_delay = 12500; |
a320e3c3d regulator: tps659... |
1098 |
} else if (i == TPS65910_REG_VDD3) { |
01bc3a140 regulator: tps659... |
1099 |
if (tps65910_chip_id(tps65910) == TPS65910) { |
a320e3c3d regulator: tps659... |
1100 |
pmic->desc[i].ops = &tps65910_ops_vdd3; |
d9fe28f96 regulator: tps659... |
1101 |
pmic->desc[i].volt_table = info->voltage_table; |
01bc3a140 regulator: tps659... |
1102 |
} else { |
a320e3c3d regulator: tps659... |
1103 |
pmic->desc[i].ops = &tps65910_ops_dcdc; |
01bc3a140 regulator: tps659... |
1104 1105 |
pmic->desc[i].ramp_delay = 5000; } |
a320e3c3d regulator: tps659... |
1106 |
} else { |
d9fe28f96 regulator: tps659... |
1107 |
if (tps65910_chip_id(tps65910) == TPS65910) { |
a320e3c3d regulator: tps659... |
1108 |
pmic->desc[i].ops = &tps65910_ops; |
d9fe28f96 regulator: tps659... |
1109 1110 |
pmic->desc[i].volt_table = info->voltage_table; } else { |
a320e3c3d regulator: tps659... |
1111 |
pmic->desc[i].ops = &tps65911_ops; |
d9fe28f96 regulator: tps659... |
1112 |
} |
a320e3c3d regulator: tps659... |
1113 |
} |
518fb721d TPS65910: Add tps... |
1114 |
|
1e0c66f49 regulator: tps659... |
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 |
err = tps65910_set_ext_sleep_config(pmic, i, pmic_plat_data->regulator_ext_sleep_control[i]); /* * Failing on regulator for configuring externally control * is not a serious issue, just throw warning. */ if (err < 0) dev_warn(tps65910->dev, "Failed to initialise ext control config "); |
518fb721d TPS65910: Add tps... |
1125 1126 |
pmic->desc[i].type = REGULATOR_VOLTAGE; pmic->desc[i].owner = THIS_MODULE; |
a40a9c436 regulator: tps659... |
1127 1128 |
pmic->desc[i].enable_reg = pmic->get_ctrl_reg(i); pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED; |
518fb721d TPS65910: Add tps... |
1129 |
|
c172708d3 regulator: core: ... |
1130 1131 1132 |
config.dev = tps65910->dev; config.init_data = reg_data; config.driver_data = pmic; |
a40a9c436 regulator: tps659... |
1133 |
config.regmap = tps65910->regmap; |
c172708d3 regulator: core: ... |
1134 |
|
84df8c124 regulator: tps659... |
1135 1136 |
if (tps65910_reg_matches) config.of_node = tps65910_reg_matches[i].of_node; |
6790178f5 regulator: tps659... |
1137 |
|
c172708d3 regulator: core: ... |
1138 |
rdev = regulator_register(&pmic->desc[i], &config); |
518fb721d TPS65910: Add tps... |
1139 1140 1141 1142 1143 1144 |
if (IS_ERR(rdev)) { dev_err(tps65910->dev, "failed to register %s regulator ", pdev->name); err = PTR_ERR(rdev); |
39aa9b6e3 regulator: tps659... |
1145 |
goto err_unregister_regulator; |
518fb721d TPS65910: Add tps... |
1146 1147 1148 1149 1150 1151 |
} /* Save regulator for cleanup */ pmic->rdev[i] = rdev; } return 0; |
39aa9b6e3 regulator: tps659... |
1152 |
err_unregister_regulator: |
518fb721d TPS65910: Add tps... |
1153 1154 |
while (--i >= 0) regulator_unregister(pmic->rdev[i]); |
518fb721d TPS65910: Add tps... |
1155 1156 1157 1158 1159 |
return err; } static int __devexit tps65910_remove(struct platform_device *pdev) { |
39aa9b6e3 regulator: tps659... |
1160 |
struct tps65910_reg *pmic = platform_get_drvdata(pdev); |
518fb721d TPS65910: Add tps... |
1161 |
int i; |
39aa9b6e3 regulator: tps659... |
1162 1163 |
for (i = 0; i < pmic->num_regulators; i++) regulator_unregister(pmic->rdev[i]); |
518fb721d TPS65910: Add tps... |
1164 |
|
518fb721d TPS65910: Add tps... |
1165 1166 |
return 0; } |
1e0c66f49 regulator: tps659... |
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 |
static void tps65910_shutdown(struct platform_device *pdev) { struct tps65910_reg *pmic = platform_get_drvdata(pdev); int i; /* * Before bootloader jumps to kernel, it makes sure that required * external control signals are in desired state so that given rails * can be configure accordingly. * If rails are configured to be controlled from external control * then before shutting down/rebooting the system, the external * control configuration need to be remove from the rails so that * its output will be available as per register programming even * if external controls are removed. This is require when the POR * value of the control signals are not in active state and before * bootloader initializes it, the system requires the rail output * to be active for booting. */ for (i = 0; i < pmic->num_regulators; i++) { int err; if (!pmic->rdev[i]) continue; err = tps65910_set_ext_sleep_config(pmic, i, 0); if (err < 0) dev_err(&pdev->dev, "Error in clearing external control "); } } |
518fb721d TPS65910: Add tps... |
1197 1198 1199 1200 1201 1202 1203 |
static struct platform_driver tps65910_driver = { .driver = { .name = "tps65910-pmic", .owner = THIS_MODULE, }, .probe = tps65910_probe, .remove = __devexit_p(tps65910_remove), |
1e0c66f49 regulator: tps659... |
1204 |
.shutdown = tps65910_shutdown, |
518fb721d TPS65910: Add tps... |
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 |
}; static int __init tps65910_init(void) { return platform_driver_register(&tps65910_driver); } subsys_initcall(tps65910_init); static void __exit tps65910_cleanup(void) { platform_driver_unregister(&tps65910_driver); } module_exit(tps65910_cleanup); MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); |
ae0e65443 regulator: Fix mo... |
1220 |
MODULE_DESCRIPTION("TPS65910/TPS65911 voltage regulator driver"); |
518fb721d TPS65910: Add tps... |
1221 1222 |
MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:tps65910-pmic"); |