Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/drivers/regulator/lp8788-buck.c

  1 /*
  2  * TI LP8788 MFD - buck regulator driver
  3  *
  4  * Copyright 2012 Texas Instruments
  5  *
  6  * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
  7  *
  8  * This program is free software; you can redistribute it and/or modify
  9  * it under the terms of the GNU General Public License version 2 as
 10  * published by the Free Software Foundation.
 11  *
 12  */
 13 
 14 #include <linux/module.h>
 15 #include <linux/slab.h>
 16 #include <linux/err.h>
 17 #include <linux/platform_device.h>
 18 #include <linux/regulator/driver.h>
 19 #include <linux/mfd/lp8788.h>
 20 #include <linux/gpio.h>
 21 
 22 /* register address */
 23 #define LP8788_EN_BUCK                  0x0C
 24 #define LP8788_BUCK_DVS_SEL             0x1D
 25 #define LP8788_BUCK1_VOUT0              0x1E
 26 #define LP8788_BUCK1_VOUT1              0x1F
 27 #define LP8788_BUCK1_VOUT2              0x20
 28 #define LP8788_BUCK1_VOUT3              0x21
 29 #define LP8788_BUCK2_VOUT0              0x22
 30 #define LP8788_BUCK2_VOUT1              0x23
 31 #define LP8788_BUCK2_VOUT2              0x24
 32 #define LP8788_BUCK2_VOUT3              0x25
 33 #define LP8788_BUCK3_VOUT               0x26
 34 #define LP8788_BUCK4_VOUT               0x27
 35 #define LP8788_BUCK1_TIMESTEP           0x28
 36 #define LP8788_BUCK_PWM                 0x2D
 37 
 38 /* mask/shift bits */
 39 #define LP8788_EN_BUCK1_M               BIT(0)  /* Addr 0Ch */
 40 #define LP8788_EN_BUCK2_M               BIT(1)
 41 #define LP8788_EN_BUCK3_M               BIT(2)
 42 #define LP8788_EN_BUCK4_M               BIT(3)
 43 #define LP8788_BUCK1_DVS_SEL_M          0x04    /* Addr 1Dh */
 44 #define LP8788_BUCK1_DVS_M              0x03
 45 #define LP8788_BUCK1_DVS_S              0
 46 #define LP8788_BUCK2_DVS_SEL_M          0x40
 47 #define LP8788_BUCK2_DVS_M              0x30
 48 #define LP8788_BUCK2_DVS_S              4
 49 #define LP8788_BUCK1_DVS_I2C            BIT(2)
 50 #define LP8788_BUCK2_DVS_I2C            BIT(6)
 51 #define LP8788_BUCK1_DVS_PIN            (0 << 2)
 52 #define LP8788_BUCK2_DVS_PIN            (0 << 6)
 53 #define LP8788_VOUT_M                   0x1F    /* Addr 1Eh ~ 27h */
 54 #define LP8788_STARTUP_TIME_M           0xF8    /* Addr 28h ~ 2Bh */
 55 #define LP8788_STARTUP_TIME_S           3
 56 #define LP8788_FPWM_BUCK1_M             BIT(0)  /* Addr 2Dh */
 57 #define LP8788_FPWM_BUCK1_S             0
 58 #define LP8788_FPWM_BUCK2_M             BIT(1)
 59 #define LP8788_FPWM_BUCK2_S             1
 60 #define LP8788_FPWM_BUCK3_M             BIT(2)
 61 #define LP8788_FPWM_BUCK3_S             2
 62 #define LP8788_FPWM_BUCK4_M             BIT(3)
 63 #define LP8788_FPWM_BUCK4_S             3
 64 
 65 #define INVALID_ADDR                    0xFF
 66 #define LP8788_FORCE_PWM                1
 67 #define LP8788_AUTO_PWM                 0
 68 #define PIN_LOW                         0
 69 #define PIN_HIGH                        1
 70 #define ENABLE_TIME_USEC                32
 71 
 72 #define BUCK_FPWM_MASK(x)               (1 << (x))
 73 #define BUCK_FPWM_SHIFT(x)              (x)
 74 
 75 enum lp8788_dvs_state {
 76         DVS_LOW  = GPIOF_OUT_INIT_LOW,
 77         DVS_HIGH = GPIOF_OUT_INIT_HIGH,
 78 };
 79 
 80 enum lp8788_dvs_mode {
 81         REGISTER,
 82         EXTPIN,
 83 };
 84 
 85 enum lp8788_buck_id {
 86         BUCK1,
 87         BUCK2,
 88         BUCK3,
 89         BUCK4,
 90 };
 91 
 92 struct lp8788_buck {
 93         struct lp8788 *lp;
 94         struct regulator_dev *regulator;
 95         void *dvs;
 96 };
 97 
 98 /* BUCK 1 ~ 4 voltage table */
 99 static const int lp8788_buck_vtbl[] = {
100          500000,  800000,  850000,  900000,  950000, 1000000, 1050000, 1100000,
101         1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000,
102         1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000,
103         1950000, 2000000,
104 };
105 
106 static void lp8788_buck1_set_dvs(struct lp8788_buck *buck)
107 {
108         struct lp8788_buck1_dvs *dvs = (struct lp8788_buck1_dvs *)buck->dvs;
109         enum lp8788_dvs_state pinstate;
110 
111         if (!dvs)
112                 return;
113 
114         pinstate = dvs->vsel == DVS_SEL_V0 ? DVS_LOW : DVS_HIGH;
115         if (gpio_is_valid(dvs->gpio))
116                 gpio_set_value(dvs->gpio, pinstate);
117 }
118 
119 static void lp8788_buck2_set_dvs(struct lp8788_buck *buck)
120 {
121         struct lp8788_buck2_dvs *dvs = (struct lp8788_buck2_dvs *)buck->dvs;
122         enum lp8788_dvs_state pin1, pin2;
123 
124         if (!dvs)
125                 return;
126 
127         switch (dvs->vsel) {
128         case DVS_SEL_V0:
129                 pin1 = DVS_LOW;
130                 pin2 = DVS_LOW;
131                 break;
132         case DVS_SEL_V1:
133                 pin1 = DVS_HIGH;
134                 pin2 = DVS_LOW;
135                 break;
136         case DVS_SEL_V2:
137                 pin1 = DVS_LOW;
138                 pin2 = DVS_HIGH;
139                 break;
140         case DVS_SEL_V3:
141                 pin1 = DVS_HIGH;
142                 pin2 = DVS_HIGH;
143                 break;
144         default:
145                 return;
146         }
147 
148         if (gpio_is_valid(dvs->gpio[0]))
149                 gpio_set_value(dvs->gpio[0], pin1);
150 
151         if (gpio_is_valid(dvs->gpio[1]))
152                 gpio_set_value(dvs->gpio[1], pin2);
153 }
154 
155 static void lp8788_set_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id)
156 {
157         switch (id) {
158         case BUCK1:
159                 lp8788_buck1_set_dvs(buck);
160                 break;
161         case BUCK2:
162                 lp8788_buck2_set_dvs(buck);
163                 break;
164         default:
165                 break;
166         }
167 }
168 
169 static enum lp8788_dvs_mode
170 lp8788_get_buck_dvs_ctrl_mode(struct lp8788_buck *buck, enum lp8788_buck_id id)
171 {
172         u8 val, mask;
173 
174         switch (id) {
175         case BUCK1:
176                 mask = LP8788_BUCK1_DVS_SEL_M;
177                 break;
178         case BUCK2:
179                 mask = LP8788_BUCK2_DVS_SEL_M;
180                 break;
181         default:
182                 return REGISTER;
183         }
184 
185         lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
186 
187         return val & mask ? REGISTER : EXTPIN;
188 }
189 
190 static bool lp8788_is_valid_buck_addr(u8 addr)
191 {
192         switch (addr) {
193         case LP8788_BUCK1_VOUT0:
194         case LP8788_BUCK1_VOUT1:
195         case LP8788_BUCK1_VOUT2:
196         case LP8788_BUCK1_VOUT3:
197         case LP8788_BUCK2_VOUT0:
198         case LP8788_BUCK2_VOUT1:
199         case LP8788_BUCK2_VOUT2:
200         case LP8788_BUCK2_VOUT3:
201                 return true;
202         default:
203                 return false;
204         }
205 }
206 
207 static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck,
208                                         enum lp8788_buck_id id)
209 {
210         enum lp8788_dvs_mode mode = lp8788_get_buck_dvs_ctrl_mode(buck, id);
211         struct lp8788_buck1_dvs *b1_dvs;
212         struct lp8788_buck2_dvs *b2_dvs;
213         u8 val, idx, addr;
214         int pin1, pin2;
215 
216         switch (id) {
217         case BUCK1:
218                 if (mode == EXTPIN) {
219                         b1_dvs = (struct lp8788_buck1_dvs *)buck->dvs;
220                         if (!b1_dvs)
221                                 goto err;
222 
223                         idx = gpio_get_value(b1_dvs->gpio) ? 1 : 0;
224                 } else {
225                         lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
226                         idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S;
227                 }
228                 addr = LP8788_BUCK1_VOUT0 + idx;
229                 break;
230         case BUCK2:
231                 if (mode == EXTPIN) {
232                         b2_dvs = (struct lp8788_buck2_dvs *)buck->dvs;
233                         if (!b2_dvs)
234                                 goto err;
235 
236                         pin1 = gpio_get_value(b2_dvs->gpio[0]);
237                         pin2 = gpio_get_value(b2_dvs->gpio[1]);
238 
239                         if (pin1 == PIN_LOW && pin2 == PIN_LOW)
240                                 idx = 0;
241                         else if (pin1 == PIN_LOW && pin2 == PIN_HIGH)
242                                 idx = 2;
243                         else if (pin1 == PIN_HIGH && pin2 == PIN_LOW)
244                                 idx = 1;
245                         else
246                                 idx = 3;
247                 } else {
248                         lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val);
249                         idx = (val & LP8788_BUCK2_DVS_M) >> LP8788_BUCK2_DVS_S;
250                 }
251                 addr = LP8788_BUCK2_VOUT0 + idx;
252                 break;
253         default:
254                 goto err;
255         }
256 
257         return addr;
258 err:
259         return INVALID_ADDR;
260 }
261 
262 static int lp8788_buck12_set_voltage_sel(struct regulator_dev *rdev,
263                                         unsigned selector)
264 {
265         struct lp8788_buck *buck = rdev_get_drvdata(rdev);
266         enum lp8788_buck_id id = rdev_get_id(rdev);
267         u8 addr;
268 
269         if (buck->dvs)
270                 lp8788_set_dvs(buck, id);
271 
272         addr = lp8788_select_buck_vout_addr(buck, id);
273         if (!lp8788_is_valid_buck_addr(addr))
274                 return -EINVAL;
275 
276         return lp8788_update_bits(buck->lp, addr, LP8788_VOUT_M, selector);
277 }
278 
279 static int lp8788_buck12_get_voltage_sel(struct regulator_dev *rdev)
280 {
281         struct lp8788_buck *buck = rdev_get_drvdata(rdev);
282         enum lp8788_buck_id id = rdev_get_id(rdev);
283         int ret;
284         u8 val, addr;
285 
286         addr = lp8788_select_buck_vout_addr(buck, id);
287         if (!lp8788_is_valid_buck_addr(addr))
288                 return -EINVAL;
289 
290         ret = lp8788_read_byte(buck->lp, addr, &val);
291         if (ret)
292                 return ret;
293 
294         return val & LP8788_VOUT_M;
295 }
296 
297 static int lp8788_buck_enable_time(struct regulator_dev *rdev)
298 {
299         struct lp8788_buck *buck = rdev_get_drvdata(rdev);
300         enum lp8788_buck_id id = rdev_get_id(rdev);
301         u8 val, addr = LP8788_BUCK1_TIMESTEP + id;
302 
303         if (lp8788_read_byte(buck->lp, addr, &val))
304                 return -EINVAL;
305 
306         val = (val & LP8788_STARTUP_TIME_M) >> LP8788_STARTUP_TIME_S;
307 
308         return ENABLE_TIME_USEC * val;
309 }
310 
311 static int lp8788_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
312 {
313         struct lp8788_buck *buck = rdev_get_drvdata(rdev);
314         enum lp8788_buck_id id = rdev_get_id(rdev);
315         u8 mask, val;
316 
317         mask = BUCK_FPWM_MASK(id);
318         switch (mode) {
319         case REGULATOR_MODE_FAST:
320                 val = LP8788_FORCE_PWM << BUCK_FPWM_SHIFT(id);
321                 break;
322         case REGULATOR_MODE_NORMAL:
323                 val = LP8788_AUTO_PWM << BUCK_FPWM_SHIFT(id);
324                 break;
325         default:
326                 return -EINVAL;
327         }
328 
329         return lp8788_update_bits(buck->lp, LP8788_BUCK_PWM, mask, val);
330 }
331 
332 static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev)
333 {
334         struct lp8788_buck *buck = rdev_get_drvdata(rdev);
335         enum lp8788_buck_id id = rdev_get_id(rdev);
336         u8 val;
337         int ret;
338 
339         ret = lp8788_read_byte(buck->lp, LP8788_BUCK_PWM, &val);
340         if (ret)
341                 return ret;
342 
343         return val & BUCK_FPWM_MASK(id) ?
344                                 REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
345 }
346 
347 static struct regulator_ops lp8788_buck12_ops = {
348         .list_voltage = regulator_list_voltage_table,
349         .map_voltage = regulator_map_voltage_ascend,
350         .set_voltage_sel = lp8788_buck12_set_voltage_sel,
351         .get_voltage_sel = lp8788_buck12_get_voltage_sel,
352         .enable = regulator_enable_regmap,
353         .disable = regulator_disable_regmap,
354         .is_enabled = regulator_is_enabled_regmap,
355         .enable_time = lp8788_buck_enable_time,
356         .set_mode = lp8788_buck_set_mode,
357         .get_mode = lp8788_buck_get_mode,
358 };
359 
360 static struct regulator_ops lp8788_buck34_ops = {
361         .list_voltage = regulator_list_voltage_table,
362         .map_voltage = regulator_map_voltage_ascend,
363         .set_voltage_sel = regulator_set_voltage_sel_regmap,
364         .get_voltage_sel = regulator_get_voltage_sel_regmap,
365         .enable = regulator_enable_regmap,
366         .disable = regulator_disable_regmap,
367         .is_enabled = regulator_is_enabled_regmap,
368         .enable_time = lp8788_buck_enable_time,
369         .set_mode = lp8788_buck_set_mode,
370         .get_mode = lp8788_buck_get_mode,
371 };
372 
373 static struct regulator_desc lp8788_buck_desc[] = {
374         {
375                 .name = "buck1",
376                 .id = BUCK1,
377                 .ops = &lp8788_buck12_ops,
378                 .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
379                 .volt_table = lp8788_buck_vtbl,
380                 .type = REGULATOR_VOLTAGE,
381                 .owner = THIS_MODULE,
382                 .enable_reg = LP8788_EN_BUCK,
383                 .enable_mask = LP8788_EN_BUCK1_M,
384         },
385         {
386                 .name = "buck2",
387                 .id = BUCK2,
388                 .ops = &lp8788_buck12_ops,
389                 .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
390                 .volt_table = lp8788_buck_vtbl,
391                 .type = REGULATOR_VOLTAGE,
392                 .owner = THIS_MODULE,
393                 .enable_reg = LP8788_EN_BUCK,
394                 .enable_mask = LP8788_EN_BUCK2_M,
395         },
396         {
397                 .name = "buck3",
398                 .id = BUCK3,
399                 .ops = &lp8788_buck34_ops,
400                 .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
401                 .volt_table = lp8788_buck_vtbl,
402                 .type = REGULATOR_VOLTAGE,
403                 .owner = THIS_MODULE,
404                 .vsel_reg = LP8788_BUCK3_VOUT,
405                 .vsel_mask = LP8788_VOUT_M,
406                 .enable_reg = LP8788_EN_BUCK,
407                 .enable_mask = LP8788_EN_BUCK3_M,
408         },
409         {
410                 .name = "buck4",
411                 .id = BUCK4,
412                 .ops = &lp8788_buck34_ops,
413                 .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl),
414                 .volt_table = lp8788_buck_vtbl,
415                 .type = REGULATOR_VOLTAGE,
416                 .owner = THIS_MODULE,
417                 .vsel_reg = LP8788_BUCK4_VOUT,
418                 .vsel_mask = LP8788_VOUT_M,
419                 .enable_reg = LP8788_EN_BUCK,
420                 .enable_mask = LP8788_EN_BUCK4_M,
421         },
422 };
423 
424 static int lp8788_dvs_gpio_request(struct platform_device *pdev,
425                                 struct lp8788_buck *buck,
426                                 enum lp8788_buck_id id)
427 {
428         struct lp8788_platform_data *pdata = buck->lp->pdata;
429         char *b1_name = "LP8788_B1_DVS";
430         char *b2_name[] = { "LP8788_B2_DVS1", "LP8788_B2_DVS2" };
431         int i, gpio, ret;
432 
433         switch (id) {
434         case BUCK1:
435                 gpio = pdata->buck1_dvs->gpio;
436                 ret = devm_gpio_request_one(&pdev->dev, gpio, DVS_LOW,
437                                             b1_name);
438                 if (ret)
439                         return ret;
440 
441                 buck->dvs = pdata->buck1_dvs;
442                 break;
443         case BUCK2:
444                 for (i = 0; i < LP8788_NUM_BUCK2_DVS; i++) {
445                         gpio = pdata->buck2_dvs->gpio[i];
446                         ret = devm_gpio_request_one(&pdev->dev, gpio,
447                                                     DVS_LOW, b2_name[i]);
448                         if (ret)
449                                 return ret;
450                 }
451                 buck->dvs = pdata->buck2_dvs;
452                 break;
453         default:
454                 break;
455         }
456 
457         return 0;
458 }
459 
460 static int lp8788_init_dvs(struct platform_device *pdev,
461                         struct lp8788_buck *buck, enum lp8788_buck_id id)
462 {
463         struct lp8788_platform_data *pdata = buck->lp->pdata;
464         u8 mask[] = { LP8788_BUCK1_DVS_SEL_M, LP8788_BUCK2_DVS_SEL_M };
465         u8 val[]  = { LP8788_BUCK1_DVS_PIN, LP8788_BUCK2_DVS_PIN };
466         u8 default_dvs_mode[] = { LP8788_BUCK1_DVS_I2C, LP8788_BUCK2_DVS_I2C };
467 
468         /* no dvs for buck3, 4 */
469         if (id > BUCK2)
470                 return 0;
471 
472         /* no dvs platform data, then dvs will be selected by I2C registers */
473         if (!pdata)
474                 goto set_default_dvs_mode;
475 
476         if ((id == BUCK1 && !pdata->buck1_dvs) ||
477                 (id == BUCK2 && !pdata->buck2_dvs))
478                 goto set_default_dvs_mode;
479 
480         if (lp8788_dvs_gpio_request(pdev, buck, id))
481                 goto set_default_dvs_mode;
482 
483         return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
484                                 val[id]);
485 
486 set_default_dvs_mode:
487         return lp8788_update_bits(buck->lp, LP8788_BUCK_DVS_SEL, mask[id],
488                                   default_dvs_mode[id]);
489 }
490 
491 static int lp8788_buck_probe(struct platform_device *pdev)
492 {
493         struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
494         int id = pdev->id;
495         struct lp8788_buck *buck;
496         struct regulator_config cfg = { };
497         struct regulator_dev *rdev;
498         int ret;
499 
500         if (id >= LP8788_NUM_BUCKS)
501                 return -EINVAL;
502 
503         buck = devm_kzalloc(&pdev->dev, sizeof(struct lp8788_buck), GFP_KERNEL);
504         if (!buck)
505                 return -ENOMEM;
506 
507         buck->lp = lp;
508 
509         ret = lp8788_init_dvs(pdev, buck, id);
510         if (ret)
511                 return ret;
512 
513         cfg.dev = pdev->dev.parent;
514         cfg.init_data = lp->pdata ? lp->pdata->buck_data[id] : NULL;
515         cfg.driver_data = buck;
516         cfg.regmap = lp->regmap;
517 
518         rdev = devm_regulator_register(&pdev->dev, &lp8788_buck_desc[id], &cfg);
519         if (IS_ERR(rdev)) {
520                 ret = PTR_ERR(rdev);
521                 dev_err(&pdev->dev, "BUCK%d regulator register err = %d\n",
522                                 id + 1, ret);
523                 return ret;
524         }
525 
526         buck->regulator = rdev;
527         platform_set_drvdata(pdev, buck);
528 
529         return 0;
530 }
531 
532 static struct platform_driver lp8788_buck_driver = {
533         .probe = lp8788_buck_probe,
534         .driver = {
535                 .name = LP8788_DEV_BUCK,
536                 .owner = THIS_MODULE,
537         },
538 };
539 
540 static int __init lp8788_buck_init(void)
541 {
542         return platform_driver_register(&lp8788_buck_driver);
543 }
544 subsys_initcall(lp8788_buck_init);
545 
546 static void __exit lp8788_buck_exit(void)
547 {
548         platform_driver_unregister(&lp8788_buck_driver);
549 }
550 module_exit(lp8788_buck_exit);
551 
552 MODULE_DESCRIPTION("TI LP8788 BUCK Driver");
553 MODULE_AUTHOR("Milo Kim");
554 MODULE_LICENSE("GPL");
555 MODULE_ALIAS("platform:lp8788-buck");
556 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us