Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) ST-Ericsson SA 2010
0004  *
0005  * Authors: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
0006  *
0007  * This file is based on drivers/regulator/ab8500.c
0008  *
0009  * AB8500 external regulators
0010  *
0011  * ab8500-ext supports the following regulators:
0012  * - VextSupply3
0013  */
0014 #include <linux/init.h>
0015 #include <linux/kernel.h>
0016 #include <linux/err.h>
0017 #include <linux/module.h>
0018 #include <linux/of.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/regulator/driver.h>
0021 #include <linux/regulator/machine.h>
0022 #include <linux/regulator/of_regulator.h>
0023 #include <linux/mfd/abx500.h>
0024 #include <linux/mfd/abx500/ab8500.h>
0025 
0026 /* AB8500 external regulators */
0027 enum ab8500_ext_regulator_id {
0028     AB8500_EXT_SUPPLY1,
0029     AB8500_EXT_SUPPLY2,
0030     AB8500_EXT_SUPPLY3,
0031     AB8500_NUM_EXT_REGULATORS,
0032 };
0033 
0034 struct ab8500_ext_regulator_cfg {
0035     bool hwreq; /* requires hw mode or high power mode */
0036 };
0037 
0038 /* supply for VextSupply3 */
0039 static struct regulator_consumer_supply ab8500_ext_supply3_consumers[] = {
0040     /* SIM supply for 3 V SIM cards */
0041     REGULATOR_SUPPLY("vinvsim", "sim-detect.0"),
0042 };
0043 
0044 /*
0045  * AB8500 external regulators
0046  */
0047 static struct regulator_init_data ab8500_ext_regulators[] = {
0048     /* fixed Vbat supplies VSMPS1_EXT_1V8 */
0049     [AB8500_EXT_SUPPLY1] = {
0050         .constraints = {
0051             .name = "ab8500-ext-supply1",
0052             .min_uV = 1800000,
0053             .max_uV = 1800000,
0054             .initial_mode = REGULATOR_MODE_IDLE,
0055             .boot_on = 1,
0056             .always_on = 1,
0057         },
0058     },
0059     /* fixed Vbat supplies VSMPS2_EXT_1V36 and VSMPS5_EXT_1V15 */
0060     [AB8500_EXT_SUPPLY2] = {
0061         .constraints = {
0062             .name = "ab8500-ext-supply2",
0063             .min_uV = 1360000,
0064             .max_uV = 1360000,
0065         },
0066     },
0067     /* fixed Vbat supplies VSMPS3_EXT_3V4 and VSMPS4_EXT_3V4 */
0068     [AB8500_EXT_SUPPLY3] = {
0069         .constraints = {
0070             .name = "ab8500-ext-supply3",
0071             .min_uV = 3400000,
0072             .max_uV = 3400000,
0073             .valid_ops_mask = REGULATOR_CHANGE_STATUS,
0074             .boot_on = 1,
0075         },
0076         .num_consumer_supplies =
0077             ARRAY_SIZE(ab8500_ext_supply3_consumers),
0078         .consumer_supplies = ab8500_ext_supply3_consumers,
0079     },
0080 };
0081 
0082 /**
0083  * struct ab8500_ext_regulator_info - ab8500 regulator information
0084  * @dev: device pointer
0085  * @desc: regulator description
0086  * @cfg: regulator configuration (extension of regulator FW configuration)
0087  * @update_bank: bank to control on/off
0088  * @update_reg: register to control on/off
0089  * @update_mask: mask to enable/disable and set mode of regulator
0090  * @update_val: bits holding the regulator current mode
0091  * @update_val_hp: bits to set EN pin active (LPn pin deactive)
0092  *                 normally this means high power mode
0093  * @update_val_lp: bits to set EN pin active and LPn pin active
0094  *                 normally this means low power mode
0095  * @update_val_hw: bits to set regulator pins in HW control
0096  *                 SysClkReq pins and logic will choose mode
0097  */
0098 struct ab8500_ext_regulator_info {
0099     struct device *dev;
0100     struct regulator_desc desc;
0101     struct ab8500_ext_regulator_cfg *cfg;
0102     u8 update_bank;
0103     u8 update_reg;
0104     u8 update_mask;
0105     u8 update_val;
0106     u8 update_val_hp;
0107     u8 update_val_lp;
0108     u8 update_val_hw;
0109 };
0110 
0111 static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
0112 {
0113     int ret;
0114     struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
0115     u8 regval;
0116 
0117     if (info == NULL) {
0118         dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
0119         return -EINVAL;
0120     }
0121 
0122     /*
0123      * To satisfy both HW high power request and SW request, the regulator
0124      * must be on in high power.
0125      */
0126     if (info->cfg && info->cfg->hwreq)
0127         regval = info->update_val_hp;
0128     else
0129         regval = info->update_val;
0130 
0131     ret = abx500_mask_and_set_register_interruptible(info->dev,
0132         info->update_bank, info->update_reg,
0133         info->update_mask, regval);
0134     if (ret < 0) {
0135         dev_err(rdev_get_dev(rdev),
0136             "couldn't set enable bits for regulator\n");
0137         return ret;
0138     }
0139 
0140     dev_dbg(rdev_get_dev(rdev),
0141         "%s-enable (bank, reg, mask, value): 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
0142         info->desc.name, info->update_bank, info->update_reg,
0143         info->update_mask, regval);
0144 
0145     return 0;
0146 }
0147 
0148 static int ab8500_ext_regulator_disable(struct regulator_dev *rdev)
0149 {
0150     int ret;
0151     struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
0152     u8 regval;
0153 
0154     if (info == NULL) {
0155         dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
0156         return -EINVAL;
0157     }
0158 
0159     /*
0160      * Set the regulator in HW request mode if configured
0161      */
0162     if (info->cfg && info->cfg->hwreq)
0163         regval = info->update_val_hw;
0164     else
0165         regval = 0;
0166 
0167     ret = abx500_mask_and_set_register_interruptible(info->dev,
0168         info->update_bank, info->update_reg,
0169         info->update_mask, regval);
0170     if (ret < 0) {
0171         dev_err(rdev_get_dev(rdev),
0172             "couldn't set disable bits for regulator\n");
0173         return ret;
0174     }
0175 
0176     dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):"
0177         " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
0178         info->desc.name, info->update_bank, info->update_reg,
0179         info->update_mask, regval);
0180 
0181     return 0;
0182 }
0183 
0184 static int ab8500_ext_regulator_is_enabled(struct regulator_dev *rdev)
0185 {
0186     int ret;
0187     struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
0188     u8 regval;
0189 
0190     if (info == NULL) {
0191         dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
0192         return -EINVAL;
0193     }
0194 
0195     ret = abx500_get_register_interruptible(info->dev,
0196         info->update_bank, info->update_reg, &regval);
0197     if (ret < 0) {
0198         dev_err(rdev_get_dev(rdev),
0199             "couldn't read 0x%x register\n", info->update_reg);
0200         return ret;
0201     }
0202 
0203     dev_dbg(rdev_get_dev(rdev), "%s-is_enabled (bank, reg, mask, value):"
0204         " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
0205         info->desc.name, info->update_bank, info->update_reg,
0206         info->update_mask, regval);
0207 
0208     if (((regval & info->update_mask) == info->update_val_lp) ||
0209         ((regval & info->update_mask) == info->update_val_hp))
0210         return 1;
0211     else
0212         return 0;
0213 }
0214 
0215 static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev,
0216                      unsigned int mode)
0217 {
0218     int ret = 0;
0219     struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
0220     u8 regval;
0221 
0222     if (info == NULL) {
0223         dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
0224         return -EINVAL;
0225     }
0226 
0227     switch (mode) {
0228     case REGULATOR_MODE_NORMAL:
0229         regval = info->update_val_hp;
0230         break;
0231     case REGULATOR_MODE_IDLE:
0232         regval = info->update_val_lp;
0233         break;
0234 
0235     default:
0236         return -EINVAL;
0237     }
0238 
0239     /* If regulator is enabled and info->cfg->hwreq is set, the regulator
0240        must be on in high power, so we don't need to write the register with
0241        the same value.
0242      */
0243     if (ab8500_ext_regulator_is_enabled(rdev) &&
0244         !(info->cfg && info->cfg->hwreq)) {
0245         ret = abx500_mask_and_set_register_interruptible(info->dev,
0246                     info->update_bank, info->update_reg,
0247                     info->update_mask, regval);
0248         if (ret < 0) {
0249             dev_err(rdev_get_dev(rdev),
0250                 "Could not set regulator mode.\n");
0251             return ret;
0252         }
0253 
0254         dev_dbg(rdev_get_dev(rdev),
0255             "%s-set_mode (bank, reg, mask, value): "
0256             "0x%x, 0x%x, 0x%x, 0x%x\n",
0257             info->desc.name, info->update_bank, info->update_reg,
0258             info->update_mask, regval);
0259     }
0260 
0261     info->update_val = regval;
0262 
0263     return 0;
0264 }
0265 
0266 static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev)
0267 {
0268     struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
0269     int ret;
0270 
0271     if (info == NULL) {
0272         dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
0273         return -EINVAL;
0274     }
0275 
0276     if (info->update_val == info->update_val_hp)
0277         ret = REGULATOR_MODE_NORMAL;
0278     else if (info->update_val == info->update_val_lp)
0279         ret = REGULATOR_MODE_IDLE;
0280     else
0281         ret = -EINVAL;
0282 
0283     return ret;
0284 }
0285 
0286 static int ab8500_ext_set_voltage(struct regulator_dev *rdev, int min_uV,
0287                   int max_uV, unsigned *selector)
0288 {
0289     struct regulation_constraints *regu_constraints = rdev->constraints;
0290 
0291     if (!regu_constraints) {
0292         dev_err(rdev_get_dev(rdev), "No regulator constraints\n");
0293         return -EINVAL;
0294     }
0295 
0296     if (regu_constraints->min_uV == min_uV &&
0297         regu_constraints->max_uV == max_uV)
0298         return 0;
0299 
0300     dev_err(rdev_get_dev(rdev),
0301         "Requested min %duV max %duV != constrained min %duV max %duV\n",
0302         min_uV, max_uV,
0303         regu_constraints->min_uV, regu_constraints->max_uV);
0304 
0305     return -EINVAL;
0306 }
0307 
0308 static int ab8500_ext_list_voltage(struct regulator_dev *rdev,
0309                    unsigned selector)
0310 {
0311     struct regulation_constraints *regu_constraints = rdev->constraints;
0312 
0313     if (regu_constraints == NULL) {
0314         dev_err(rdev_get_dev(rdev), "regulator constraints null pointer\n");
0315         return -EINVAL;
0316     }
0317     /* return the uV for the fixed regulators */
0318     if (regu_constraints->min_uV && regu_constraints->max_uV) {
0319         if (regu_constraints->min_uV == regu_constraints->max_uV)
0320             return regu_constraints->min_uV;
0321     }
0322     return -EINVAL;
0323 }
0324 
0325 static const struct regulator_ops ab8500_ext_regulator_ops = {
0326     .enable         = ab8500_ext_regulator_enable,
0327     .disable        = ab8500_ext_regulator_disable,
0328     .is_enabled     = ab8500_ext_regulator_is_enabled,
0329     .set_mode       = ab8500_ext_regulator_set_mode,
0330     .get_mode       = ab8500_ext_regulator_get_mode,
0331     .set_voltage        = ab8500_ext_set_voltage,
0332     .list_voltage       = ab8500_ext_list_voltage,
0333 };
0334 
0335 static struct ab8500_ext_regulator_info
0336         ab8500_ext_regulator_info[AB8500_NUM_EXT_REGULATORS] = {
0337     [AB8500_EXT_SUPPLY1] = {
0338         .desc = {
0339             .name       = "VEXTSUPPLY1",
0340             .of_match   = of_match_ptr("ab8500_ext1"),
0341             .ops        = &ab8500_ext_regulator_ops,
0342             .type       = REGULATOR_VOLTAGE,
0343             .id     = AB8500_EXT_SUPPLY1,
0344             .owner      = THIS_MODULE,
0345             .n_voltages = 1,
0346         },
0347         .update_bank        = 0x04,
0348         .update_reg     = 0x08,
0349         .update_mask        = 0x03,
0350         .update_val     = 0x01,
0351         .update_val_hp      = 0x01,
0352         .update_val_lp      = 0x03,
0353         .update_val_hw      = 0x02,
0354     },
0355     [AB8500_EXT_SUPPLY2] = {
0356         .desc = {
0357             .name       = "VEXTSUPPLY2",
0358             .of_match   = of_match_ptr("ab8500_ext2"),
0359             .ops        = &ab8500_ext_regulator_ops,
0360             .type       = REGULATOR_VOLTAGE,
0361             .id     = AB8500_EXT_SUPPLY2,
0362             .owner      = THIS_MODULE,
0363             .n_voltages = 1,
0364         },
0365         .update_bank        = 0x04,
0366         .update_reg     = 0x08,
0367         .update_mask        = 0x0c,
0368         .update_val     = 0x04,
0369         .update_val_hp      = 0x04,
0370         .update_val_lp      = 0x0c,
0371         .update_val_hw      = 0x08,
0372     },
0373     [AB8500_EXT_SUPPLY3] = {
0374         .desc = {
0375             .name       = "VEXTSUPPLY3",
0376             .of_match   = of_match_ptr("ab8500_ext3"),
0377             .ops        = &ab8500_ext_regulator_ops,
0378             .type       = REGULATOR_VOLTAGE,
0379             .id     = AB8500_EXT_SUPPLY3,
0380             .owner      = THIS_MODULE,
0381             .n_voltages = 1,
0382         },
0383         .update_bank        = 0x04,
0384         .update_reg     = 0x08,
0385         .update_mask        = 0x30,
0386         .update_val     = 0x10,
0387         .update_val_hp      = 0x10,
0388         .update_val_lp      = 0x30,
0389         .update_val_hw      = 0x20,
0390     },
0391 };
0392 
0393 static int ab8500_ext_regulator_probe(struct platform_device *pdev)
0394 {
0395     struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
0396     struct regulator_config config = { };
0397     struct regulator_dev *rdev;
0398     int i;
0399 
0400     if (!ab8500) {
0401         dev_err(&pdev->dev, "null mfd parent\n");
0402         return -EINVAL;
0403     }
0404 
0405     /* check for AB8500 2.x */
0406     if (is_ab8500_2p0_or_earlier(ab8500)) {
0407         struct ab8500_ext_regulator_info *info;
0408 
0409         /* VextSupply3LPn is inverted on AB8500 2.x */
0410         info = &ab8500_ext_regulator_info[AB8500_EXT_SUPPLY3];
0411         info->update_val = 0x30;
0412         info->update_val_hp = 0x30;
0413         info->update_val_lp = 0x10;
0414     }
0415 
0416     /* register all regulators */
0417     for (i = 0; i < ARRAY_SIZE(ab8500_ext_regulator_info); i++) {
0418         struct ab8500_ext_regulator_info *info = NULL;
0419 
0420         /* assign per-regulator data */
0421         info = &ab8500_ext_regulator_info[i];
0422         info->dev = &pdev->dev;
0423         info->cfg = (struct ab8500_ext_regulator_cfg *)
0424             ab8500_ext_regulators[i].driver_data;
0425 
0426         config.dev = &pdev->dev;
0427         config.driver_data = info;
0428         config.init_data = &ab8500_ext_regulators[i];
0429 
0430         /* register regulator with framework */
0431         rdev = devm_regulator_register(&pdev->dev, &info->desc,
0432                            &config);
0433         if (IS_ERR(rdev)) {
0434             dev_err(&pdev->dev, "failed to register regulator %s\n",
0435                     info->desc.name);
0436             return PTR_ERR(rdev);
0437         }
0438 
0439         dev_dbg(&pdev->dev, "%s-probed\n", info->desc.name);
0440     }
0441 
0442     return 0;
0443 }
0444 
0445 static struct platform_driver ab8500_ext_regulator_driver = {
0446     .probe = ab8500_ext_regulator_probe,
0447     .driver         = {
0448         .name   = "ab8500-ext-regulator",
0449     },
0450 };
0451 
0452 static int __init ab8500_ext_regulator_init(void)
0453 {
0454     int ret;
0455 
0456     ret = platform_driver_register(&ab8500_ext_regulator_driver);
0457     if (ret)
0458         pr_err("Failed to register ab8500 ext regulator: %d\n", ret);
0459 
0460     return ret;
0461 }
0462 subsys_initcall(ab8500_ext_regulator_init);
0463 
0464 static void __exit ab8500_ext_regulator_exit(void)
0465 {
0466     platform_driver_unregister(&ab8500_ext_regulator_driver);
0467 }
0468 module_exit(ab8500_ext_regulator_exit);
0469 
0470 MODULE_LICENSE("GPL v2");
0471 MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
0472 MODULE_DESCRIPTION("AB8500 external regulator driver");
0473 MODULE_ALIAS("platform:ab8500-ext-regulator");