Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Copyright (C) 2018 BayLibre SAS
0004 // Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
0005 //
0006 // Regulator driver for MAXIM 77650/77651 charger/power-supply.
0007 
0008 #include <linux/of.h>
0009 #include <linux/mfd/max77650.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/regmap.h>
0013 #include <linux/regulator/driver.h>
0014 
0015 #define MAX77650_REGULATOR_EN_CTRL_MASK     GENMASK(3, 0)
0016 #define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \
0017         ((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK)
0018 #define MAX77650_REGULATOR_ENABLED      GENMASK(2, 1)
0019 #define MAX77650_REGULATOR_DISABLED     BIT(2)
0020 
0021 #define MAX77650_REGULATOR_V_LDO_MASK       GENMASK(6, 0)
0022 #define MAX77650_REGULATOR_V_SBB_MASK       GENMASK(5, 0)
0023 #define MAX77651_REGULATOR_V_SBB1_MASK      GENMASK(5, 2)
0024 #define MAX77651_REGULATOR_V_SBB1_RANGE_MASK    GENMASK(1, 0)
0025 
0026 #define MAX77650_REGULATOR_AD_MASK      BIT(3)
0027 #define MAX77650_REGULATOR_AD_DISABLED      0x00
0028 #define MAX77650_REGULATOR_AD_ENABLED       BIT(3)
0029 
0030 #define MAX77650_REGULATOR_CURR_LIM_MASK    GENMASK(7, 6)
0031 
0032 enum {
0033     MAX77650_REGULATOR_ID_LDO = 0,
0034     MAX77650_REGULATOR_ID_SBB0,
0035     MAX77650_REGULATOR_ID_SBB1,
0036     MAX77650_REGULATOR_ID_SBB2,
0037     MAX77650_REGULATOR_NUM_REGULATORS,
0038 };
0039 
0040 struct max77650_regulator_desc {
0041     struct regulator_desc desc;
0042     unsigned int regA;
0043     unsigned int regB;
0044 };
0045 
0046 static struct max77650_regulator_desc max77651_SBB1_desc;
0047 
0048 static const unsigned int max77651_sbb1_volt_range_sel[] = {
0049     0x0, 0x1, 0x2, 0x3
0050 };
0051 
0052 static const struct linear_range max77651_sbb1_volt_ranges[] = {
0053     /* range index 0 */
0054     REGULATOR_LINEAR_RANGE(2400000, 0x00, 0x0f, 50000),
0055     /* range index 1 */
0056     REGULATOR_LINEAR_RANGE(3200000, 0x00, 0x0f, 50000),
0057     /* range index 2 */
0058     REGULATOR_LINEAR_RANGE(4000000, 0x00, 0x0f, 50000),
0059     /* range index 3 */
0060     REGULATOR_LINEAR_RANGE(4800000, 0x00, 0x09, 50000),
0061 };
0062 
0063 static const unsigned int max77650_current_limit_table[] = {
0064     1000000, 866000, 707000, 500000,
0065 };
0066 
0067 static int max77650_regulator_is_enabled(struct regulator_dev *rdev)
0068 {
0069     struct max77650_regulator_desc *rdesc;
0070     struct regmap *map;
0071     int val, rv, en;
0072 
0073     rdesc = rdev_get_drvdata(rdev);
0074     map = rdev_get_regmap(rdev);
0075 
0076     rv = regmap_read(map, rdesc->regB, &val);
0077     if (rv)
0078         return rv;
0079 
0080     en = MAX77650_REGULATOR_EN_CTRL_BITS(val);
0081 
0082     return en != MAX77650_REGULATOR_DISABLED;
0083 }
0084 
0085 static int max77650_regulator_enable(struct regulator_dev *rdev)
0086 {
0087     struct max77650_regulator_desc *rdesc;
0088     struct regmap *map;
0089 
0090     rdesc = rdev_get_drvdata(rdev);
0091     map = rdev_get_regmap(rdev);
0092 
0093     return regmap_update_bits(map, rdesc->regB,
0094                   MAX77650_REGULATOR_EN_CTRL_MASK,
0095                   MAX77650_REGULATOR_ENABLED);
0096 }
0097 
0098 static int max77650_regulator_disable(struct regulator_dev *rdev)
0099 {
0100     struct max77650_regulator_desc *rdesc;
0101     struct regmap *map;
0102 
0103     rdesc = rdev_get_drvdata(rdev);
0104     map = rdev_get_regmap(rdev);
0105 
0106     return regmap_update_bits(map, rdesc->regB,
0107                   MAX77650_REGULATOR_EN_CTRL_MASK,
0108                   MAX77650_REGULATOR_DISABLED);
0109 }
0110 
0111 static const struct regulator_ops max77650_regulator_LDO_ops = {
0112     .is_enabled     = max77650_regulator_is_enabled,
0113     .enable         = max77650_regulator_enable,
0114     .disable        = max77650_regulator_disable,
0115     .list_voltage       = regulator_list_voltage_linear,
0116     .map_voltage        = regulator_map_voltage_linear,
0117     .get_voltage_sel    = regulator_get_voltage_sel_regmap,
0118     .set_voltage_sel    = regulator_set_voltage_sel_regmap,
0119     .set_active_discharge   = regulator_set_active_discharge_regmap,
0120 };
0121 
0122 static const struct regulator_ops max77650_regulator_SBB_ops = {
0123     .is_enabled     = max77650_regulator_is_enabled,
0124     .enable         = max77650_regulator_enable,
0125     .disable        = max77650_regulator_disable,
0126     .list_voltage       = regulator_list_voltage_linear,
0127     .map_voltage        = regulator_map_voltage_linear,
0128     .get_voltage_sel    = regulator_get_voltage_sel_regmap,
0129     .set_voltage_sel    = regulator_set_voltage_sel_regmap,
0130     .get_current_limit  = regulator_get_current_limit_regmap,
0131     .set_current_limit  = regulator_set_current_limit_regmap,
0132     .set_active_discharge   = regulator_set_active_discharge_regmap,
0133 };
0134 
0135 /* Special case for max77651 SBB1 - pickable linear-range voltage mapping. */
0136 static const struct regulator_ops max77651_SBB1_regulator_ops = {
0137     .is_enabled     = max77650_regulator_is_enabled,
0138     .enable         = max77650_regulator_enable,
0139     .disable        = max77650_regulator_disable,
0140     .list_voltage       = regulator_list_voltage_pickable_linear_range,
0141     .get_voltage_sel    = regulator_get_voltage_sel_pickable_regmap,
0142     .set_voltage_sel    = regulator_set_voltage_sel_pickable_regmap,
0143     .get_current_limit  = regulator_get_current_limit_regmap,
0144     .set_current_limit  = regulator_set_current_limit_regmap,
0145     .set_active_discharge   = regulator_set_active_discharge_regmap,
0146 };
0147 
0148 static struct max77650_regulator_desc max77650_LDO_desc = {
0149     .desc = {
0150         .name           = "ldo",
0151         .of_match       = of_match_ptr("ldo"),
0152         .regulators_node    = of_match_ptr("regulators"),
0153         .supply_name        = "in-ldo",
0154         .id         = MAX77650_REGULATOR_ID_LDO,
0155         .ops            = &max77650_regulator_LDO_ops,
0156         .min_uV         = 1350000,
0157         .uV_step        = 12500,
0158         .n_voltages     = 128,
0159         .vsel_step      = 1,
0160         .vsel_mask      = MAX77650_REGULATOR_V_LDO_MASK,
0161         .vsel_reg       = MAX77650_REG_CNFG_LDO_A,
0162         .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
0163         .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
0164         .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
0165         .active_discharge_reg   = MAX77650_REG_CNFG_LDO_B,
0166         .enable_time        = 100,
0167         .type           = REGULATOR_VOLTAGE,
0168         .owner          = THIS_MODULE,
0169     },
0170     .regA       = MAX77650_REG_CNFG_LDO_A,
0171     .regB       = MAX77650_REG_CNFG_LDO_B,
0172 };
0173 
0174 static struct max77650_regulator_desc max77650_SBB0_desc = {
0175     .desc = {
0176         .name           = "sbb0",
0177         .of_match       = of_match_ptr("sbb0"),
0178         .regulators_node    = of_match_ptr("regulators"),
0179         .supply_name        = "in-sbb0",
0180         .id         = MAX77650_REGULATOR_ID_SBB0,
0181         .ops            = &max77650_regulator_SBB_ops,
0182         .min_uV         = 800000,
0183         .uV_step        = 25000,
0184         .n_voltages     = 64,
0185         .vsel_step      = 1,
0186         .vsel_mask      = MAX77650_REGULATOR_V_SBB_MASK,
0187         .vsel_reg       = MAX77650_REG_CNFG_SBB0_A,
0188         .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
0189         .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
0190         .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
0191         .active_discharge_reg   = MAX77650_REG_CNFG_SBB0_B,
0192         .enable_time        = 100,
0193         .type           = REGULATOR_VOLTAGE,
0194         .owner          = THIS_MODULE,
0195         .csel_reg       = MAX77650_REG_CNFG_SBB0_A,
0196         .csel_mask      = MAX77650_REGULATOR_CURR_LIM_MASK,
0197         .curr_table     = max77650_current_limit_table,
0198         .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
0199     },
0200     .regA       = MAX77650_REG_CNFG_SBB0_A,
0201     .regB       = MAX77650_REG_CNFG_SBB0_B,
0202 };
0203 
0204 static struct max77650_regulator_desc max77650_SBB1_desc = {
0205     .desc = {
0206         .name           = "sbb1",
0207         .of_match       = of_match_ptr("sbb1"),
0208         .regulators_node    = of_match_ptr("regulators"),
0209         .supply_name        = "in-sbb1",
0210         .id         = MAX77650_REGULATOR_ID_SBB1,
0211         .ops            = &max77650_regulator_SBB_ops,
0212         .min_uV         = 800000,
0213         .uV_step        = 12500,
0214         .n_voltages     = 64,
0215         .vsel_step      = 1,
0216         .vsel_mask      = MAX77650_REGULATOR_V_SBB_MASK,
0217         .vsel_reg       = MAX77650_REG_CNFG_SBB1_A,
0218         .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
0219         .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
0220         .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
0221         .active_discharge_reg   = MAX77650_REG_CNFG_SBB1_B,
0222         .enable_time        = 100,
0223         .type           = REGULATOR_VOLTAGE,
0224         .owner          = THIS_MODULE,
0225         .csel_reg       = MAX77650_REG_CNFG_SBB1_A,
0226         .csel_mask      = MAX77650_REGULATOR_CURR_LIM_MASK,
0227         .curr_table     = max77650_current_limit_table,
0228         .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
0229     },
0230     .regA       = MAX77650_REG_CNFG_SBB1_A,
0231     .regB       = MAX77650_REG_CNFG_SBB1_B,
0232 };
0233 
0234 static struct max77650_regulator_desc max77651_SBB1_desc = {
0235     .desc = {
0236         .name           = "sbb1",
0237         .of_match       = of_match_ptr("sbb1"),
0238         .regulators_node    = of_match_ptr("regulators"),
0239         .supply_name        = "in-sbb1",
0240         .id         = MAX77650_REGULATOR_ID_SBB1,
0241         .ops            = &max77651_SBB1_regulator_ops,
0242         .linear_range_selectors = max77651_sbb1_volt_range_sel,
0243         .linear_ranges      = max77651_sbb1_volt_ranges,
0244         .n_linear_ranges    = ARRAY_SIZE(max77651_sbb1_volt_ranges),
0245         .n_voltages     = 58,
0246         .vsel_step      = 1,
0247         .vsel_range_mask    = MAX77651_REGULATOR_V_SBB1_RANGE_MASK,
0248         .vsel_range_reg     = MAX77650_REG_CNFG_SBB1_A,
0249         .vsel_mask      = MAX77651_REGULATOR_V_SBB1_MASK,
0250         .vsel_reg       = MAX77650_REG_CNFG_SBB1_A,
0251         .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
0252         .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
0253         .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
0254         .active_discharge_reg   = MAX77650_REG_CNFG_SBB1_B,
0255         .enable_time        = 100,
0256         .type           = REGULATOR_VOLTAGE,
0257         .owner          = THIS_MODULE,
0258         .csel_reg       = MAX77650_REG_CNFG_SBB1_A,
0259         .csel_mask      = MAX77650_REGULATOR_CURR_LIM_MASK,
0260         .curr_table     = max77650_current_limit_table,
0261         .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
0262     },
0263     .regA       = MAX77650_REG_CNFG_SBB1_A,
0264     .regB       = MAX77650_REG_CNFG_SBB1_B,
0265 };
0266 
0267 static struct max77650_regulator_desc max77650_SBB2_desc = {
0268     .desc = {
0269         .name           = "sbb2",
0270         .of_match       = of_match_ptr("sbb2"),
0271         .regulators_node    = of_match_ptr("regulators"),
0272         .supply_name        = "in-sbb0",
0273         .id         = MAX77650_REGULATOR_ID_SBB2,
0274         .ops            = &max77650_regulator_SBB_ops,
0275         .min_uV         = 800000,
0276         .uV_step        = 50000,
0277         .n_voltages     = 64,
0278         .vsel_step      = 1,
0279         .vsel_mask      = MAX77650_REGULATOR_V_SBB_MASK,
0280         .vsel_reg       = MAX77650_REG_CNFG_SBB2_A,
0281         .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
0282         .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
0283         .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
0284         .active_discharge_reg   = MAX77650_REG_CNFG_SBB2_B,
0285         .enable_time        = 100,
0286         .type           = REGULATOR_VOLTAGE,
0287         .owner          = THIS_MODULE,
0288         .csel_reg       = MAX77650_REG_CNFG_SBB2_A,
0289         .csel_mask      = MAX77650_REGULATOR_CURR_LIM_MASK,
0290         .curr_table     = max77650_current_limit_table,
0291         .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
0292     },
0293     .regA       = MAX77650_REG_CNFG_SBB2_A,
0294     .regB       = MAX77650_REG_CNFG_SBB2_B,
0295 };
0296 
0297 static struct max77650_regulator_desc max77651_SBB2_desc = {
0298     .desc = {
0299         .name           = "sbb2",
0300         .of_match       = of_match_ptr("sbb2"),
0301         .regulators_node    = of_match_ptr("regulators"),
0302         .supply_name        = "in-sbb0",
0303         .id         = MAX77650_REGULATOR_ID_SBB2,
0304         .ops            = &max77650_regulator_SBB_ops,
0305         .min_uV         = 2400000,
0306         .uV_step        = 50000,
0307         .n_voltages     = 64,
0308         .vsel_step      = 1,
0309         .vsel_mask      = MAX77650_REGULATOR_V_SBB_MASK,
0310         .vsel_reg       = MAX77650_REG_CNFG_SBB2_A,
0311         .active_discharge_off   = MAX77650_REGULATOR_AD_DISABLED,
0312         .active_discharge_on    = MAX77650_REGULATOR_AD_ENABLED,
0313         .active_discharge_mask  = MAX77650_REGULATOR_AD_MASK,
0314         .active_discharge_reg   = MAX77650_REG_CNFG_SBB2_B,
0315         .enable_time        = 100,
0316         .type           = REGULATOR_VOLTAGE,
0317         .owner          = THIS_MODULE,
0318         .csel_reg       = MAX77650_REG_CNFG_SBB2_A,
0319         .csel_mask      = MAX77650_REGULATOR_CURR_LIM_MASK,
0320         .curr_table     = max77650_current_limit_table,
0321         .n_current_limits = ARRAY_SIZE(max77650_current_limit_table),
0322     },
0323     .regA       = MAX77650_REG_CNFG_SBB2_A,
0324     .regB       = MAX77650_REG_CNFG_SBB2_B,
0325 };
0326 
0327 static int max77650_regulator_probe(struct platform_device *pdev)
0328 {
0329     struct max77650_regulator_desc **rdescs;
0330     struct max77650_regulator_desc *rdesc;
0331     struct regulator_config config = { };
0332     struct device *dev, *parent;
0333     struct regulator_dev *rdev;
0334     struct regmap *map;
0335     unsigned int val;
0336     int i, rv;
0337 
0338     dev = &pdev->dev;
0339     parent = dev->parent;
0340 
0341     if (!dev->of_node)
0342         dev->of_node = parent->of_node;
0343 
0344     rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS,
0345                   sizeof(*rdescs), GFP_KERNEL);
0346     if (!rdescs)
0347         return -ENOMEM;
0348 
0349     map = dev_get_regmap(parent, NULL);
0350     if (!map)
0351         return -ENODEV;
0352 
0353     rv = regmap_read(map, MAX77650_REG_CID, &val);
0354     if (rv)
0355         return rv;
0356 
0357     rdescs[MAX77650_REGULATOR_ID_LDO] = &max77650_LDO_desc;
0358     rdescs[MAX77650_REGULATOR_ID_SBB0] = &max77650_SBB0_desc;
0359 
0360     switch (MAX77650_CID_BITS(val)) {
0361     case MAX77650_CID_77650A:
0362     case MAX77650_CID_77650C:
0363         rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77650_SBB1_desc;
0364         rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77650_SBB2_desc;
0365         break;
0366     case MAX77650_CID_77651A:
0367     case MAX77650_CID_77651B:
0368         rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77651_SBB1_desc;
0369         rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77651_SBB2_desc;
0370         break;
0371     default:
0372         return -ENODEV;
0373     }
0374 
0375     config.dev = parent;
0376 
0377     for (i = 0; i < MAX77650_REGULATOR_NUM_REGULATORS; i++) {
0378         rdesc = rdescs[i];
0379         config.driver_data = rdesc;
0380 
0381         rdev = devm_regulator_register(dev, &rdesc->desc, &config);
0382         if (IS_ERR(rdev))
0383             return PTR_ERR(rdev);
0384     }
0385 
0386     return 0;
0387 }
0388 
0389 static const struct of_device_id max77650_regulator_of_match[] = {
0390     { .compatible = "maxim,max77650-regulator" },
0391     { }
0392 };
0393 MODULE_DEVICE_TABLE(of, max77650_regulator_of_match);
0394 
0395 static struct platform_driver max77650_regulator_driver = {
0396     .driver = {
0397         .name = "max77650-regulator",
0398         .of_match_table = max77650_regulator_of_match,
0399     },
0400     .probe = max77650_regulator_probe,
0401 };
0402 module_platform_driver(max77650_regulator_driver);
0403 
0404 MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver");
0405 MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
0406 MODULE_LICENSE("GPL v2");
0407 MODULE_ALIAS("platform:max77650-regulator");