0001
0002
0003
0004 #include <linux/module.h>
0005 #include <linux/of_irq.h>
0006 #include <linux/of.h>
0007 #include <linux/of_device.h>
0008 #include <linux/platform_device.h>
0009 #include <linux/regmap.h>
0010 #include <linux/regulator/driver.h>
0011 #include <linux/regulator/of_regulator.h>
0012
0013 #define REG_PERPH_TYPE 0x04
0014
0015 #define QCOM_LAB_TYPE 0x24
0016 #define QCOM_IBB_TYPE 0x20
0017
0018 #define PMI8998_LAB_REG_BASE 0xde00
0019 #define PMI8998_IBB_REG_BASE 0xdc00
0020 #define PMI8998_IBB_LAB_REG_OFFSET 0x200
0021
0022 #define REG_LABIBB_STATUS1 0x08
0023 #define LABIBB_STATUS1_SC_BIT BIT(6)
0024 #define LABIBB_STATUS1_VREG_OK_BIT BIT(7)
0025
0026 #define REG_LABIBB_INT_SET_TYPE 0x11
0027 #define REG_LABIBB_INT_POLARITY_HIGH 0x12
0028 #define REG_LABIBB_INT_POLARITY_LOW 0x13
0029 #define REG_LABIBB_INT_LATCHED_CLR 0x14
0030 #define REG_LABIBB_INT_EN_SET 0x15
0031 #define REG_LABIBB_INT_EN_CLR 0x16
0032 #define LABIBB_INT_VREG_OK BIT(0)
0033 #define LABIBB_INT_VREG_TYPE_LEVEL 0
0034
0035 #define REG_LABIBB_VOLTAGE 0x41
0036 #define LABIBB_VOLTAGE_OVERRIDE_EN BIT(7)
0037 #define LAB_VOLTAGE_SET_MASK GENMASK(3, 0)
0038 #define IBB_VOLTAGE_SET_MASK GENMASK(5, 0)
0039
0040 #define REG_LABIBB_ENABLE_CTL 0x46
0041 #define LABIBB_CONTROL_ENABLE BIT(7)
0042
0043 #define REG_LABIBB_PD_CTL 0x47
0044 #define LAB_PD_CTL_MASK GENMASK(1, 0)
0045 #define IBB_PD_CTL_MASK (BIT(0) | BIT(7))
0046 #define LAB_PD_CTL_STRONG_PULL BIT(0)
0047 #define IBB_PD_CTL_HALF_STRENGTH BIT(0)
0048 #define IBB_PD_CTL_EN BIT(7)
0049
0050 #define REG_LABIBB_CURRENT_LIMIT 0x4b
0051 #define LAB_CURRENT_LIMIT_MASK GENMASK(2, 0)
0052 #define IBB_CURRENT_LIMIT_MASK GENMASK(4, 0)
0053 #define LAB_CURRENT_LIMIT_OVERRIDE_EN BIT(3)
0054 #define LABIBB_CURRENT_LIMIT_EN BIT(7)
0055
0056 #define REG_IBB_PWRUP_PWRDN_CTL_1 0x58
0057 #define IBB_CTL_1_DISCHARGE_EN BIT(2)
0058
0059 #define REG_LABIBB_SOFT_START_CTL 0x5f
0060 #define REG_LABIBB_SEC_ACCESS 0xd0
0061 #define LABIBB_SEC_UNLOCK_CODE 0xa5
0062
0063 #define LAB_ENABLE_CTL_MASK BIT(7)
0064 #define IBB_ENABLE_CTL_MASK (BIT(7) | BIT(6))
0065
0066 #define LABIBB_OFF_ON_DELAY 1000
0067 #define LAB_ENABLE_TIME (LABIBB_OFF_ON_DELAY * 2)
0068 #define IBB_ENABLE_TIME (LABIBB_OFF_ON_DELAY * 10)
0069 #define LABIBB_POLL_ENABLED_TIME 1000
0070 #define OCP_RECOVERY_INTERVAL_MS 500
0071 #define SC_RECOVERY_INTERVAL_MS 250
0072 #define LABIBB_MAX_OCP_COUNT 4
0073 #define LABIBB_MAX_SC_COUNT 3
0074 #define LABIBB_MAX_FATAL_COUNT 2
0075
0076 struct labibb_current_limits {
0077 u32 uA_min;
0078 u32 uA_step;
0079 u8 ovr_val;
0080 };
0081
0082 struct labibb_regulator {
0083 struct regulator_desc desc;
0084 struct device *dev;
0085 struct regmap *regmap;
0086 struct regulator_dev *rdev;
0087 struct labibb_current_limits uA_limits;
0088 struct delayed_work ocp_recovery_work;
0089 struct delayed_work sc_recovery_work;
0090 u16 base;
0091 u8 type;
0092 u8 dischg_sel;
0093 u8 soft_start_sel;
0094 int sc_irq;
0095 int sc_count;
0096 int ocp_irq;
0097 int ocp_irq_count;
0098 int fatal_count;
0099 };
0100
0101 struct labibb_regulator_data {
0102 const char *name;
0103 u8 type;
0104 u16 base;
0105 const struct regulator_desc *desc;
0106 };
0107
0108 static int qcom_labibb_ocp_hw_enable(struct regulator_dev *rdev)
0109 {
0110 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
0111 int ret;
0112
0113
0114 ret = regmap_update_bits(rdev->regmap,
0115 vreg->base + REG_LABIBB_INT_LATCHED_CLR,
0116 LABIBB_INT_VREG_OK, 1);
0117 if (ret)
0118 return ret;
0119
0120
0121 return regmap_update_bits(rdev->regmap,
0122 vreg->base + REG_LABIBB_INT_EN_SET,
0123 LABIBB_INT_VREG_OK, 1);
0124 }
0125
0126 static int qcom_labibb_ocp_hw_disable(struct regulator_dev *rdev)
0127 {
0128 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
0129
0130 return regmap_update_bits(rdev->regmap,
0131 vreg->base + REG_LABIBB_INT_EN_CLR,
0132 LABIBB_INT_VREG_OK, 1);
0133 }
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 static int qcom_labibb_check_ocp_status(struct labibb_regulator *vreg)
0146 {
0147 u32 cur_status;
0148 int ret;
0149
0150 ret = regmap_read(vreg->rdev->regmap, vreg->base + REG_LABIBB_STATUS1,
0151 &cur_status);
0152 if (ret)
0153 return ret;
0154
0155 return !(cur_status & LABIBB_STATUS1_VREG_OK_BIT);
0156 }
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179 static void qcom_labibb_ocp_recovery_worker(struct work_struct *work)
0180 {
0181 struct labibb_regulator *vreg;
0182 const struct regulator_ops *ops;
0183 int ret;
0184
0185 vreg = container_of(work, struct labibb_regulator,
0186 ocp_recovery_work.work);
0187 ops = vreg->rdev->desc->ops;
0188
0189 if (vreg->ocp_irq_count >= LABIBB_MAX_OCP_COUNT) {
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 BUG_ON(vreg->fatal_count > LABIBB_MAX_FATAL_COUNT);
0200 dev_err(&vreg->rdev->dev, "LABIBB: CRITICAL: Disabling regulator\n");
0201
0202
0203 ret = ops->disable(vreg->rdev);
0204 if (ret) {
0205 vreg->fatal_count++;
0206 goto reschedule;
0207 }
0208 enable_irq(vreg->ocp_irq);
0209 vreg->fatal_count = 0;
0210 return;
0211 }
0212
0213 ret = qcom_labibb_check_ocp_status(vreg);
0214 if (ret != 0) {
0215 vreg->ocp_irq_count++;
0216 goto reschedule;
0217 }
0218
0219 ret = qcom_labibb_ocp_hw_enable(vreg->rdev);
0220 if (ret) {
0221
0222 dev_err(vreg->dev, "Cannot enable OCP IRQ\n");
0223 vreg->ocp_irq_count++;
0224 goto reschedule;
0225 }
0226
0227 enable_irq(vreg->ocp_irq);
0228
0229 vreg->ocp_irq_count = 0;
0230 return;
0231
0232 reschedule:
0233 mod_delayed_work(system_wq, &vreg->ocp_recovery_work,
0234 msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));
0235 }
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255 static irqreturn_t qcom_labibb_ocp_isr(int irq, void *chip)
0256 {
0257 struct labibb_regulator *vreg = chip;
0258 const struct regulator_ops *ops = vreg->rdev->desc->ops;
0259 int ret;
0260
0261
0262 if (!ops->is_enabled(vreg->rdev))
0263 return IRQ_HANDLED;
0264
0265
0266 if (vreg->ocp_irq_count > LABIBB_MAX_OCP_COUNT)
0267 return IRQ_NONE;
0268
0269
0270
0271
0272
0273
0274
0275 ret = qcom_labibb_check_ocp_status(vreg);
0276 if (ret == 0) {
0277 vreg->ocp_irq_count = 0;
0278 goto end;
0279 }
0280 vreg->ocp_irq_count++;
0281
0282
0283
0284
0285
0286 disable_irq_nosync(irq);
0287
0288
0289 dev_warn(vreg->dev, "Over-Current interrupt fired!\n");
0290
0291
0292 ret = qcom_labibb_ocp_hw_disable(vreg->rdev);
0293 if (ret)
0294 goto end;
0295
0296
0297 regulator_notifier_call_chain(vreg->rdev,
0298 REGULATOR_EVENT_OVER_CURRENT, NULL);
0299
0300 end:
0301
0302 schedule_delayed_work(&vreg->ocp_recovery_work,
0303 msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));
0304 if (ret)
0305 return IRQ_NONE;
0306
0307 return IRQ_HANDLED;
0308 }
0309
0310 static int qcom_labibb_set_ocp(struct regulator_dev *rdev, int lim,
0311 int severity, bool enable)
0312 {
0313 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
0314 char *ocp_irq_name;
0315 u32 irq_flags = IRQF_ONESHOT;
0316 int irq_trig_low, ret;
0317
0318
0319
0320
0321
0322 if (lim || severity != REGULATOR_SEVERITY_PROT || !enable)
0323 return -EINVAL;
0324
0325
0326 if (vreg->ocp_irq <= 0)
0327 return -EINVAL;
0328
0329 ocp_irq_name = devm_kasprintf(vreg->dev, GFP_KERNEL, "%s-over-current",
0330 vreg->desc.name);
0331 if (!ocp_irq_name)
0332 return -ENOMEM;
0333
0334
0335 switch (vreg->type) {
0336 case QCOM_LAB_TYPE:
0337 irq_flags |= IRQF_TRIGGER_LOW;
0338 irq_trig_low = 1;
0339 break;
0340 case QCOM_IBB_TYPE:
0341 irq_flags |= IRQF_TRIGGER_HIGH;
0342 irq_trig_low = 0;
0343 break;
0344 default:
0345 return -EINVAL;
0346 }
0347
0348
0349 ret = regmap_update_bits(rdev->regmap,
0350 vreg->base + REG_LABIBB_INT_SET_TYPE,
0351 LABIBB_INT_VREG_OK,
0352 LABIBB_INT_VREG_TYPE_LEVEL);
0353 if (ret)
0354 return ret;
0355
0356
0357 ret = regmap_update_bits(rdev->regmap,
0358 vreg->base + REG_LABIBB_INT_POLARITY_HIGH,
0359 LABIBB_INT_VREG_OK, !irq_trig_low);
0360 if (ret)
0361 return ret;
0362 ret = regmap_update_bits(rdev->regmap,
0363 vreg->base + REG_LABIBB_INT_POLARITY_LOW,
0364 LABIBB_INT_VREG_OK, irq_trig_low);
0365 if (ret)
0366 return ret;
0367
0368 ret = qcom_labibb_ocp_hw_enable(rdev);
0369 if (ret)
0370 return ret;
0371
0372 return devm_request_threaded_irq(vreg->dev, vreg->ocp_irq, NULL,
0373 qcom_labibb_ocp_isr, irq_flags,
0374 ocp_irq_name, vreg);
0375 }
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388 static int qcom_labibb_check_sc_status(struct labibb_regulator *vreg)
0389 {
0390 u32 ibb_status, ibb_reg, lab_status, lab_reg;
0391 int ret;
0392
0393
0394 lab_reg = ibb_reg = vreg->base + REG_LABIBB_STATUS1;
0395 if (vreg->type == QCOM_LAB_TYPE)
0396 ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;
0397 else
0398 lab_reg += PMI8998_IBB_LAB_REG_OFFSET;
0399
0400 ret = regmap_read(vreg->rdev->regmap, lab_reg, &lab_status);
0401 if (ret)
0402 return ret;
0403 ret = regmap_read(vreg->rdev->regmap, ibb_reg, &ibb_status);
0404 if (ret)
0405 return ret;
0406
0407 return !!(lab_status & LABIBB_STATUS1_SC_BIT) ||
0408 !!(ibb_status & LABIBB_STATUS1_SC_BIT);
0409 }
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428 static void qcom_labibb_sc_recovery_worker(struct work_struct *work)
0429 {
0430 struct labibb_regulator *vreg;
0431 const struct regulator_ops *ops;
0432 u32 lab_reg, ibb_reg, lab_val, ibb_val, val;
0433 bool pbs_cut = false;
0434 int i, sc, ret;
0435
0436 vreg = container_of(work, struct labibb_regulator,
0437 sc_recovery_work.work);
0438 ops = vreg->rdev->desc->ops;
0439
0440
0441
0442
0443
0444
0445 if (vreg->fatal_count > LABIBB_MAX_FATAL_COUNT)
0446 return;
0447
0448
0449 if (vreg->sc_count > LABIBB_MAX_SC_COUNT)
0450 return;
0451
0452
0453
0454
0455
0456
0457 lab_reg = ibb_reg = vreg->base + REG_LABIBB_ENABLE_CTL;
0458 if (vreg->type == QCOM_LAB_TYPE)
0459 ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;
0460 else
0461 lab_reg += PMI8998_IBB_LAB_REG_OFFSET;
0462
0463 sc = qcom_labibb_check_sc_status(vreg);
0464 if (sc)
0465 goto reschedule;
0466
0467 for (i = 0; i < LABIBB_MAX_SC_COUNT; i++) {
0468 ret = regmap_read(vreg->regmap, lab_reg, &lab_val);
0469 if (ret) {
0470 vreg->fatal_count++;
0471 goto reschedule;
0472 }
0473
0474 ret = regmap_read(vreg->regmap, ibb_reg, &ibb_val);
0475 if (ret) {
0476 vreg->fatal_count++;
0477 goto reschedule;
0478 }
0479 val = lab_val & ibb_val;
0480
0481 if (!(val & LABIBB_CONTROL_ENABLE)) {
0482 pbs_cut = true;
0483 break;
0484 }
0485 usleep_range(5000, 6000);
0486 }
0487 if (pbs_cut)
0488 goto reschedule;
0489
0490
0491
0492
0493
0494
0495
0496
0497 ret = ops->enable(vreg->rdev);
0498 if (ret)
0499 goto reschedule;
0500
0501
0502 vreg->sc_count = 0;
0503 enable_irq(vreg->sc_irq);
0504 return;
0505
0506 reschedule:
0507
0508
0509
0510
0511
0512 vreg->sc_count++;
0513 mod_delayed_work(system_wq, &vreg->sc_recovery_work,
0514 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));
0515 }
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533 static irqreturn_t qcom_labibb_sc_isr(int irq, void *chip)
0534 {
0535 struct labibb_regulator *vreg = chip;
0536
0537 if (vreg->sc_count > LABIBB_MAX_SC_COUNT)
0538 return IRQ_NONE;
0539
0540
0541 dev_warn(vreg->dev, "Short-Circuit interrupt fired!\n");
0542
0543
0544
0545
0546
0547 disable_irq_nosync(irq);
0548
0549
0550 regulator_notifier_call_chain(vreg->rdev,
0551 REGULATOR_EVENT_REGULATION_OUT, NULL);
0552
0553
0554 mod_delayed_work(system_highpri_wq, &vreg->sc_recovery_work,
0555 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));
0556 return IRQ_HANDLED;
0557 }
0558
0559
0560 static int qcom_labibb_set_current_limit(struct regulator_dev *rdev,
0561 int min_uA, int max_uA)
0562 {
0563 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
0564 struct regulator_desc *desc = &vreg->desc;
0565 struct labibb_current_limits *lim = &vreg->uA_limits;
0566 u32 mask, val;
0567 int i, ret, sel = -1;
0568
0569 if (min_uA < lim->uA_min || max_uA < lim->uA_min)
0570 return -EINVAL;
0571
0572 for (i = 0; i < desc->n_current_limits; i++) {
0573 int uA_limit = (lim->uA_step * i) + lim->uA_min;
0574
0575 if (max_uA >= uA_limit && min_uA <= uA_limit)
0576 sel = i;
0577 }
0578 if (sel < 0)
0579 return -EINVAL;
0580
0581
0582 ret = regmap_write(vreg->regmap, vreg->base + REG_LABIBB_SEC_ACCESS,
0583 LABIBB_SEC_UNLOCK_CODE);
0584 if (ret)
0585 return ret;
0586
0587 mask = desc->csel_mask | lim->ovr_val;
0588 mask |= LABIBB_CURRENT_LIMIT_EN;
0589 val = (u32)sel | lim->ovr_val;
0590 val |= LABIBB_CURRENT_LIMIT_EN;
0591
0592 return regmap_update_bits(vreg->regmap, desc->csel_reg, mask, val);
0593 }
0594
0595 static int qcom_labibb_get_current_limit(struct regulator_dev *rdev)
0596 {
0597 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
0598 struct regulator_desc *desc = &vreg->desc;
0599 struct labibb_current_limits *lim = &vreg->uA_limits;
0600 unsigned int cur_step;
0601 int ret;
0602
0603 ret = regmap_read(vreg->regmap, desc->csel_reg, &cur_step);
0604 if (ret)
0605 return ret;
0606 cur_step &= desc->csel_mask;
0607
0608 return (cur_step * lim->uA_step) + lim->uA_min;
0609 }
0610
0611 static int qcom_labibb_set_soft_start(struct regulator_dev *rdev)
0612 {
0613 struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
0614 u32 val = 0;
0615
0616 if (vreg->type == QCOM_IBB_TYPE)
0617 val = vreg->dischg_sel;
0618 else
0619 val = vreg->soft_start_sel;
0620
0621 return regmap_write(rdev->regmap, rdev->desc->soft_start_reg, val);
0622 }
0623
0624 static int qcom_labibb_get_table_sel(const int *table, int sz, u32 value)
0625 {
0626 int i;
0627
0628 for (i = 0; i < sz; i++)
0629 if (table[i] == value)
0630 return i;
0631 return -EINVAL;
0632 }
0633
0634
0635 static const int dischg_resistor_values[] = { 300, 64, 32, 16 };
0636
0637
0638 static const int soft_start_values[] = { 200, 400, 600, 800 };
0639
0640 static int qcom_labibb_of_parse_cb(struct device_node *np,
0641 const struct regulator_desc *desc,
0642 struct regulator_config *config)
0643 {
0644 struct labibb_regulator *vreg = config->driver_data;
0645 u32 dischg_kohms, soft_start_time;
0646 int ret;
0647
0648 ret = of_property_read_u32(np, "qcom,discharge-resistor-kohms",
0649 &dischg_kohms);
0650 if (ret)
0651 dischg_kohms = 300;
0652
0653 ret = qcom_labibb_get_table_sel(dischg_resistor_values,
0654 ARRAY_SIZE(dischg_resistor_values),
0655 dischg_kohms);
0656 if (ret < 0)
0657 return ret;
0658 vreg->dischg_sel = (u8)ret;
0659
0660 ret = of_property_read_u32(np, "qcom,soft-start-us",
0661 &soft_start_time);
0662 if (ret)
0663 soft_start_time = 200;
0664
0665 ret = qcom_labibb_get_table_sel(soft_start_values,
0666 ARRAY_SIZE(soft_start_values),
0667 soft_start_time);
0668 if (ret < 0)
0669 return ret;
0670 vreg->soft_start_sel = (u8)ret;
0671
0672 return 0;
0673 }
0674
0675 static const struct regulator_ops qcom_labibb_ops = {
0676 .enable = regulator_enable_regmap,
0677 .disable = regulator_disable_regmap,
0678 .is_enabled = regulator_is_enabled_regmap,
0679 .set_voltage_sel = regulator_set_voltage_sel_regmap,
0680 .get_voltage_sel = regulator_get_voltage_sel_regmap,
0681 .list_voltage = regulator_list_voltage_linear,
0682 .map_voltage = regulator_map_voltage_linear,
0683 .set_active_discharge = regulator_set_active_discharge_regmap,
0684 .set_pull_down = regulator_set_pull_down_regmap,
0685 .set_current_limit = qcom_labibb_set_current_limit,
0686 .get_current_limit = qcom_labibb_get_current_limit,
0687 .set_soft_start = qcom_labibb_set_soft_start,
0688 .set_over_current_protection = qcom_labibb_set_ocp,
0689 };
0690
0691 static const struct regulator_desc pmi8998_lab_desc = {
0692 .enable_mask = LAB_ENABLE_CTL_MASK,
0693 .enable_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_ENABLE_CTL),
0694 .enable_val = LABIBB_CONTROL_ENABLE,
0695 .enable_time = LAB_ENABLE_TIME,
0696 .poll_enabled_time = LABIBB_POLL_ENABLED_TIME,
0697 .soft_start_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_SOFT_START_CTL),
0698 .pull_down_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_PD_CTL),
0699 .pull_down_mask = LAB_PD_CTL_MASK,
0700 .pull_down_val_on = LAB_PD_CTL_STRONG_PULL,
0701 .vsel_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),
0702 .vsel_mask = LAB_VOLTAGE_SET_MASK,
0703 .apply_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),
0704 .apply_bit = LABIBB_VOLTAGE_OVERRIDE_EN,
0705 .csel_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),
0706 .csel_mask = LAB_CURRENT_LIMIT_MASK,
0707 .n_current_limits = 8,
0708 .off_on_delay = LABIBB_OFF_ON_DELAY,
0709 .owner = THIS_MODULE,
0710 .type = REGULATOR_VOLTAGE,
0711 .min_uV = 4600000,
0712 .uV_step = 100000,
0713 .n_voltages = 16,
0714 .ops = &qcom_labibb_ops,
0715 .of_parse_cb = qcom_labibb_of_parse_cb,
0716 };
0717
0718 static const struct regulator_desc pmi8998_ibb_desc = {
0719 .enable_mask = IBB_ENABLE_CTL_MASK,
0720 .enable_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_ENABLE_CTL),
0721 .enable_val = LABIBB_CONTROL_ENABLE,
0722 .enable_time = IBB_ENABLE_TIME,
0723 .poll_enabled_time = LABIBB_POLL_ENABLED_TIME,
0724 .soft_start_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_SOFT_START_CTL),
0725 .active_discharge_off = 0,
0726 .active_discharge_on = IBB_CTL_1_DISCHARGE_EN,
0727 .active_discharge_mask = IBB_CTL_1_DISCHARGE_EN,
0728 .active_discharge_reg = (PMI8998_IBB_REG_BASE + REG_IBB_PWRUP_PWRDN_CTL_1),
0729 .pull_down_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_PD_CTL),
0730 .pull_down_mask = IBB_PD_CTL_MASK,
0731 .pull_down_val_on = IBB_PD_CTL_HALF_STRENGTH | IBB_PD_CTL_EN,
0732 .vsel_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),
0733 .vsel_mask = IBB_VOLTAGE_SET_MASK,
0734 .apply_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),
0735 .apply_bit = LABIBB_VOLTAGE_OVERRIDE_EN,
0736 .csel_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),
0737 .csel_mask = IBB_CURRENT_LIMIT_MASK,
0738 .n_current_limits = 32,
0739 .off_on_delay = LABIBB_OFF_ON_DELAY,
0740 .owner = THIS_MODULE,
0741 .type = REGULATOR_VOLTAGE,
0742 .min_uV = 1400000,
0743 .uV_step = 100000,
0744 .n_voltages = 64,
0745 .ops = &qcom_labibb_ops,
0746 .of_parse_cb = qcom_labibb_of_parse_cb,
0747 };
0748
0749 static const struct labibb_regulator_data pmi8998_labibb_data[] = {
0750 {"lab", QCOM_LAB_TYPE, PMI8998_LAB_REG_BASE, &pmi8998_lab_desc},
0751 {"ibb", QCOM_IBB_TYPE, PMI8998_IBB_REG_BASE, &pmi8998_ibb_desc},
0752 { },
0753 };
0754
0755 static const struct of_device_id qcom_labibb_match[] = {
0756 { .compatible = "qcom,pmi8998-lab-ibb", .data = &pmi8998_labibb_data},
0757 { },
0758 };
0759 MODULE_DEVICE_TABLE(of, qcom_labibb_match);
0760
0761 static int qcom_labibb_regulator_probe(struct platform_device *pdev)
0762 {
0763 struct labibb_regulator *vreg;
0764 struct device *dev = &pdev->dev;
0765 struct regulator_config cfg = {};
0766 struct device_node *reg_node;
0767 const struct of_device_id *match;
0768 const struct labibb_regulator_data *reg_data;
0769 struct regmap *reg_regmap;
0770 unsigned int type;
0771 int ret;
0772
0773 reg_regmap = dev_get_regmap(pdev->dev.parent, NULL);
0774 if (!reg_regmap) {
0775 dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
0776 return -ENODEV;
0777 }
0778
0779 match = of_match_device(qcom_labibb_match, &pdev->dev);
0780 if (!match)
0781 return -ENODEV;
0782
0783 for (reg_data = match->data; reg_data->name; reg_data++) {
0784 char *sc_irq_name;
0785 int irq = 0;
0786
0787
0788
0789
0790 ret = regmap_read(reg_regmap, reg_data->base + REG_PERPH_TYPE,
0791 &type);
0792 if (ret < 0) {
0793 dev_err(dev,
0794 "Peripheral type read failed ret=%d\n",
0795 ret);
0796 return -EINVAL;
0797 }
0798
0799 if (WARN_ON((type != QCOM_LAB_TYPE) && (type != QCOM_IBB_TYPE)) ||
0800 WARN_ON(type != reg_data->type))
0801 return -EINVAL;
0802
0803 vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg),
0804 GFP_KERNEL);
0805 if (!vreg)
0806 return -ENOMEM;
0807
0808 sc_irq_name = devm_kasprintf(dev, GFP_KERNEL,
0809 "%s-short-circuit",
0810 reg_data->name);
0811 if (!sc_irq_name)
0812 return -ENOMEM;
0813
0814 reg_node = of_get_child_by_name(pdev->dev.of_node,
0815 reg_data->name);
0816 if (!reg_node)
0817 return -EINVAL;
0818
0819
0820 irq = of_irq_get_byname(reg_node, "sc-err");
0821 if (irq <= 0) {
0822 if (irq == 0)
0823 irq = -EINVAL;
0824
0825 return dev_err_probe(vreg->dev, irq,
0826 "Short-circuit irq not found.\n");
0827 }
0828 vreg->sc_irq = irq;
0829
0830
0831 irq = of_irq_get_byname(reg_node, "ocp");
0832 vreg->ocp_irq = irq;
0833 vreg->ocp_irq_count = 0;
0834 of_node_put(reg_node);
0835
0836 vreg->regmap = reg_regmap;
0837 vreg->dev = dev;
0838 vreg->base = reg_data->base;
0839 vreg->type = reg_data->type;
0840 INIT_DELAYED_WORK(&vreg->sc_recovery_work,
0841 qcom_labibb_sc_recovery_worker);
0842
0843 if (vreg->ocp_irq > 0)
0844 INIT_DELAYED_WORK(&vreg->ocp_recovery_work,
0845 qcom_labibb_ocp_recovery_worker);
0846
0847 switch (vreg->type) {
0848 case QCOM_LAB_TYPE:
0849
0850 vreg->uA_limits.uA_min = 200000;
0851 vreg->uA_limits.uA_step = 200000;
0852 vreg->uA_limits.ovr_val = LAB_CURRENT_LIMIT_OVERRIDE_EN;
0853 break;
0854 case QCOM_IBB_TYPE:
0855
0856 vreg->uA_limits.uA_min = 0;
0857 vreg->uA_limits.uA_step = 50000;
0858 vreg->uA_limits.ovr_val = 0;
0859 break;
0860 default:
0861 return -EINVAL;
0862 }
0863
0864 memcpy(&vreg->desc, reg_data->desc, sizeof(vreg->desc));
0865 vreg->desc.of_match = reg_data->name;
0866 vreg->desc.name = reg_data->name;
0867
0868 cfg.dev = vreg->dev;
0869 cfg.driver_data = vreg;
0870 cfg.regmap = vreg->regmap;
0871
0872 vreg->rdev = devm_regulator_register(vreg->dev, &vreg->desc,
0873 &cfg);
0874
0875 if (IS_ERR(vreg->rdev)) {
0876 dev_err(dev, "qcom_labibb: error registering %s : %d\n",
0877 reg_data->name, ret);
0878 return PTR_ERR(vreg->rdev);
0879 }
0880
0881 ret = devm_request_threaded_irq(vreg->dev, vreg->sc_irq, NULL,
0882 qcom_labibb_sc_isr,
0883 IRQF_ONESHOT |
0884 IRQF_TRIGGER_RISING,
0885 sc_irq_name, vreg);
0886 if (ret)
0887 return ret;
0888 }
0889
0890 return 0;
0891 }
0892
0893 static struct platform_driver qcom_labibb_regulator_driver = {
0894 .driver = {
0895 .name = "qcom-lab-ibb-regulator",
0896 .of_match_table = qcom_labibb_match,
0897 },
0898 .probe = qcom_labibb_regulator_probe,
0899 };
0900 module_platform_driver(qcom_labibb_regulator_driver);
0901
0902 MODULE_DESCRIPTION("Qualcomm labibb driver");
0903 MODULE_AUTHOR("Nisha Kumari <nishakumari@codeaurora.org>");
0904 MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>");
0905 MODULE_LICENSE("GPL v2");