xref: /linux/drivers/regulator/cpcap-regulator.c (revision 26fbb4c8c7c3ee9a4c3b4de555a8587b5a19154e)
1 /*
2  * Motorola CPCAP PMIC regulator driver
3  *
4  * Based on cpcap-regulator.c from Motorola Linux kernel tree
5  * Copyright (C) 2009-2011 Motorola, Inc.
6  *
7  * Rewritten for mainline kernel to use device tree and regmap
8  * Copyright (C) 2017 Tony Lindgren <tony@atomide.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
15  * kind, whether express or implied; without even the implied warranty
16  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  */
19 
20 #include <linux/err.h>
21 #include <linux/module.h>
22 #include <linux/of.h>
23 #include <linux/of_platform.h>
24 #include <linux/regmap.h>
25 #include <linux/regulator/driver.h>
26 #include <linux/regulator/machine.h>
27 #include <linux/regulator/of_regulator.h>
28 #include <linux/mfd/motorola-cpcap.h>
29 
30 /*
31  * Resource assignment register bits. These seem to control the state
32  * idle modes adn are used at least for omap4.
33  */
34 
35 /* CPCAP_REG_ASSIGN2 bits - Resource Assignment 2 */
36 #define CPCAP_BIT_VSDIO_SEL		BIT(15)
37 #define CPCAP_BIT_VDIG_SEL		BIT(14)
38 #define CPCAP_BIT_VCAM_SEL		BIT(13)
39 #define CPCAP_BIT_SW6_SEL		BIT(12)
40 #define CPCAP_BIT_SW5_SEL		BIT(11)
41 #define CPCAP_BIT_SW4_SEL		BIT(10)
42 #define CPCAP_BIT_SW3_SEL		BIT(9)
43 #define CPCAP_BIT_SW2_SEL		BIT(8)
44 #define CPCAP_BIT_SW1_SEL		BIT(7)
45 
46 /* CPCAP_REG_ASSIGN3 bits - Resource Assignment 3 */
47 #define CPCAP_BIT_VUSBINT2_SEL		BIT(15)
48 #define CPCAP_BIT_VUSBINT1_SEL		BIT(14)
49 #define CPCAP_BIT_VVIB_SEL		BIT(13)
50 #define CPCAP_BIT_VWLAN1_SEL		BIT(12)
51 #define CPCAP_BIT_VRF1_SEL		BIT(11)
52 #define CPCAP_BIT_VHVIO_SEL		BIT(10)
53 #define CPCAP_BIT_VDAC_SEL		BIT(9)
54 #define CPCAP_BIT_VUSB_SEL		BIT(8)
55 #define CPCAP_BIT_VSIM_SEL		BIT(7)
56 #define CPCAP_BIT_VRFREF_SEL		BIT(6)
57 #define CPCAP_BIT_VPLL_SEL		BIT(5)
58 #define CPCAP_BIT_VFUSE_SEL		BIT(4)
59 #define CPCAP_BIT_VCSI_SEL		BIT(3)
60 #define CPCAP_BIT_SPARE_14_2		BIT(2)
61 #define CPCAP_BIT_VWLAN2_SEL		BIT(1)
62 #define CPCAP_BIT_VRF2_SEL		BIT(0)
63 
64 /* CPCAP_REG_ASSIGN4 bits - Resource Assignment 4 */
65 #define CPCAP_BIT_VAUDIO_SEL		BIT(0)
66 
67 /*
68  * Enable register bits. At least CPCAP_BIT_AUDIO_LOW_PWR is generic,
69  * and not limited to audio regulator. Let's use the Motorola kernel
70  * naming for now until we have a better understanding of the other
71  * enable register bits. No idea why BIT(3) is not defined.
72  */
73 #define CPCAP_BIT_AUDIO_LOW_PWR		BIT(6)
74 #define CPCAP_BIT_AUD_LOWPWR_SPEED	BIT(5)
75 #define CPCAP_BIT_VAUDIOPRISTBY		BIT(4)
76 #define CPCAP_BIT_VAUDIO_MODE1		BIT(2)
77 #define CPCAP_BIT_VAUDIO_MODE0		BIT(1)
78 #define CPCAP_BIT_V_AUDIO_EN		BIT(0)
79 
80 #define CPCAP_BIT_AUDIO_NORMAL_MODE	0x00
81 
82 /*
83  * Off mode configuration bit. Used currently only by SW5 on omap4. There's
84  * the following comment in Motorola Linux kernel tree for it:
85  *
86  * When set in the regulator mode, the regulator assignment will be changed
87  * to secondary when the regulator is disabled. The mode will be set back to
88  * primary when the regulator is turned on.
89  */
90 #define CPCAP_REG_OFF_MODE_SEC		BIT(15)
91 
92 /*
93  * SoC specific configuration for CPCAP regulator. There are at least three
94  * different SoCs each with their own parameters: omap3, omap4 and tegra2.
95  *
96  * The assign_reg and assign_mask seem to allow toggling between primary
97  * and secondary mode that at least omap4 uses for off mode.
98  */
99 struct cpcap_regulator {
100 	struct regulator_desc rdesc;
101 	const u16 assign_reg;
102 	const u16 assign_mask;
103 };
104 
105 #define CPCAP_REG(_ID, reg, assignment_reg, assignment_mask, val_tbl,	\
106 		mode_mask, volt_mask, mode_val, off_val,		\
107 		volt_trans_time) {					\
108 	.rdesc = {							\
109 		.name = #_ID,						\
110 		.of_match = of_match_ptr(#_ID),				\
111 		.ops = &cpcap_regulator_ops,				\
112 		.regulators_node = of_match_ptr("regulators"),		\
113 		.type = REGULATOR_VOLTAGE,				\
114 		.id = CPCAP_##_ID,					\
115 		.owner = THIS_MODULE,					\
116 		.n_voltages = ARRAY_SIZE(val_tbl),			\
117 		.volt_table = (val_tbl),				\
118 		.vsel_reg = (reg),					\
119 		.vsel_mask = (volt_mask),				\
120 		.enable_reg = (reg),					\
121 		.enable_mask = (mode_mask),				\
122 		.enable_val = (mode_val),				\
123 		.disable_val = (off_val),				\
124 		.ramp_delay = (volt_trans_time),			\
125 		.of_map_mode = cpcap_map_mode,				\
126 	},								\
127 	.assign_reg = (assignment_reg),					\
128 	.assign_mask = (assignment_mask),				\
129 }
130 
131 struct cpcap_ddata {
132 	struct regmap *reg;
133 	struct device *dev;
134 	const struct cpcap_regulator *soc;
135 };
136 
137 enum cpcap_regulator_id {
138 	CPCAP_SW1,
139 	CPCAP_SW2,
140 	CPCAP_SW3,
141 	CPCAP_SW4,
142 	CPCAP_SW5,
143 	CPCAP_SW6,
144 	CPCAP_VCAM,
145 	CPCAP_VCSI,
146 	CPCAP_VDAC,
147 	CPCAP_VDIG,
148 	CPCAP_VFUSE,
149 	CPCAP_VHVIO,
150 	CPCAP_VSDIO,
151 	CPCAP_VPLL,
152 	CPCAP_VRF1,
153 	CPCAP_VRF2,
154 	CPCAP_VRFREF,
155 	CPCAP_VWLAN1,
156 	CPCAP_VWLAN2,
157 	CPCAP_VSIM,
158 	CPCAP_VSIMCARD,
159 	CPCAP_VVIB,
160 	CPCAP_VUSB,
161 	CPCAP_VAUDIO,
162 	CPCAP_NR_REGULATORS,
163 };
164 
165 /*
166  * We need to also configure regulator idle mode for SoC off mode if
167  * CPCAP_REG_OFF_MODE_SEC is set.
168  */
169 static int cpcap_regulator_enable(struct regulator_dev *rdev)
170 {
171 	struct cpcap_regulator *regulator = rdev_get_drvdata(rdev);
172 	int error;
173 
174 	error = regulator_enable_regmap(rdev);
175 	if (error)
176 		return error;
177 
178 	if (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC) {
179 		error = regmap_update_bits(rdev->regmap, regulator->assign_reg,
180 					   regulator->assign_mask,
181 					   regulator->assign_mask);
182 		if (error)
183 			regulator_disable_regmap(rdev);
184 	}
185 
186 	return error;
187 }
188 
189 /*
190  * We need to also configure regulator idle mode for SoC off mode if
191  * CPCAP_REG_OFF_MODE_SEC is set.
192  */
193 static int cpcap_regulator_disable(struct regulator_dev *rdev)
194 {
195 	struct cpcap_regulator *regulator = rdev_get_drvdata(rdev);
196 	int error;
197 
198 	if (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC) {
199 		error = regmap_update_bits(rdev->regmap, regulator->assign_reg,
200 					   regulator->assign_mask, 0);
201 		if (error)
202 			return error;
203 	}
204 
205 	error = regulator_disable_regmap(rdev);
206 	if (error && (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC)) {
207 		regmap_update_bits(rdev->regmap, regulator->assign_reg,
208 				   regulator->assign_mask,
209 				   regulator->assign_mask);
210 	}
211 
212 	return error;
213 }
214 
215 static unsigned int cpcap_map_mode(unsigned int mode)
216 {
217 	switch (mode) {
218 	case CPCAP_BIT_AUDIO_NORMAL_MODE:
219 		return REGULATOR_MODE_NORMAL;
220 	case CPCAP_BIT_AUDIO_LOW_PWR:
221 		return REGULATOR_MODE_STANDBY;
222 	default:
223 		return REGULATOR_MODE_INVALID;
224 	}
225 }
226 
227 static unsigned int cpcap_regulator_get_mode(struct regulator_dev *rdev)
228 {
229 	int value;
230 
231 	regmap_read(rdev->regmap, rdev->desc->enable_reg, &value);
232 
233 	if (value & CPCAP_BIT_AUDIO_LOW_PWR)
234 		return REGULATOR_MODE_STANDBY;
235 
236 	return REGULATOR_MODE_NORMAL;
237 }
238 
239 static int cpcap_regulator_set_mode(struct regulator_dev *rdev,
240 				    unsigned int mode)
241 {
242 	int value;
243 
244 	switch (mode) {
245 	case REGULATOR_MODE_NORMAL:
246 		value = CPCAP_BIT_AUDIO_NORMAL_MODE;
247 		break;
248 	case REGULATOR_MODE_STANDBY:
249 		value = CPCAP_BIT_AUDIO_LOW_PWR;
250 		break;
251 	default:
252 		return -EINVAL;
253 	}
254 
255 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
256 				  CPCAP_BIT_AUDIO_LOW_PWR, value);
257 }
258 
259 static const struct regulator_ops cpcap_regulator_ops = {
260 	.enable = cpcap_regulator_enable,
261 	.disable = cpcap_regulator_disable,
262 	.is_enabled = regulator_is_enabled_regmap,
263 	.list_voltage = regulator_list_voltage_table,
264 	.map_voltage = regulator_map_voltage_iterate,
265 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
266 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
267 	.get_mode = cpcap_regulator_get_mode,
268 	.set_mode = cpcap_regulator_set_mode,
269 };
270 
271 static const unsigned int unknown_val_tbl[] = { 0, };
272 static const unsigned int sw2_sw4_val_tbl[] = { 612500, 625000, 637500,
273 						650000, 662500, 675000,
274 						687500, 700000, 712500,
275 						725000, 737500, 750000,
276 						762500, 775000, 787500,
277 						800000, 812500, 825000,
278 						837500, 850000, 862500,
279 						875000, 887500, 900000,
280 						912500, 925000, 937500,
281 						950000, 962500, 975000,
282 						987500, 1000000, 1012500,
283 						1025000, 1037500, 1050000,
284 						1062500, 1075000, 1087500,
285 						1100000, 1112500, 1125000,
286 						1137500, 1150000, 1162500,
287 						1175000, 1187500, 1200000,
288 						1212500, 1225000, 1237500,
289 						1250000, 1262500, 1275000,
290 						1287500, 1300000, 1312500,
291 						1325000, 1337500, 1350000,
292 						1362500, 1375000, 1387500,
293 						1400000, 1412500, 1425000,
294 						1437500, 1450000, 1462500, };
295 static const unsigned int sw5_val_tbl[] = { 0, 5050000, };
296 static const unsigned int vcam_val_tbl[] = { 2600000, 2700000, 2800000,
297 					     2900000, };
298 static const unsigned int vcsi_val_tbl[] = { 1200000, 1800000, };
299 static const unsigned int vdac_val_tbl[] = { 1200000, 1500000, 1800000,
300 					     2500000,};
301 static const unsigned int vdig_val_tbl[] = { 1200000, 1350000, 1500000,
302 					     1875000, };
303 static const unsigned int vfuse_val_tbl[] = { 1500000, 1600000, 1700000,
304 					      1800000, 1900000, 2000000,
305 					      2100000, 2200000, 2300000,
306 					      2400000, 2500000, 2600000,
307 					      2700000, 3150000, };
308 static const unsigned int vhvio_val_tbl[] = { 2775000, };
309 static const unsigned int vsdio_val_tbl[] = { 1500000, 1600000, 1800000,
310 					      2600000, 2700000, 2800000,
311 					      2900000, 3000000, };
312 static const unsigned int vpll_val_tbl[] = { 1200000, 1300000, 1400000,
313 					     1800000, };
314 /* Quirk: 2775000 is before 2500000 for vrf1 regulator */
315 static const unsigned int vrf1_val_tbl[] = { 2775000, 2500000, };
316 static const unsigned int vrf2_val_tbl[] = { 0, 2775000, };
317 static const unsigned int vrfref_val_tbl[] = { 2500000, 2775000, };
318 static const unsigned int vwlan1_val_tbl[] = { 1800000, 1900000, };
319 static const unsigned int vwlan2_val_tbl[] = { 2775000, 3000000, 3300000,
320 					       3300000, };
321 static const unsigned int vsim_val_tbl[] = { 1800000, 2900000, };
322 static const unsigned int vsimcard_val_tbl[] = { 1800000, 2900000, };
323 static const unsigned int vvib_val_tbl[] = { 1300000, 1800000, 2000000,
324 					     3000000, };
325 static const unsigned int vusb_val_tbl[] = { 0, 3300000, };
326 static const unsigned int vaudio_val_tbl[] = { 0, 2775000, };
327 
328 /*
329  * SoC specific configuration for omap4. The data below is comes from Motorola
330  * Linux kernel tree. It's basically the values of cpcap_regltr_data,
331  * cpcap_regulator_mode_values and cpcap_regulator_off_mode_values, see
332  * CPCAP_REG macro above.
333  *
334  * SW1 to SW4 and SW6 seems to be unused for mapphone. Note that VSIM and
335  * VSIMCARD have a shared resource assignment bit.
336  */
337 static const struct cpcap_regulator omap4_regulators[] = {
338 	CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2,
339 		  CPCAP_BIT_SW1_SEL, unknown_val_tbl,
340 		  0, 0, 0, 0, 0),
341 	CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2,
342 		  CPCAP_BIT_SW2_SEL, unknown_val_tbl,
343 		  0, 0, 0, 0, 0),
344 	CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2,
345 		  CPCAP_BIT_SW3_SEL, unknown_val_tbl,
346 		  0, 0, 0, 0, 0),
347 	CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2,
348 		  CPCAP_BIT_SW4_SEL, unknown_val_tbl,
349 		  0, 0, 0, 0, 0),
350 	CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2,
351 		  CPCAP_BIT_SW5_SEL, sw5_val_tbl,
352 		  0x28, 0, 0x20 | CPCAP_REG_OFF_MODE_SEC, 0, 0),
353 	CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2,
354 		  CPCAP_BIT_SW6_SEL, unknown_val_tbl,
355 		  0, 0, 0, 0, 0),
356 	CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2,
357 		  CPCAP_BIT_VCAM_SEL, vcam_val_tbl,
358 		  0x87, 0x30, 0x3, 0, 420),
359 	CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3,
360 		  CPCAP_BIT_VCSI_SEL, vcsi_val_tbl,
361 		  0x47, 0x10, 0x43, 0x41, 350),
362 	CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3,
363 		  CPCAP_BIT_VDAC_SEL, vdac_val_tbl,
364 		  0x87, 0x30, 0x3, 0, 420),
365 	CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2,
366 		  CPCAP_BIT_VDIG_SEL, vdig_val_tbl,
367 		  0x87, 0x30, 0x82, 0, 420),
368 	CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3,
369 		  CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl,
370 		  0x80, 0xf, 0x80, 0, 420),
371 	CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3,
372 		  CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl,
373 		  0x17, 0, 0, 0x12, 0),
374 	CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2,
375 		  CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl,
376 		  0x87, 0x38, 0x82, 0, 420),
377 	CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3,
378 		  CPCAP_BIT_VPLL_SEL, vpll_val_tbl,
379 		  0x43, 0x18, 0x2, 0, 420),
380 	CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3,
381 		  CPCAP_BIT_VRF1_SEL, vrf1_val_tbl,
382 		  0xac, 0x2, 0x4, 0, 10),
383 	CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3,
384 		  CPCAP_BIT_VRF2_SEL, vrf2_val_tbl,
385 		  0x23, 0x8, 0, 0, 10),
386 	CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3,
387 		  CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl,
388 		  0x23, 0x8, 0, 0, 420),
389 	CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3,
390 		  CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl,
391 		  0x47, 0x10, 0, 0, 420),
392 	CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3,
393 		  CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl,
394 		  0x20c, 0xc0, 0x20c, 0, 420),
395 	CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
396 		  0xffff, vsim_val_tbl,
397 		  0x23, 0x8, 0x3, 0, 420),
398 	CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
399 		  0xffff, vsimcard_val_tbl,
400 		  0x1e80, 0x8, 0x1e00, 0, 420),
401 	CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3,
402 		  CPCAP_BIT_VVIB_SEL, vvib_val_tbl,
403 		  0x1, 0xc, 0x1, 0, 500),
404 	CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3,
405 		  CPCAP_BIT_VUSB_SEL, vusb_val_tbl,
406 		  0x11c, 0x40, 0xc, 0, 0),
407 	CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4,
408 		  CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl,
409 		  0x16, 0x1, 0x4, 0, 0),
410 	{ /* sentinel */ },
411 };
412 
413 static const struct cpcap_regulator xoom_regulators[] = {
414 	CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2,
415 		  CPCAP_BIT_SW1_SEL, unknown_val_tbl,
416 		  0, 0, 0, 0, 0),
417 	CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2,
418 		  CPCAP_BIT_SW2_SEL, sw2_sw4_val_tbl,
419 		  0xf00, 0x7f, 0x800, 0, 120),
420 	CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2,
421 		  CPCAP_BIT_SW3_SEL, unknown_val_tbl,
422 		  0, 0, 0, 0, 0),
423 	CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2,
424 		  CPCAP_BIT_SW4_SEL, sw2_sw4_val_tbl,
425 		  0xf00, 0x7f, 0x900, 0, 100),
426 	CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2,
427 		  CPCAP_BIT_SW5_SEL, sw5_val_tbl,
428 		  0x2a, 0, 0x22, 0, 0),
429 	CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2,
430 		  CPCAP_BIT_SW6_SEL, unknown_val_tbl,
431 		  0, 0, 0, 0, 0),
432 	CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2,
433 		  CPCAP_BIT_VCAM_SEL, vcam_val_tbl,
434 		  0x87, 0x30, 0x7, 0, 420),
435 	CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3,
436 		  CPCAP_BIT_VCSI_SEL, vcsi_val_tbl,
437 		  0x47, 0x10, 0x7, 0, 350),
438 	CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3,
439 		  CPCAP_BIT_VDAC_SEL, vdac_val_tbl,
440 		  0x87, 0x30, 0x3, 0, 420),
441 	CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2,
442 		  CPCAP_BIT_VDIG_SEL, vdig_val_tbl,
443 		  0x87, 0x30, 0x5, 0, 420),
444 	CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3,
445 		  CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl,
446 		  0x80, 0xf, 0x80, 0, 420),
447 	CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3,
448 		  CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl,
449 		  0x17, 0, 0x2, 0, 0),
450 	CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2,
451 		  CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl,
452 		  0x87, 0x38, 0x2, 0, 420),
453 	CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3,
454 		  CPCAP_BIT_VPLL_SEL, vpll_val_tbl,
455 		  0x43, 0x18, 0x1, 0, 420),
456 	CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3,
457 		  CPCAP_BIT_VRF1_SEL, vrf1_val_tbl,
458 		  0xac, 0x2, 0xc, 0, 10),
459 	CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3,
460 		  CPCAP_BIT_VRF2_SEL, vrf2_val_tbl,
461 		  0x23, 0x8, 0x3, 0, 10),
462 	CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3,
463 		  CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl,
464 		  0x23, 0x8, 0x3, 0, 420),
465 	CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3,
466 		  CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl,
467 		  0x47, 0x10, 0x5, 0, 420),
468 	CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3,
469 		  CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl,
470 		  0x20c, 0xc0, 0x8, 0, 420),
471 	CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
472 		  0xffff, vsim_val_tbl,
473 		  0x23, 0x8, 0x3, 0, 420),
474 	CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
475 		  0xffff, vsimcard_val_tbl,
476 		  0x1e80, 0x8, 0x1e00, 0, 420),
477 	CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3,
478 		  CPCAP_BIT_VVIB_SEL, vvib_val_tbl,
479 		  0x1, 0xc, 0, 0x1, 500),
480 	CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3,
481 		  CPCAP_BIT_VUSB_SEL, vusb_val_tbl,
482 		  0x11c, 0x40, 0xc, 0, 0),
483 	CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4,
484 		  CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl,
485 		  0x16, 0x1, 0x4, 0, 0),
486 	{ /* sentinel */ },
487 };
488 
489 static const struct of_device_id cpcap_regulator_id_table[] = {
490 	{
491 		.compatible = "motorola,cpcap-regulator",
492 	},
493 	{
494 		.compatible = "motorola,mapphone-cpcap-regulator",
495 		.data = omap4_regulators,
496 	},
497 	{
498 		.compatible = "motorola,xoom-cpcap-regulator",
499 		.data = xoom_regulators,
500 	},
501 	{},
502 };
503 MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table);
504 
505 static int cpcap_regulator_probe(struct platform_device *pdev)
506 {
507 	struct cpcap_ddata *ddata;
508 	const struct cpcap_regulator *match_data;
509 	struct regulator_config config;
510 	int i;
511 
512 	match_data = of_device_get_match_data(&pdev->dev);
513 	if (!match_data) {
514 		dev_err(&pdev->dev, "no configuration data found\n");
515 
516 		return -ENODEV;
517 	}
518 
519 	ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
520 	if (!ddata)
521 		return -ENOMEM;
522 
523 	ddata->reg = dev_get_regmap(pdev->dev.parent, NULL);
524 	if (!ddata->reg)
525 		return -ENODEV;
526 
527 	ddata->dev = &pdev->dev;
528 	ddata->soc = match_data;
529 	platform_set_drvdata(pdev, ddata);
530 
531 	memset(&config, 0, sizeof(config));
532 	config.dev = &pdev->dev;
533 	config.regmap = ddata->reg;
534 
535 	for (i = 0; i < CPCAP_NR_REGULATORS; i++) {
536 		const struct cpcap_regulator *regulator = &ddata->soc[i];
537 		struct regulator_dev *rdev;
538 
539 		if (!regulator->rdesc.name)
540 			break;
541 
542 		if (regulator->rdesc.volt_table == unknown_val_tbl)
543 			continue;
544 
545 		config.driver_data = (void *)regulator;
546 		rdev = devm_regulator_register(&pdev->dev,
547 					       &regulator->rdesc,
548 					       &config);
549 		if (IS_ERR(rdev)) {
550 			dev_err(&pdev->dev, "failed to register regulator %s\n",
551 				regulator->rdesc.name);
552 
553 			return PTR_ERR(rdev);
554 		}
555 	}
556 
557 	return 0;
558 }
559 
560 static struct platform_driver cpcap_regulator_driver = {
561 	.probe		= cpcap_regulator_probe,
562 	.driver		= {
563 		.name	= "cpcap-regulator",
564 		.of_match_table = of_match_ptr(cpcap_regulator_id_table),
565 	},
566 };
567 
568 module_platform_driver(cpcap_regulator_driver);
569 
570 MODULE_ALIAS("platform:cpcap-regulator");
571 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
572 MODULE_DESCRIPTION("CPCAP regulator driver");
573 MODULE_LICENSE("GPL v2");
574