1
2
3
4
5
6
7
8
9
10
11#include <linux/gpio.h>
12#include <linux/i2c.h>
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/regmap.h>
18#include <linux/regulator/driver.h>
19#include <linux/suspend.h>
20#include <linux/gpio/consumer.h>
21
22#define VDD_LOW_SEL 0x0D
23#define VDD_HIGH_SEL 0x3F
24
25#define MCP16502_FLT BIT(7)
26#define MCP16502_DVSR GENMASK(3, 2)
27#define MCP16502_ENS BIT(0)
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58#define MCP16502_REG_BASE(i, r) ((((i) + 1) << 4) + MCP16502_REG_##r)
59#define MCP16502_STAT_BASE(i) ((i) + 5)
60
61#define MCP16502_OPMODE_ACTIVE REGULATOR_MODE_NORMAL
62#define MCP16502_OPMODE_LPM REGULATOR_MODE_IDLE
63#define MCP16502_OPMODE_HIB REGULATOR_MODE_STANDBY
64
65#define MCP16502_MODE_AUTO_PFM 0
66#define MCP16502_MODE_FPWM BIT(6)
67
68#define MCP16502_VSEL 0x3F
69#define MCP16502_EN BIT(7)
70#define MCP16502_MODE BIT(6)
71
72#define MCP16502_MIN_REG 0x0
73#define MCP16502_MAX_REG 0x65
74
75
76
77
78
79
80
81
82
83enum mcp16502_reg {
84 MCP16502_REG_A,
85 MCP16502_REG_LPM,
86 MCP16502_REG_HIB,
87 MCP16502_REG_HPM,
88 MCP16502_REG_SEQ,
89 MCP16502_REG_CFG,
90};
91
92
93static const int mcp16502_ramp_b1l12[] = { 6250, 3125, 2083, 1563 };
94
95
96static const int mcp16502_ramp_b234[] = { 3125, 1563, 1042, 781 };
97
98static unsigned int mcp16502_of_map_mode(unsigned int mode)
99{
100 if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE)
101 return mode;
102
103 return REGULATOR_MODE_INVALID;
104}
105
106#define MCP16502_REGULATOR(_name, _id, _ranges, _ops) \
107 [_id] = { \
108 .name = _name, \
109 .regulators_node = of_match_ptr("regulators"), \
110 .id = _id, \
111 .ops = &(_ops), \
112 .type = REGULATOR_VOLTAGE, \
113 .owner = THIS_MODULE, \
114 .n_voltages = MCP16502_VSEL + 1, \
115 .linear_ranges = _ranges, \
116 .linear_min_sel = VDD_LOW_SEL, \
117 .n_linear_ranges = ARRAY_SIZE(_ranges), \
118 .of_match = of_match_ptr(_name), \
119 .of_map_mode = mcp16502_of_map_mode, \
120 .vsel_reg = (((_id) + 1) << 4), \
121 .vsel_mask = MCP16502_VSEL, \
122 .enable_reg = (((_id) + 1) << 4), \
123 .enable_mask = MCP16502_EN, \
124 }
125
126enum {
127 BUCK1 = 0,
128 BUCK2,
129 BUCK3,
130 BUCK4,
131 LDO1,
132 LDO2,
133 NUM_REGULATORS
134};
135
136
137
138
139
140struct mcp16502 {
141 struct gpio_desc *lpm;
142};
143
144
145
146
147
148
149static void mcp16502_gpio_set_mode(struct mcp16502 *mcp, int mode)
150{
151 switch (mode) {
152 case MCP16502_OPMODE_ACTIVE:
153 gpiod_set_value(mcp->lpm, 0);
154 break;
155 case MCP16502_OPMODE_LPM:
156 case MCP16502_OPMODE_HIB:
157 gpiod_set_value(mcp->lpm, 1);
158 break;
159 default:
160 pr_err("%s: %d invalid\n", __func__, mode);
161 }
162}
163
164
165
166
167
168
169
170static int mcp16502_get_state_reg(struct regulator_dev *rdev, int opmode)
171{
172 switch (opmode) {
173 case MCP16502_OPMODE_ACTIVE:
174 return MCP16502_REG_BASE(rdev_get_id(rdev), A);
175 case MCP16502_OPMODE_LPM:
176 return MCP16502_REG_BASE(rdev_get_id(rdev), LPM);
177 case MCP16502_OPMODE_HIB:
178 return MCP16502_REG_BASE(rdev_get_id(rdev), HIB);
179 default:
180 return -EINVAL;
181 }
182}
183
184
185
186
187
188
189
190
191
192
193static unsigned int mcp16502_get_mode(struct regulator_dev *rdev)
194{
195 unsigned int val;
196 int ret, reg;
197
198 reg = mcp16502_get_state_reg(rdev, MCP16502_OPMODE_ACTIVE);
199 if (reg < 0)
200 return reg;
201
202 ret = regmap_read(rdev->regmap, reg, &val);
203 if (ret)
204 return ret;
205
206 switch (val & MCP16502_MODE) {
207 case MCP16502_MODE_FPWM:
208 return REGULATOR_MODE_NORMAL;
209 case MCP16502_MODE_AUTO_PFM:
210 return REGULATOR_MODE_IDLE;
211 default:
212 return REGULATOR_MODE_INVALID;
213 }
214}
215
216
217
218
219
220
221
222
223static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode,
224 unsigned int op_mode)
225{
226 int val;
227 int reg;
228
229 reg = mcp16502_get_state_reg(rdev, op_mode);
230 if (reg < 0)
231 return reg;
232
233 switch (mode) {
234 case REGULATOR_MODE_NORMAL:
235 val = MCP16502_MODE_FPWM;
236 break;
237 case REGULATOR_MODE_IDLE:
238 val = MCP16502_MODE_AUTO_PFM;
239 break;
240 default:
241 return -EINVAL;
242 }
243
244 reg = regmap_update_bits(rdev->regmap, reg, MCP16502_MODE, val);
245 return reg;
246}
247
248
249
250
251static int mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode)
252{
253 return _mcp16502_set_mode(rdev, mode, MCP16502_OPMODE_ACTIVE);
254}
255
256
257
258
259static int mcp16502_get_status(struct regulator_dev *rdev)
260{
261 int ret;
262 unsigned int val;
263
264 ret = regmap_read(rdev->regmap, MCP16502_STAT_BASE(rdev_get_id(rdev)),
265 &val);
266 if (ret)
267 return ret;
268
269 if (val & MCP16502_FLT)
270 return REGULATOR_STATUS_ERROR;
271 else if (val & MCP16502_ENS)
272 return REGULATOR_STATUS_ON;
273 else if (!(val & MCP16502_ENS))
274 return REGULATOR_STATUS_OFF;
275
276 return REGULATOR_STATUS_UNDEFINED;
277}
278
279static int mcp16502_set_voltage_time_sel(struct regulator_dev *rdev,
280 unsigned int old_sel,
281 unsigned int new_sel)
282{
283 static const u8 us_ramp[] = { 8, 16, 24, 32 };
284 int id = rdev_get_id(rdev);
285 unsigned int uV_delta, val;
286 int ret;
287
288 ret = regmap_read(rdev->regmap, MCP16502_REG_BASE(id, CFG), &val);
289 if (ret)
290 return ret;
291
292 val = (val & MCP16502_DVSR) >> 2;
293 uV_delta = abs(new_sel * rdev->desc->linear_ranges->step -
294 old_sel * rdev->desc->linear_ranges->step);
295 switch (id) {
296 case BUCK1:
297 case LDO1:
298 case LDO2:
299 ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val],
300 mcp16502_ramp_b1l12[val]);
301 break;
302
303 case BUCK2:
304 case BUCK3:
305 case BUCK4:
306 ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val],
307 mcp16502_ramp_b234[val]);
308 break;
309
310 default:
311 return -EINVAL;
312 }
313
314 return ret;
315}
316
317static int mcp16502_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
318{
319 const int *ramp;
320 int id = rdev_get_id(rdev);
321 unsigned int i, size;
322
323 switch (id) {
324 case BUCK1:
325 case LDO1:
326 case LDO2:
327 ramp = mcp16502_ramp_b1l12;
328 size = ARRAY_SIZE(mcp16502_ramp_b1l12);
329 break;
330
331 case BUCK2:
332 case BUCK3:
333 case BUCK4:
334 ramp = mcp16502_ramp_b234;
335 size = ARRAY_SIZE(mcp16502_ramp_b234);
336 break;
337
338 default:
339 return -EINVAL;
340 }
341
342 for (i = 0; i < size; i++) {
343 if (ramp[i] == ramp_delay)
344 break;
345 }
346 if (i == size)
347 return -EINVAL;
348
349 return regmap_update_bits(rdev->regmap, MCP16502_REG_BASE(id, CFG),
350 MCP16502_DVSR, (i << 2));
351}
352
353#ifdef CONFIG_SUSPEND
354
355
356
357
358static int mcp16502_suspend_get_target_reg(struct regulator_dev *rdev)
359{
360 switch (pm_suspend_target_state) {
361 case PM_SUSPEND_STANDBY:
362 return mcp16502_get_state_reg(rdev, MCP16502_OPMODE_LPM);
363 case PM_SUSPEND_ON:
364 case PM_SUSPEND_MEM:
365 return mcp16502_get_state_reg(rdev, MCP16502_OPMODE_HIB);
366 default:
367 dev_err(&rdev->dev, "invalid suspend target: %d\n",
368 pm_suspend_target_state);
369 }
370
371 return -EINVAL;
372}
373
374
375
376
377static int mcp16502_set_suspend_voltage(struct regulator_dev *rdev, int uV)
378{
379 int sel = regulator_map_voltage_linear_range(rdev, uV, uV);
380 int reg = mcp16502_suspend_get_target_reg(rdev);
381
382 if (sel < 0)
383 return sel;
384
385 if (reg < 0)
386 return reg;
387
388 return regmap_update_bits(rdev->regmap, reg, MCP16502_VSEL, sel);
389}
390
391
392
393
394static int mcp16502_set_suspend_mode(struct regulator_dev *rdev,
395 unsigned int mode)
396{
397 switch (pm_suspend_target_state) {
398 case PM_SUSPEND_STANDBY:
399 return _mcp16502_set_mode(rdev, mode, MCP16502_OPMODE_LPM);
400 case PM_SUSPEND_ON:
401 case PM_SUSPEND_MEM:
402 return _mcp16502_set_mode(rdev, mode, MCP16502_OPMODE_HIB);
403 default:
404 dev_err(&rdev->dev, "invalid suspend target: %d\n",
405 pm_suspend_target_state);
406 }
407
408 return -EINVAL;
409}
410
411
412
413
414static int mcp16502_set_suspend_enable(struct regulator_dev *rdev)
415{
416 int reg = mcp16502_suspend_get_target_reg(rdev);
417
418 if (reg < 0)
419 return reg;
420
421 return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, MCP16502_EN);
422}
423
424
425
426
427static int mcp16502_set_suspend_disable(struct regulator_dev *rdev)
428{
429 int reg = mcp16502_suspend_get_target_reg(rdev);
430
431 if (reg < 0)
432 return reg;
433
434 return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, 0);
435}
436#endif
437
438static const struct regulator_ops mcp16502_buck_ops = {
439 .list_voltage = regulator_list_voltage_linear_range,
440 .map_voltage = regulator_map_voltage_linear_range,
441 .get_voltage_sel = regulator_get_voltage_sel_regmap,
442 .set_voltage_sel = regulator_set_voltage_sel_regmap,
443 .enable = regulator_enable_regmap,
444 .disable = regulator_disable_regmap,
445 .is_enabled = regulator_is_enabled_regmap,
446 .get_status = mcp16502_get_status,
447 .set_voltage_time_sel = mcp16502_set_voltage_time_sel,
448 .set_ramp_delay = mcp16502_set_ramp_delay,
449
450 .set_mode = mcp16502_set_mode,
451 .get_mode = mcp16502_get_mode,
452
453#ifdef CONFIG_SUSPEND
454 .set_suspend_voltage = mcp16502_set_suspend_voltage,
455 .set_suspend_mode = mcp16502_set_suspend_mode,
456 .set_suspend_enable = mcp16502_set_suspend_enable,
457 .set_suspend_disable = mcp16502_set_suspend_disable,
458#endif
459};
460
461
462
463
464static const struct regulator_ops mcp16502_ldo_ops = {
465 .list_voltage = regulator_list_voltage_linear_range,
466 .map_voltage = regulator_map_voltage_linear_range,
467 .get_voltage_sel = regulator_get_voltage_sel_regmap,
468 .set_voltage_sel = regulator_set_voltage_sel_regmap,
469 .enable = regulator_enable_regmap,
470 .disable = regulator_disable_regmap,
471 .is_enabled = regulator_is_enabled_regmap,
472 .get_status = mcp16502_get_status,
473 .set_voltage_time_sel = mcp16502_set_voltage_time_sel,
474 .set_ramp_delay = mcp16502_set_ramp_delay,
475
476#ifdef CONFIG_SUSPEND
477 .set_suspend_voltage = mcp16502_set_suspend_voltage,
478 .set_suspend_enable = mcp16502_set_suspend_enable,
479 .set_suspend_disable = mcp16502_set_suspend_disable,
480#endif
481};
482
483static const struct of_device_id mcp16502_ids[] = {
484 { .compatible = "microchip,mcp16502", },
485 {}
486};
487MODULE_DEVICE_TABLE(of, mcp16502_ids);
488
489static const struct linear_range b1l12_ranges[] = {
490 REGULATOR_LINEAR_RANGE(1200000, VDD_LOW_SEL, VDD_HIGH_SEL, 50000),
491};
492
493static const struct linear_range b234_ranges[] = {
494 REGULATOR_LINEAR_RANGE(600000, VDD_LOW_SEL, VDD_HIGH_SEL, 25000),
495};
496
497static const struct regulator_desc mcp16502_desc[] = {
498
499 MCP16502_REGULATOR("VDD_IO", BUCK1, b1l12_ranges, mcp16502_buck_ops),
500 MCP16502_REGULATOR("VDD_DDR", BUCK2, b234_ranges, mcp16502_buck_ops),
501 MCP16502_REGULATOR("VDD_CORE", BUCK3, b234_ranges, mcp16502_buck_ops),
502 MCP16502_REGULATOR("VDD_OTHER", BUCK4, b234_ranges, mcp16502_buck_ops),
503 MCP16502_REGULATOR("LDO1", LDO1, b1l12_ranges, mcp16502_ldo_ops),
504 MCP16502_REGULATOR("LDO2", LDO2, b1l12_ranges, mcp16502_ldo_ops)
505};
506
507static const struct regmap_range mcp16502_ranges[] = {
508 regmap_reg_range(MCP16502_MIN_REG, MCP16502_MAX_REG)
509};
510
511static const struct regmap_access_table mcp16502_yes_reg_table = {
512 .yes_ranges = mcp16502_ranges,
513 .n_yes_ranges = ARRAY_SIZE(mcp16502_ranges),
514};
515
516static const struct regmap_config mcp16502_regmap_config = {
517 .reg_bits = 8,
518 .val_bits = 8,
519 .max_register = MCP16502_MAX_REG,
520 .cache_type = REGCACHE_NONE,
521 .rd_table = &mcp16502_yes_reg_table,
522 .wr_table = &mcp16502_yes_reg_table,
523};
524
525static int mcp16502_probe(struct i2c_client *client,
526 const struct i2c_device_id *id)
527{
528 struct regulator_config config = { };
529 struct regulator_dev *rdev;
530 struct device *dev;
531 struct mcp16502 *mcp;
532 struct regmap *rmap;
533 int i, ret;
534
535 dev = &client->dev;
536 config.dev = dev;
537
538 mcp = devm_kzalloc(dev, sizeof(*mcp), GFP_KERNEL);
539 if (!mcp)
540 return -ENOMEM;
541
542 rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config);
543 if (IS_ERR(rmap)) {
544 ret = PTR_ERR(rmap);
545 dev_err(dev, "regmap init failed: %d\n", ret);
546 return ret;
547 }
548
549 i2c_set_clientdata(client, mcp);
550 config.regmap = rmap;
551 config.driver_data = mcp;
552
553 mcp->lpm = devm_gpiod_get_optional(dev, "lpm", GPIOD_OUT_LOW);
554 if (IS_ERR(mcp->lpm)) {
555 dev_err(dev, "failed to get lpm pin: %ld\n", PTR_ERR(mcp->lpm));
556 return PTR_ERR(mcp->lpm);
557 }
558
559 for (i = 0; i < NUM_REGULATORS; i++) {
560 rdev = devm_regulator_register(dev, &mcp16502_desc[i], &config);
561 if (IS_ERR(rdev)) {
562 dev_err(dev,
563 "failed to register %s regulator %ld\n",
564 mcp16502_desc[i].name, PTR_ERR(rdev));
565 return PTR_ERR(rdev);
566 }
567 }
568
569 mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
570
571 return 0;
572}
573
574#ifdef CONFIG_PM_SLEEP
575static int mcp16502_suspend_noirq(struct device *dev)
576{
577 struct i2c_client *client = to_i2c_client(dev);
578 struct mcp16502 *mcp = i2c_get_clientdata(client);
579
580 mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_LPM);
581
582 return 0;
583}
584
585static int mcp16502_resume_noirq(struct device *dev)
586{
587 struct i2c_client *client = to_i2c_client(dev);
588 struct mcp16502 *mcp = i2c_get_clientdata(client);
589
590 mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
591
592 return 0;
593}
594#endif
595
596#ifdef CONFIG_PM
597static const struct dev_pm_ops mcp16502_pm_ops = {
598 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mcp16502_suspend_noirq,
599 mcp16502_resume_noirq)
600};
601#endif
602static const struct i2c_device_id mcp16502_i2c_id[] = {
603 { "mcp16502", 0 },
604 { }
605};
606MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);
607
608static struct i2c_driver mcp16502_drv = {
609 .probe = mcp16502_probe,
610 .driver = {
611 .name = "mcp16502-regulator",
612 .of_match_table = of_match_ptr(mcp16502_ids),
613#ifdef CONFIG_PM
614 .pm = &mcp16502_pm_ops,
615#endif
616 },
617 .id_table = mcp16502_i2c_id,
618};
619
620module_i2c_driver(mcp16502_drv);
621
622MODULE_LICENSE("GPL v2");
623MODULE_DESCRIPTION("MCP16502 PMIC driver");
624MODULE_AUTHOR("Andrei Stefanescu andrei.stefanescu@microchip.com");
625