Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Regulators driver for Maxim max8925
0004  *
0005  * Copyright (C) 2009 Marvell International Ltd.
0006  *      Haojian Zhuang <haojian.zhuang@marvell.com>
0007  */
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/err.h>
0012 #include <linux/i2c.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/regulator/driver.h>
0015 #include <linux/regulator/machine.h>
0016 #include <linux/mfd/max8925.h>
0017 #include <linux/of.h>
0018 #include <linux/regulator/of_regulator.h>
0019 
0020 #define SD1_DVM_VMIN        850000
0021 #define SD1_DVM_VMAX        1000000
0022 #define SD1_DVM_STEP        50000
0023 #define SD1_DVM_SHIFT       5       /* SDCTL1 bit5 */
0024 #define SD1_DVM_EN      6       /* SDV1 bit 6 */
0025 
0026 /* bit definitions in LDO control registers */
0027 #define LDO_SEQ_I2C     0x7     /* Power U/D by i2c */
0028 #define LDO_SEQ_MASK        0x7     /* Power U/D sequence mask */
0029 #define LDO_SEQ_SHIFT       2       /* Power U/D sequence offset */
0030 #define LDO_I2C_EN      0x1     /* Enable by i2c */
0031 #define LDO_I2C_EN_MASK     0x1     /* Enable mask by i2c */
0032 #define LDO_I2C_EN_SHIFT    0       /* Enable offset by i2c */
0033 
0034 struct max8925_regulator_info {
0035     struct regulator_desc   desc;
0036     struct i2c_client   *i2c;
0037 
0038     int vol_reg;
0039     int enable_reg;
0040 };
0041 
0042 static int max8925_set_voltage_sel(struct regulator_dev *rdev,
0043                    unsigned int selector)
0044 {
0045     struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
0046     unsigned char mask = rdev->desc->n_voltages - 1;
0047 
0048     return max8925_set_bits(info->i2c, info->vol_reg, mask, selector);
0049 }
0050 
0051 static int max8925_get_voltage_sel(struct regulator_dev *rdev)
0052 {
0053     struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
0054     unsigned char data, mask;
0055     int ret;
0056 
0057     ret = max8925_reg_read(info->i2c, info->vol_reg);
0058     if (ret < 0)
0059         return ret;
0060     mask = rdev->desc->n_voltages - 1;
0061     data = ret & mask;
0062 
0063     return data;
0064 }
0065 
0066 static int max8925_enable(struct regulator_dev *rdev)
0067 {
0068     struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
0069 
0070     return max8925_set_bits(info->i2c, info->enable_reg,
0071                 LDO_SEQ_MASK << LDO_SEQ_SHIFT |
0072                 LDO_I2C_EN_MASK << LDO_I2C_EN_SHIFT,
0073                 LDO_SEQ_I2C << LDO_SEQ_SHIFT |
0074                 LDO_I2C_EN << LDO_I2C_EN_SHIFT);
0075 }
0076 
0077 static int max8925_disable(struct regulator_dev *rdev)
0078 {
0079     struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
0080 
0081     return max8925_set_bits(info->i2c, info->enable_reg,
0082                 LDO_SEQ_MASK << LDO_SEQ_SHIFT |
0083                 LDO_I2C_EN_MASK << LDO_I2C_EN_SHIFT,
0084                 LDO_SEQ_I2C << LDO_SEQ_SHIFT);
0085 }
0086 
0087 static int max8925_is_enabled(struct regulator_dev *rdev)
0088 {
0089     struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
0090     int ldo_seq, ret;
0091 
0092     ret = max8925_reg_read(info->i2c, info->enable_reg);
0093     if (ret < 0)
0094         return ret;
0095     ldo_seq = (ret >> LDO_SEQ_SHIFT) & LDO_SEQ_MASK;
0096     if (ldo_seq != LDO_SEQ_I2C)
0097         return 1;
0098     else
0099         return ret & (LDO_I2C_EN_MASK << LDO_I2C_EN_SHIFT);
0100 }
0101 
0102 static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV)
0103 {
0104     struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
0105     unsigned char data, mask;
0106 
0107     if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX)
0108         return -EINVAL;
0109 
0110     data = DIV_ROUND_UP(uV - SD1_DVM_VMIN, SD1_DVM_STEP);
0111     data <<= SD1_DVM_SHIFT;
0112     mask = 3 << SD1_DVM_SHIFT;
0113 
0114     return max8925_set_bits(info->i2c, info->enable_reg, mask, data);
0115 }
0116 
0117 static int max8925_set_dvm_enable(struct regulator_dev *rdev)
0118 {
0119     struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
0120 
0121     return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN,
0122                 1 << SD1_DVM_EN);
0123 }
0124 
0125 static int max8925_set_dvm_disable(struct regulator_dev *rdev)
0126 {
0127     struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
0128 
0129     return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, 0);
0130 }
0131 
0132 static const struct regulator_ops max8925_regulator_sdv_ops = {
0133     .map_voltage        = regulator_map_voltage_linear,
0134     .list_voltage       = regulator_list_voltage_linear,
0135     .set_voltage_sel    = max8925_set_voltage_sel,
0136     .get_voltage_sel    = max8925_get_voltage_sel,
0137     .enable         = max8925_enable,
0138     .disable        = max8925_disable,
0139     .is_enabled     = max8925_is_enabled,
0140     .set_suspend_voltage    = max8925_set_dvm_voltage,
0141     .set_suspend_enable = max8925_set_dvm_enable,
0142     .set_suspend_disable    = max8925_set_dvm_disable,
0143 };
0144 
0145 static const struct regulator_ops max8925_regulator_ldo_ops = {
0146     .map_voltage        = regulator_map_voltage_linear,
0147     .list_voltage       = regulator_list_voltage_linear,
0148     .set_voltage_sel    = max8925_set_voltage_sel,
0149     .get_voltage_sel    = max8925_get_voltage_sel,
0150     .enable         = max8925_enable,
0151     .disable        = max8925_disable,
0152     .is_enabled     = max8925_is_enabled,
0153 };
0154 
0155 #define MAX8925_SDV(_id, min, max, step)            \
0156 {                               \
0157     .desc   = {                     \
0158         .name   = "SDV" #_id,               \
0159         .of_match = of_match_ptr("SDV" #_id),       \
0160         .regulators_node = of_match_ptr("regulators"),  \
0161         .ops    = &max8925_regulator_sdv_ops,       \
0162         .type   = REGULATOR_VOLTAGE,            \
0163         .id = MAX8925_ID_SD##_id,           \
0164         .owner  = THIS_MODULE,              \
0165         .n_voltages = 64,               \
0166         .min_uV = min * 1000,               \
0167         .uV_step = step * 1000,             \
0168     },                          \
0169     .vol_reg    = MAX8925_SDV##_id,         \
0170     .enable_reg = MAX8925_SDCTL##_id,           \
0171 }
0172 
0173 #define MAX8925_LDO(_id, min, max, step)            \
0174 {                               \
0175     .desc   = {                     \
0176         .name   = "LDO" #_id,               \
0177         .of_match = of_match_ptr("LDO" #_id),       \
0178         .regulators_node = of_match_ptr("regulators"),  \
0179         .ops    = &max8925_regulator_ldo_ops,       \
0180         .type   = REGULATOR_VOLTAGE,            \
0181         .id = MAX8925_ID_LDO##_id,          \
0182         .owner  = THIS_MODULE,              \
0183         .n_voltages = 64,               \
0184         .min_uV = min * 1000,               \
0185         .uV_step = step * 1000,             \
0186     },                          \
0187     .vol_reg    = MAX8925_LDOVOUT##_id,         \
0188     .enable_reg = MAX8925_LDOCTL##_id,          \
0189 }
0190 
0191 static struct max8925_regulator_info max8925_regulator_info[] = {
0192     MAX8925_SDV(1, 637.5, 1425, 12.5),
0193     MAX8925_SDV(2,   650, 2225,   25),
0194     MAX8925_SDV(3,   750, 3900,   50),
0195 
0196     MAX8925_LDO(1,  750, 3900, 50),
0197     MAX8925_LDO(2,  650, 2250, 25),
0198     MAX8925_LDO(3,  650, 2250, 25),
0199     MAX8925_LDO(4,  750, 3900, 50),
0200     MAX8925_LDO(5,  750, 3900, 50),
0201     MAX8925_LDO(6,  750, 3900, 50),
0202     MAX8925_LDO(7,  750, 3900, 50),
0203     MAX8925_LDO(8,  750, 3900, 50),
0204     MAX8925_LDO(9,  750, 3900, 50),
0205     MAX8925_LDO(10, 750, 3900, 50),
0206     MAX8925_LDO(11, 750, 3900, 50),
0207     MAX8925_LDO(12, 750, 3900, 50),
0208     MAX8925_LDO(13, 750, 3900, 50),
0209     MAX8925_LDO(14, 750, 3900, 50),
0210     MAX8925_LDO(15, 750, 3900, 50),
0211     MAX8925_LDO(16, 750, 3900, 50),
0212     MAX8925_LDO(17, 650, 2250, 25),
0213     MAX8925_LDO(18, 650, 2250, 25),
0214     MAX8925_LDO(19, 750, 3900, 50),
0215     MAX8925_LDO(20, 750, 3900, 50),
0216 };
0217 
0218 static int max8925_regulator_probe(struct platform_device *pdev)
0219 {
0220     struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
0221     struct regulator_init_data *pdata = dev_get_platdata(&pdev->dev);
0222     struct regulator_config config = { };
0223     struct max8925_regulator_info *ri;
0224     struct resource *res;
0225     struct regulator_dev *rdev;
0226     int i;
0227 
0228     res = platform_get_resource(pdev, IORESOURCE_REG, 0);
0229     if (!res) {
0230         dev_err(&pdev->dev, "No REG resource!\n");
0231         return -EINVAL;
0232     }
0233     for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
0234         ri = &max8925_regulator_info[i];
0235         if (ri->vol_reg == res->start)
0236             break;
0237     }
0238 
0239     if (i == ARRAY_SIZE(max8925_regulator_info)) {
0240         dev_err(&pdev->dev, "Failed to find regulator %llu\n",
0241             (unsigned long long)res->start);
0242         return -EINVAL;
0243     }
0244     ri->i2c = chip->i2c;
0245 
0246     config.dev = chip->dev;
0247     config.driver_data = ri;
0248 
0249     if (pdata)
0250         config.init_data = pdata;
0251 
0252     rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
0253     if (IS_ERR(rdev)) {
0254         dev_err(&pdev->dev, "failed to register regulator %s\n",
0255                 ri->desc.name);
0256         return PTR_ERR(rdev);
0257     }
0258 
0259     platform_set_drvdata(pdev, rdev);
0260     return 0;
0261 }
0262 
0263 static struct platform_driver max8925_regulator_driver = {
0264     .driver     = {
0265         .name   = "max8925-regulator",
0266     },
0267     .probe      = max8925_regulator_probe,
0268 };
0269 
0270 static int __init max8925_regulator_init(void)
0271 {
0272     return platform_driver_register(&max8925_regulator_driver);
0273 }
0274 subsys_initcall(max8925_regulator_init);
0275 
0276 static void __exit max8925_regulator_exit(void)
0277 {
0278     platform_driver_unregister(&max8925_regulator_driver);
0279 }
0280 module_exit(max8925_regulator_exit);
0281 
0282 MODULE_LICENSE("GPL");
0283 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
0284 MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC");
0285 MODULE_ALIAS("platform:max8925-regulator");