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

source code of linux/drivers/regulator/cpcap-regulator.c