Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 //
0003 // Regulator driver for DA9055 PMIC
0004 //
0005 // Copyright(c) 2012 Dialog Semiconductor Ltd.
0006 //
0007 // Author: David Dajun Chen <dchen@diasemi.com>
0008 
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/err.h>
0012 #include <linux/gpio.h>
0013 #include <linux/gpio/consumer.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regulator/driver.h>
0016 #include <linux/regulator/machine.h>
0017 #include <linux/of.h>
0018 #include <linux/regulator/of_regulator.h>
0019 
0020 #include <linux/mfd/da9055/core.h>
0021 #include <linux/mfd/da9055/reg.h>
0022 #include <linux/mfd/da9055/pdata.h>
0023 
0024 #define DA9055_MIN_UA       0
0025 #define DA9055_MAX_UA       3
0026 
0027 #define DA9055_LDO_MODE_SYNC    0
0028 #define DA9055_LDO_MODE_SLEEP   1
0029 
0030 #define DA9055_BUCK_MODE_SLEEP  1
0031 #define DA9055_BUCK_MODE_SYNC   2
0032 #define DA9055_BUCK_MODE_AUTO   3
0033 
0034 /* DA9055 REGULATOR IDs */
0035 #define DA9055_ID_BUCK1 0
0036 #define DA9055_ID_BUCK2 1
0037 #define DA9055_ID_LDO1      2
0038 #define DA9055_ID_LDO2      3
0039 #define DA9055_ID_LDO3      4
0040 #define DA9055_ID_LDO4      5
0041 #define DA9055_ID_LDO5      6
0042 #define DA9055_ID_LDO6      7
0043 
0044 /* DA9055 BUCK current limit */
0045 static const unsigned int da9055_current_limits[] = {
0046     500000, 600000, 700000, 800000
0047 };
0048 
0049 struct da9055_conf_reg {
0050     int reg;
0051     int sel_mask;
0052     int en_mask;
0053 };
0054 
0055 struct da9055_volt_reg {
0056     int reg_a;
0057     int reg_b;
0058     int sl_shift;
0059     int v_mask;
0060 };
0061 
0062 struct da9055_mode_reg {
0063     int reg;
0064     int mask;
0065     int shift;
0066 };
0067 
0068 struct da9055_regulator_info {
0069     struct regulator_desc reg_desc;
0070     struct da9055_conf_reg conf;
0071     struct da9055_volt_reg volt;
0072     struct da9055_mode_reg mode;
0073 };
0074 
0075 struct da9055_regulator {
0076     struct da9055 *da9055;
0077     struct da9055_regulator_info *info;
0078     struct regulator_dev *rdev;
0079     enum gpio_select reg_rselect;
0080 };
0081 
0082 static unsigned int da9055_buck_get_mode(struct regulator_dev *rdev)
0083 {
0084     struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
0085     struct da9055_regulator_info *info = regulator->info;
0086     int ret, mode = 0;
0087 
0088     ret = da9055_reg_read(regulator->da9055, info->mode.reg);
0089     if (ret < 0)
0090         return ret;
0091 
0092     switch ((ret & info->mode.mask) >> info->mode.shift) {
0093     case DA9055_BUCK_MODE_SYNC:
0094         mode = REGULATOR_MODE_FAST;
0095         break;
0096     case DA9055_BUCK_MODE_AUTO:
0097         mode = REGULATOR_MODE_NORMAL;
0098         break;
0099     case DA9055_BUCK_MODE_SLEEP:
0100         mode = REGULATOR_MODE_STANDBY;
0101         break;
0102     }
0103 
0104     return mode;
0105 }
0106 
0107 static int da9055_buck_set_mode(struct regulator_dev *rdev,
0108                     unsigned int mode)
0109 {
0110     struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
0111     struct da9055_regulator_info *info = regulator->info;
0112     int val = 0;
0113 
0114     switch (mode) {
0115     case REGULATOR_MODE_FAST:
0116         val = DA9055_BUCK_MODE_SYNC << info->mode.shift;
0117         break;
0118     case REGULATOR_MODE_NORMAL:
0119         val = DA9055_BUCK_MODE_AUTO << info->mode.shift;
0120         break;
0121     case REGULATOR_MODE_STANDBY:
0122         val = DA9055_BUCK_MODE_SLEEP << info->mode.shift;
0123         break;
0124     }
0125 
0126     return da9055_reg_update(regulator->da9055, info->mode.reg,
0127                  info->mode.mask, val);
0128 }
0129 
0130 static unsigned int da9055_ldo_get_mode(struct regulator_dev *rdev)
0131 {
0132     struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
0133     struct da9055_regulator_info *info = regulator->info;
0134     int ret;
0135 
0136     ret = da9055_reg_read(regulator->da9055, info->volt.reg_b);
0137     if (ret < 0)
0138         return ret;
0139 
0140     if (ret >> info->volt.sl_shift)
0141         return REGULATOR_MODE_STANDBY;
0142     else
0143         return REGULATOR_MODE_NORMAL;
0144 }
0145 
0146 static int da9055_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
0147 {
0148     struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
0149     struct da9055_regulator_info *info = regulator->info;
0150     struct da9055_volt_reg volt = info->volt;
0151     int val = 0;
0152 
0153     switch (mode) {
0154     case REGULATOR_MODE_NORMAL:
0155     case REGULATOR_MODE_FAST:
0156         val = DA9055_LDO_MODE_SYNC;
0157         break;
0158     case REGULATOR_MODE_STANDBY:
0159         val = DA9055_LDO_MODE_SLEEP;
0160         break;
0161     }
0162 
0163     return da9055_reg_update(regulator->da9055, volt.reg_b,
0164                  1 << volt.sl_shift,
0165                  val << volt.sl_shift);
0166 }
0167 
0168 static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev)
0169 {
0170     struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
0171     struct da9055_regulator_info *info = regulator->info;
0172     struct da9055_volt_reg volt = info->volt;
0173     int ret, sel;
0174 
0175     /*
0176      * There are two voltage register set A & B for voltage ramping but
0177      * either one of then can be active therefore we first determine
0178      * the active register set.
0179      */
0180     ret = da9055_reg_read(regulator->da9055, info->conf.reg);
0181     if (ret < 0)
0182         return ret;
0183 
0184     ret &= info->conf.sel_mask;
0185 
0186     /* Get the voltage for the active register set A/B */
0187     if (ret == DA9055_REGUALTOR_SET_A)
0188         ret = da9055_reg_read(regulator->da9055, volt.reg_a);
0189     else
0190         ret = da9055_reg_read(regulator->da9055, volt.reg_b);
0191 
0192     if (ret < 0)
0193         return ret;
0194 
0195     sel = (ret & volt.v_mask);
0196     return sel;
0197 }
0198 
0199 static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev,
0200                         unsigned int selector)
0201 {
0202     struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
0203     struct da9055_regulator_info *info = regulator->info;
0204     int ret;
0205 
0206     /*
0207      * Regulator register set A/B is not selected through GPIO therefore
0208      * we use default register set A for voltage ramping.
0209      */
0210     if (regulator->reg_rselect == NO_GPIO) {
0211         /* Select register set A */
0212         ret = da9055_reg_update(regulator->da9055, info->conf.reg,
0213                     info->conf.sel_mask, DA9055_SEL_REG_A);
0214         if (ret < 0)
0215             return ret;
0216 
0217         /* Set the voltage */
0218         return da9055_reg_update(regulator->da9055, info->volt.reg_a,
0219                      info->volt.v_mask, selector);
0220     }
0221 
0222     /*
0223      * Here regulator register set A/B is selected through GPIO.
0224      * Therefore we first determine the selected register set A/B and
0225      * then set the desired voltage for that register set A/B.
0226      */
0227     ret = da9055_reg_read(regulator->da9055, info->conf.reg);
0228     if (ret < 0)
0229         return ret;
0230 
0231     ret &= info->conf.sel_mask;
0232 
0233     /* Set the voltage */
0234     if (ret == DA9055_REGUALTOR_SET_A)
0235         return da9055_reg_update(regulator->da9055, info->volt.reg_a,
0236                      info->volt.v_mask, selector);
0237     else
0238         return da9055_reg_update(regulator->da9055, info->volt.reg_b,
0239                      info->volt.v_mask, selector);
0240 }
0241 
0242 static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev,
0243                         int uV)
0244 {
0245     struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
0246     struct da9055_regulator_info *info = regulator->info;
0247     int ret;
0248 
0249     /* Select register set B for suspend voltage ramping. */
0250     if (regulator->reg_rselect == NO_GPIO) {
0251         ret = da9055_reg_update(regulator->da9055, info->conf.reg,
0252                     info->conf.sel_mask, DA9055_SEL_REG_B);
0253         if (ret < 0)
0254             return ret;
0255     }
0256 
0257     ret = regulator_map_voltage_linear(rdev, uV, uV);
0258     if (ret < 0)
0259         return ret;
0260 
0261     return da9055_reg_update(regulator->da9055, info->volt.reg_b,
0262                  info->volt.v_mask, ret);
0263 }
0264 
0265 static int da9055_suspend_enable(struct regulator_dev *rdev)
0266 {
0267     struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
0268     struct da9055_regulator_info *info = regulator->info;
0269 
0270     /* Select register set B for voltage ramping. */
0271     if (regulator->reg_rselect == NO_GPIO)
0272         return da9055_reg_update(regulator->da9055, info->conf.reg,
0273                     info->conf.sel_mask, DA9055_SEL_REG_B);
0274     else
0275         return 0;
0276 }
0277 
0278 static int da9055_suspend_disable(struct regulator_dev *rdev)
0279 {
0280     struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
0281     struct da9055_regulator_info *info = regulator->info;
0282 
0283     /* Diselect register set B. */
0284     if (regulator->reg_rselect == NO_GPIO)
0285         return da9055_reg_update(regulator->da9055, info->conf.reg,
0286                     info->conf.sel_mask, DA9055_SEL_REG_A);
0287     else
0288         return 0;
0289 }
0290 
0291 static const struct regulator_ops da9055_buck_ops = {
0292     .get_mode = da9055_buck_get_mode,
0293     .set_mode = da9055_buck_set_mode,
0294 
0295     .get_current_limit = regulator_get_current_limit_regmap,
0296     .set_current_limit = regulator_set_current_limit_regmap,
0297 
0298     .get_voltage_sel = da9055_regulator_get_voltage_sel,
0299     .set_voltage_sel = da9055_regulator_set_voltage_sel,
0300     .list_voltage = regulator_list_voltage_linear,
0301     .map_voltage = regulator_map_voltage_linear,
0302     .is_enabled = regulator_is_enabled_regmap,
0303     .enable = regulator_enable_regmap,
0304     .disable = regulator_disable_regmap,
0305 
0306     .set_suspend_voltage = da9055_regulator_set_suspend_voltage,
0307     .set_suspend_enable = da9055_suspend_enable,
0308     .set_suspend_disable = da9055_suspend_disable,
0309     .set_suspend_mode = da9055_buck_set_mode,
0310 };
0311 
0312 static const struct regulator_ops da9055_ldo_ops = {
0313     .get_mode = da9055_ldo_get_mode,
0314     .set_mode = da9055_ldo_set_mode,
0315 
0316     .get_voltage_sel = da9055_regulator_get_voltage_sel,
0317     .set_voltage_sel = da9055_regulator_set_voltage_sel,
0318     .list_voltage = regulator_list_voltage_linear,
0319     .map_voltage = regulator_map_voltage_linear,
0320     .is_enabled = regulator_is_enabled_regmap,
0321     .enable = regulator_enable_regmap,
0322     .disable = regulator_disable_regmap,
0323 
0324     .set_suspend_voltage = da9055_regulator_set_suspend_voltage,
0325     .set_suspend_enable = da9055_suspend_enable,
0326     .set_suspend_disable = da9055_suspend_disable,
0327     .set_suspend_mode = da9055_ldo_set_mode,
0328 
0329 };
0330 
0331 #define DA9055_LDO(_id, step, min, max, vbits, voffset) \
0332 {\
0333     .reg_desc = {\
0334         .name = #_id,\
0335         .of_match = of_match_ptr(#_id),\
0336         .regulators_node = of_match_ptr("regulators"),\
0337         .ops = &da9055_ldo_ops,\
0338         .type = REGULATOR_VOLTAGE,\
0339         .id = DA9055_ID_##_id,\
0340         .n_voltages = (max - min) / step + 1 + (voffset), \
0341         .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \
0342         .enable_mask = 1, \
0343         .min_uV = (min) * 1000,\
0344         .uV_step = (step) * 1000,\
0345         .linear_min_sel = (voffset),\
0346         .owner = THIS_MODULE,\
0347     },\
0348     .conf = {\
0349         .reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \
0350         .sel_mask = (1 << 4),\
0351         .en_mask = 1,\
0352     },\
0353     .volt = {\
0354         .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \
0355         .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \
0356         .sl_shift = 7,\
0357         .v_mask = (1 << (vbits)) - 1,\
0358     },\
0359 }
0360 
0361 #define DA9055_BUCK(_id, step, min, max, vbits, voffset, mbits, sbits) \
0362 {\
0363     .reg_desc = {\
0364         .name = #_id,\
0365         .of_match = of_match_ptr(#_id),\
0366         .regulators_node = of_match_ptr("regulators"),\
0367         .ops = &da9055_buck_ops,\
0368         .type = REGULATOR_VOLTAGE,\
0369         .id = DA9055_ID_##_id,\
0370         .n_voltages = (max - min) / step + 1 + (voffset), \
0371         .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \
0372         .enable_mask = 1,\
0373         .min_uV = (min) * 1000,\
0374         .uV_step = (step) * 1000,\
0375         .linear_min_sel = (voffset),\
0376         .owner = THIS_MODULE,\
0377         .curr_table = da9055_current_limits,\
0378         .n_current_limits = ARRAY_SIZE(da9055_current_limits),\
0379         .csel_reg = DA9055_REG_BUCK_LIM,\
0380         .csel_mask = (mbits),\
0381     },\
0382     .conf = {\
0383         .reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \
0384         .sel_mask = (1 << 4),\
0385         .en_mask = 1,\
0386     },\
0387     .volt = {\
0388         .reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \
0389         .reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \
0390         .sl_shift = 7,\
0391         .v_mask = (1 << (vbits)) - 1,\
0392     },\
0393     .mode = {\
0394         .reg = DA9055_REG_BCORE_MODE,\
0395         .mask = (mbits),\
0396         .shift = (sbits),\
0397     },\
0398 }
0399 
0400 static struct da9055_regulator_info da9055_regulator_info[] = {
0401     DA9055_BUCK(BUCK1, 25, 725, 2075, 6, 9, 0xc, 2),
0402     DA9055_BUCK(BUCK2, 25, 925, 2500, 6, 0, 3, 0),
0403     DA9055_LDO(LDO1, 50, 900, 3300, 6, 2),
0404     DA9055_LDO(LDO2, 50, 900, 3300, 6, 3),
0405     DA9055_LDO(LDO3, 50, 900, 3300, 6, 2),
0406     DA9055_LDO(LDO4, 50, 900, 3300, 6, 2),
0407     DA9055_LDO(LDO5, 50, 900, 2750, 6, 2),
0408     DA9055_LDO(LDO6, 20, 900, 3300, 7, 0),
0409 };
0410 
0411 /*
0412  * Configures regulator to be controlled either through GPIO 1 or 2.
0413  * GPIO can control regulator state and/or select the regulator register
0414  * set A/B for voltage ramping.
0415  */
0416 static int da9055_gpio_init(struct da9055_regulator *regulator,
0417                 struct regulator_config *config,
0418                 struct da9055_pdata *pdata, int id)
0419 {
0420     struct da9055_regulator_info *info = regulator->info;
0421     int ret = 0;
0422 
0423     if (!pdata)
0424         return 0;
0425 
0426     if (pdata->gpio_ren && pdata->gpio_ren[id]) {
0427         char name[18];
0428         int gpio_mux = pdata->gpio_ren[id];
0429 
0430         config->ena_gpiod = pdata->ena_gpiods[id];
0431 
0432         /*
0433          * GPI pin is muxed with regulator to control the
0434          * regulator state.
0435          */
0436         sprintf(name, "DA9055 GPI %d", gpio_mux);
0437         ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN,
0438                         name);
0439         if (ret < 0)
0440             goto err;
0441 
0442         /*
0443          * Let the regulator know that its state is controlled
0444          * through GPI.
0445          */
0446         ret = da9055_reg_update(regulator->da9055, info->conf.reg,
0447                     DA9055_E_GPI_MASK,
0448                     pdata->reg_ren[id]
0449                     << DA9055_E_GPI_SHIFT);
0450         if (ret < 0)
0451             goto err;
0452     }
0453 
0454     if (pdata->gpio_rsel && pdata->gpio_rsel[id]) {
0455         char name[18];
0456         int gpio_mux = pdata->gpio_rsel[id];
0457 
0458         regulator->reg_rselect = pdata->reg_rsel[id];
0459 
0460         /*
0461          * GPI pin is muxed with regulator to select the
0462          * regulator register set A/B for voltage ramping.
0463          */
0464         sprintf(name, "DA9055 GPI %d", gpio_mux);
0465         ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN,
0466                         name);
0467         if (ret < 0)
0468             goto err;
0469 
0470         /*
0471          * Let the regulator know that its register set A/B
0472          * will be selected through GPI for voltage ramping.
0473          */
0474         ret = da9055_reg_update(regulator->da9055, info->conf.reg,
0475                     DA9055_V_GPI_MASK,
0476                     pdata->reg_rsel[id]
0477                     << DA9055_V_GPI_SHIFT);
0478     }
0479 
0480 err:
0481     return ret;
0482 }
0483 
0484 static irqreturn_t da9055_ldo5_6_oc_irq(int irq, void *data)
0485 {
0486     struct da9055_regulator *regulator = data;
0487 
0488     regulator_notifier_call_chain(regulator->rdev,
0489                       REGULATOR_EVENT_OVER_CURRENT, NULL);
0490 
0491     return IRQ_HANDLED;
0492 }
0493 
0494 static inline struct da9055_regulator_info *find_regulator_info(int id)
0495 {
0496     struct da9055_regulator_info *info;
0497     int i;
0498 
0499     for (i = 0; i < ARRAY_SIZE(da9055_regulator_info); i++) {
0500         info = &da9055_regulator_info[i];
0501         if (info->reg_desc.id == id)
0502             return info;
0503     }
0504 
0505     return NULL;
0506 }
0507 
0508 static int da9055_regulator_probe(struct platform_device *pdev)
0509 {
0510     struct regulator_config config = { };
0511     struct da9055_regulator *regulator;
0512     struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent);
0513     struct da9055_pdata *pdata = dev_get_platdata(da9055->dev);
0514     int ret, irq;
0515 
0516     regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator),
0517                  GFP_KERNEL);
0518     if (!regulator)
0519         return -ENOMEM;
0520 
0521     regulator->info = find_regulator_info(pdev->id);
0522     if (regulator->info == NULL) {
0523         dev_err(&pdev->dev, "invalid regulator ID specified\n");
0524         return -EINVAL;
0525     }
0526 
0527     regulator->da9055 = da9055;
0528     config.dev = da9055->dev;
0529     config.driver_data = regulator;
0530     config.regmap = da9055->regmap;
0531 
0532     if (pdata)
0533         config.init_data = pdata->regulators[pdev->id];
0534 
0535     ret = da9055_gpio_init(regulator, &config, pdata, pdev->id);
0536     if (ret < 0)
0537         return ret;
0538 
0539     regulator->rdev = devm_regulator_register(&pdev->dev,
0540                           &regulator->info->reg_desc,
0541                           &config);
0542     if (IS_ERR(regulator->rdev)) {
0543         dev_err(&pdev->dev, "Failed to register regulator %s\n",
0544             regulator->info->reg_desc.name);
0545         return PTR_ERR(regulator->rdev);
0546     }
0547 
0548     /* Only LDO 5 and 6 has got the over current interrupt */
0549     if (pdev->id == DA9055_ID_LDO5 || pdev->id ==  DA9055_ID_LDO6) {
0550         irq = platform_get_irq_byname(pdev, "REGULATOR");
0551         if (irq < 0)
0552             return irq;
0553 
0554         ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
0555                         da9055_ldo5_6_oc_irq,
0556                         IRQF_TRIGGER_HIGH |
0557                         IRQF_ONESHOT |
0558                         IRQF_PROBE_SHARED,
0559                         pdev->name, regulator);
0560         if (ret != 0) {
0561             if (ret != -EBUSY) {
0562                 dev_err(&pdev->dev,
0563                 "Failed to request Regulator IRQ %d: %d\n",
0564                 irq, ret);
0565                 return ret;
0566             }
0567         }
0568     }
0569 
0570     platform_set_drvdata(pdev, regulator);
0571 
0572     return 0;
0573 }
0574 
0575 static struct platform_driver da9055_regulator_driver = {
0576     .probe = da9055_regulator_probe,
0577     .driver = {
0578         .name = "da9055-regulator",
0579     },
0580 };
0581 
0582 static int __init da9055_regulator_init(void)
0583 {
0584     return platform_driver_register(&da9055_regulator_driver);
0585 }
0586 subsys_initcall(da9055_regulator_init);
0587 
0588 static void __exit da9055_regulator_exit(void)
0589 {
0590     platform_driver_unregister(&da9055_regulator_driver);
0591 }
0592 module_exit(da9055_regulator_exit);
0593 
0594 MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
0595 MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9055 PMIC");
0596 MODULE_LICENSE("GPL");
0597 MODULE_ALIAS("platform:da9055-regulator");