Version:  2.0.40 2.2.26 2.4.37 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 3.19

Linux/drivers/regulator/max77686.c

  1 /*
  2  * max77686.c - Regulator driver for the Maxim 77686
  3  *
  4  * Copyright (C) 2012 Samsung Electronics
  5  * Chiwoong Byun <woong.byun@smasung.com>
  6  * Jonghwa Lee <jonghwa3.lee@samsung.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 as published by
 10  * the Free Software Foundation; either version 2 of the License, or
 11  * (at your option) any later version.
 12  *
 13  * This program is distributed in the hope that it will be useful,
 14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16  * GNU General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU General Public License
 19  * along with this program; if not, write to the Free Software
 20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 21  *
 22  * This driver is based on max8997.c
 23  */
 24 
 25 #include <linux/kernel.h>
 26 #include <linux/bug.h>
 27 #include <linux/err.h>
 28 #include <linux/gpio.h>
 29 #include <linux/slab.h>
 30 #include <linux/platform_device.h>
 31 #include <linux/regulator/driver.h>
 32 #include <linux/regulator/machine.h>
 33 #include <linux/regulator/of_regulator.h>
 34 #include <linux/mfd/max77686.h>
 35 #include <linux/mfd/max77686-private.h>
 36 
 37 #define MAX77686_LDO_MINUV      800000
 38 #define MAX77686_LDO_UVSTEP     50000
 39 #define MAX77686_LDO_LOW_MINUV  800000
 40 #define MAX77686_LDO_LOW_UVSTEP 25000
 41 #define MAX77686_BUCK_MINUV     750000
 42 #define MAX77686_BUCK_UVSTEP    50000
 43 #define MAX77686_RAMP_DELAY     100000                  /* uV/us */
 44 #define MAX77686_DVS_RAMP_DELAY 27500                   /* uV/us */
 45 #define MAX77686_DVS_MINUV      600000
 46 #define MAX77686_DVS_UVSTEP     12500
 47 
 48 /*
 49  * Values used for configuring LDOs and bucks.
 50  * Forcing low power mode: LDO1, 3-5, 9, 13, 17-26
 51  */
 52 #define MAX77686_LDO_LOWPOWER           0x1
 53 /*
 54  * On/off controlled by PWRREQ:
 55  *  - LDO2, 6-8, 10-12, 14-16
 56  *  - buck[1234]
 57  */
 58 #define MAX77686_OFF_PWRREQ             0x1
 59 /* Low power mode controlled by PWRREQ: All LDOs */
 60 #define MAX77686_LDO_LOWPOWER_PWRREQ    0x2
 61 /* Forcing low power mode: buck[234] */
 62 #define MAX77686_BUCK_LOWPOWER          0x2
 63 #define MAX77686_NORMAL                 0x3
 64 
 65 #define MAX77686_OPMODE_SHIFT   6
 66 #define MAX77686_OPMODE_BUCK234_SHIFT   4
 67 #define MAX77686_OPMODE_MASK    0x3
 68 
 69 #define MAX77686_VSEL_MASK      0x3F
 70 #define MAX77686_DVS_VSEL_MASK  0xFF
 71 
 72 #define MAX77686_RAMP_RATE_MASK 0xC0
 73 
 74 #define MAX77686_REGULATORS     MAX77686_REG_MAX
 75 #define MAX77686_LDOS           26
 76 
 77 enum max77686_ramp_rate {
 78         RAMP_RATE_13P75MV,
 79         RAMP_RATE_27P5MV,
 80         RAMP_RATE_55MV,
 81         RAMP_RATE_NO_CTRL,      /* 100mV/us */
 82 };
 83 
 84 struct max77686_data {
 85         /* Array indexed by regulator id */
 86         unsigned int opmode[MAX77686_REGULATORS];
 87 };
 88 
 89 static unsigned int max77686_get_opmode_shift(int id)
 90 {
 91         switch (id) {
 92         case MAX77686_BUCK1:
 93         case MAX77686_BUCK5 ... MAX77686_BUCK9:
 94                 return 0;
 95         case MAX77686_BUCK2 ... MAX77686_BUCK4:
 96                 return MAX77686_OPMODE_BUCK234_SHIFT;
 97         default:
 98                 /* all LDOs */
 99                 return MAX77686_OPMODE_SHIFT;
100         }
101 }
102 
103 /* Some BUCKs and LDOs supports Normal[ON/OFF] mode during suspend */
104 static int max77686_set_suspend_disable(struct regulator_dev *rdev)
105 {
106         unsigned int val, shift;
107         struct max77686_data *max77686 = rdev_get_drvdata(rdev);
108         int ret, id = rdev_get_id(rdev);
109 
110         shift = max77686_get_opmode_shift(id);
111         val = MAX77686_OFF_PWRREQ;
112 
113         ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
114                                  rdev->desc->enable_mask, val << shift);
115         if (ret)
116                 return ret;
117 
118         max77686->opmode[id] = val;
119         return 0;
120 }
121 
122 /* Some LDOs supports [LPM/Normal]ON mode during suspend state */
123 static int max77686_set_suspend_mode(struct regulator_dev *rdev,
124                                      unsigned int mode)
125 {
126         struct max77686_data *max77686 = rdev_get_drvdata(rdev);
127         unsigned int val;
128         int ret, id = rdev_get_id(rdev);
129 
130         /* BUCK[5-9] doesn't support this feature */
131         if (id >= MAX77686_BUCK5)
132                 return 0;
133 
134         switch (mode) {
135         case REGULATOR_MODE_IDLE:                       /* ON in LP Mode */
136                 val = MAX77686_LDO_LOWPOWER_PWRREQ;
137                 break;
138         case REGULATOR_MODE_NORMAL:                     /* ON in Normal Mode */
139                 val = MAX77686_NORMAL;
140                 break;
141         default:
142                 pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
143                         rdev->desc->name, mode);
144                 return -EINVAL;
145         }
146 
147         ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
148                                   rdev->desc->enable_mask,
149                                   val << MAX77686_OPMODE_SHIFT);
150         if (ret)
151                 return ret;
152 
153         max77686->opmode[id] = val;
154         return 0;
155 }
156 
157 /* Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state */
158 static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
159                                      unsigned int mode)
160 {
161         unsigned int val;
162         struct max77686_data *max77686 = rdev_get_drvdata(rdev);
163         int ret;
164 
165         switch (mode) {
166         case REGULATOR_MODE_STANDBY:                    /* switch off */
167                 val = MAX77686_OFF_PWRREQ;
168                 break;
169         case REGULATOR_MODE_IDLE:                       /* ON in LP Mode */
170                 val = MAX77686_LDO_LOWPOWER_PWRREQ;
171                 break;
172         case REGULATOR_MODE_NORMAL:                     /* ON in Normal Mode */
173                 val = MAX77686_NORMAL;
174                 break;
175         default:
176                 pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
177                         rdev->desc->name, mode);
178                 return -EINVAL;
179         }
180 
181         ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
182                                  rdev->desc->enable_mask,
183                                  val << MAX77686_OPMODE_SHIFT);
184         if (ret)
185                 return ret;
186 
187         max77686->opmode[rdev_get_id(rdev)] = val;
188         return 0;
189 }
190 
191 static int max77686_enable(struct regulator_dev *rdev)
192 {
193         struct max77686_data *max77686 = rdev_get_drvdata(rdev);
194         unsigned int shift;
195         int id = rdev_get_id(rdev);
196 
197         shift = max77686_get_opmode_shift(id);
198 
199         if (max77686->opmode[id] == MAX77686_OFF_PWRREQ)
200                 max77686->opmode[id] = MAX77686_NORMAL;
201 
202         return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
203                                   rdev->desc->enable_mask,
204                                   max77686->opmode[id] << shift);
205 }
206 
207 static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
208 {
209         unsigned int ramp_value = RAMP_RATE_NO_CTRL;
210 
211         switch (ramp_delay) {
212         case 1 ... 13750:
213                 ramp_value = RAMP_RATE_13P75MV;
214                 break;
215         case 13751 ... 27500:
216                 ramp_value = RAMP_RATE_27P5MV;
217                 break;
218         case 27501 ... 55000:
219                 ramp_value = RAMP_RATE_55MV;
220                 break;
221         case 55001 ... 100000:
222                 break;
223         default:
224                 pr_warn("%s: ramp_delay: %d not supported, setting 100000\n",
225                         rdev->desc->name, ramp_delay);
226         }
227 
228         return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
229                                   MAX77686_RAMP_RATE_MASK, ramp_value << 6);
230 }
231 
232 static struct regulator_ops max77686_ops = {
233         .list_voltage           = regulator_list_voltage_linear,
234         .map_voltage            = regulator_map_voltage_linear,
235         .is_enabled             = regulator_is_enabled_regmap,
236         .enable                 = max77686_enable,
237         .disable                = regulator_disable_regmap,
238         .get_voltage_sel        = regulator_get_voltage_sel_regmap,
239         .set_voltage_sel        = regulator_set_voltage_sel_regmap,
240         .set_voltage_time_sel   = regulator_set_voltage_time_sel,
241         .set_suspend_mode       = max77686_set_suspend_mode,
242 };
243 
244 static struct regulator_ops max77686_ldo_ops = {
245         .list_voltage           = regulator_list_voltage_linear,
246         .map_voltage            = regulator_map_voltage_linear,
247         .is_enabled             = regulator_is_enabled_regmap,
248         .enable                 = max77686_enable,
249         .disable                = regulator_disable_regmap,
250         .get_voltage_sel        = regulator_get_voltage_sel_regmap,
251         .set_voltage_sel        = regulator_set_voltage_sel_regmap,
252         .set_voltage_time_sel   = regulator_set_voltage_time_sel,
253         .set_suspend_mode       = max77686_ldo_set_suspend_mode,
254         .set_suspend_disable    = max77686_set_suspend_disable,
255 };
256 
257 static struct regulator_ops max77686_buck1_ops = {
258         .list_voltage           = regulator_list_voltage_linear,
259         .map_voltage            = regulator_map_voltage_linear,
260         .is_enabled             = regulator_is_enabled_regmap,
261         .enable                 = max77686_enable,
262         .disable                = regulator_disable_regmap,
263         .get_voltage_sel        = regulator_get_voltage_sel_regmap,
264         .set_voltage_sel        = regulator_set_voltage_sel_regmap,
265         .set_voltage_time_sel   = regulator_set_voltage_time_sel,
266         .set_suspend_disable    = max77686_set_suspend_disable,
267 };
268 
269 static struct regulator_ops max77686_buck_dvs_ops = {
270         .list_voltage           = regulator_list_voltage_linear,
271         .map_voltage            = regulator_map_voltage_linear,
272         .is_enabled             = regulator_is_enabled_regmap,
273         .enable                 = max77686_enable,
274         .disable                = regulator_disable_regmap,
275         .get_voltage_sel        = regulator_get_voltage_sel_regmap,
276         .set_voltage_sel        = regulator_set_voltage_sel_regmap,
277         .set_voltage_time_sel   = regulator_set_voltage_time_sel,
278         .set_ramp_delay         = max77686_set_ramp_delay,
279         .set_suspend_disable    = max77686_set_suspend_disable,
280 };
281 
282 #define regulator_desc_ldo(num)         {                               \
283         .name           = "LDO"#num,                                    \
284         .of_match       = of_match_ptr("LDO"#num),                      \
285         .regulators_node        = of_match_ptr("voltage-regulators"),   \
286         .id             = MAX77686_LDO##num,                            \
287         .ops            = &max77686_ops,                                \
288         .type           = REGULATOR_VOLTAGE,                            \
289         .owner          = THIS_MODULE,                                  \
290         .min_uV         = MAX77686_LDO_MINUV,                           \
291         .uV_step        = MAX77686_LDO_UVSTEP,                          \
292         .ramp_delay     = MAX77686_RAMP_DELAY,                          \
293         .n_voltages     = MAX77686_VSEL_MASK + 1,                       \
294         .vsel_reg       = MAX77686_REG_LDO1CTRL1 + num - 1,             \
295         .vsel_mask      = MAX77686_VSEL_MASK,                           \
296         .enable_reg     = MAX77686_REG_LDO1CTRL1 + num - 1,             \
297         .enable_mask    = MAX77686_OPMODE_MASK                          \
298                         << MAX77686_OPMODE_SHIFT,                       \
299 }
300 #define regulator_desc_lpm_ldo(num)     {                               \
301         .name           = "LDO"#num,                                    \
302         .of_match       = of_match_ptr("LDO"#num),                      \
303         .regulators_node        = of_match_ptr("voltage-regulators"),   \
304         .id             = MAX77686_LDO##num,                            \
305         .ops            = &max77686_ldo_ops,                            \
306         .type           = REGULATOR_VOLTAGE,                            \
307         .owner          = THIS_MODULE,                                  \
308         .min_uV         = MAX77686_LDO_MINUV,                           \
309         .uV_step        = MAX77686_LDO_UVSTEP,                          \
310         .ramp_delay     = MAX77686_RAMP_DELAY,                          \
311         .n_voltages     = MAX77686_VSEL_MASK + 1,                       \
312         .vsel_reg       = MAX77686_REG_LDO1CTRL1 + num - 1,             \
313         .vsel_mask      = MAX77686_VSEL_MASK,                           \
314         .enable_reg     = MAX77686_REG_LDO1CTRL1 + num - 1,             \
315         .enable_mask    = MAX77686_OPMODE_MASK                          \
316                         << MAX77686_OPMODE_SHIFT,                       \
317 }
318 #define regulator_desc_ldo_low(num)             {                       \
319         .name           = "LDO"#num,                                    \
320         .of_match       = of_match_ptr("LDO"#num),                      \
321         .regulators_node        = of_match_ptr("voltage-regulators"),   \
322         .id             = MAX77686_LDO##num,                            \
323         .ops            = &max77686_ldo_ops,                            \
324         .type           = REGULATOR_VOLTAGE,                            \
325         .owner          = THIS_MODULE,                                  \
326         .min_uV         = MAX77686_LDO_LOW_MINUV,                       \
327         .uV_step        = MAX77686_LDO_LOW_UVSTEP,                      \
328         .ramp_delay     = MAX77686_RAMP_DELAY,                          \
329         .n_voltages     = MAX77686_VSEL_MASK + 1,                       \
330         .vsel_reg       = MAX77686_REG_LDO1CTRL1 + num - 1,             \
331         .vsel_mask      = MAX77686_VSEL_MASK,                           \
332         .enable_reg     = MAX77686_REG_LDO1CTRL1 + num - 1,             \
333         .enable_mask    = MAX77686_OPMODE_MASK                          \
334                         << MAX77686_OPMODE_SHIFT,                       \
335 }
336 #define regulator_desc_ldo1_low(num)            {                       \
337         .name           = "LDO"#num,                                    \
338         .of_match       = of_match_ptr("LDO"#num),                      \
339         .regulators_node        = of_match_ptr("voltage-regulators"),   \
340         .id             = MAX77686_LDO##num,                            \
341         .ops            = &max77686_ops,                                \
342         .type           = REGULATOR_VOLTAGE,                            \
343         .owner          = THIS_MODULE,                                  \
344         .min_uV         = MAX77686_LDO_LOW_MINUV,                       \
345         .uV_step        = MAX77686_LDO_LOW_UVSTEP,                      \
346         .ramp_delay     = MAX77686_RAMP_DELAY,                          \
347         .n_voltages     = MAX77686_VSEL_MASK + 1,                       \
348         .vsel_reg       = MAX77686_REG_LDO1CTRL1 + num - 1,             \
349         .vsel_mask      = MAX77686_VSEL_MASK,                           \
350         .enable_reg     = MAX77686_REG_LDO1CTRL1 + num - 1,             \
351         .enable_mask    = MAX77686_OPMODE_MASK                          \
352                         << MAX77686_OPMODE_SHIFT,                       \
353 }
354 #define regulator_desc_buck(num)                {                       \
355         .name           = "BUCK"#num,                                   \
356         .of_match       = of_match_ptr("BUCK"#num),                     \
357         .regulators_node        = of_match_ptr("voltage-regulators"),   \
358         .id             = MAX77686_BUCK##num,                           \
359         .ops            = &max77686_ops,                                \
360         .type           = REGULATOR_VOLTAGE,                            \
361         .owner          = THIS_MODULE,                                  \
362         .min_uV         = MAX77686_BUCK_MINUV,                          \
363         .uV_step        = MAX77686_BUCK_UVSTEP,                         \
364         .ramp_delay     = MAX77686_RAMP_DELAY,                          \
365         .n_voltages     = MAX77686_VSEL_MASK + 1,                       \
366         .vsel_reg       = MAX77686_REG_BUCK5OUT + (num - 5) * 2,        \
367         .vsel_mask      = MAX77686_VSEL_MASK,                           \
368         .enable_reg     = MAX77686_REG_BUCK5CTRL + (num - 5) * 2,       \
369         .enable_mask    = MAX77686_OPMODE_MASK,                         \
370 }
371 #define regulator_desc_buck1(num)               {                       \
372         .name           = "BUCK"#num,                                   \
373         .of_match       = of_match_ptr("BUCK"#num),                     \
374         .regulators_node        = of_match_ptr("voltage-regulators"),   \
375         .id             = MAX77686_BUCK##num,                           \
376         .ops            = &max77686_buck1_ops,                          \
377         .type           = REGULATOR_VOLTAGE,                            \
378         .owner          = THIS_MODULE,                                  \
379         .min_uV         = MAX77686_BUCK_MINUV,                          \
380         .uV_step        = MAX77686_BUCK_UVSTEP,                         \
381         .ramp_delay     = MAX77686_RAMP_DELAY,                          \
382         .n_voltages     = MAX77686_VSEL_MASK + 1,                       \
383         .vsel_reg       = MAX77686_REG_BUCK1OUT,                        \
384         .vsel_mask      = MAX77686_VSEL_MASK,                           \
385         .enable_reg     = MAX77686_REG_BUCK1CTRL,                       \
386         .enable_mask    = MAX77686_OPMODE_MASK,                         \
387 }
388 #define regulator_desc_buck_dvs(num)            {                       \
389         .name           = "BUCK"#num,                                   \
390         .of_match       = of_match_ptr("BUCK"#num),                     \
391         .regulators_node        = of_match_ptr("voltage-regulators"),   \
392         .id             = MAX77686_BUCK##num,                           \
393         .ops            = &max77686_buck_dvs_ops,                       \
394         .type           = REGULATOR_VOLTAGE,                            \
395         .owner          = THIS_MODULE,                                  \
396         .min_uV         = MAX77686_DVS_MINUV,                           \
397         .uV_step        = MAX77686_DVS_UVSTEP,                          \
398         .ramp_delay     = MAX77686_DVS_RAMP_DELAY,                      \
399         .n_voltages     = MAX77686_DVS_VSEL_MASK + 1,                   \
400         .vsel_reg       = MAX77686_REG_BUCK2DVS1 + (num - 2) * 10,      \
401         .vsel_mask      = MAX77686_DVS_VSEL_MASK,                       \
402         .enable_reg     = MAX77686_REG_BUCK2CTRL1 + (num - 2) * 10,     \
403         .enable_mask    = MAX77686_OPMODE_MASK                          \
404                         << MAX77686_OPMODE_BUCK234_SHIFT,               \
405 }
406 
407 static const struct regulator_desc regulators[] = {
408         regulator_desc_ldo1_low(1),
409         regulator_desc_ldo_low(2),
410         regulator_desc_ldo(3),
411         regulator_desc_ldo(4),
412         regulator_desc_ldo(5),
413         regulator_desc_ldo_low(6),
414         regulator_desc_ldo_low(7),
415         regulator_desc_ldo_low(8),
416         regulator_desc_ldo(9),
417         regulator_desc_lpm_ldo(10),
418         regulator_desc_lpm_ldo(11),
419         regulator_desc_lpm_ldo(12),
420         regulator_desc_ldo(13),
421         regulator_desc_lpm_ldo(14),
422         regulator_desc_ldo_low(15),
423         regulator_desc_lpm_ldo(16),
424         regulator_desc_ldo(17),
425         regulator_desc_ldo(18),
426         regulator_desc_ldo(19),
427         regulator_desc_ldo(20),
428         regulator_desc_ldo(21),
429         regulator_desc_ldo(22),
430         regulator_desc_ldo(23),
431         regulator_desc_ldo(24),
432         regulator_desc_ldo(25),
433         regulator_desc_ldo(26),
434         regulator_desc_buck1(1),
435         regulator_desc_buck_dvs(2),
436         regulator_desc_buck_dvs(3),
437         regulator_desc_buck_dvs(4),
438         regulator_desc_buck(5),
439         regulator_desc_buck(6),
440         regulator_desc_buck(7),
441         regulator_desc_buck(8),
442         regulator_desc_buck(9),
443 };
444 
445 static int max77686_pmic_probe(struct platform_device *pdev)
446 {
447         struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
448         struct max77686_data *max77686;
449         int i;
450         struct regulator_config config = { };
451 
452         dev_dbg(&pdev->dev, "%s\n", __func__);
453 
454         max77686 = devm_kzalloc(&pdev->dev, sizeof(struct max77686_data),
455                                 GFP_KERNEL);
456         if (!max77686)
457                 return -ENOMEM;
458 
459         config.dev = iodev->dev;
460         config.regmap = iodev->regmap;
461         config.driver_data = max77686;
462         platform_set_drvdata(pdev, max77686);
463 
464         for (i = 0; i < MAX77686_REGULATORS; i++) {
465                 struct regulator_dev *rdev;
466                 int id = regulators[i].id;
467 
468                 max77686->opmode[id] = MAX77686_NORMAL;
469                 rdev = devm_regulator_register(&pdev->dev,
470                                                 &regulators[i], &config);
471                 if (IS_ERR(rdev)) {
472                         int ret = PTR_ERR(rdev);
473                         dev_err(&pdev->dev,
474                                 "regulator init failed for %d: %d\n", i, ret);
475                         return ret;
476                 }
477         }
478 
479         return 0;
480 }
481 
482 static const struct platform_device_id max77686_pmic_id[] = {
483         {"max77686-pmic", 0},
484         { },
485 };
486 MODULE_DEVICE_TABLE(platform, max77686_pmic_id);
487 
488 static struct platform_driver max77686_pmic_driver = {
489         .driver = {
490                 .name = "max77686-pmic",
491         },
492         .probe = max77686_pmic_probe,
493         .id_table = max77686_pmic_id,
494 };
495 
496 static int __init max77686_pmic_init(void)
497 {
498         return platform_driver_register(&max77686_pmic_driver);
499 }
500 subsys_initcall(max77686_pmic_init);
501 
502 static void __exit max77686_pmic_cleanup(void)
503 {
504         platform_driver_unregister(&max77686_pmic_driver);
505 }
506 module_exit(max77686_pmic_cleanup);
507 
508 MODULE_DESCRIPTION("MAXIM 77686 Regulator Driver");
509 MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>");
510 MODULE_LICENSE("GPL");
511 

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