2 * Copyright (C) 2009 Motorola, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/device.h>
23 #include <linux/err.h>
24 #include <linux/platform_device.h>
25 #include <linux/delay.h>
27 #include <linux/regulator/driver.h>
28 #include <linux/regulator/machine.h>
30 #include <linux/spi/spi.h>
31 #include <linux/spi/cpcap.h>
32 #include <linux/spi/cpcap-regbits.h>
34 #define CPCAP_REGULATOR(_name, _id) \
38 .ops = &cpcap_regulator_ops, \
39 .type = REGULATOR_VOLTAGE, \
40 .owner = THIS_MODULE, \
44 static const int sw5_val_tbl[] = {0, 5050000};
45 static const int vcam_val_tbl[] = {2600000, 2700000, 2800000, 2900000};
46 static const int vcsi_val_tbl[] = {1200000, 1800000};
47 static const int vdac_val_tbl[] = {1200000, 1500000, 1800000, 2500000};
48 static const int vdig_val_tbl[] = {1200000, 1350000, 1500000, 1875000};
49 static const int vfuse_val_tbl[] = {1500000, 1600000, 1700000, 1800000, 1900000,
50 2000000, 2100000, 2200000, 2300000, 2400000,
51 2500000, 2600000, 2700000, 3150000};
52 static const int vhvio_val_tbl[] = {2775000};
53 static const int vsdio_val_tbl[] = {1500000, 1600000, 1800000, 2600000,
54 2700000, 2800000, 2900000, 3000000};
55 static const int vpll_val_tbl[] = {1200000, 1300000, 1400000, 1800000};
56 static const int vrf1_val_tbl[] = {2775000, 2500000}; /* Yes, this is correct */
57 static const int vrf2_val_tbl[] = {0, 2775000};
58 static const int vrfref_val_tbl[] = {2500000, 2775000};
59 static const int vwlan1_val_tbl[] = {1800000, 1900000};
60 static const int vwlan2_val_tbl[] = {2775000, 3000000, 3300000, 3300000};
61 static const int vsim_val_tbl[] = {1800000, 2900000};
62 static const int vsimcard_val_tbl[] = {1800000, 2900000};
63 static const int vvib_val_tbl[] = {1300000, 1800000, 2000000, 3000000};
64 static const int vusb_val_tbl[] = {0, 3300000};
65 static const int vaudio_val_tbl[] = {0, 2775000};
68 const enum cpcap_reg reg;
69 const unsigned short mode_mask;
70 const unsigned short volt_mask;
71 const unsigned char volt_shft;
72 unsigned short mode_val;
73 unsigned short off_mode_val;
76 unsigned int mode_cntr;
77 const unsigned int volt_trans_time; /* in micro seconds */
78 const unsigned int turn_on_time; /* in micro seconds */
79 } cpcap_regltr_data[CPCAP_NUM_REGULATORS] = {
80 [CPCAP_SW5] = {CPCAP_REG_S5C,
86 ARRAY_SIZE(sw5_val_tbl),
92 [CPCAP_VCAM] = {CPCAP_REG_VCAMC,
98 ARRAY_SIZE(vcam_val_tbl),
104 [CPCAP_VCSI] = {CPCAP_REG_VCSIC,
110 ARRAY_SIZE(vcsi_val_tbl),
116 [CPCAP_VDAC] = {CPCAP_REG_VDACC,
122 ARRAY_SIZE(vdac_val_tbl),
128 [CPCAP_VDIG] = {CPCAP_REG_VDIGC,
134 ARRAY_SIZE(vdig_val_tbl),
140 [CPCAP_VFUSE] = {CPCAP_REG_VFUSEC,
146 ARRAY_SIZE(vfuse_val_tbl),
152 [CPCAP_VHVIO] = {CPCAP_REG_VHVIOC,
158 ARRAY_SIZE(vhvio_val_tbl),
164 [CPCAP_VSDIO] = {CPCAP_REG_VSDIOC,
170 ARRAY_SIZE(vsdio_val_tbl),
176 [CPCAP_VPLL] = {CPCAP_REG_VPLLC,
182 ARRAY_SIZE(vpll_val_tbl),
188 [CPCAP_VRF1] = {CPCAP_REG_VRF1C,
194 ARRAY_SIZE(vrf1_val_tbl),
200 [CPCAP_VRF2] = {CPCAP_REG_VRF2C,
206 ARRAY_SIZE(vrf2_val_tbl),
212 [CPCAP_VRFREF] = {CPCAP_REG_VRFREFC,
218 ARRAY_SIZE(vrfref_val_tbl),
224 [CPCAP_VWLAN1] = {CPCAP_REG_VWLAN1C,
230 ARRAY_SIZE(vwlan1_val_tbl),
236 [CPCAP_VWLAN2] = {CPCAP_REG_VWLAN2C,
242 ARRAY_SIZE(vwlan2_val_tbl),
248 [CPCAP_VSIM] = {CPCAP_REG_VSIMC,
254 ARRAY_SIZE(vsim_val_tbl),
260 [CPCAP_VSIMCARD] = {CPCAP_REG_VSIMC,
266 ARRAY_SIZE(vsimcard_val_tbl),
272 [CPCAP_VVIB] = {CPCAP_REG_VVIBC,
278 ARRAY_SIZE(vvib_val_tbl),
284 [CPCAP_VUSB] = {CPCAP_REG_VUSBC,
290 ARRAY_SIZE(vusb_val_tbl),
296 [CPCAP_VAUDIO] = {CPCAP_REG_VAUDIOC,
302 ARRAY_SIZE(vaudio_val_tbl),
309 static int cpcap_regulator_set_voltage(struct regulator_dev *rdev,
310 int min_uV, int max_uV)
312 struct cpcap_device *cpcap;
315 enum cpcap_reg regnr;
318 cpcap = rdev_get_drvdata(rdev);
320 regltr_id = rdev_get_id(rdev);
321 if (regltr_id >= CPCAP_NUM_REGULATORS)
324 regnr = cpcap_regltr_data[regltr_id].reg;
326 if (regltr_id == CPCAP_VRF1) {
327 if (min_uV > 2500000)
330 i = cpcap_regltr_data[regltr_id].volt_mask;
332 for (i = 0; i < cpcap_regltr_data[regltr_id].val_tbl_sz; i++)
333 if (cpcap_regltr_data[regltr_id].val_tbl[i] >= min_uV)
336 if (i >= cpcap_regltr_data[regltr_id].val_tbl_sz)
339 i <<= cpcap_regltr_data[regltr_id].volt_shft;
342 retval = cpcap_regacc_write(cpcap, regnr, i,
343 cpcap_regltr_data[regltr_id].volt_mask);
345 if ((cpcap_regltr_data[regltr_id].volt_trans_time) && (retval == 0))
346 udelay(cpcap_regltr_data[regltr_id].volt_trans_time);
351 static int cpcap_regulator_get_voltage(struct regulator_dev *rdev)
353 struct cpcap_device *cpcap;
355 unsigned short volt_bits;
356 enum cpcap_reg regnr;
359 cpcap = rdev_get_drvdata(rdev);
361 regltr_id = rdev_get_id(rdev);
362 if (regltr_id >= CPCAP_NUM_REGULATORS)
365 regnr = cpcap_regltr_data[regltr_id].reg;
367 if (cpcap_regacc_read(cpcap, regnr, &volt_bits) < 0)
370 if (!(volt_bits & cpcap_regltr_data[regltr_id].mode_mask))
373 volt_bits &= cpcap_regltr_data[regltr_id].volt_mask;
374 shift = cpcap_regltr_data[regltr_id].volt_shft;
376 return cpcap_regltr_data[regltr_id].val_tbl[volt_bits >> shift];
379 static int cpcap_regulator_enable(struct regulator_dev *rdev)
381 struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
384 enum cpcap_reg regnr;
386 regltr_id = rdev_get_id(rdev);
387 if (regltr_id >= CPCAP_NUM_REGULATORS)
390 regnr = cpcap_regltr_data[regltr_id].reg;
392 retval = cpcap_regacc_write(cpcap, regnr,
393 cpcap_regltr_data[regltr_id].mode_val,
394 cpcap_regltr_data[regltr_id].mode_mask);
396 if ((cpcap_regltr_data[regltr_id].turn_on_time) && (retval == 0))
397 udelay(cpcap_regltr_data[regltr_id].turn_on_time);
402 static int cpcap_regulator_disable(struct regulator_dev *rdev)
404 struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
406 enum cpcap_reg regnr;
408 regltr_id = rdev_get_id(rdev);
409 if (regltr_id >= CPCAP_NUM_REGULATORS)
412 regnr = cpcap_regltr_data[regltr_id].reg;
414 return cpcap_regacc_write(cpcap, regnr,
415 cpcap_regltr_data[regltr_id].off_mode_val,
416 cpcap_regltr_data[regltr_id].mode_mask);
419 static int cpcap_regulator_is_enabled(struct regulator_dev *rdev)
421 struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
423 enum cpcap_reg regnr;
424 unsigned short value;
426 regltr_id = rdev_get_id(rdev);
427 if (regltr_id >= CPCAP_NUM_REGULATORS)
430 regnr = cpcap_regltr_data[regltr_id].reg;
432 if (cpcap_regacc_read(cpcap, regnr, &value))
435 return (value & cpcap_regltr_data[regltr_id].mode_mask) ? 1 : 0;
438 static int cpcap_regulator_set_mode(struct regulator_dev *rdev,
441 struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
443 enum cpcap_reg regnr;
446 regltr_id = rdev_get_id(rdev);
447 if (regltr_id != CPCAP_VAUDIO)
450 regnr = cpcap_regltr_data[regltr_id].reg;
452 if (mode == REGULATOR_MODE_NORMAL) {
453 if (cpcap_regltr_data[regltr_id].mode_cntr == 0) {
454 ret = cpcap_regacc_write(cpcap, regnr,
456 CPCAP_BIT_AUDIO_LOW_PWR);
459 cpcap_regltr_data[regltr_id].mode_cntr++;
460 } else if (mode == REGULATOR_MODE_STANDBY) {
461 if (cpcap_regltr_data[regltr_id].mode_cntr == 1) {
462 ret = cpcap_regacc_write(cpcap, regnr,
463 CPCAP_BIT_AUDIO_LOW_PWR,
464 CPCAP_BIT_AUDIO_LOW_PWR);
465 } else if (WARN((cpcap_regltr_data[regltr_id].mode_cntr == 0),
466 "Unbalanced modes for supply vaudio\n"))
470 cpcap_regltr_data[regltr_id].mode_cntr--;
476 static struct regulator_ops cpcap_regulator_ops = {
477 .set_voltage = cpcap_regulator_set_voltage,
478 .get_voltage = cpcap_regulator_get_voltage,
479 .enable = cpcap_regulator_enable,
480 .disable = cpcap_regulator_disable,
481 .is_enabled = cpcap_regulator_is_enabled,
482 .set_mode = cpcap_regulator_set_mode,
485 static struct regulator_desc regulators[] = {
486 [CPCAP_SW5] = CPCAP_REGULATOR("sw5", CPCAP_SW5),
487 [CPCAP_VCAM] = CPCAP_REGULATOR("vcam", CPCAP_VCAM),
488 [CPCAP_VCSI] = CPCAP_REGULATOR("vcsi", CPCAP_VCSI),
489 [CPCAP_VDAC] = CPCAP_REGULATOR("vdac", CPCAP_VDAC),
490 [CPCAP_VDIG] = CPCAP_REGULATOR("vdig", CPCAP_VDIG),
491 [CPCAP_VFUSE] = CPCAP_REGULATOR("vfuse", CPCAP_VFUSE),
492 [CPCAP_VHVIO] = CPCAP_REGULATOR("vhvio", CPCAP_VHVIO),
493 [CPCAP_VSDIO] = CPCAP_REGULATOR("vsdio", CPCAP_VSDIO),
494 [CPCAP_VPLL] = CPCAP_REGULATOR("vpll", CPCAP_VPLL),
495 [CPCAP_VRF1] = CPCAP_REGULATOR("vrf1", CPCAP_VRF1),
496 [CPCAP_VRF2] = CPCAP_REGULATOR("vrf2", CPCAP_VRF2),
497 [CPCAP_VRFREF] = CPCAP_REGULATOR("vrfref", CPCAP_VRFREF),
498 [CPCAP_VWLAN1] = CPCAP_REGULATOR("vwlan1", CPCAP_VWLAN1),
499 [CPCAP_VWLAN2] = CPCAP_REGULATOR("vwlan2", CPCAP_VWLAN2),
500 [CPCAP_VSIM] = CPCAP_REGULATOR("vsim", CPCAP_VSIM),
501 [CPCAP_VSIMCARD] = CPCAP_REGULATOR("vsimcard", CPCAP_VSIMCARD),
502 [CPCAP_VVIB] = CPCAP_REGULATOR("vvib", CPCAP_VVIB),
503 [CPCAP_VUSB] = CPCAP_REGULATOR("vusb", CPCAP_VUSB),
504 [CPCAP_VAUDIO] = CPCAP_REGULATOR("vaudio", CPCAP_VAUDIO),
507 static int __devinit cpcap_regulator_probe(struct platform_device *pdev)
509 struct regulator_dev *rdev;
510 struct cpcap_device *cpcap;
511 struct cpcap_platform_data *data;
512 struct regulator_init_data *init;
515 /* Already set by core driver */
516 cpcap = platform_get_drvdata(pdev);
517 data = cpcap->spi->controller_data;
518 init = pdev->dev.platform_data;
520 for (i = 0; i < CPCAP_NUM_REGULATORS; i++) {
521 cpcap_regltr_data[i].mode_val = data->regulator_mode_values[i];
522 cpcap_regltr_data[i].off_mode_val =
523 data->regulator_off_mode_values[i];
526 rdev = regulator_register(®ulators[pdev->id], &pdev->dev,
529 return PTR_ERR(rdev);
530 /* this is ok since the cpcap is still reachable from the rdev */
531 platform_set_drvdata(pdev, rdev);
533 if (pdev->id == CPCAP_SW5) {
534 init = cpcap->regulator_pdev[CPCAP_VUSB]->dev.platform_data;
535 init->supply_regulator_dev = rdev_get_dev(rdev);
536 platform_device_add(cpcap->regulator_pdev[CPCAP_VUSB]);
542 static int __devexit cpcap_regulator_remove(struct platform_device *pdev)
544 struct regulator_dev *rdev = platform_get_drvdata(pdev);
546 regulator_unregister(rdev);
551 static struct platform_driver cpcap_regulator_driver = {
553 .name = "cpcap-regltr",
555 .probe = cpcap_regulator_probe,
556 .remove = __devexit_p(cpcap_regulator_remove),
559 static int __init cpcap_regulator_init(void)
561 return platform_driver_register(&cpcap_regulator_driver);
563 subsys_initcall(cpcap_regulator_init);
565 static void __exit cpcap_regulator_exit(void)
567 platform_driver_unregister(&cpcap_regulator_driver);
569 module_exit(cpcap_regulator_exit);
571 MODULE_ALIAS("platform:cpcap-regulator");
572 MODULE_DESCRIPTION("CPCAP regulator driver");
573 MODULE_AUTHOR("Motorola");
574 MODULE_LICENSE("GPL");