temp revert rk change
[firefly-linux-kernel-4.4.55.git] / drivers / regulator / cpcap-regulator.c
1 /*
2  * Copyright (C) 2009 Motorola, Inc.
3  *
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.
7  *
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.
12  *
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
16  * 02111-1307, USA
17  */
18
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>
26
27 #include <linux/regulator/driver.h>
28 #include <linux/regulator/machine.h>
29
30 #include <linux/spi/spi.h>
31 #include <linux/spi/cpcap.h>
32 #include <linux/spi/cpcap-regbits.h>
33
34 #define CPCAP_REGULATOR(_name, _id)             \
35         {                                       \
36                 .name = _name,                  \
37                 .id = _id,                      \
38                 .ops = &cpcap_regulator_ops,    \
39                 .type = REGULATOR_VOLTAGE,      \
40                 .owner = THIS_MODULE,           \
41         }
42
43
44 #define SW2_SW4_VAL_TBL_SIZE 69
45 #define SW2_SW4_VAL_TBL_STEP 12500
46
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};
70
71 static struct {
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;
78         const int val_tbl_sz;
79         const int *val_tbl;
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,
85                             0x0F00,
86                             0x007F,
87                             0,
88                             0x0000,
89                             0x0000,
90                             ARRAY_SIZE(sw2_sw4_val_tbl),
91                             sw2_sw4_val_tbl,
92                             0,
93                             120,
94                             1500},
95
96         [CPCAP_SW4]      = {CPCAP_REG_S4C1,
97                             0x0F00,
98                             0x007F,
99                             0,
100                             0x0000,
101                             0x0000,
102                             ARRAY_SIZE(sw2_sw4_val_tbl),
103                             sw2_sw4_val_tbl,
104                             0,
105                             100,
106                             1500},
107
108         [CPCAP_SW5]      = {CPCAP_REG_S5C,
109                             0x002A,
110                             0x0000,
111                             0,
112                             0x0000,
113                             0x0000,
114                             ARRAY_SIZE(sw5_val_tbl),
115                             sw5_val_tbl,
116                             0,
117                             0,
118                             1500},
119
120         [CPCAP_VCAM]     = {CPCAP_REG_VCAMC,
121                             0x0087,
122                             0x0030,
123                             4,
124                             0x0000,
125                             0x0000,
126                             ARRAY_SIZE(vcam_val_tbl),
127                             vcam_val_tbl,
128                             0,
129                             420,
130                             1000},
131
132         [CPCAP_VCSI]     = {CPCAP_REG_VCSIC,
133                             0x0047,
134                             0x0010,
135                             4,
136                             0x0000,
137                             0x0000,
138                             ARRAY_SIZE(vcsi_val_tbl),
139                             vcsi_val_tbl,
140                             0,
141                             350,
142                             1000},
143
144         [CPCAP_VDAC]     = {CPCAP_REG_VDACC,
145                             0x0087,
146                             0x0030,
147                             4,
148                             0x0000,
149                             0x0000,
150                             ARRAY_SIZE(vdac_val_tbl),
151                             vdac_val_tbl,
152                             0,
153                             420,
154                             1000},
155
156         [CPCAP_VDIG]     = {CPCAP_REG_VDIGC,
157                             0x0087,
158                             0x0030,
159                             4,
160                             0x0000,
161                             0x0000,
162                             ARRAY_SIZE(vdig_val_tbl),
163                             vdig_val_tbl,
164                             0,
165                             420,
166                             1000},
167
168         [CPCAP_VFUSE]    = {CPCAP_REG_VFUSEC,
169                             0x0080,
170                             0x000F,
171                             0,
172                             0x0000,
173                             0x0000,
174                             ARRAY_SIZE(vfuse_val_tbl),
175                             vfuse_val_tbl,
176                             0,
177                             420,
178                             1000},
179
180         [CPCAP_VHVIO]    = {CPCAP_REG_VHVIOC,
181                             0x0017,
182                             0x0000,
183                             0,
184                             0x0000,
185                             0x0000,
186                             ARRAY_SIZE(vhvio_val_tbl),
187                             vhvio_val_tbl,
188                             0,
189                             0,
190                             1000},
191
192         [CPCAP_VSDIO]    = {CPCAP_REG_VSDIOC,
193                             0x0087,
194                             0x0038,
195                             3,
196                             0x0000,
197                             0x0000,
198                             ARRAY_SIZE(vsdio_val_tbl),
199                             vsdio_val_tbl,
200                             0,
201                             420,
202                             1000},
203
204         [CPCAP_VPLL]     = {CPCAP_REG_VPLLC,
205                             0x0043,
206                             0x0018,
207                             3,
208                             0x0000,
209                             0x0000,
210                             ARRAY_SIZE(vpll_val_tbl),
211                             vpll_val_tbl,
212                             0,
213                             420,
214                             100},
215
216         [CPCAP_VRF1]     = {CPCAP_REG_VRF1C,
217                             0x00AC,
218                             0x0002,
219                             1,
220                             0x0000,
221                             0x0000,
222                             ARRAY_SIZE(vrf1_val_tbl),
223                             vrf1_val_tbl,
224                             0,
225                             10,
226                             1000},
227
228         [CPCAP_VRF2]     = {CPCAP_REG_VRF2C,
229                             0x0023,
230                             0x0008,
231                             3,
232                             0x0000,
233                             0x0000,
234                             ARRAY_SIZE(vrf2_val_tbl),
235                             vrf2_val_tbl,
236                             0,
237                             10,
238                             1000},
239
240         [CPCAP_VRFREF]   = {CPCAP_REG_VRFREFC,
241                             0x0023,
242                             0x0008,
243                             3,
244                             0x0000,
245                             0x0000,
246                             ARRAY_SIZE(vrfref_val_tbl),
247                             vrfref_val_tbl,
248                             0,
249                             420,
250                             100},
251
252         [CPCAP_VWLAN1]   = {CPCAP_REG_VWLAN1C,
253                             0x0047,
254                             0x0010,
255                             4,
256                             0x0000,
257                             0x0000,
258                             ARRAY_SIZE(vwlan1_val_tbl),
259                             vwlan1_val_tbl,
260                             0,
261                             420,
262                             1000},
263
264         [CPCAP_VWLAN2]   = {CPCAP_REG_VWLAN2C,
265                             0x020C,
266                             0x00C0,
267                             6,
268                             0x0000,
269                             0x0000,
270                             ARRAY_SIZE(vwlan2_val_tbl),
271                             vwlan2_val_tbl,
272                             0,
273                             420,
274                             1000},
275
276         [CPCAP_VSIM]     = {CPCAP_REG_VSIMC,
277                             0x0023,
278                             0x0008,
279                             3,
280                             0x0000,
281                             0x0000,
282                             ARRAY_SIZE(vsim_val_tbl),
283                             vsim_val_tbl,
284                             0,
285                             420,
286                             1000},
287
288         [CPCAP_VSIMCARD] = {CPCAP_REG_VSIMC,
289                             0x1E80,
290                             0x0008,
291                             3,
292                             0x0000,
293                             0x0000,
294                             ARRAY_SIZE(vsimcard_val_tbl),
295                             vsimcard_val_tbl,
296                             0,
297                             420,
298                             1000},
299
300         [CPCAP_VVIB]     = {CPCAP_REG_VVIBC,
301                             0x0001,
302                             0x000C,
303                             2,
304                             0x0000,
305                             0x0000,
306                             ARRAY_SIZE(vvib_val_tbl),
307                             vvib_val_tbl,
308                             0,
309                             500,
310                             500},
311
312         [CPCAP_VUSB]     = {CPCAP_REG_VUSBC,
313                             0x011C,
314                             0x0040,
315                             6,
316                             0x0000,
317                             0x0000,
318                             ARRAY_SIZE(vusb_val_tbl),
319                             vusb_val_tbl,
320                             0,
321                             0,
322                             1000},
323
324         [CPCAP_VAUDIO]   = {CPCAP_REG_VAUDIOC,
325                             0x0016,
326                             0x0001,
327                             0,
328                             0x0000,
329                             0x0000,
330                             ARRAY_SIZE(vaudio_val_tbl),
331                             vaudio_val_tbl,
332                             0,
333                             0,
334                             1000},
335 };
336
337 static int cpcap_regulator_set_voltage(struct regulator_dev *rdev,
338                                        int min_uV, int max_uV)
339 {
340         struct cpcap_device *cpcap;
341         int regltr_id;
342         int retval;
343         enum cpcap_reg regnr;
344         int i;
345
346         cpcap = rdev_get_drvdata(rdev);
347
348         regltr_id = rdev_get_id(rdev);
349         if (regltr_id >= CPCAP_NUM_REGULATORS)
350                 return -EINVAL;
351
352         regnr = cpcap_regltr_data[regltr_id].reg;
353
354         if (regltr_id == CPCAP_VRF1) {
355                 if (min_uV > 2500000)
356                         i = 0;
357                 else
358                         i = cpcap_regltr_data[regltr_id].volt_mask;
359         } else {
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)
362                                 break;
363
364                 if (i >= cpcap_regltr_data[regltr_id].val_tbl_sz)
365                         i--;
366
367                 i <<= cpcap_regltr_data[regltr_id].volt_shft;
368         }
369
370         retval = cpcap_regacc_write(cpcap, regnr, i,
371                                     cpcap_regltr_data[regltr_id].volt_mask);
372
373         if ((cpcap_regltr_data[regltr_id].volt_trans_time) && (retval == 0))
374                 udelay(cpcap_regltr_data[regltr_id].volt_trans_time);
375
376         return retval;
377 }
378
379 static int cpcap_regulator_get_voltage(struct regulator_dev *rdev)
380 {
381         struct cpcap_device *cpcap;
382         int regltr_id;
383         unsigned short volt_bits;
384         enum cpcap_reg regnr;
385         unsigned int shift;
386
387         cpcap = rdev_get_drvdata(rdev);
388
389         regltr_id = rdev_get_id(rdev);
390         if (regltr_id >= CPCAP_NUM_REGULATORS)
391                 return -EINVAL;
392
393         regnr = cpcap_regltr_data[regltr_id].reg;
394
395         if (cpcap_regacc_read(cpcap, regnr, &volt_bits) < 0)
396                 return -1;
397
398         if (!(volt_bits & cpcap_regltr_data[regltr_id].mode_mask))
399                 return 0;
400
401         volt_bits &= cpcap_regltr_data[regltr_id].volt_mask;
402         shift = cpcap_regltr_data[regltr_id].volt_shft;
403
404         return cpcap_regltr_data[regltr_id].val_tbl[volt_bits >> shift];
405 }
406
407 static int cpcap_regulator_enable(struct regulator_dev *rdev)
408 {
409         struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
410         int regltr_id;
411         int retval;
412         enum cpcap_reg regnr;
413
414         regltr_id = rdev_get_id(rdev);
415         if (regltr_id >= CPCAP_NUM_REGULATORS)
416                 return -EINVAL;
417
418         regnr = cpcap_regltr_data[regltr_id].reg;
419
420         retval = cpcap_regacc_write(cpcap, regnr,
421                                     cpcap_regltr_data[regltr_id].mode_val,
422                                     cpcap_regltr_data[regltr_id].mode_mask);
423
424         if ((cpcap_regltr_data[regltr_id].turn_on_time) && (retval == 0))
425                 udelay(cpcap_regltr_data[regltr_id].turn_on_time);
426
427         return retval;
428 }
429
430 static int cpcap_regulator_disable(struct regulator_dev *rdev)
431 {
432         struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
433         int regltr_id;
434         enum cpcap_reg regnr;
435
436         regltr_id = rdev_get_id(rdev);
437         if (regltr_id >= CPCAP_NUM_REGULATORS)
438                 return -EINVAL;
439
440         regnr = cpcap_regltr_data[regltr_id].reg;
441
442         return cpcap_regacc_write(cpcap, regnr,
443                                   cpcap_regltr_data[regltr_id].off_mode_val,
444                                   cpcap_regltr_data[regltr_id].mode_mask);
445 }
446
447 static int cpcap_regulator_is_enabled(struct regulator_dev *rdev)
448 {
449         struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
450         int regltr_id;
451         enum cpcap_reg regnr;
452         unsigned short value;
453
454         regltr_id = rdev_get_id(rdev);
455         if (regltr_id >= CPCAP_NUM_REGULATORS)
456                 return -EINVAL;
457
458         regnr = cpcap_regltr_data[regltr_id].reg;
459
460         if (cpcap_regacc_read(cpcap, regnr, &value))
461                 return -1;
462
463         return (value & cpcap_regltr_data[regltr_id].mode_mask) ? 1 : 0;
464 }
465
466 static int cpcap_regulator_set_mode(struct regulator_dev *rdev,
467                                     unsigned int mode)
468 {
469         struct cpcap_device *cpcap = rdev_get_drvdata(rdev);
470         int regltr_id;
471         enum cpcap_reg regnr;
472         int ret = 0;
473
474         regltr_id = rdev_get_id(rdev);
475         if (regltr_id != CPCAP_VAUDIO)
476                 return -EINVAL;
477
478         regnr = cpcap_regltr_data[regltr_id].reg;
479
480         if (mode == REGULATOR_MODE_NORMAL) {
481                 if (cpcap_regltr_data[regltr_id].mode_cntr == 0) {
482                         ret = cpcap_regacc_write(cpcap, regnr,
483                                                  0,
484                                                  CPCAP_BIT_AUDIO_LOW_PWR);
485                 }
486                 if (ret == 0)
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"))
495                         ret = -EIO;
496
497                 if (ret == 0)
498                         cpcap_regltr_data[regltr_id].mode_cntr--;
499         }
500
501         return ret;
502 }
503
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,
511 };
512
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),
535 };
536
537 static int __devinit cpcap_regulator_probe(struct platform_device *pdev)
538 {
539         struct regulator_dev *rdev;
540         struct cpcap_device *cpcap;
541         struct cpcap_platform_data *data;
542         struct regulator_init_data *init;
543         int i;
544
545         /* Already set by core driver */
546         cpcap = platform_get_drvdata(pdev);
547         data = cpcap->spi->controller_data;
548         init = pdev->dev.platform_data;
549
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];
554         }
555
556         rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
557                                   init, cpcap);
558         if (IS_ERR(rdev))
559                 return PTR_ERR(rdev);
560         /* this is ok since the cpcap is still reachable from the rdev */
561         platform_set_drvdata(pdev, rdev);
562
563         return 0;
564 }
565
566 static int __devexit cpcap_regulator_remove(struct platform_device *pdev)
567 {
568         struct regulator_dev *rdev = platform_get_drvdata(pdev);
569
570         regulator_unregister(rdev);
571
572         return 0;
573 }
574
575 static struct platform_driver cpcap_regulator_driver = {
576         .driver = {
577                 .name = "cpcap-regltr",
578         },
579         .probe = cpcap_regulator_probe,
580         .remove = __devexit_p(cpcap_regulator_remove),
581 };
582
583 static int __init cpcap_regulator_init(void)
584 {
585         int i;
586
587         for (i = 0; i < SW2_SW4_VAL_TBL_SIZE; i++)
588                 sw2_sw4_val_tbl[i] = 600000 + (i * SW2_SW4_VAL_TBL_STEP);
589
590         return platform_driver_register(&cpcap_regulator_driver);
591 }
592 subsys_initcall(cpcap_regulator_init);
593
594 static void __exit cpcap_regulator_exit(void)
595 {
596         platform_driver_unregister(&cpcap_regulator_driver);
597 }
598 module_exit(cpcap_regulator_exit);
599
600 MODULE_ALIAS("platform:cpcap-regulator");
601 MODULE_DESCRIPTION("CPCAP regulator driver");
602 MODULE_AUTHOR("Motorola");
603 MODULE_LICENSE("GPL");