1
2
3
4#include <linux/module.h>
5#include <linux/of_irq.h>
6#include <linux/of.h>
7#include <linux/of_device.h>
8#include <linux/platform_device.h>
9#include <linux/regmap.h>
10#include <linux/regulator/driver.h>
11#include <linux/regulator/of_regulator.h>
12
13#define REG_PERPH_TYPE 0x04
14
15#define QCOM_LAB_TYPE 0x24
16#define QCOM_IBB_TYPE 0x20
17
18#define PMI8998_LAB_REG_BASE 0xde00
19#define PMI8998_IBB_REG_BASE 0xdc00
20#define PMI8998_IBB_LAB_REG_OFFSET 0x200
21
22#define REG_LABIBB_STATUS1 0x08
23 #define LABIBB_STATUS1_SC_BIT BIT(6)
24 #define LABIBB_STATUS1_VREG_OK_BIT BIT(7)
25
26#define REG_LABIBB_INT_SET_TYPE 0x11
27#define REG_LABIBB_INT_POLARITY_HIGH 0x12
28#define REG_LABIBB_INT_POLARITY_LOW 0x13
29#define REG_LABIBB_INT_LATCHED_CLR 0x14
30#define REG_LABIBB_INT_EN_SET 0x15
31#define REG_LABIBB_INT_EN_CLR 0x16
32 #define LABIBB_INT_VREG_OK BIT(0)
33 #define LABIBB_INT_VREG_TYPE_LEVEL 0
34
35#define REG_LABIBB_VOLTAGE 0x41
36 #define LABIBB_VOLTAGE_OVERRIDE_EN BIT(7)
37 #define LAB_VOLTAGE_SET_MASK GENMASK(3, 0)
38 #define IBB_VOLTAGE_SET_MASK GENMASK(5, 0)
39
40#define REG_LABIBB_ENABLE_CTL 0x46
41 #define LABIBB_CONTROL_ENABLE BIT(7)
42
43#define REG_LABIBB_PD_CTL 0x47
44 #define LAB_PD_CTL_MASK GENMASK(1, 0)
45 #define IBB_PD_CTL_MASK (BIT(0) | BIT(7))
46 #define LAB_PD_CTL_STRONG_PULL BIT(0)
47 #define IBB_PD_CTL_HALF_STRENGTH BIT(0)
48 #define IBB_PD_CTL_EN BIT(7)
49
50#define REG_LABIBB_CURRENT_LIMIT 0x4b
51 #define LAB_CURRENT_LIMIT_MASK GENMASK(2, 0)
52 #define IBB_CURRENT_LIMIT_MASK GENMASK(4, 0)
53 #define LAB_CURRENT_LIMIT_OVERRIDE_EN BIT(3)
54 #define LABIBB_CURRENT_LIMIT_EN BIT(7)
55
56#define REG_IBB_PWRUP_PWRDN_CTL_1 0x58
57 #define IBB_CTL_1_DISCHARGE_EN BIT(2)
58
59#define REG_LABIBB_SOFT_START_CTL 0x5f
60#define REG_LABIBB_SEC_ACCESS 0xd0
61 #define LABIBB_SEC_UNLOCK_CODE 0xa5
62
63#define LAB_ENABLE_CTL_MASK BIT(7)
64#define IBB_ENABLE_CTL_MASK (BIT(7) | BIT(6))
65
66#define LABIBB_OFF_ON_DELAY 1000
67#define LAB_ENABLE_TIME (LABIBB_OFF_ON_DELAY * 2)
68#define IBB_ENABLE_TIME (LABIBB_OFF_ON_DELAY * 10)
69#define LABIBB_POLL_ENABLED_TIME 1000
70#define OCP_RECOVERY_INTERVAL_MS 500
71#define SC_RECOVERY_INTERVAL_MS 250
72#define LABIBB_MAX_OCP_COUNT 4
73#define LABIBB_MAX_SC_COUNT 3
74#define LABIBB_MAX_FATAL_COUNT 2
75
76struct labibb_current_limits {
77 u32 uA_min;
78 u32 uA_step;
79 u8 ovr_val;
80};
81
82struct labibb_regulator {
83 struct regulator_desc desc;
84 struct device *dev;
85 struct regmap *regmap;
86 struct regulator_dev *rdev;
87 struct labibb_current_limits uA_limits;
88 struct delayed_work ocp_recovery_work;
89 struct delayed_work sc_recovery_work;
90 u16 base;
91 u8 type;
92 u8 dischg_sel;
93 u8 soft_start_sel;
94 int sc_irq;
95 int sc_count;
96 int ocp_irq;
97 int ocp_irq_count;
98 int fatal_count;
99};
100
101struct labibb_regulator_data {
102 const char *name;
103 u8 type;
104 u16 base;
105 const struct regulator_desc *desc;
106};
107
108static int qcom_labibb_ocp_hw_enable(struct regulator_dev *rdev)
109{
110 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
111 int ret;
112
113
114 ret = regmap_update_bits(rdev->regmap,
115 vreg->base + REG_LABIBB_INT_LATCHED_CLR,
116 LABIBB_INT_VREG_OK, 1);
117 if (ret)
118 return ret;
119
120
121 return regmap_update_bits(rdev->regmap,
122 vreg->base + REG_LABIBB_INT_EN_SET,
123 LABIBB_INT_VREG_OK, 1);
124}
125
126static int qcom_labibb_ocp_hw_disable(struct regulator_dev *rdev)
127{
128 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
129
130 return regmap_update_bits(rdev->regmap,
131 vreg->base + REG_LABIBB_INT_EN_CLR,
132 LABIBB_INT_VREG_OK, 1);
133}
134
135
136
137
138
139
140
141
142
143
144
145static int qcom_labibb_check_ocp_status(struct labibb_regulator *vreg)
146{
147 u32 cur_status;
148 int ret;
149
150 ret = regmap_read(vreg->rdev->regmap, vreg->base + REG_LABIBB_STATUS1,
151 &cur_status);
152 if (ret)
153 return ret;
154
155 return !(cur_status & LABIBB_STATUS1_VREG_OK_BIT);
156}
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179static void qcom_labibb_ocp_recovery_worker(struct work_struct *work)
180{
181 struct labibb_regulator *vreg;
182 const struct regulator_ops *ops;
183 int ret;
184
185 vreg = container_of(work, struct labibb_regulator,
186 ocp_recovery_work.work);
187 ops = vreg->rdev->desc->ops;
188
189 if (vreg->ocp_irq_count >= LABIBB_MAX_OCP_COUNT) {
190
191
192
193
194
195
196
197
198
199 BUG_ON(vreg->fatal_count > LABIBB_MAX_FATAL_COUNT);
200 dev_err(&vreg->rdev->dev, "LABIBB: CRITICAL: Disabling regulator\n");
201
202
203 ret = ops->disable(vreg->rdev);
204 if (ret) {
205 vreg->fatal_count++;
206 goto reschedule;
207 }
208 enable_irq(vreg->ocp_irq);
209 vreg->fatal_count = 0;
210 return;
211 }
212
213 ret = qcom_labibb_check_ocp_status(vreg);
214 if (ret != 0) {
215 vreg->ocp_irq_count++;
216 goto reschedule;
217 }
218
219 ret = qcom_labibb_ocp_hw_enable(vreg->rdev);
220 if (ret) {
221
222 dev_err(vreg->dev, "Cannot enable OCP IRQ\n");
223 vreg->ocp_irq_count++;
224 goto reschedule;
225 }
226
227 enable_irq(vreg->ocp_irq);
228
229 vreg->ocp_irq_count = 0;
230 return;
231
232reschedule:
233 mod_delayed_work(system_wq, &vreg->ocp_recovery_work,
234 msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));
235}
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255static irqreturn_t qcom_labibb_ocp_isr(int irq, void *chip)
256{
257 struct labibb_regulator *vreg = chip;
258 const struct regulator_ops *ops = vreg->rdev->desc->ops;
259 int ret;
260
261
262 if (!ops->is_enabled(vreg->rdev))
263 return 0;
264
265
266 if (vreg->ocp_irq_count > LABIBB_MAX_OCP_COUNT)
267 return IRQ_NONE;
268
269
270
271
272
273
274
275 ret = qcom_labibb_check_ocp_status(vreg);
276 if (ret == 0) {
277 vreg->ocp_irq_count = 0;
278 goto end;
279 }
280 vreg->ocp_irq_count++;
281
282
283
284
285
286 disable_irq_nosync(irq);
287
288
289 dev_warn(vreg->dev, "Over-Current interrupt fired!\n");
290
291
292 ret = qcom_labibb_ocp_hw_disable(vreg->rdev);
293 if (ret)
294 goto end;
295
296
297 regulator_notifier_call_chain(vreg->rdev,
298 REGULATOR_EVENT_OVER_CURRENT, NULL);
299
300end:
301
302 schedule_delayed_work(&vreg->ocp_recovery_work,
303 msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));
304 if (ret)
305 return IRQ_NONE;
306
307 return IRQ_HANDLED;
308}
309
310static int qcom_labibb_set_ocp(struct regulator_dev *rdev)
311{
312 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
313 char *ocp_irq_name;
314 u32 irq_flags = IRQF_ONESHOT;
315 int irq_trig_low, ret;
316
317
318 if (vreg->ocp_irq <= 0)
319 return -EINVAL;
320
321 ocp_irq_name = devm_kasprintf(vreg->dev, GFP_KERNEL, "%s-over-current",
322 vreg->desc.name);
323 if (!ocp_irq_name)
324 return -ENOMEM;
325
326
327 switch (vreg->type) {
328 case QCOM_LAB_TYPE:
329 irq_flags |= IRQF_TRIGGER_LOW;
330 irq_trig_low = 1;
331 break;
332 case QCOM_IBB_TYPE:
333 irq_flags |= IRQF_TRIGGER_HIGH;
334 irq_trig_low = 0;
335 break;
336 default:
337 return -EINVAL;
338 }
339
340
341 ret = regmap_update_bits(rdev->regmap,
342 vreg->base + REG_LABIBB_INT_SET_TYPE,
343 LABIBB_INT_VREG_OK,
344 LABIBB_INT_VREG_TYPE_LEVEL);
345 if (ret)
346 return ret;
347
348
349 ret = regmap_update_bits(rdev->regmap,
350 vreg->base + REG_LABIBB_INT_POLARITY_HIGH,
351 LABIBB_INT_VREG_OK, !irq_trig_low);
352 if (ret)
353 return ret;
354 ret = regmap_update_bits(rdev->regmap,
355 vreg->base + REG_LABIBB_INT_POLARITY_LOW,
356 LABIBB_INT_VREG_OK, irq_trig_low);
357 if (ret)
358 return ret;
359
360 ret = qcom_labibb_ocp_hw_enable(rdev);
361 if (ret)
362 return ret;
363
364 return devm_request_threaded_irq(vreg->dev, vreg->ocp_irq, NULL,
365 qcom_labibb_ocp_isr, irq_flags,
366 ocp_irq_name, vreg);
367}
368
369
370
371
372
373
374
375
376
377
378
379
380static int qcom_labibb_check_sc_status(struct labibb_regulator *vreg)
381{
382 u32 ibb_status, ibb_reg, lab_status, lab_reg;
383 int ret;
384
385
386 lab_reg = ibb_reg = vreg->base + REG_LABIBB_STATUS1;
387 if (vreg->type == QCOM_LAB_TYPE)
388 ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;
389 else
390 lab_reg += PMI8998_IBB_LAB_REG_OFFSET;
391
392 ret = regmap_read(vreg->rdev->regmap, lab_reg, &lab_status);
393 if (ret)
394 return ret;
395 ret = regmap_read(vreg->rdev->regmap, ibb_reg, &ibb_status);
396 if (ret)
397 return ret;
398
399 return !!(lab_status & LABIBB_STATUS1_SC_BIT) ||
400 !!(ibb_status & LABIBB_STATUS1_SC_BIT);
401}
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420static void qcom_labibb_sc_recovery_worker(struct work_struct *work)
421{
422 struct labibb_regulator *vreg;
423 const struct regulator_ops *ops;
424 u32 lab_reg, ibb_reg, lab_val, ibb_val, val;
425 bool pbs_cut = false;
426 int i, sc, ret;
427
428 vreg = container_of(work, struct labibb_regulator,
429 sc_recovery_work.work);
430 ops = vreg->rdev->desc->ops;
431
432
433
434
435
436
437 if (vreg->fatal_count > LABIBB_MAX_FATAL_COUNT)
438 return;
439
440
441 if (vreg->sc_count > LABIBB_MAX_SC_COUNT)
442 return;
443
444
445
446
447
448
449 lab_reg = ibb_reg = vreg->base + REG_LABIBB_ENABLE_CTL;
450 if (vreg->type == QCOM_LAB_TYPE)
451 ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;
452 else
453 lab_reg += PMI8998_IBB_LAB_REG_OFFSET;
454
455 sc = qcom_labibb_check_sc_status(vreg);
456 if (sc)
457 goto reschedule;
458
459 for (i = 0; i < LABIBB_MAX_SC_COUNT; i++) {
460 ret = regmap_read(vreg->regmap, lab_reg, &lab_val);
461 if (ret) {
462 vreg->fatal_count++;
463 goto reschedule;
464 }
465
466 ret = regmap_read(vreg->regmap, ibb_reg, &ibb_val);
467 if (ret) {
468 vreg->fatal_count++;
469 goto reschedule;
470 }
471 val = lab_val & ibb_val;
472
473 if (!(val & LABIBB_CONTROL_ENABLE)) {
474 pbs_cut = true;
475 break;
476 }
477 usleep_range(5000, 6000);
478 }
479 if (pbs_cut)
480 goto reschedule;
481
482
483
484
485
486
487
488
489 ret = ops->enable(vreg->rdev);
490 if (ret)
491 goto reschedule;
492
493
494 vreg->sc_count = 0;
495 enable_irq(vreg->sc_irq);
496 return;
497
498reschedule:
499
500
501
502
503
504 vreg->sc_count++;
505 mod_delayed_work(system_wq, &vreg->sc_recovery_work,
506 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));
507}
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525static irqreturn_t qcom_labibb_sc_isr(int irq, void *chip)
526{
527 struct labibb_regulator *vreg = chip;
528
529 if (vreg->sc_count > LABIBB_MAX_SC_COUNT)
530 return IRQ_NONE;
531
532
533 dev_warn(vreg->dev, "Short-Circuit interrupt fired!\n");
534
535
536
537
538
539 disable_irq_nosync(irq);
540
541
542 regulator_notifier_call_chain(vreg->rdev,
543 REGULATOR_EVENT_REGULATION_OUT, NULL);
544
545
546 mod_delayed_work(system_highpri_wq, &vreg->sc_recovery_work,
547 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));
548 return IRQ_HANDLED;
549}
550
551
552static int qcom_labibb_set_current_limit(struct regulator_dev *rdev,
553 int min_uA, int max_uA)
554{
555 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
556 struct regulator_desc *desc = &vreg->desc;
557 struct labibb_current_limits *lim = &vreg->uA_limits;
558 u32 mask, val;
559 int i, ret, sel = -1;
560
561 if (min_uA < lim->uA_min || max_uA < lim->uA_min)
562 return -EINVAL;
563
564 for (i = 0; i < desc->n_current_limits; i++) {
565 int uA_limit = (lim->uA_step * i) + lim->uA_min;
566
567 if (max_uA >= uA_limit && min_uA <= uA_limit)
568 sel = i;
569 }
570 if (sel < 0)
571 return -EINVAL;
572
573
574 ret = regmap_write(vreg->regmap, vreg->base + REG_LABIBB_SEC_ACCESS,
575 LABIBB_SEC_UNLOCK_CODE);
576 if (ret)
577 return ret;
578
579 mask = desc->csel_mask | lim->ovr_val;
580 mask |= LABIBB_CURRENT_LIMIT_EN;
581 val = (u32)sel | lim->ovr_val;
582 val |= LABIBB_CURRENT_LIMIT_EN;
583
584 return regmap_update_bits(vreg->regmap, desc->csel_reg, mask, val);
585}
586
587static int qcom_labibb_get_current_limit(struct regulator_dev *rdev)
588{
589 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
590 struct regulator_desc *desc = &vreg->desc;
591 struct labibb_current_limits *lim = &vreg->uA_limits;
592 unsigned int cur_step;
593 int ret;
594
595 ret = regmap_read(vreg->regmap, desc->csel_reg, &cur_step);
596 if (ret)
597 return ret;
598 cur_step &= desc->csel_mask;
599
600 return (cur_step * lim->uA_step) + lim->uA_min;
601}
602
603static int qcom_labibb_set_soft_start(struct regulator_dev *rdev)
604{
605 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
606 u32 val = 0;
607
608 if (vreg->type == QCOM_IBB_TYPE)
609 val = vreg->dischg_sel;
610 else
611 val = vreg->soft_start_sel;
612
613 return regmap_write(rdev->regmap, rdev->desc->soft_start_reg, val);
614}
615
616static int qcom_labibb_get_table_sel(const int *table, int sz, u32 value)
617{
618 int i;
619
620 for (i = 0; i < sz; i++)
621 if (table[i] == value)
622 return i;
623 return -EINVAL;
624}
625
626
627static const int dischg_resistor_values[] = { 300, 64, 32, 16 };
628
629
630static const int soft_start_values[] = { 200, 400, 600, 800 };
631
632static int qcom_labibb_of_parse_cb(struct device_node *np,
633 const struct regulator_desc *desc,
634 struct regulator_config *config)
635{
636 struct labibb_regulator *vreg = config->driver_data;
637 u32 dischg_kohms, soft_start_time;
638 int ret;
639
640 ret = of_property_read_u32(np, "qcom,discharge-resistor-kohms",
641 &dischg_kohms);
642 if (ret)
643 dischg_kohms = 300;
644
645 ret = qcom_labibb_get_table_sel(dischg_resistor_values,
646 ARRAY_SIZE(dischg_resistor_values),
647 dischg_kohms);
648 if (ret < 0)
649 return ret;
650 vreg->dischg_sel = (u8)ret;
651
652 ret = of_property_read_u32(np, "qcom,soft-start-us",
653 &soft_start_time);
654 if (ret)
655 soft_start_time = 200;
656
657 ret = qcom_labibb_get_table_sel(soft_start_values,
658 ARRAY_SIZE(soft_start_values),
659 soft_start_time);
660 if (ret < 0)
661 return ret;
662 vreg->soft_start_sel = (u8)ret;
663
664 return 0;
665}
666
667static const struct regulator_ops qcom_labibb_ops = {
668 .enable = regulator_enable_regmap,
669 .disable = regulator_disable_regmap,
670 .is_enabled = regulator_is_enabled_regmap,
671 .set_voltage_sel = regulator_set_voltage_sel_regmap,
672 .get_voltage_sel = regulator_get_voltage_sel_regmap,
673 .list_voltage = regulator_list_voltage_linear,
674 .map_voltage = regulator_map_voltage_linear,
675 .set_active_discharge = regulator_set_active_discharge_regmap,
676 .set_pull_down = regulator_set_pull_down_regmap,
677 .set_current_limit = qcom_labibb_set_current_limit,
678 .get_current_limit = qcom_labibb_get_current_limit,
679 .set_soft_start = qcom_labibb_set_soft_start,
680 .set_over_current_protection = qcom_labibb_set_ocp,
681};
682
683static const struct regulator_desc pmi8998_lab_desc = {
684 .enable_mask = LAB_ENABLE_CTL_MASK,
685 .enable_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_ENABLE_CTL),
686 .enable_val = LABIBB_CONTROL_ENABLE,
687 .enable_time = LAB_ENABLE_TIME,
688 .poll_enabled_time = LABIBB_POLL_ENABLED_TIME,
689 .soft_start_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_SOFT_START_CTL),
690 .pull_down_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_PD_CTL),
691 .pull_down_mask = LAB_PD_CTL_MASK,
692 .pull_down_val_on = LAB_PD_CTL_STRONG_PULL,
693 .vsel_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),
694 .vsel_mask = LAB_VOLTAGE_SET_MASK,
695 .apply_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),
696 .apply_bit = LABIBB_VOLTAGE_OVERRIDE_EN,
697 .csel_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),
698 .csel_mask = LAB_CURRENT_LIMIT_MASK,
699 .n_current_limits = 8,
700 .off_on_delay = LABIBB_OFF_ON_DELAY,
701 .owner = THIS_MODULE,
702 .type = REGULATOR_VOLTAGE,
703 .min_uV = 4600000,
704 .uV_step = 100000,
705 .n_voltages = 16,
706 .ops = &qcom_labibb_ops,
707 .of_parse_cb = qcom_labibb_of_parse_cb,
708};
709
710static const struct regulator_desc pmi8998_ibb_desc = {
711 .enable_mask = IBB_ENABLE_CTL_MASK,
712 .enable_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_ENABLE_CTL),
713 .enable_val = LABIBB_CONTROL_ENABLE,
714 .enable_time = IBB_ENABLE_TIME,
715 .poll_enabled_time = LABIBB_POLL_ENABLED_TIME,
716 .soft_start_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_SOFT_START_CTL),
717 .active_discharge_off = 0,
718 .active_discharge_on = IBB_CTL_1_DISCHARGE_EN,
719 .active_discharge_mask = IBB_CTL_1_DISCHARGE_EN,
720 .active_discharge_reg = (PMI8998_IBB_REG_BASE + REG_IBB_PWRUP_PWRDN_CTL_1),
721 .pull_down_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_PD_CTL),
722 .pull_down_mask = IBB_PD_CTL_MASK,
723 .pull_down_val_on = IBB_PD_CTL_HALF_STRENGTH | IBB_PD_CTL_EN,
724 .vsel_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),
725 .vsel_mask = IBB_VOLTAGE_SET_MASK,
726 .apply_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),
727 .apply_bit = LABIBB_VOLTAGE_OVERRIDE_EN,
728 .csel_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),
729 .csel_mask = IBB_CURRENT_LIMIT_MASK,
730 .n_current_limits = 32,
731 .off_on_delay = LABIBB_OFF_ON_DELAY,
732 .owner = THIS_MODULE,
733 .type = REGULATOR_VOLTAGE,
734 .min_uV = 1400000,
735 .uV_step = 100000,
736 .n_voltages = 64,
737 .ops = &qcom_labibb_ops,
738 .of_parse_cb = qcom_labibb_of_parse_cb,
739};
740
741static const struct labibb_regulator_data pmi8998_labibb_data[] = {
742 {"lab", QCOM_LAB_TYPE, PMI8998_LAB_REG_BASE, &pmi8998_lab_desc},
743 {"ibb", QCOM_IBB_TYPE, PMI8998_IBB_REG_BASE, &pmi8998_ibb_desc},
744 { },
745};
746
747static const struct of_device_id qcom_labibb_match[] = {
748 { .compatible = "qcom,pmi8998-lab-ibb", .data = &pmi8998_labibb_data},
749 { },
750};
751MODULE_DEVICE_TABLE(of, qcom_labibb_match);
752
753static int qcom_labibb_regulator_probe(struct platform_device *pdev)
754{
755 struct labibb_regulator *vreg;
756 struct device *dev = &pdev->dev;
757 struct regulator_config cfg = {};
758 struct device_node *reg_node;
759 const struct of_device_id *match;
760 const struct labibb_regulator_data *reg_data;
761 struct regmap *reg_regmap;
762 unsigned int type;
763 int ret;
764
765 reg_regmap = dev_get_regmap(pdev->dev.parent, NULL);
766 if (!reg_regmap) {
767 dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
768 return -ENODEV;
769 }
770
771 match = of_match_device(qcom_labibb_match, &pdev->dev);
772 if (!match)
773 return -ENODEV;
774
775 for (reg_data = match->data; reg_data->name; reg_data++) {
776 char *sc_irq_name;
777 int irq = 0;
778
779
780
781
782 ret = regmap_read(reg_regmap, reg_data->base + REG_PERPH_TYPE,
783 &type);
784 if (ret < 0) {
785 dev_err(dev,
786 "Peripheral type read failed ret=%d\n",
787 ret);
788 return -EINVAL;
789 }
790
791 if (WARN_ON((type != QCOM_LAB_TYPE) && (type != QCOM_IBB_TYPE)) ||
792 WARN_ON(type != reg_data->type))
793 return -EINVAL;
794
795 vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg),
796 GFP_KERNEL);
797 if (!vreg)
798 return -ENOMEM;
799
800 sc_irq_name = devm_kasprintf(dev, GFP_KERNEL,
801 "%s-short-circuit",
802 reg_data->name);
803 if (!sc_irq_name)
804 return -ENOMEM;
805
806 reg_node = of_get_child_by_name(pdev->dev.of_node,
807 reg_data->name);
808 if (!reg_node)
809 return -EINVAL;
810
811
812 irq = of_irq_get_byname(reg_node, "sc-err");
813 if (irq <= 0) {
814 if (irq == 0)
815 irq = -EINVAL;
816
817 return dev_err_probe(vreg->dev, irq,
818 "Short-circuit irq not found.\n");
819 }
820 vreg->sc_irq = irq;
821
822
823 irq = of_irq_get_byname(reg_node, "ocp");
824 vreg->ocp_irq = irq;
825 vreg->ocp_irq_count = 0;
826 of_node_put(reg_node);
827
828 vreg->regmap = reg_regmap;
829 vreg->dev = dev;
830 vreg->base = reg_data->base;
831 vreg->type = reg_data->type;
832 INIT_DELAYED_WORK(&vreg->sc_recovery_work,
833 qcom_labibb_sc_recovery_worker);
834
835 if (vreg->ocp_irq > 0)
836 INIT_DELAYED_WORK(&vreg->ocp_recovery_work,
837 qcom_labibb_ocp_recovery_worker);
838
839 switch (vreg->type) {
840 case QCOM_LAB_TYPE:
841
842 vreg->uA_limits.uA_min = 200000;
843 vreg->uA_limits.uA_step = 200000;
844 vreg->uA_limits.ovr_val = LAB_CURRENT_LIMIT_OVERRIDE_EN;
845 break;
846 case QCOM_IBB_TYPE:
847
848 vreg->uA_limits.uA_min = 0;
849 vreg->uA_limits.uA_step = 50000;
850 vreg->uA_limits.ovr_val = 0;
851 break;
852 default:
853 return -EINVAL;
854 }
855
856 memcpy(&vreg->desc, reg_data->desc, sizeof(vreg->desc));
857 vreg->desc.of_match = reg_data->name;
858 vreg->desc.name = reg_data->name;
859
860 cfg.dev = vreg->dev;
861 cfg.driver_data = vreg;
862 cfg.regmap = vreg->regmap;
863
864 vreg->rdev = devm_regulator_register(vreg->dev, &vreg->desc,
865 &cfg);
866
867 if (IS_ERR(vreg->rdev)) {
868 dev_err(dev, "qcom_labibb: error registering %s : %d\n",
869 reg_data->name, ret);
870 return PTR_ERR(vreg->rdev);
871 }
872
873 ret = devm_request_threaded_irq(vreg->dev, vreg->sc_irq, NULL,
874 qcom_labibb_sc_isr,
875 IRQF_ONESHOT |
876 IRQF_TRIGGER_RISING,
877 sc_irq_name, vreg);
878 if (ret)
879 return ret;
880 }
881
882 return 0;
883}
884
885static struct platform_driver qcom_labibb_regulator_driver = {
886 .driver = {
887 .name = "qcom-lab-ibb-regulator",
888 .of_match_table = qcom_labibb_match,
889 },
890 .probe = qcom_labibb_regulator_probe,
891};
892module_platform_driver(qcom_labibb_regulator_driver);
893
894MODULE_DESCRIPTION("Qualcomm labibb driver");
895MODULE_AUTHOR("Nisha Kumari <nishakumari@codeaurora.org>");
896MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>");
897MODULE_LICENSE("GPL v2");
898