Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Regulators driver for Marvell 88PM8607
0004  *
0005  * Copyright (C) 2009 Marvell International Ltd.
0006  *  Haojian Zhuang <haojian.zhuang@marvell.com>
0007  */
0008 #include <linux/kernel.h>
0009 #include <linux/init.h>
0010 #include <linux/err.h>
0011 #include <linux/of.h>
0012 #include <linux/regulator/of_regulator.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/regulator/driver.h>
0015 #include <linux/regulator/machine.h>
0016 #include <linux/mfd/88pm860x.h>
0017 #include <linux/module.h>
0018 
0019 struct pm8607_regulator_info {
0020     struct regulator_desc   desc;
0021 
0022     unsigned int    *vol_suspend;
0023 
0024     int slope_double;
0025 };
0026 
0027 static const unsigned int BUCK1_table[] = {
0028      725000,  750000,  775000,  800000,  825000,  850000,  875000,  900000,
0029      925000,  950000,  975000, 1000000, 1025000, 1050000, 1075000, 1100000,
0030     1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000,
0031     1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000,
0032           0,   25000,   50000,   75000,  100000,  125000,  150000,  175000,
0033      200000,  225000,  250000,  275000,  300000,  325000,  350000,  375000,
0034      400000,  425000,  450000,  475000,  500000,  525000,  550000,  575000,
0035      600000,  625000,  650000,  675000,  700000,  725000,  750000,  775000,
0036 };
0037 
0038 static const unsigned int BUCK1_suspend_table[] = {
0039           0,   25000,   50000,   75000,  100000,  125000,  150000,  175000,
0040      200000,  225000,  250000,  275000,  300000,  325000,  350000,  375000,
0041      400000,  425000,  450000,  475000,  500000,  525000,  550000,  575000,
0042      600000,  625000,  650000,  675000,  700000,  725000,  750000,  775000,
0043      800000,  825000,  850000,  875000,  900000,  925000,  950000,  975000,
0044     1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
0045     1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
0046     1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000,
0047 };
0048 
0049 static const unsigned int BUCK2_table[] = {
0050           0,   50000,  100000,  150000,  200000,  250000,  300000,  350000,
0051      400000,  450000,  500000,  550000,  600000,  650000,  700000,  750000,
0052      800000,  850000,  900000,  950000, 1000000, 1050000, 1100000, 1150000,
0053     1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
0054     1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000,
0055     2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000,
0056     2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000,
0057     2800000, 2850000, 2900000, 2950000, 3000000, 3000000, 3000000, 3000000,
0058 };
0059 
0060 static const unsigned int BUCK2_suspend_table[] = {
0061           0,   50000,  100000,  150000,  200000,  250000,  300000,  350000,
0062      400000,  450000,  500000,  550000,  600000,  650000,  700000,  750000,
0063      800000,  850000,  900000,  950000, 1000000, 1050000, 1100000, 1150000,
0064     1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000,
0065     1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000,
0066     2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000,
0067     2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000,
0068     2800000, 2850000, 2900000, 2950000, 3000000, 3000000, 3000000, 3000000,
0069 };
0070 
0071 static const unsigned int BUCK3_table[] = {
0072           0,   25000,   50000,   75000,  100000,  125000,  150000,  175000,
0073      200000,  225000,  250000,  275000,  300000,  325000,  350000,  375000,
0074      400000,  425000,  450000,  475000,  500000,  525000,  550000,  575000,
0075      600000,  625000,  650000,  675000,  700000,  725000,  750000,  775000,
0076      800000,  825000,  850000,  875000,  900000,  925000,  950000,  975000,
0077     1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
0078     1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
0079     1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000,
0080 };
0081 
0082 static const unsigned int BUCK3_suspend_table[] = {
0083           0,   25000,   50000,   75000,  100000,  125000,  150000,  175000,
0084      200000,  225000,  250000,  275000,  300000,  325000,  350000,  375000,
0085      400000,  425000,  450000,  475000,  500000,  525000,  550000,  575000,
0086      600000,  625000,  650000,  675000,  700000,  725000,  750000,  775000,
0087      800000,  825000,  850000,  875000,  900000,  925000,  950000,  975000,
0088     1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000,
0089     1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000,
0090     1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000,
0091 };
0092 
0093 static const unsigned int LDO1_table[] = {
0094     1800000, 1200000, 2800000, 0,
0095 };
0096 
0097 static const unsigned int LDO1_suspend_table[] = {
0098     1800000, 1200000, 0, 0,
0099 };
0100 
0101 static const unsigned int LDO2_table[] = {
0102     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
0103 };
0104 
0105 static const unsigned int LDO2_suspend_table[] = {
0106     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
0107 };
0108 
0109 static const unsigned int LDO3_table[] = {
0110     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
0111 };
0112 
0113 static const unsigned int LDO3_suspend_table[] = {
0114     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
0115 };
0116 
0117 static const unsigned int LDO4_table[] = {
0118     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2900000, 3300000,
0119 };
0120 
0121 static const unsigned int LDO4_suspend_table[] = {
0122     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2900000, 2900000,
0123 };
0124 
0125 static const unsigned int LDO5_table[] = {
0126     2900000, 3000000, 3100000, 3300000,
0127 };
0128 
0129 static const unsigned int LDO5_suspend_table[] = {
0130     2900000, 0, 0, 0,
0131 };
0132 
0133 static const unsigned int LDO6_table[] = {
0134     1800000, 1850000, 2600000, 2650000, 2700000, 2750000, 2800000, 3300000,
0135 };
0136 
0137 static const unsigned int LDO6_suspend_table[] = {
0138     1800000, 1850000, 2600000, 2650000, 2700000, 2750000, 2800000, 2900000,
0139 };
0140 
0141 static const unsigned int LDO7_table[] = {
0142     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
0143 };
0144 
0145 static const unsigned int LDO7_suspend_table[] = {
0146     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
0147 };
0148 
0149 static const unsigned int LDO8_table[] = {
0150     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
0151 };
0152 
0153 static const unsigned int LDO8_suspend_table[] = {
0154     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
0155 };
0156 
0157 static const unsigned int LDO9_table[] = {
0158     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
0159 };
0160 
0161 static const unsigned int LDO9_suspend_table[] = {
0162     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
0163 };
0164 
0165 static const unsigned int LDO10_table[] = {
0166     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000,
0167     1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
0168 };
0169 
0170 static const unsigned int LDO10_suspend_table[] = {
0171     1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000,
0172     1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
0173 };
0174 
0175 static const unsigned int LDO12_table[] = {
0176     1800000, 1900000, 2700000, 2800000, 2900000, 3000000, 3100000, 3300000,
0177     1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
0178 };
0179 
0180 static const unsigned int LDO12_suspend_table[] = {
0181     1800000, 1900000, 2700000, 2800000, 2900000, 2900000, 2900000, 2900000,
0182     1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000,
0183 };
0184 
0185 static const unsigned int LDO13_table[] = {
0186     1200000, 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0,
0187 };
0188 
0189 static const unsigned int LDO13_suspend_table[] = {
0190     0,
0191 };
0192 
0193 static const unsigned int LDO14_table[] = {
0194     1800000, 1850000, 2700000, 2750000, 2800000, 2850000, 2900000, 3300000,
0195 };
0196 
0197 static const unsigned int LDO14_suspend_table[] = {
0198     1800000, 1850000, 2700000, 2750000, 2800000, 2850000, 2900000, 2900000,
0199 };
0200 
0201 static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
0202 {
0203     struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
0204     int ret;
0205 
0206     ret = regulator_list_voltage_table(rdev, index);
0207     if (ret < 0)
0208         return ret;
0209 
0210     if (info->slope_double)
0211         ret <<= 1;
0212 
0213     return ret;
0214 }
0215 
0216 static const struct regulator_ops pm8607_regulator_ops = {
0217     .list_voltage   = pm8607_list_voltage,
0218     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0219     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0220     .enable = regulator_enable_regmap,
0221     .disable = regulator_disable_regmap,
0222     .is_enabled = regulator_is_enabled_regmap,
0223 };
0224 
0225 static const struct regulator_ops pm8606_preg_ops = {
0226     .enable     = regulator_enable_regmap,
0227     .disable    = regulator_disable_regmap,
0228     .is_enabled = regulator_is_enabled_regmap,
0229 };
0230 
0231 #define PM8606_PREG(ereg, ebit)                     \
0232 {                                   \
0233     .desc   = {                         \
0234         .name   = "PREG",                   \
0235         .of_match = of_match_ptr("PREG"),           \
0236         .regulators_node = of_match_ptr("regulators"),      \
0237         .ops    = &pm8606_preg_ops,             \
0238         .type   = REGULATOR_CURRENT,                \
0239         .id = PM8606_ID_PREG,               \
0240         .owner  = THIS_MODULE,                  \
0241         .enable_reg = PM8606_##ereg,                \
0242         .enable_mask = (ebit),                  \
0243         .enable_is_inverted = true,             \
0244     },                              \
0245 }
0246 
0247 #define PM8607_DVC(vreg, ureg, ubit, ereg, ebit)            \
0248 {                                   \
0249     .desc   = {                         \
0250         .name   = #vreg,                    \
0251         .of_match = of_match_ptr(#vreg),            \
0252         .regulators_node = of_match_ptr("regulators"),      \
0253         .ops    = &pm8607_regulator_ops,            \
0254         .type   = REGULATOR_VOLTAGE,                \
0255         .id = PM8607_ID_##vreg,             \
0256         .owner  = THIS_MODULE,                  \
0257         .volt_table = vreg##_table,             \
0258         .n_voltages = ARRAY_SIZE(vreg##_table),         \
0259         .vsel_reg = PM8607_##vreg,              \
0260         .vsel_mask = ARRAY_SIZE(vreg##_table) - 1,      \
0261         .apply_reg = PM8607_##ureg,             \
0262         .apply_bit = (ubit),                    \
0263         .enable_reg = PM8607_##ereg,                \
0264         .enable_mask = 1 << (ebit),             \
0265     },                              \
0266     .slope_double   = (0),                      \
0267     .vol_suspend    = (unsigned int *)&vreg##_suspend_table,    \
0268 }
0269 
0270 #define PM8607_LDO(_id, vreg, shift, ereg, ebit)            \
0271 {                                   \
0272     .desc   = {                         \
0273         .name   = "LDO" #_id,                   \
0274         .of_match = of_match_ptr("LDO" #_id),           \
0275         .regulators_node = of_match_ptr("regulators"),      \
0276         .ops    = &pm8607_regulator_ops,            \
0277         .type   = REGULATOR_VOLTAGE,                \
0278         .id = PM8607_ID_LDO##_id,               \
0279         .owner  = THIS_MODULE,                  \
0280         .volt_table = LDO##_id##_table,             \
0281         .n_voltages = ARRAY_SIZE(LDO##_id##_table),     \
0282         .vsel_reg = PM8607_##vreg,              \
0283         .vsel_mask = (ARRAY_SIZE(LDO##_id##_table) - 1) << (shift), \
0284         .enable_reg = PM8607_##ereg,                \
0285         .enable_mask = 1 << (ebit),             \
0286     },                              \
0287     .slope_double   = (0),                      \
0288     .vol_suspend    = (unsigned int *)&LDO##_id##_suspend_table,    \
0289 }
0290 
0291 static struct pm8607_regulator_info pm8607_regulator_info[] = {
0292     PM8607_DVC(BUCK1, GO, BIT(0), SUPPLIES_EN11, 0),
0293     PM8607_DVC(BUCK2, GO, BIT(1), SUPPLIES_EN11, 1),
0294     PM8607_DVC(BUCK3, GO, BIT(2), SUPPLIES_EN11, 2),
0295 
0296     PM8607_LDO(1,         LDO1, 0, SUPPLIES_EN11, 3),
0297     PM8607_LDO(2,         LDO2, 0, SUPPLIES_EN11, 4),
0298     PM8607_LDO(3,         LDO3, 0, SUPPLIES_EN11, 5),
0299     PM8607_LDO(4,         LDO4, 0, SUPPLIES_EN11, 6),
0300     PM8607_LDO(5,         LDO5, 0, SUPPLIES_EN11, 7),
0301     PM8607_LDO(6,         LDO6, 0, SUPPLIES_EN12, 0),
0302     PM8607_LDO(7,         LDO7, 0, SUPPLIES_EN12, 1),
0303     PM8607_LDO(8,         LDO8, 0, SUPPLIES_EN12, 2),
0304     PM8607_LDO(9,         LDO9, 0, SUPPLIES_EN12, 3),
0305     PM8607_LDO(10,        LDO10, 0, SUPPLIES_EN12, 4),
0306     PM8607_LDO(12,        LDO12, 0, SUPPLIES_EN12, 5),
0307     PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0),
0308     PM8607_LDO(14,        LDO14, 0, SUPPLIES_EN12, 6),
0309 };
0310 
0311 static struct pm8607_regulator_info pm8606_regulator_info[] = {
0312     PM8606_PREG(PREREGULATORB, 5),
0313 };
0314 
0315 static int pm8607_regulator_probe(struct platform_device *pdev)
0316 {
0317     struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
0318     struct pm8607_regulator_info *info = NULL;
0319     struct regulator_init_data *pdata = dev_get_platdata(&pdev->dev);
0320     struct regulator_config config = { };
0321     struct regulator_dev *rdev;
0322     struct resource *res;
0323     int i;
0324 
0325     res = platform_get_resource(pdev, IORESOURCE_REG, 0);
0326     if (res) {
0327         /* There're resources in 88PM8607 regulator driver */
0328         for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
0329             info = &pm8607_regulator_info[i];
0330             if (info->desc.vsel_reg == res->start)
0331                 break;
0332         }
0333         if (i == ARRAY_SIZE(pm8607_regulator_info)) {
0334             dev_err(&pdev->dev, "Failed to find regulator %llu\n",
0335                 (unsigned long long)res->start);
0336             return -EINVAL;
0337         }
0338     } else {
0339         /* There's no resource in 88PM8606 PREG regulator driver */
0340         info = &pm8606_regulator_info[0];
0341         /* i is used to check regulator ID */
0342         i = -1;
0343     }
0344 
0345     /* check DVC ramp slope double */
0346     if ((i == PM8607_ID_BUCK3) && chip->buck3_double)
0347         info->slope_double = 1;
0348 
0349     config.dev = chip->dev;
0350     config.driver_data = info;
0351 
0352     if (pdata)
0353         config.init_data = pdata;
0354 
0355     if (chip->id == CHIP_PM8607)
0356         config.regmap = chip->regmap;
0357     else
0358         config.regmap = chip->regmap_companion;
0359 
0360     rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
0361     if (IS_ERR(rdev)) {
0362         dev_err(&pdev->dev, "failed to register regulator %s\n",
0363             info->desc.name);
0364         return PTR_ERR(rdev);
0365     }
0366 
0367     platform_set_drvdata(pdev, info);
0368     return 0;
0369 }
0370 
0371 static const struct platform_device_id pm8607_regulator_driver_ids[] = {
0372     {
0373         .name   = "88pm860x-regulator",
0374         .driver_data    = 0,
0375     }, {
0376         .name   = "88pm860x-preg",
0377         .driver_data    = 0,
0378     },
0379     { },
0380 };
0381 MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids);
0382 
0383 static struct platform_driver pm8607_regulator_driver = {
0384     .driver     = {
0385         .name   = "88pm860x-regulator",
0386     },
0387     .probe      = pm8607_regulator_probe,
0388     .id_table   = pm8607_regulator_driver_ids,
0389 };
0390 
0391 static int __init pm8607_regulator_init(void)
0392 {
0393     return platform_driver_register(&pm8607_regulator_driver);
0394 }
0395 subsys_initcall(pm8607_regulator_init);
0396 
0397 static void __exit pm8607_regulator_exit(void)
0398 {
0399     platform_driver_unregister(&pm8607_regulator_driver);
0400 }
0401 module_exit(pm8607_regulator_exit);
0402 
0403 MODULE_LICENSE("GPL");
0404 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
0405 MODULE_DESCRIPTION("Regulator Driver for Marvell 88PM8607 PMIC");
0406 MODULE_ALIAS("platform:88pm8607-regulator");