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 #define SW2_SW4_VAL_TBL_SIZE 69
45 #define SW2_SW4_VAL_TBL_STEP 12500
47 static int sw2_sw4_val_tbl[SW2_SW4_VAL_TBL_SIZE];
48 static const int sw5_val_tbl[] = {0, 5050000};
49 static const int vcam_val_tbl[] = {2600000, 2700000, 2800000, 2900000};
50 static const int vcsi_val_tbl[] = {1200000, 1800000};
51 static const int vdac_val_tbl[] = {1200000, 1500000, 1800000, 2500000};
52 static const int vdig_val_tbl[] = {1200000, 1350000, 1500000, 1875000};
53 static const int vfuse_val_tbl[] = {1500000, 1600000, 1700000, 1800000, 1900000,
54 2000000, 2100000, 2200000, 2300000, 2400000,
55 2500000, 2600000, 2700000, 3150000};
56 static const int vhvio_val_tbl[] = {2775000};
57 static const int vsdio_val_tbl[] = {1500000, 1600000, 1800000, 2600000,
58 2700000, 2800000, 2900000, 3000000};
59 static const int vpll_val_tbl[] = {1200000, 1300000, 1400000, 1800000};
60 static const int vrf1_val_tbl[] = {2775000, 2500000}; /* Yes, this is correct */
61 static const int vrf2_val_tbl[] = {0, 2775000};
62 static const int vrfref_val_tbl[] = {2500000, 2775000};
63 static const int vwlan1_val_tbl[] = {1800000, 1900000};
64 static const int vwlan2_val_tbl[] = {2775000, 3000000, 3300000, 3300000};
65 static const int vsim_val_tbl[] = {1800000, 2900000};
66 static const int vsimcard_val_tbl[] = {1800000, 2900000};
67 static const int vvib_val_tbl[] = {1300000, 1800000, 2000000, 3000000};
68 static const int vusb_val_tbl[] = {0, 3300000};
69 static const int vaudio_val_tbl[] = {0, 2775000};
72 const enum cpcap_reg reg;
73 const unsigned short mode_mask;
74 const unsigned short volt_mask;
75 const unsigned char volt_shft;
76 unsigned short mode_val;
77 unsigned short off_mode_val;
80 unsigned int mode_cntr;
81 const unsigned int volt_trans_time; /* in micro seconds */
82 const unsigned int turn_on_time; /* in micro seconds */
83 } cpcap_regltr_data[CPCAP_NUM_REGULATORS] = {
84 [CPCAP_SW2] = {CPCAP_REG_S2C1,
90 ARRAY_SIZE(sw2_sw4_val_tbl),
96 [CPCAP_SW4] = {CPCAP_REG_S4C1,
102 ARRAY_SIZE(sw2_sw4_val_tbl),
108 [CPCAP_SW5] = {CPCAP_REG_S5C,
114 ARRAY_SIZE(sw5_val_tbl),
120 [CPCAP_VCAM] = {CPCAP_REG_VCAMC,
126 ARRAY_SIZE(vcam_val_tbl),
132 [CPCAP_VCSI] = {CPCAP_REG_VCSIC,
138 ARRAY_SIZE(vcsi_val_tbl),
144 [CPCAP_VDAC] = {CPCAP_REG_VDACC,
150 ARRAY_SIZE(vdac_val_tbl),
156 [CPCAP_VDIG] = {CPCAP_REG_VDIGC,
162 ARRAY_SIZE(vdig_val_tbl),
168 [CPCAP_VFUSE] = {CPCAP_REG_VFUSEC,
174 ARRAY_SIZE(vfuse_val_tbl),
180 [CPCAP_VHVIO] = {CPCAP_REG_VHVIOC,
186 ARRAY_SIZE(vhvio_val_tbl),
192 [CPCAP_VSDIO] = {CPCAP_REG_VSDIOC,
198 ARRAY_SIZE(vsdio_val_tbl),
204 [CPCAP_VPLL] = {CPCAP_REG_VPLLC,
210 ARRAY_SIZE(vpll_val_tbl),
216 [CPCAP_VRF1] = {CPCAP_REG_VRF1C,
222 ARRAY_SIZE(vrf1_val_tbl),
228 [CPCAP_VRF2] = {CPCAP_REG_VRF2C,
234 ARRAY_SIZE(vrf2_val_tbl),
240 [CPCAP_VRFREF] = {CPCAP_REG_VRFREFC,
246 ARRAY_SIZE(vrfref_val_tbl),
252 [CPCAP_VWLAN1] = {CPCAP_REG_VWLAN1C,
258 ARRAY_SIZE(vwlan1_val_tbl),
264 [CPCAP_VWLAN2] = {CPCAP_REG_VWLAN2C,
270 ARRAY_SIZE(vwlan2_val_tbl),
276 [CPCAP_VSIM] = {CPCAP_REG_VSIMC,
282 ARRAY_SIZE(vsim_val_tbl),
288 [CPCAP_VSIMCARD] = {CPCAP_REG_VSIMC,
294 ARRAY_SIZE(vsimcard_val_tbl),
300 [CPCAP_VVIB] = {CPCAP_REG_VVIBC,
306 ARRAY_SIZE(vvib_val_tbl),
312 [CPCAP_VUSB] = {CPCAP_REG_VUSBC,
318 ARRAY_SIZE(vusb_val_tbl),
324 [CPCAP_VAUDIO] = {CPCAP_REG_VAUDIOC,
330 ARRAY_SIZE(vaudio_val_tbl),
337 static int cpcap_regulator_set_voltage(struct regulator_dev *rdev,
338 int min_uV, int max_uV)
340 struct cpcap_device *cpcap;
343 enum cpcap_reg regnr;
346 cpcap = rdev_get_drvdata(rdev);
348 regltr_id = rdev_get_id(rdev);
349 if (regltr_id >= CPCAP_NUM_REGULATORS)
352 regnr = cpcap_regltr_data[regltr_id].reg;
354 if (regltr_id == CPCAP_VRF1) {
355 if (min_uV > 2500000)
358 i = cpcap_regltr_data[regltr_id].volt_mask;
360 for (i = 0; i < cpcap_regltr_data[regltr_id].val_tbl_sz; i++)
361 if (cpcap_regltr_data[regltr_id].val_tbl[i] >= min_uV)
364 if (i >= cpcap_regltr_data[regltr_id].val_tbl_sz)
367 i <<= cpcap_regltr_data[regltr_id].volt_shft;
370 retval = cpcap_regacc_write(cpcap, regnr, i,
371 cpcap_regltr_data[regltr_id].volt_mask);
373 if ((cpcap_regltr_data[regltr_id].volt_trans_time) && (retval == 0))
374 udelay(cpcap_regltr_data[regltr_id].volt_trans_time);
379 static int cpcap_regulator_get_voltage(struct regulator_dev *rdev)
381 struct cpcap_device *cpcap;
383 unsigned short volt_bits;
384 enum cpcap_reg regnr;
387 cpcap = rdev_get_drvdata(rdev);
389 regltr_id = rdev_get_id(rdev);
390 if (regltr_id >= CPCAP_NUM_REGULATORS)
393 regnr = cpcap_regltr_data[regltr_id].reg;
395 if (cpcap_regacc_read(cpcap, regnr, &volt_bits) < 0)
398 if (!(volt_bits & cpcap_regltr_data[regltr_id].mode_mask))
401 volt_bits &= cpcap_regltr_data[regltr_id].volt_mask;
402 shift = cpcap_regltr_data[regltr_id].volt_shft;
404 return cpcap_regltr_data[regltr_id].val_tbl[volt_bits >> shift];
407 static int cpcap_regulator_enable(struct regulator_dev *rdev)
409 struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
412 enum cpcap_reg regnr;
414 regltr_id = rdev_get_id(rdev);
415 if (regltr_id >= CPCAP_NUM_REGULATORS)
418 regnr = cpcap_regltr_data[regltr_id].reg;
420 retval = cpcap_regacc_write(cpcap, regnr,
421 cpcap_regltr_data[regltr_id].mode_val,
422 cpcap_regltr_data[regltr_id].mode_mask);
424 if ((cpcap_regltr_data[regltr_id].turn_on_time) && (retval == 0))
425 udelay(cpcap_regltr_data[regltr_id].turn_on_time);
430 static int cpcap_regulator_disable(struct regulator_dev *rdev)
432 struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
434 enum cpcap_reg regnr;
436 regltr_id = rdev_get_id(rdev);
437 if (regltr_id >= CPCAP_NUM_REGULATORS)
440 regnr = cpcap_regltr_data[regltr_id].reg;
442 return cpcap_regacc_write(cpcap, regnr,
443 cpcap_regltr_data[regltr_id].off_mode_val,
444 cpcap_regltr_data[regltr_id].mode_mask);
447 static int cpcap_regulator_is_enabled(struct regulator_dev *rdev)
449 struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
451 enum cpcap_reg regnr;
452 unsigned short value;
454 regltr_id = rdev_get_id(rdev);
455 if (regltr_id >= CPCAP_NUM_REGULATORS)
458 regnr = cpcap_regltr_data[regltr_id].reg;
460 if (cpcap_regacc_read(cpcap, regnr, &value))
463 return (value & cpcap_regltr_data[regltr_id].mode_mask) ? 1 : 0;
466 static int cpcap_regulator_set_mode(struct regulator_dev *rdev,
469 struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
471 enum cpcap_reg regnr;
474 regltr_id = rdev_get_id(rdev);
475 if (regltr_id != CPCAP_VAUDIO)
478 regnr = cpcap_regltr_data[regltr_id].reg;
480 if (mode == REGULATOR_MODE_NORMAL) {
481 if (cpcap_regltr_data[regltr_id].mode_cntr == 0) {
482 ret = cpcap_regacc_write(cpcap, regnr,
484 CPCAP_BIT_AUDIO_LOW_PWR);
487 cpcap_regltr_data[regltr_id].mode_cntr++;
488 } else if (mode == REGULATOR_MODE_STANDBY) {
489 if (cpcap_regltr_data[regltr_id].mode_cntr == 1) {
490 ret = cpcap_regacc_write(cpcap, regnr,
491 CPCAP_BIT_AUDIO_LOW_PWR,
492 CPCAP_BIT_AUDIO_LOW_PWR);
493 } else if (WARN((cpcap_regltr_data[regltr_id].mode_cntr == 0),
494 "Unbalanced modes for supply vaudio\n"))
498 cpcap_regltr_data[regltr_id].mode_cntr--;
504 static struct regulator_ops cpcap_regulator_ops = {
505 .set_voltage = cpcap_regulator_set_voltage,
506 .get_voltage = cpcap_regulator_get_voltage,
507 .enable = cpcap_regulator_enable,
508 .disable = cpcap_regulator_disable,
509 .is_enabled = cpcap_regulator_is_enabled,
510 .set_mode = cpcap_regulator_set_mode,
513 static struct regulator_desc regulators[] = {
514 [CPCAP_SW2] = CPCAP_REGULATOR("sw2", CPCAP_SW2),
515 [CPCAP_SW4] = CPCAP_REGULATOR("sw4", CPCAP_SW4),
516 [CPCAP_SW5] = CPCAP_REGULATOR("sw5", CPCAP_SW5),
517 [CPCAP_VCAM] = CPCAP_REGULATOR("vcam", CPCAP_VCAM),
518 [CPCAP_VCSI] = CPCAP_REGULATOR("vcsi", CPCAP_VCSI),
519 [CPCAP_VDAC] = CPCAP_REGULATOR("vdac", CPCAP_VDAC),
520 [CPCAP_VDIG] = CPCAP_REGULATOR("vdig", CPCAP_VDIG),
521 [CPCAP_VFUSE] = CPCAP_REGULATOR("vfuse", CPCAP_VFUSE),
522 [CPCAP_VHVIO] = CPCAP_REGULATOR("vhvio", CPCAP_VHVIO),
523 [CPCAP_VSDIO] = CPCAP_REGULATOR("vsdio", CPCAP_VSDIO),
524 [CPCAP_VPLL] = CPCAP_REGULATOR("vpll", CPCAP_VPLL),
525 [CPCAP_VRF1] = CPCAP_REGULATOR("vrf1", CPCAP_VRF1),
526 [CPCAP_VRF2] = CPCAP_REGULATOR("vrf2", CPCAP_VRF2),
527 [CPCAP_VRFREF] = CPCAP_REGULATOR("vrfref", CPCAP_VRFREF),
528 [CPCAP_VWLAN1] = CPCAP_REGULATOR("vwlan1", CPCAP_VWLAN1),
529 [CPCAP_VWLAN2] = CPCAP_REGULATOR("vwlan2", CPCAP_VWLAN2),
530 [CPCAP_VSIM] = CPCAP_REGULATOR("vsim", CPCAP_VSIM),
531 [CPCAP_VSIMCARD] = CPCAP_REGULATOR("vsimcard", CPCAP_VSIMCARD),
532 [CPCAP_VVIB] = CPCAP_REGULATOR("vvib", CPCAP_VVIB),
533 [CPCAP_VUSB] = CPCAP_REGULATOR("vusb", CPCAP_VUSB),
534 [CPCAP_VAUDIO] = CPCAP_REGULATOR("vaudio", CPCAP_VAUDIO),
537 static int __devinit cpcap_regulator_probe(struct platform_device *pdev)
539 struct regulator_dev *rdev;
540 struct cpcap_device *cpcap;
541 struct cpcap_platform_data *data;
542 struct regulator_init_data *init;
545 /* Already set by core driver */
546 cpcap = platform_get_drvdata(pdev);
547 data = cpcap->spi->controller_data;
548 init = pdev->dev.platform_data;
550 for (i = 0; i < CPCAP_NUM_REGULATORS; i++) {
551 cpcap_regltr_data[i].mode_val = data->regulator_mode_values[i];
552 cpcap_regltr_data[i].off_mode_val =
553 data->regulator_off_mode_values[i];
556 rdev = regulator_register(®ulators[pdev->id], &pdev->dev,
559 return PTR_ERR(rdev);
560 /* this is ok since the cpcap is still reachable from the rdev */
561 platform_set_drvdata(pdev, rdev);
566 static int __devexit cpcap_regulator_remove(struct platform_device *pdev)
568 struct regulator_dev *rdev = platform_get_drvdata(pdev);
570 regulator_unregister(rdev);
575 static struct platform_driver cpcap_regulator_driver = {
577 .name = "cpcap-regltr",
579 .probe = cpcap_regulator_probe,
580 .remove = __devexit_p(cpcap_regulator_remove),
583 static int __init cpcap_regulator_init(void)
587 for (i = 0; i < SW2_SW4_VAL_TBL_SIZE; i++)
588 sw2_sw4_val_tbl[i] = 600000 + (i * SW2_SW4_VAL_TBL_STEP);
590 return platform_driver_register(&cpcap_regulator_driver);
592 subsys_initcall(cpcap_regulator_init);
594 static void __exit cpcap_regulator_exit(void)
596 platform_driver_unregister(&cpcap_regulator_driver);
598 module_exit(cpcap_regulator_exit);
600 MODULE_ALIAS("platform:cpcap-regulator");
601 MODULE_DESCRIPTION("CPCAP regulator driver");
602 MODULE_AUTHOR("Motorola");
603 MODULE_LICENSE("GPL");