Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Device driver for regulators in Hisi IC
0004 //
0005 // Copyright (c) 2013 Linaro Ltd.
0006 // Copyright (c) 2011 HiSilicon Ltd.
0007 // Copyright (c) 2020-2021 Huawei Technologies Co., Ltd.
0008 //
0009 // Guodong Xu <guodong.xu@linaro.org>
0010 
0011 #include <linux/delay.h>
0012 #include <linux/module.h>
0013 #include <linux/of.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regmap.h>
0016 #include <linux/regulator/driver.h>
0017 #include <linux/spmi.h>
0018 
0019 struct hi6421_spmi_reg_priv {
0020     /* Serialize regulator enable logic */
0021     struct mutex enable_mutex;
0022 };
0023 
0024 struct hi6421_spmi_reg_info {
0025     struct regulator_desc   desc;
0026     u8          eco_mode_mask;
0027     u32         eco_uA;
0028 };
0029 
0030 static const unsigned int range_1v5_to_2v0[] = {
0031     1500000, 1550000, 1600000, 1650000,
0032     1700000, 1725000, 1750000, 1775000,
0033     1800000, 1825000, 1850000, 1875000,
0034     1900000, 1925000, 1950000, 2000000
0035 };
0036 
0037 static const unsigned int range_1v725_to_1v9[] = {
0038     1725000, 1750000, 1775000, 1800000,
0039     1825000, 1850000, 1875000, 1900000
0040 };
0041 
0042 static const unsigned int range_1v75_to_3v3[] = {
0043     1750000, 1800000, 1825000, 2800000,
0044     2850000, 2950000, 3000000, 3300000
0045 };
0046 
0047 static const unsigned int range_1v8_to_3v0[] = {
0048     1800000, 1850000, 2400000, 2600000,
0049     2700000, 2850000, 2950000, 3000000
0050 };
0051 
0052 static const unsigned int range_2v5_to_3v3[] = {
0053     2500000, 2600000, 2700000, 2800000,
0054     3000000, 3100000, 3200000, 3300000
0055 };
0056 
0057 static const unsigned int range_2v6_to_3v3[] = {
0058     2600000, 2700000, 2800000, 2900000,
0059     3000000, 3100000, 3200000, 3300000
0060 };
0061 
0062 /**
0063  * HI6421V600_LDO() - specify a LDO power line
0064  * @_id: LDO id name string
0065  * @vtable: voltage table
0066  * @ereg: enable register
0067  * @emask: enable mask
0068  * @vreg: voltage select register
0069  * @odelay: off/on delay time in uS
0070  * @etime: enable time in uS
0071  * @ecomask: eco mode mask
0072  * @ecoamp: eco mode load uppler limit in uA
0073  */
0074 #define HI6421V600_LDO(_id, vtable, ereg, emask, vreg,                 \
0075                odelay, etime, ecomask, ecoamp)                 \
0076     [hi6421v600_##_id] = {                             \
0077         .desc = {                              \
0078             .name       = #_id,                    \
0079             .of_match        = of_match_ptr(#_id),             \
0080             .regulators_node = of_match_ptr("regulators"),         \
0081             .ops        = &hi6421_spmi_ldo_rops,           \
0082             .type       = REGULATOR_VOLTAGE,               \
0083             .id     = hi6421v600_##_id,            \
0084             .owner      = THIS_MODULE,                 \
0085             .volt_table = vtable,                  \
0086             .n_voltages = ARRAY_SIZE(vtable),              \
0087             .vsel_mask  = ARRAY_SIZE(vtable) - 1,          \
0088             .vsel_reg   = vreg,                    \
0089             .enable_reg = ereg,                    \
0090             .enable_mask    = emask,                   \
0091             .enable_time    = etime,                   \
0092             .ramp_delay = etime,                   \
0093             .off_on_delay   = odelay,                  \
0094         },                                 \
0095         .eco_mode_mask      = ecomask,                 \
0096         .eco_uA         = ecoamp,                  \
0097     }
0098 
0099 static int hi6421_spmi_regulator_enable(struct regulator_dev *rdev)
0100 {
0101     struct hi6421_spmi_reg_priv *priv = rdev_get_drvdata(rdev);
0102     int ret;
0103 
0104     /* cannot enable more than one regulator at one time */
0105     mutex_lock(&priv->enable_mutex);
0106 
0107     ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
0108                  rdev->desc->enable_mask,
0109                  rdev->desc->enable_mask);
0110 
0111     /* Avoid powering up multiple devices at the same time */
0112     usleep_range(rdev->desc->off_on_delay, rdev->desc->off_on_delay + 60);
0113 
0114     mutex_unlock(&priv->enable_mutex);
0115 
0116     return ret;
0117 }
0118 
0119 static unsigned int hi6421_spmi_regulator_get_mode(struct regulator_dev *rdev)
0120 {
0121     struct hi6421_spmi_reg_info *sreg;
0122     unsigned int reg_val;
0123 
0124     sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc);
0125     regmap_read(rdev->regmap, rdev->desc->enable_reg, &reg_val);
0126 
0127     if (reg_val & sreg->eco_mode_mask)
0128         return REGULATOR_MODE_IDLE;
0129 
0130     return REGULATOR_MODE_NORMAL;
0131 }
0132 
0133 static int hi6421_spmi_regulator_set_mode(struct regulator_dev *rdev,
0134                       unsigned int mode)
0135 {
0136     struct hi6421_spmi_reg_info *sreg;
0137     unsigned int val;
0138 
0139     sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc);
0140     switch (mode) {
0141     case REGULATOR_MODE_NORMAL:
0142         val = 0;
0143         break;
0144     case REGULATOR_MODE_IDLE:
0145         if (!sreg->eco_mode_mask)
0146             return -EINVAL;
0147 
0148         val = sreg->eco_mode_mask;
0149         break;
0150     default:
0151         return -EINVAL;
0152     }
0153 
0154     return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
0155                   sreg->eco_mode_mask, val);
0156 }
0157 
0158 static unsigned int
0159 hi6421_spmi_regulator_get_optimum_mode(struct regulator_dev *rdev,
0160                        int input_uV, int output_uV,
0161                        int load_uA)
0162 {
0163     struct hi6421_spmi_reg_info *sreg;
0164 
0165     sreg = container_of(rdev->desc, struct hi6421_spmi_reg_info, desc);
0166 
0167     if (!sreg->eco_uA || ((unsigned int)load_uA > sreg->eco_uA))
0168         return REGULATOR_MODE_NORMAL;
0169 
0170     return REGULATOR_MODE_IDLE;
0171 }
0172 
0173 static const struct regulator_ops hi6421_spmi_ldo_rops = {
0174     .is_enabled = regulator_is_enabled_regmap,
0175     .enable = hi6421_spmi_regulator_enable,
0176     .disable = regulator_disable_regmap,
0177     .list_voltage = regulator_list_voltage_table,
0178     .map_voltage = regulator_map_voltage_ascend,
0179     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0180     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0181     .get_mode = hi6421_spmi_regulator_get_mode,
0182     .set_mode = hi6421_spmi_regulator_set_mode,
0183     .get_optimum_mode = hi6421_spmi_regulator_get_optimum_mode,
0184 };
0185 
0186 /* HI6421v600 regulators with known registers */
0187 enum hi6421_spmi_regulator_id {
0188     hi6421v600_ldo3,
0189     hi6421v600_ldo4,
0190     hi6421v600_ldo9,
0191     hi6421v600_ldo15,
0192     hi6421v600_ldo16,
0193     hi6421v600_ldo17,
0194     hi6421v600_ldo33,
0195     hi6421v600_ldo34,
0196 };
0197 
0198 static struct hi6421_spmi_reg_info regulator_info[] = {
0199     HI6421V600_LDO(ldo3, range_1v5_to_2v0,
0200                0x16, 0x01, 0x51,
0201                20000, 120,
0202                0, 0),
0203     HI6421V600_LDO(ldo4, range_1v725_to_1v9,
0204                0x17, 0x01, 0x52,
0205                20000, 120,
0206                0x10, 10000),
0207     HI6421V600_LDO(ldo9, range_1v75_to_3v3,
0208                0x1c, 0x01, 0x57,
0209                20000, 360,
0210                0x10, 10000),
0211     HI6421V600_LDO(ldo15, range_1v8_to_3v0,
0212                0x21, 0x01, 0x5c,
0213                20000, 360,
0214                0x10, 10000),
0215     HI6421V600_LDO(ldo16, range_1v8_to_3v0,
0216                0x22, 0x01, 0x5d,
0217                20000, 360,
0218                0x10, 10000),
0219     HI6421V600_LDO(ldo17, range_2v5_to_3v3,
0220                0x23, 0x01, 0x5e,
0221                20000, 120,
0222                0x10, 10000),
0223     HI6421V600_LDO(ldo33, range_2v5_to_3v3,
0224                0x32, 0x01, 0x6d,
0225                20000, 120,
0226                0, 0),
0227     HI6421V600_LDO(ldo34, range_2v6_to_3v3,
0228                0x33, 0x01, 0x6e,
0229                20000, 120,
0230                0, 0),
0231 };
0232 
0233 static int hi6421_spmi_regulator_probe(struct platform_device *pdev)
0234 {
0235     struct device *pmic_dev = pdev->dev.parent;
0236     struct regulator_config config = { };
0237     struct hi6421_spmi_reg_priv *priv;
0238     struct hi6421_spmi_reg_info *info;
0239     struct device *dev = &pdev->dev;
0240     struct regmap *regmap;
0241     struct regulator_dev *rdev;
0242     int i;
0243 
0244     /*
0245      * This driver is meant to be called by hi6421-spmi-core,
0246      * which should first set drvdata. If this doesn't happen, hit
0247      * a warn on and return.
0248      */
0249     regmap = dev_get_drvdata(pmic_dev);
0250     if (WARN_ON(!regmap))
0251         return -ENODEV;
0252 
0253     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0254     if (!priv)
0255         return -ENOMEM;
0256 
0257     mutex_init(&priv->enable_mutex);
0258 
0259     for (i = 0; i < ARRAY_SIZE(regulator_info); i++) {
0260         info = &regulator_info[i];
0261 
0262         config.dev = pdev->dev.parent;
0263         config.driver_data = priv;
0264         config.regmap = regmap;
0265 
0266         rdev = devm_regulator_register(dev, &info->desc, &config);
0267         if (IS_ERR(rdev)) {
0268             dev_err(dev, "failed to register %s\n",
0269                 info->desc.name);
0270             return PTR_ERR(rdev);
0271         }
0272     }
0273 
0274     return 0;
0275 }
0276 
0277 static const struct platform_device_id hi6421_spmi_regulator_table[] = {
0278     { .name = "hi6421v600-regulator" },
0279     {},
0280 };
0281 MODULE_DEVICE_TABLE(platform, hi6421_spmi_regulator_table);
0282 
0283 static struct platform_driver hi6421_spmi_regulator_driver = {
0284     .id_table = hi6421_spmi_regulator_table,
0285     .driver = {
0286         .name = "hi6421v600-regulator",
0287     },
0288     .probe  = hi6421_spmi_regulator_probe,
0289 };
0290 module_platform_driver(hi6421_spmi_regulator_driver);
0291 
0292 MODULE_DESCRIPTION("Hi6421v600 SPMI regulator driver");
0293 MODULE_LICENSE("GPL v2");
0294