Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Copyright (c) 2021 MediaTek Inc.
0004 
0005 #include <linux/module.h>
0006 #include <linux/of_device.h>
0007 #include <linux/regmap.h>
0008 #include <linux/regulator/driver.h>
0009 #include <linux/regulator/machine.h>
0010 #include <linux/regulator/mt6315-regulator.h>
0011 #include <linux/regulator/of_regulator.h>
0012 #include <linux/spmi.h>
0013 
0014 #define MT6315_BUCK_MODE_AUTO       0
0015 #define MT6315_BUCK_MODE_FORCE_PWM  1
0016 #define MT6315_BUCK_MODE_LP     2
0017 
0018 struct mt6315_regulator_info {
0019     struct regulator_desc desc;
0020     u32 status_reg;
0021     u32 lp_mode_mask;
0022     u32 lp_mode_shift;
0023 };
0024 
0025 struct mt_regulator_init_data {
0026     u32 modeset_mask[MT6315_VBUCK_MAX];
0027 };
0028 
0029 struct mt6315_chip {
0030     struct device *dev;
0031     struct regmap *regmap;
0032 };
0033 
0034 #define MT_BUCK(_name, _bid, _vsel)             \
0035 [_bid] = {                          \
0036     .desc = {                       \
0037         .name = _name,                  \
0038         .of_match = of_match_ptr(_name),        \
0039         .regulators_node = "regulators",        \
0040         .ops = &mt6315_volt_range_ops,          \
0041         .type = REGULATOR_VOLTAGE,          \
0042         .id = _bid,                 \
0043         .owner = THIS_MODULE,               \
0044         .n_voltages = 0xc0,             \
0045         .linear_ranges = mt_volt_range1,        \
0046         .n_linear_ranges = ARRAY_SIZE(mt_volt_range1),  \
0047         .vsel_reg = _vsel,              \
0048         .vsel_mask = 0xff,              \
0049         .enable_reg = MT6315_BUCK_TOP_CON0,     \
0050         .enable_mask = BIT(_bid),           \
0051         .of_map_mode = mt6315_map_mode,         \
0052     },                          \
0053     .status_reg = _bid##_DBG4,              \
0054     .lp_mode_mask = BIT(_bid),              \
0055     .lp_mode_shift = _bid,                  \
0056 }
0057 
0058 static const struct linear_range mt_volt_range1[] = {
0059     REGULATOR_LINEAR_RANGE(0, 0, 0xbf, 6250),
0060 };
0061 
0062 static unsigned int mt6315_map_mode(unsigned int mode)
0063 {
0064     switch (mode) {
0065     case MT6315_BUCK_MODE_AUTO:
0066         return REGULATOR_MODE_NORMAL;
0067     case MT6315_BUCK_MODE_FORCE_PWM:
0068         return REGULATOR_MODE_FAST;
0069     case MT6315_BUCK_MODE_LP:
0070         return REGULATOR_MODE_IDLE;
0071     default:
0072         return REGULATOR_MODE_INVALID;
0073     }
0074 }
0075 
0076 static unsigned int mt6315_regulator_get_mode(struct regulator_dev *rdev)
0077 {
0078     struct mt_regulator_init_data *init = rdev_get_drvdata(rdev);
0079     const struct mt6315_regulator_info *info;
0080     int ret, regval;
0081     u32 modeset_mask;
0082 
0083     info = container_of(rdev->desc, struct mt6315_regulator_info, desc);
0084     modeset_mask = init->modeset_mask[rdev_get_id(rdev)];
0085     ret = regmap_read(rdev->regmap, MT6315_BUCK_TOP_4PHASE_ANA_CON42, &regval);
0086     if (ret != 0) {
0087         dev_err(&rdev->dev, "Failed to get mode: %d\n", ret);
0088         return ret;
0089     }
0090 
0091     if ((regval & modeset_mask) == modeset_mask)
0092         return REGULATOR_MODE_FAST;
0093 
0094     ret = regmap_read(rdev->regmap, MT6315_BUCK_TOP_CON1, &regval);
0095     if (ret != 0) {
0096         dev_err(&rdev->dev, "Failed to get lp mode: %d\n", ret);
0097         return ret;
0098     }
0099 
0100     if (regval & info->lp_mode_mask)
0101         return REGULATOR_MODE_IDLE;
0102     else
0103         return REGULATOR_MODE_NORMAL;
0104 }
0105 
0106 static int mt6315_regulator_set_mode(struct regulator_dev *rdev,
0107                      u32 mode)
0108 {
0109     struct mt_regulator_init_data *init = rdev_get_drvdata(rdev);
0110     const struct mt6315_regulator_info *info;
0111     int ret, val, curr_mode;
0112     u32 modeset_mask;
0113 
0114     info = container_of(rdev->desc, struct mt6315_regulator_info, desc);
0115     modeset_mask = init->modeset_mask[rdev_get_id(rdev)];
0116     curr_mode = mt6315_regulator_get_mode(rdev);
0117     switch (mode) {
0118     case REGULATOR_MODE_FAST:
0119         ret = regmap_update_bits(rdev->regmap,
0120                      MT6315_BUCK_TOP_4PHASE_ANA_CON42,
0121                      modeset_mask,
0122                      modeset_mask);
0123         break;
0124     case REGULATOR_MODE_NORMAL:
0125         if (curr_mode == REGULATOR_MODE_FAST) {
0126             ret = regmap_update_bits(rdev->regmap,
0127                          MT6315_BUCK_TOP_4PHASE_ANA_CON42,
0128                          modeset_mask,
0129                          0);
0130         } else if (curr_mode == REGULATOR_MODE_IDLE) {
0131             ret = regmap_update_bits(rdev->regmap,
0132                          MT6315_BUCK_TOP_CON1,
0133                          info->lp_mode_mask,
0134                          0);
0135             usleep_range(100, 110);
0136         } else {
0137             ret = -EINVAL;
0138         }
0139         break;
0140     case REGULATOR_MODE_IDLE:
0141         val = MT6315_BUCK_MODE_LP >> 1;
0142         val <<= info->lp_mode_shift;
0143         ret = regmap_update_bits(rdev->regmap,
0144                      MT6315_BUCK_TOP_CON1,
0145                      info->lp_mode_mask,
0146                      val);
0147         break;
0148     default:
0149         ret = -EINVAL;
0150         dev_err(&rdev->dev, "Unsupported mode: %d\n", mode);
0151         break;
0152     }
0153 
0154     if (ret != 0) {
0155         dev_err(&rdev->dev, "Failed to set mode: %d\n", ret);
0156         return ret;
0157     }
0158 
0159     return 0;
0160 }
0161 
0162 static int mt6315_get_status(struct regulator_dev *rdev)
0163 {
0164     const struct mt6315_regulator_info *info;
0165     int ret;
0166     u32 regval;
0167 
0168     info = container_of(rdev->desc, struct mt6315_regulator_info, desc);
0169     ret = regmap_read(rdev->regmap, info->status_reg, &regval);
0170     if (ret < 0) {
0171         dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
0172         return ret;
0173     }
0174 
0175     return (regval & BIT(0)) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
0176 }
0177 
0178 static const struct regulator_ops mt6315_volt_range_ops = {
0179     .list_voltage = regulator_list_voltage_linear_range,
0180     .map_voltage = regulator_map_voltage_linear_range,
0181     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0182     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0183     .set_voltage_time_sel = regulator_set_voltage_time_sel,
0184     .enable = regulator_enable_regmap,
0185     .disable = regulator_disable_regmap,
0186     .is_enabled = regulator_is_enabled_regmap,
0187     .get_status = mt6315_get_status,
0188     .set_mode = mt6315_regulator_set_mode,
0189     .get_mode = mt6315_regulator_get_mode,
0190 };
0191 
0192 static const struct mt6315_regulator_info mt6315_regulators[MT6315_VBUCK_MAX] = {
0193     MT_BUCK("vbuck1", MT6315_VBUCK1, MT6315_BUCK_TOP_ELR0),
0194     MT_BUCK("vbuck2", MT6315_VBUCK2, MT6315_BUCK_TOP_ELR2),
0195     MT_BUCK("vbuck3", MT6315_VBUCK3, MT6315_BUCK_TOP_ELR4),
0196     MT_BUCK("vbuck4", MT6315_VBUCK4, MT6315_BUCK_TOP_ELR6),
0197 };
0198 
0199 static const struct regmap_config mt6315_regmap_config = {
0200     .reg_bits   = 16,
0201     .val_bits   = 8,
0202     .max_register   = 0x16d0,
0203     .fast_io    = true,
0204 };
0205 
0206 static const struct of_device_id mt6315_of_match[] = {
0207     {
0208         .compatible = "mediatek,mt6315-regulator",
0209     }, {
0210         /* sentinel */
0211     },
0212 };
0213 MODULE_DEVICE_TABLE(of, mt6315_of_match);
0214 
0215 static int mt6315_regulator_probe(struct spmi_device *pdev)
0216 {
0217     struct device *dev = &pdev->dev;
0218     struct regmap *regmap;
0219     struct mt6315_chip *chip;
0220     struct mt_regulator_init_data *init_data;
0221     struct regulator_config config = {};
0222     struct regulator_dev *rdev;
0223     int i;
0224 
0225     regmap = devm_regmap_init_spmi_ext(pdev, &mt6315_regmap_config);
0226     if (IS_ERR(regmap))
0227         return PTR_ERR(regmap);
0228 
0229     chip = devm_kzalloc(dev, sizeof(struct mt6315_chip), GFP_KERNEL);
0230     if (!chip)
0231         return -ENOMEM;
0232 
0233     init_data = devm_kzalloc(dev, sizeof(struct mt_regulator_init_data), GFP_KERNEL);
0234     if (!init_data)
0235         return -ENOMEM;
0236 
0237     switch (pdev->usid) {
0238     case MT6315_PP:
0239         init_data->modeset_mask[MT6315_VBUCK1] = BIT(MT6315_VBUCK1) | BIT(MT6315_VBUCK2) |
0240                              BIT(MT6315_VBUCK4);
0241         break;
0242     case MT6315_SP:
0243     case MT6315_RP:
0244         init_data->modeset_mask[MT6315_VBUCK1] = BIT(MT6315_VBUCK1) | BIT(MT6315_VBUCK2);
0245         break;
0246     default:
0247         init_data->modeset_mask[MT6315_VBUCK1] = BIT(MT6315_VBUCK1);
0248         break;
0249     }
0250     for (i = MT6315_VBUCK2; i < MT6315_VBUCK_MAX; i++)
0251         init_data->modeset_mask[i] = BIT(i);
0252 
0253     chip->dev = dev;
0254     chip->regmap = regmap;
0255     dev_set_drvdata(dev, chip);
0256 
0257     config.dev = dev;
0258     config.regmap = regmap;
0259     for (i = MT6315_VBUCK1; i < MT6315_VBUCK_MAX; i++) {
0260         config.driver_data = init_data;
0261         rdev = devm_regulator_register(dev, &mt6315_regulators[i].desc, &config);
0262         if (IS_ERR(rdev)) {
0263             dev_err(dev, "Failed to register %s\n",
0264                 mt6315_regulators[i].desc.name);
0265             return PTR_ERR(rdev);
0266         }
0267     }
0268 
0269     return 0;
0270 }
0271 
0272 static void mt6315_regulator_shutdown(struct spmi_device *pdev)
0273 {
0274     struct mt6315_chip *chip = dev_get_drvdata(&pdev->dev);
0275     int ret = 0;
0276 
0277     ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY_H, PROTECTION_KEY_H);
0278     ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY, PROTECTION_KEY);
0279     ret |= regmap_update_bits(chip->regmap, MT6315_TOP2_ELR7, 1, 1);
0280     ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY, 0);
0281     ret |= regmap_write(chip->regmap, MT6315_TOP_TMA_KEY_H, 0);
0282     if (ret < 0)
0283         dev_err(&pdev->dev, "[%#x] Failed to enable power off sequence. %d\n",
0284                pdev->usid, ret);
0285 }
0286 
0287 static struct spmi_driver mt6315_regulator_driver = {
0288     .driver     = {
0289         .name   = "mt6315-regulator",
0290         .of_match_table = mt6315_of_match,
0291     },
0292     .probe = mt6315_regulator_probe,
0293     .shutdown = mt6315_regulator_shutdown,
0294 };
0295 
0296 module_spmi_driver(mt6315_regulator_driver);
0297 
0298 MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
0299 MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6315 PMIC");
0300 MODULE_LICENSE("GPL");