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