Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 //
0003 // max14577.c - Regulator driver for the Maxim 14577/77836
0004 //
0005 // Copyright (C) 2013,2014 Samsung Electronics
0006 // Krzysztof Kozlowski <krzk@kernel.org>
0007 
0008 #include <linux/module.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/regulator/driver.h>
0011 #include <linux/mfd/max14577.h>
0012 #include <linux/mfd/max14577-private.h>
0013 #include <linux/regulator/of_regulator.h>
0014 
0015 static int max14577_reg_is_enabled(struct regulator_dev *rdev)
0016 {
0017     int rid = rdev_get_id(rdev);
0018     struct regmap *rmap = rdev->regmap;
0019     u8 reg_data;
0020 
0021     switch (rid) {
0022     case MAX14577_CHARGER:
0023         max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL2, &reg_data);
0024         if ((reg_data & CHGCTRL2_MBCHOSTEN_MASK) == 0)
0025             return 0;
0026         max14577_read_reg(rmap, MAX14577_CHG_REG_STATUS3, &reg_data);
0027         if ((reg_data & STATUS3_CGMBC_MASK) == 0)
0028             return 0;
0029         /* MBCHOSTEN and CGMBC are on */
0030         return 1;
0031     default:
0032         return -EINVAL;
0033     }
0034 }
0035 
0036 static int max14577_reg_get_current_limit(struct regulator_dev *rdev)
0037 {
0038     u8 reg_data;
0039     struct regmap *rmap = rdev->regmap;
0040     struct max14577 *max14577 = rdev_get_drvdata(rdev);
0041     const struct maxim_charger_current *limits =
0042         &maxim_charger_currents[max14577->dev_type];
0043 
0044     if (rdev_get_id(rdev) != MAX14577_CHARGER)
0045         return -EINVAL;
0046 
0047     max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL4, &reg_data);
0048 
0049     if ((reg_data & CHGCTRL4_MBCICHWRCL_MASK) == 0)
0050         return limits->min;
0051 
0052     reg_data = ((reg_data & CHGCTRL4_MBCICHWRCH_MASK) >>
0053             CHGCTRL4_MBCICHWRCH_SHIFT);
0054     return limits->high_start + reg_data * limits->high_step;
0055 }
0056 
0057 static int max14577_reg_set_current_limit(struct regulator_dev *rdev,
0058         int min_uA, int max_uA)
0059 {
0060     u8 reg_data;
0061     int ret;
0062     struct max14577 *max14577 = rdev_get_drvdata(rdev);
0063     const struct maxim_charger_current *limits =
0064         &maxim_charger_currents[max14577->dev_type];
0065 
0066     if (rdev_get_id(rdev) != MAX14577_CHARGER)
0067         return -EINVAL;
0068 
0069     ret = maxim_charger_calc_reg_current(limits, min_uA, max_uA, &reg_data);
0070     if (ret)
0071         return ret;
0072 
0073     return max14577_update_reg(rdev->regmap, MAX14577_CHG_REG_CHG_CTRL4,
0074             CHGCTRL4_MBCICHWRCL_MASK | CHGCTRL4_MBCICHWRCH_MASK,
0075             reg_data);
0076 }
0077 
0078 static const struct regulator_ops max14577_safeout_ops = {
0079     .is_enabled     = regulator_is_enabled_regmap,
0080     .enable         = regulator_enable_regmap,
0081     .disable        = regulator_disable_regmap,
0082     .list_voltage       = regulator_list_voltage_linear,
0083 };
0084 
0085 static const struct regulator_ops max14577_charger_ops = {
0086     .is_enabled     = max14577_reg_is_enabled,
0087     .enable         = regulator_enable_regmap,
0088     .disable        = regulator_disable_regmap,
0089     .get_current_limit  = max14577_reg_get_current_limit,
0090     .set_current_limit  = max14577_reg_set_current_limit,
0091 };
0092 
0093 #define MAX14577_SAFEOUT_REG    { \
0094     .name       = "SAFEOUT", \
0095     .of_match   = of_match_ptr("SAFEOUT"), \
0096     .regulators_node = of_match_ptr("regulators"), \
0097     .id     = MAX14577_SAFEOUT, \
0098     .ops        = &max14577_safeout_ops, \
0099     .type       = REGULATOR_VOLTAGE, \
0100     .owner      = THIS_MODULE, \
0101     .n_voltages = 1, \
0102     .min_uV     = MAX14577_REGULATOR_SAFEOUT_VOLTAGE, \
0103     .enable_reg = MAX14577_REG_CONTROL2, \
0104     .enable_mask    = CTRL2_SFOUTORD_MASK, \
0105 }
0106 #define MAX14577_CHARGER_REG    { \
0107     .name       = "CHARGER", \
0108     .of_match   = of_match_ptr("CHARGER"), \
0109     .regulators_node = of_match_ptr("regulators"), \
0110     .id     = MAX14577_CHARGER, \
0111     .ops        = &max14577_charger_ops, \
0112     .type       = REGULATOR_CURRENT, \
0113     .owner      = THIS_MODULE, \
0114     .enable_reg = MAX14577_CHG_REG_CHG_CTRL2, \
0115     .enable_mask    = CHGCTRL2_MBCHOSTEN_MASK, \
0116 }
0117 
0118 static const struct regulator_desc max14577_supported_regulators[] = {
0119     [MAX14577_SAFEOUT] = MAX14577_SAFEOUT_REG,
0120     [MAX14577_CHARGER] = MAX14577_CHARGER_REG,
0121 };
0122 
0123 static const struct regulator_ops max77836_ldo_ops = {
0124     .is_enabled     = regulator_is_enabled_regmap,
0125     .enable         = regulator_enable_regmap,
0126     .disable        = regulator_disable_regmap,
0127     .list_voltage       = regulator_list_voltage_linear,
0128     .map_voltage        = regulator_map_voltage_linear,
0129     .get_voltage_sel    = regulator_get_voltage_sel_regmap,
0130     .set_voltage_sel    = regulator_set_voltage_sel_regmap,
0131     /* TODO: add .set_suspend_mode */
0132 };
0133 
0134 #define MAX77836_LDO_REG(num)   { \
0135     .name       = "LDO" # num, \
0136     .of_match   = of_match_ptr("LDO" # num), \
0137     .regulators_node = of_match_ptr("regulators"), \
0138     .id     = MAX77836_LDO ## num, \
0139     .ops        = &max77836_ldo_ops, \
0140     .type       = REGULATOR_VOLTAGE, \
0141     .owner      = THIS_MODULE, \
0142     .n_voltages = MAX77836_REGULATOR_LDO_VOLTAGE_STEPS_NUM, \
0143     .min_uV     = MAX77836_REGULATOR_LDO_VOLTAGE_MIN, \
0144     .uV_step    = MAX77836_REGULATOR_LDO_VOLTAGE_STEP, \
0145     .enable_reg = MAX77836_LDO_REG_CNFG1_LDO ## num, \
0146     .enable_mask    = MAX77836_CNFG1_LDO_PWRMD_MASK, \
0147     .vsel_reg   = MAX77836_LDO_REG_CNFG1_LDO ## num, \
0148     .vsel_mask  = MAX77836_CNFG1_LDO_TV_MASK, \
0149 }
0150 
0151 static const struct regulator_desc max77836_supported_regulators[] = {
0152     [MAX14577_SAFEOUT] = MAX14577_SAFEOUT_REG,
0153     [MAX14577_CHARGER] = MAX14577_CHARGER_REG,
0154     [MAX77836_LDO1] = MAX77836_LDO_REG(1),
0155     [MAX77836_LDO2] = MAX77836_LDO_REG(2),
0156 };
0157 
0158 /*
0159  * Registers for regulators of max77836 use different I2C slave addresses so
0160  * different regmaps must be used for them.
0161  *
0162  * Returns proper regmap for accessing regulator passed by id.
0163  */
0164 static struct regmap *max14577_get_regmap(struct max14577 *max14577,
0165         int reg_id)
0166 {
0167     switch (max14577->dev_type) {
0168     case MAXIM_DEVICE_TYPE_MAX77836:
0169         switch (reg_id) {
0170         case MAX77836_SAFEOUT ... MAX77836_CHARGER:
0171             return max14577->regmap;
0172         default:
0173             /* MAX77836_LDO1 ... MAX77836_LDO2 */
0174             return max14577->regmap_pmic;
0175         }
0176 
0177     case MAXIM_DEVICE_TYPE_MAX14577:
0178     default:
0179         return max14577->regmap;
0180     }
0181 }
0182 
0183 static int max14577_regulator_probe(struct platform_device *pdev)
0184 {
0185     struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
0186     struct max14577_platform_data *pdata = dev_get_platdata(max14577->dev);
0187     int i, ret = 0;
0188     struct regulator_config config = {};
0189     const struct regulator_desc *supported_regulators;
0190     unsigned int supported_regulators_size;
0191     enum maxim_device_type dev_type = max14577->dev_type;
0192 
0193     switch (dev_type) {
0194     case MAXIM_DEVICE_TYPE_MAX77836:
0195         supported_regulators = max77836_supported_regulators;
0196         supported_regulators_size = ARRAY_SIZE(max77836_supported_regulators);
0197         break;
0198     case MAXIM_DEVICE_TYPE_MAX14577:
0199     default:
0200         supported_regulators = max14577_supported_regulators;
0201         supported_regulators_size = ARRAY_SIZE(max14577_supported_regulators);
0202     }
0203 
0204     config.dev = max14577->dev;
0205     config.driver_data = max14577;
0206 
0207     for (i = 0; i < supported_regulators_size; i++) {
0208         struct regulator_dev *regulator;
0209         /*
0210          * Index of supported_regulators[] is also the id and must
0211          * match index of pdata->regulators[].
0212          */
0213         if (pdata && pdata->regulators) {
0214             config.init_data = pdata->regulators[i].initdata;
0215             config.of_node = pdata->regulators[i].of_node;
0216         }
0217         config.regmap = max14577_get_regmap(max14577,
0218                 supported_regulators[i].id);
0219 
0220         regulator = devm_regulator_register(&pdev->dev,
0221                 &supported_regulators[i], &config);
0222         if (IS_ERR(regulator)) {
0223             ret = PTR_ERR(regulator);
0224             dev_err(&pdev->dev,
0225                     "Regulator init failed for %d/%s with error: %d\n",
0226                     i, supported_regulators[i].name, ret);
0227             return ret;
0228         }
0229     }
0230 
0231     return ret;
0232 }
0233 
0234 static const struct platform_device_id max14577_regulator_id[] = {
0235     { "max14577-regulator", MAXIM_DEVICE_TYPE_MAX14577, },
0236     { "max77836-regulator", MAXIM_DEVICE_TYPE_MAX77836, },
0237     { }
0238 };
0239 MODULE_DEVICE_TABLE(platform, max14577_regulator_id);
0240 
0241 static struct platform_driver max14577_regulator_driver = {
0242     .driver = {
0243            .name = "max14577-regulator",
0244            },
0245     .probe      = max14577_regulator_probe,
0246     .id_table   = max14577_regulator_id,
0247 };
0248 
0249 static int __init max14577_regulator_init(void)
0250 {
0251     BUILD_BUG_ON(ARRAY_SIZE(max14577_supported_regulators) != MAX14577_REGULATOR_NUM);
0252     BUILD_BUG_ON(ARRAY_SIZE(max77836_supported_regulators) != MAX77836_REGULATOR_NUM);
0253 
0254     BUILD_BUG_ON(MAX77836_REGULATOR_LDO_VOLTAGE_MIN +
0255             (MAX77836_REGULATOR_LDO_VOLTAGE_STEP *
0256               (MAX77836_REGULATOR_LDO_VOLTAGE_STEPS_NUM - 1)) !=
0257             MAX77836_REGULATOR_LDO_VOLTAGE_MAX);
0258 
0259     return platform_driver_register(&max14577_regulator_driver);
0260 }
0261 subsys_initcall(max14577_regulator_init);
0262 
0263 static void __exit max14577_regulator_exit(void)
0264 {
0265     platform_driver_unregister(&max14577_regulator_driver);
0266 }
0267 module_exit(max14577_regulator_exit);
0268 
0269 MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
0270 MODULE_DESCRIPTION("Maxim 14577/77836 regulator driver");
0271 MODULE_LICENSE("GPL");