Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Voltage regulator support for AMS AS3722 PMIC
0004  *
0005  * Copyright (C) 2013 ams
0006  *
0007  * Author: Florian Lobmaier <florian.lobmaier@ams.com>
0008  * Author: Laxman Dewangan <ldewangan@nvidia.com>
0009  */
0010 
0011 #include <linux/err.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/mfd/as3722.h>
0015 #include <linux/of.h>
0016 #include <linux/of_platform.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/regulator/driver.h>
0019 #include <linux/regulator/machine.h>
0020 #include <linux/regulator/of_regulator.h>
0021 #include <linux/slab.h>
0022 
0023 /* Regulator IDs */
0024 enum as3722_regulators_id {
0025     AS3722_REGULATOR_ID_SD0,
0026     AS3722_REGULATOR_ID_SD1,
0027     AS3722_REGULATOR_ID_SD2,
0028     AS3722_REGULATOR_ID_SD3,
0029     AS3722_REGULATOR_ID_SD4,
0030     AS3722_REGULATOR_ID_SD5,
0031     AS3722_REGULATOR_ID_SD6,
0032     AS3722_REGULATOR_ID_LDO0,
0033     AS3722_REGULATOR_ID_LDO1,
0034     AS3722_REGULATOR_ID_LDO2,
0035     AS3722_REGULATOR_ID_LDO3,
0036     AS3722_REGULATOR_ID_LDO4,
0037     AS3722_REGULATOR_ID_LDO5,
0038     AS3722_REGULATOR_ID_LDO6,
0039     AS3722_REGULATOR_ID_LDO7,
0040     AS3722_REGULATOR_ID_LDO9,
0041     AS3722_REGULATOR_ID_LDO10,
0042     AS3722_REGULATOR_ID_LDO11,
0043     AS3722_REGULATOR_ID_MAX,
0044 };
0045 
0046 struct as3722_register_mapping {
0047     u8 regulator_id;
0048     const char *name;
0049     const char *sname;
0050     u8 vsel_reg;
0051     u8 vsel_mask;
0052     int n_voltages;
0053     u32 enable_reg;
0054     u8 enable_mask;
0055     u32 control_reg;
0056     u8 mode_mask;
0057     u32 sleep_ctrl_reg;
0058     u8 sleep_ctrl_mask;
0059 };
0060 
0061 struct as3722_regulator_config_data {
0062     struct regulator_init_data *reg_init;
0063     bool enable_tracking;
0064     int ext_control;
0065 };
0066 
0067 struct as3722_regulators {
0068     struct device *dev;
0069     struct as3722 *as3722;
0070     struct regulator_desc desc[AS3722_REGULATOR_ID_MAX];
0071     struct as3722_regulator_config_data
0072             reg_config_data[AS3722_REGULATOR_ID_MAX];
0073 };
0074 
0075 static const struct as3722_register_mapping as3722_reg_lookup[] = {
0076     {
0077         .regulator_id = AS3722_REGULATOR_ID_SD0,
0078         .name = "as3722-sd0",
0079         .vsel_reg = AS3722_SD0_VOLTAGE_REG,
0080         .vsel_mask = AS3722_SD_VSEL_MASK,
0081         .enable_reg = AS3722_SD_CONTROL_REG,
0082         .enable_mask = AS3722_SDn_CTRL(0),
0083         .sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
0084         .sleep_ctrl_mask = AS3722_SD0_EXT_ENABLE_MASK,
0085         .control_reg = AS3722_SD0_CONTROL_REG,
0086         .mode_mask = AS3722_SD0_MODE_FAST,
0087     },
0088     {
0089         .regulator_id = AS3722_REGULATOR_ID_SD1,
0090         .name = "as3722-sd1",
0091         .vsel_reg = AS3722_SD1_VOLTAGE_REG,
0092         .vsel_mask = AS3722_SD_VSEL_MASK,
0093         .enable_reg = AS3722_SD_CONTROL_REG,
0094         .enable_mask = AS3722_SDn_CTRL(1),
0095         .sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
0096         .sleep_ctrl_mask = AS3722_SD1_EXT_ENABLE_MASK,
0097         .control_reg = AS3722_SD1_CONTROL_REG,
0098         .mode_mask = AS3722_SD1_MODE_FAST,
0099     },
0100     {
0101         .regulator_id = AS3722_REGULATOR_ID_SD2,
0102         .name = "as3722-sd2",
0103         .sname = "vsup-sd2",
0104         .vsel_reg = AS3722_SD2_VOLTAGE_REG,
0105         .vsel_mask = AS3722_SD_VSEL_MASK,
0106         .enable_reg = AS3722_SD_CONTROL_REG,
0107         .enable_mask = AS3722_SDn_CTRL(2),
0108         .sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
0109         .sleep_ctrl_mask = AS3722_SD2_EXT_ENABLE_MASK,
0110         .control_reg = AS3722_SD23_CONTROL_REG,
0111         .mode_mask = AS3722_SD2_MODE_FAST,
0112         .n_voltages = AS3722_SD2_VSEL_MAX + 1,
0113     },
0114     {
0115         .regulator_id = AS3722_REGULATOR_ID_SD3,
0116         .name = "as3722-sd3",
0117         .sname = "vsup-sd3",
0118         .vsel_reg = AS3722_SD3_VOLTAGE_REG,
0119         .vsel_mask = AS3722_SD_VSEL_MASK,
0120         .enable_reg = AS3722_SD_CONTROL_REG,
0121         .enable_mask = AS3722_SDn_CTRL(3),
0122         .sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
0123         .sleep_ctrl_mask = AS3722_SD3_EXT_ENABLE_MASK,
0124         .control_reg = AS3722_SD23_CONTROL_REG,
0125         .mode_mask = AS3722_SD3_MODE_FAST,
0126         .n_voltages = AS3722_SD2_VSEL_MAX + 1,
0127     },
0128     {
0129         .regulator_id = AS3722_REGULATOR_ID_SD4,
0130         .name = "as3722-sd4",
0131         .sname = "vsup-sd4",
0132         .vsel_reg = AS3722_SD4_VOLTAGE_REG,
0133         .vsel_mask = AS3722_SD_VSEL_MASK,
0134         .enable_reg = AS3722_SD_CONTROL_REG,
0135         .enable_mask = AS3722_SDn_CTRL(4),
0136         .sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
0137         .sleep_ctrl_mask = AS3722_SD4_EXT_ENABLE_MASK,
0138         .control_reg = AS3722_SD4_CONTROL_REG,
0139         .mode_mask = AS3722_SD4_MODE_FAST,
0140         .n_voltages = AS3722_SD2_VSEL_MAX + 1,
0141     },
0142     {
0143         .regulator_id = AS3722_REGULATOR_ID_SD5,
0144         .name = "as3722-sd5",
0145         .sname = "vsup-sd5",
0146         .vsel_reg = AS3722_SD5_VOLTAGE_REG,
0147         .vsel_mask = AS3722_SD_VSEL_MASK,
0148         .enable_reg = AS3722_SD_CONTROL_REG,
0149         .enable_mask = AS3722_SDn_CTRL(5),
0150         .sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
0151         .sleep_ctrl_mask = AS3722_SD5_EXT_ENABLE_MASK,
0152         .control_reg = AS3722_SD5_CONTROL_REG,
0153         .mode_mask = AS3722_SD5_MODE_FAST,
0154         .n_voltages = AS3722_SD2_VSEL_MAX + 1,
0155     },
0156     {
0157         .regulator_id = AS3722_REGULATOR_ID_SD6,
0158         .name = "as3722-sd6",
0159         .vsel_reg = AS3722_SD6_VOLTAGE_REG,
0160         .vsel_mask = AS3722_SD_VSEL_MASK,
0161         .enable_reg = AS3722_SD_CONTROL_REG,
0162         .enable_mask = AS3722_SDn_CTRL(6),
0163         .sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
0164         .sleep_ctrl_mask = AS3722_SD6_EXT_ENABLE_MASK,
0165         .control_reg = AS3722_SD6_CONTROL_REG,
0166         .mode_mask = AS3722_SD6_MODE_FAST,
0167     },
0168     {
0169         .regulator_id = AS3722_REGULATOR_ID_LDO0,
0170         .name = "as3722-ldo0",
0171         .sname = "vin-ldo0",
0172         .vsel_reg = AS3722_LDO0_VOLTAGE_REG,
0173         .vsel_mask = AS3722_LDO0_VSEL_MASK,
0174         .enable_reg = AS3722_LDOCONTROL0_REG,
0175         .enable_mask = AS3722_LDO0_CTRL,
0176         .sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
0177         .sleep_ctrl_mask = AS3722_LDO0_EXT_ENABLE_MASK,
0178         .n_voltages = AS3722_LDO0_NUM_VOLT,
0179     },
0180     {
0181         .regulator_id = AS3722_REGULATOR_ID_LDO1,
0182         .name = "as3722-ldo1",
0183         .sname = "vin-ldo1-6",
0184         .vsel_reg = AS3722_LDO1_VOLTAGE_REG,
0185         .vsel_mask = AS3722_LDO_VSEL_MASK,
0186         .enable_reg = AS3722_LDOCONTROL0_REG,
0187         .enable_mask = AS3722_LDO1_CTRL,
0188         .sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
0189         .sleep_ctrl_mask = AS3722_LDO1_EXT_ENABLE_MASK,
0190         .n_voltages = AS3722_LDO_NUM_VOLT,
0191     },
0192     {
0193         .regulator_id = AS3722_REGULATOR_ID_LDO2,
0194         .name = "as3722-ldo2",
0195         .sname = "vin-ldo2-5-7",
0196         .vsel_reg = AS3722_LDO2_VOLTAGE_REG,
0197         .vsel_mask = AS3722_LDO_VSEL_MASK,
0198         .enable_reg = AS3722_LDOCONTROL0_REG,
0199         .enable_mask = AS3722_LDO2_CTRL,
0200         .sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
0201         .sleep_ctrl_mask = AS3722_LDO2_EXT_ENABLE_MASK,
0202         .n_voltages = AS3722_LDO_NUM_VOLT,
0203     },
0204     {
0205         .regulator_id = AS3722_REGULATOR_ID_LDO3,
0206         .name = "as3722-ldo3",
0207         .sname = "vin-ldo3-4",
0208         .vsel_reg = AS3722_LDO3_VOLTAGE_REG,
0209         .vsel_mask = AS3722_LDO3_VSEL_MASK,
0210         .enable_reg = AS3722_LDOCONTROL0_REG,
0211         .enable_mask = AS3722_LDO3_CTRL,
0212         .sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
0213         .sleep_ctrl_mask = AS3722_LDO3_EXT_ENABLE_MASK,
0214         .n_voltages = AS3722_LDO3_NUM_VOLT,
0215     },
0216     {
0217         .regulator_id = AS3722_REGULATOR_ID_LDO4,
0218         .name = "as3722-ldo4",
0219         .sname = "vin-ldo3-4",
0220         .vsel_reg = AS3722_LDO4_VOLTAGE_REG,
0221         .vsel_mask = AS3722_LDO_VSEL_MASK,
0222         .enable_reg = AS3722_LDOCONTROL0_REG,
0223         .enable_mask = AS3722_LDO4_CTRL,
0224         .sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
0225         .sleep_ctrl_mask = AS3722_LDO4_EXT_ENABLE_MASK,
0226         .n_voltages = AS3722_LDO_NUM_VOLT,
0227     },
0228     {
0229         .regulator_id = AS3722_REGULATOR_ID_LDO5,
0230         .name = "as3722-ldo5",
0231         .sname = "vin-ldo2-5-7",
0232         .vsel_reg = AS3722_LDO5_VOLTAGE_REG,
0233         .vsel_mask = AS3722_LDO_VSEL_MASK,
0234         .enable_reg = AS3722_LDOCONTROL0_REG,
0235         .enable_mask = AS3722_LDO5_CTRL,
0236         .sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
0237         .sleep_ctrl_mask = AS3722_LDO5_EXT_ENABLE_MASK,
0238         .n_voltages = AS3722_LDO_NUM_VOLT,
0239     },
0240     {
0241         .regulator_id = AS3722_REGULATOR_ID_LDO6,
0242         .name = "as3722-ldo6",
0243         .sname = "vin-ldo1-6",
0244         .vsel_reg = AS3722_LDO6_VOLTAGE_REG,
0245         .vsel_mask = AS3722_LDO_VSEL_MASK,
0246         .enable_reg = AS3722_LDOCONTROL0_REG,
0247         .enable_mask = AS3722_LDO6_CTRL,
0248         .sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
0249         .sleep_ctrl_mask = AS3722_LDO6_EXT_ENABLE_MASK,
0250         .n_voltages = AS3722_LDO_NUM_VOLT,
0251     },
0252     {
0253         .regulator_id = AS3722_REGULATOR_ID_LDO7,
0254         .name = "as3722-ldo7",
0255         .sname = "vin-ldo2-5-7",
0256         .vsel_reg = AS3722_LDO7_VOLTAGE_REG,
0257         .vsel_mask = AS3722_LDO_VSEL_MASK,
0258         .enable_reg = AS3722_LDOCONTROL0_REG,
0259         .enable_mask = AS3722_LDO7_CTRL,
0260         .sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
0261         .sleep_ctrl_mask = AS3722_LDO7_EXT_ENABLE_MASK,
0262         .n_voltages = AS3722_LDO_NUM_VOLT,
0263     },
0264     {
0265         .regulator_id = AS3722_REGULATOR_ID_LDO9,
0266         .name = "as3722-ldo9",
0267         .sname = "vin-ldo9-10",
0268         .vsel_reg = AS3722_LDO9_VOLTAGE_REG,
0269         .vsel_mask = AS3722_LDO_VSEL_MASK,
0270         .enable_reg = AS3722_LDOCONTROL1_REG,
0271         .enable_mask = AS3722_LDO9_CTRL,
0272         .sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG,
0273         .sleep_ctrl_mask = AS3722_LDO9_EXT_ENABLE_MASK,
0274         .n_voltages = AS3722_LDO_NUM_VOLT,
0275     },
0276     {
0277         .regulator_id = AS3722_REGULATOR_ID_LDO10,
0278         .name = "as3722-ldo10",
0279         .sname = "vin-ldo9-10",
0280         .vsel_reg = AS3722_LDO10_VOLTAGE_REG,
0281         .vsel_mask = AS3722_LDO_VSEL_MASK,
0282         .enable_reg = AS3722_LDOCONTROL1_REG,
0283         .enable_mask = AS3722_LDO10_CTRL,
0284         .sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG,
0285         .sleep_ctrl_mask = AS3722_LDO10_EXT_ENABLE_MASK,
0286         .n_voltages = AS3722_LDO_NUM_VOLT,
0287     },
0288     {
0289         .regulator_id = AS3722_REGULATOR_ID_LDO11,
0290         .name = "as3722-ldo11",
0291         .sname = "vin-ldo11",
0292         .vsel_reg = AS3722_LDO11_VOLTAGE_REG,
0293         .vsel_mask = AS3722_LDO_VSEL_MASK,
0294         .enable_reg = AS3722_LDOCONTROL1_REG,
0295         .enable_mask = AS3722_LDO11_CTRL,
0296         .sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG,
0297         .sleep_ctrl_mask = AS3722_LDO11_EXT_ENABLE_MASK,
0298         .n_voltages = AS3722_LDO_NUM_VOLT,
0299     },
0300 };
0301 
0302 static const unsigned int as3722_ldo_current[] = { 150000, 300000 };
0303 static const unsigned int as3722_sd016_current[] = {
0304     2500000, 3000000, 3500000
0305 };
0306 
0307 static const struct regulator_ops as3722_ldo0_ops = {
0308     .is_enabled = regulator_is_enabled_regmap,
0309     .enable = regulator_enable_regmap,
0310     .disable = regulator_disable_regmap,
0311     .list_voltage = regulator_list_voltage_linear,
0312     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0313     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0314     .get_current_limit = regulator_get_current_limit_regmap,
0315     .set_current_limit = regulator_set_current_limit_regmap,
0316 };
0317 
0318 static const struct regulator_ops as3722_ldo0_extcntrl_ops = {
0319     .list_voltage = regulator_list_voltage_linear,
0320     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0321     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0322     .get_current_limit = regulator_get_current_limit_regmap,
0323     .set_current_limit = regulator_set_current_limit_regmap,
0324 };
0325 
0326 static int as3722_ldo3_set_tracking_mode(struct as3722_regulators *as3722_reg,
0327         int id, u8 mode)
0328 {
0329     struct as3722 *as3722 = as3722_reg->as3722;
0330 
0331     switch (mode) {
0332     case AS3722_LDO3_MODE_PMOS:
0333     case AS3722_LDO3_MODE_PMOS_TRACKING:
0334     case AS3722_LDO3_MODE_NMOS:
0335     case AS3722_LDO3_MODE_SWITCH:
0336         return as3722_update_bits(as3722,
0337             as3722_reg_lookup[id].vsel_reg,
0338             AS3722_LDO3_MODE_MASK, mode);
0339 
0340     default:
0341         return -EINVAL;
0342     }
0343 }
0344 
0345 static int as3722_ldo3_get_current_limit(struct regulator_dev *rdev)
0346 {
0347     return 150000;
0348 }
0349 
0350 static const struct regulator_ops as3722_ldo3_ops = {
0351     .is_enabled = regulator_is_enabled_regmap,
0352     .enable = regulator_enable_regmap,
0353     .disable = regulator_disable_regmap,
0354     .list_voltage = regulator_list_voltage_linear,
0355     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0356     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0357     .get_current_limit = as3722_ldo3_get_current_limit,
0358 };
0359 
0360 static const struct regulator_ops as3722_ldo3_extcntrl_ops = {
0361     .list_voltage = regulator_list_voltage_linear,
0362     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0363     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0364     .get_current_limit = as3722_ldo3_get_current_limit,
0365 };
0366 
0367 static const struct regulator_ops as3722_ldo6_ops = {
0368     .is_enabled = regulator_is_enabled_regmap,
0369     .enable = regulator_enable_regmap,
0370     .disable = regulator_disable_regmap,
0371     .map_voltage = regulator_map_voltage_linear_range,
0372     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0373     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0374     .list_voltage = regulator_list_voltage_linear_range,
0375     .get_current_limit = regulator_get_current_limit_regmap,
0376     .set_current_limit = regulator_set_current_limit_regmap,
0377     .get_bypass = regulator_get_bypass_regmap,
0378     .set_bypass = regulator_set_bypass_regmap,
0379 };
0380 
0381 static const struct regulator_ops as3722_ldo6_extcntrl_ops = {
0382     .map_voltage = regulator_map_voltage_linear_range,
0383     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0384     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0385     .list_voltage = regulator_list_voltage_linear_range,
0386     .get_current_limit = regulator_get_current_limit_regmap,
0387     .set_current_limit = regulator_set_current_limit_regmap,
0388     .get_bypass = regulator_get_bypass_regmap,
0389     .set_bypass = regulator_set_bypass_regmap,
0390 };
0391 
0392 static const struct linear_range as3722_ldo_ranges[] = {
0393     REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0),
0394     REGULATOR_LINEAR_RANGE(825000, 0x01, 0x24, 25000),
0395     REGULATOR_LINEAR_RANGE(1725000, 0x40, 0x7F, 25000),
0396 };
0397 
0398 static const struct regulator_ops as3722_ldo_ops = {
0399     .is_enabled = regulator_is_enabled_regmap,
0400     .enable = regulator_enable_regmap,
0401     .disable = regulator_disable_regmap,
0402     .map_voltage = regulator_map_voltage_linear_range,
0403     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0404     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0405     .list_voltage = regulator_list_voltage_linear_range,
0406     .get_current_limit = regulator_get_current_limit_regmap,
0407     .set_current_limit = regulator_set_current_limit_regmap,
0408 };
0409 
0410 static const struct regulator_ops as3722_ldo_extcntrl_ops = {
0411     .map_voltage = regulator_map_voltage_linear_range,
0412     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0413     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0414     .list_voltage = regulator_list_voltage_linear_range,
0415     .get_current_limit = regulator_get_current_limit_regmap,
0416     .set_current_limit = regulator_set_current_limit_regmap,
0417 };
0418 
0419 static unsigned int as3722_sd_get_mode(struct regulator_dev *rdev)
0420 {
0421     struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
0422     struct as3722 *as3722 = as3722_regs->as3722;
0423     int id = rdev_get_id(rdev);
0424     u32 val;
0425     int ret;
0426 
0427     if (!as3722_reg_lookup[id].control_reg)
0428         return -ENOTSUPP;
0429 
0430     ret = as3722_read(as3722, as3722_reg_lookup[id].control_reg, &val);
0431     if (ret < 0) {
0432         dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
0433             as3722_reg_lookup[id].control_reg, ret);
0434         return ret;
0435     }
0436 
0437     if (val & as3722_reg_lookup[id].mode_mask)
0438         return REGULATOR_MODE_FAST;
0439     else
0440         return REGULATOR_MODE_NORMAL;
0441 }
0442 
0443 static int as3722_sd_set_mode(struct regulator_dev *rdev,
0444         unsigned int mode)
0445 {
0446     struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
0447     struct as3722 *as3722 = as3722_regs->as3722;
0448     u8 id = rdev_get_id(rdev);
0449     u8 val = 0;
0450     int ret;
0451 
0452     if (!as3722_reg_lookup[id].control_reg)
0453         return -ERANGE;
0454 
0455     switch (mode) {
0456     case REGULATOR_MODE_FAST:
0457         val = as3722_reg_lookup[id].mode_mask;
0458         fallthrough;
0459     case REGULATOR_MODE_NORMAL:
0460         break;
0461     default:
0462         return -EINVAL;
0463     }
0464 
0465     ret = as3722_update_bits(as3722, as3722_reg_lookup[id].control_reg,
0466             as3722_reg_lookup[id].mode_mask, val);
0467     if (ret < 0) {
0468         dev_err(as3722_regs->dev, "Reg 0x%02x update failed: %d\n",
0469             as3722_reg_lookup[id].control_reg, ret);
0470         return ret;
0471     }
0472     return ret;
0473 }
0474 
0475 static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs)
0476 {
0477     int err;
0478     unsigned val;
0479 
0480     err = as3722_read(as3722_regs->as3722, AS3722_FUSE7_REG, &val);
0481     if (err < 0) {
0482         dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
0483             AS3722_FUSE7_REG, err);
0484         return false;
0485     }
0486     if (val & AS3722_FUSE7_SD0_LOW_VOLTAGE)
0487         return true;
0488     return false;
0489 }
0490 
0491 static const struct linear_range as3722_sd2345_ranges[] = {
0492     REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0),
0493     REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500),
0494     REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000),
0495     REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7F, 50000),
0496 };
0497 
0498 static const struct regulator_ops as3722_sd016_ops = {
0499     .is_enabled = regulator_is_enabled_regmap,
0500     .enable = regulator_enable_regmap,
0501     .disable = regulator_disable_regmap,
0502     .list_voltage = regulator_list_voltage_linear,
0503     .map_voltage = regulator_map_voltage_linear,
0504     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0505     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0506     .get_current_limit = regulator_get_current_limit_regmap,
0507     .set_current_limit = regulator_set_current_limit_regmap,
0508     .get_mode = as3722_sd_get_mode,
0509     .set_mode = as3722_sd_set_mode,
0510 };
0511 
0512 static const struct regulator_ops as3722_sd016_extcntrl_ops = {
0513     .list_voltage = regulator_list_voltage_linear,
0514     .map_voltage = regulator_map_voltage_linear,
0515     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0516     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0517     .get_current_limit = regulator_get_current_limit_regmap,
0518     .set_current_limit = regulator_set_current_limit_regmap,
0519     .get_mode = as3722_sd_get_mode,
0520     .set_mode = as3722_sd_set_mode,
0521 };
0522 
0523 static const struct regulator_ops as3722_sd2345_ops = {
0524     .is_enabled = regulator_is_enabled_regmap,
0525     .enable = regulator_enable_regmap,
0526     .disable = regulator_disable_regmap,
0527     .list_voltage = regulator_list_voltage_linear_range,
0528     .map_voltage = regulator_map_voltage_linear_range,
0529     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0530     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0531     .get_mode = as3722_sd_get_mode,
0532     .set_mode = as3722_sd_set_mode,
0533 };
0534 
0535 static const struct regulator_ops as3722_sd2345_extcntrl_ops = {
0536     .list_voltage = regulator_list_voltage_linear_range,
0537     .map_voltage = regulator_map_voltage_linear_range,
0538     .set_voltage_sel = regulator_set_voltage_sel_regmap,
0539     .get_voltage_sel = regulator_get_voltage_sel_regmap,
0540     .get_mode = as3722_sd_get_mode,
0541     .set_mode = as3722_sd_set_mode,
0542 };
0543 
0544 static int as3722_extreg_init(struct as3722_regulators *as3722_regs, int id,
0545         int ext_pwr_ctrl)
0546 {
0547     int ret;
0548     unsigned int val;
0549 
0550     if ((ext_pwr_ctrl < AS3722_EXT_CONTROL_ENABLE1) ||
0551         (ext_pwr_ctrl > AS3722_EXT_CONTROL_ENABLE3))
0552         return -EINVAL;
0553 
0554     val =  ext_pwr_ctrl << (ffs(as3722_reg_lookup[id].sleep_ctrl_mask) - 1);
0555     ret = as3722_update_bits(as3722_regs->as3722,
0556             as3722_reg_lookup[id].sleep_ctrl_reg,
0557             as3722_reg_lookup[id].sleep_ctrl_mask, val);
0558     if (ret < 0)
0559         dev_err(as3722_regs->dev, "Reg 0x%02x update failed: %d\n",
0560             as3722_reg_lookup[id].sleep_ctrl_reg, ret);
0561     return ret;
0562 }
0563 
0564 static struct of_regulator_match as3722_regulator_matches[] = {
0565     { .name = "sd0", },
0566     { .name = "sd1", },
0567     { .name = "sd2", },
0568     { .name = "sd3", },
0569     { .name = "sd4", },
0570     { .name = "sd5", },
0571     { .name = "sd6", },
0572     { .name = "ldo0", },
0573     { .name = "ldo1", },
0574     { .name = "ldo2", },
0575     { .name = "ldo3", },
0576     { .name = "ldo4", },
0577     { .name = "ldo5", },
0578     { .name = "ldo6", },
0579     { .name = "ldo7", },
0580     { .name = "ldo9", },
0581     { .name = "ldo10", },
0582     { .name = "ldo11", },
0583 };
0584 
0585 static int as3722_get_regulator_dt_data(struct platform_device *pdev,
0586         struct as3722_regulators *as3722_regs)
0587 {
0588     struct device_node *np;
0589     struct as3722_regulator_config_data *reg_config;
0590     u32 prop;
0591     int id;
0592     int ret;
0593 
0594     np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
0595     if (!np) {
0596         dev_err(&pdev->dev, "Device is not having regulators node\n");
0597         return -ENODEV;
0598     }
0599     pdev->dev.of_node = np;
0600 
0601     ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches,
0602             ARRAY_SIZE(as3722_regulator_matches));
0603     of_node_put(np);
0604     if (ret < 0) {
0605         dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n",
0606             ret);
0607         return ret;
0608     }
0609 
0610     for (id = 0; id < ARRAY_SIZE(as3722_regulator_matches); ++id) {
0611         struct device_node *reg_node;
0612 
0613         reg_config = &as3722_regs->reg_config_data[id];
0614         reg_config->reg_init = as3722_regulator_matches[id].init_data;
0615         reg_node = as3722_regulator_matches[id].of_node;
0616 
0617         if (!reg_config->reg_init || !reg_node)
0618             continue;
0619 
0620         ret = of_property_read_u32(reg_node, "ams,ext-control", &prop);
0621         if (!ret) {
0622             if (prop < 3)
0623                 reg_config->ext_control = prop;
0624             else
0625                 dev_warn(&pdev->dev,
0626                     "ext-control have invalid option: %u\n",
0627                     prop);
0628         }
0629         reg_config->enable_tracking =
0630             of_property_read_bool(reg_node, "ams,enable-tracking");
0631     }
0632     return 0;
0633 }
0634 
0635 static int as3722_regulator_probe(struct platform_device *pdev)
0636 {
0637     struct as3722 *as3722 = dev_get_drvdata(pdev->dev.parent);
0638     struct as3722_regulators *as3722_regs;
0639     struct as3722_regulator_config_data *reg_config;
0640     struct regulator_dev *rdev;
0641     struct regulator_config config = { };
0642     const struct regulator_ops *ops;
0643     int id;
0644     int ret;
0645 
0646     as3722_regs = devm_kzalloc(&pdev->dev, sizeof(*as3722_regs),
0647                 GFP_KERNEL);
0648     if (!as3722_regs)
0649         return -ENOMEM;
0650 
0651     as3722_regs->dev = &pdev->dev;
0652     as3722_regs->as3722 = as3722;
0653     platform_set_drvdata(pdev, as3722_regs);
0654 
0655     ret = as3722_get_regulator_dt_data(pdev, as3722_regs);
0656     if (ret < 0)
0657         return ret;
0658 
0659     config.dev = &pdev->dev;
0660     config.driver_data = as3722_regs;
0661     config.regmap = as3722->regmap;
0662 
0663     for (id = 0; id < AS3722_REGULATOR_ID_MAX; id++) {
0664         struct regulator_desc *desc;
0665 
0666         desc = &as3722_regs->desc[id];
0667         reg_config = &as3722_regs->reg_config_data[id];
0668 
0669         desc->name = as3722_reg_lookup[id].name;
0670         desc->supply_name = as3722_reg_lookup[id].sname;
0671         desc->id = as3722_reg_lookup[id].regulator_id;
0672         desc->n_voltages = as3722_reg_lookup[id].n_voltages;
0673         desc->type = REGULATOR_VOLTAGE;
0674         desc->owner = THIS_MODULE;
0675         desc->enable_reg = as3722_reg_lookup[id].enable_reg;
0676         desc->enable_mask = as3722_reg_lookup[id].enable_mask;
0677         desc->vsel_reg = as3722_reg_lookup[id].vsel_reg;
0678         desc->vsel_mask = as3722_reg_lookup[id].vsel_mask;
0679         switch (id) {
0680         case AS3722_REGULATOR_ID_LDO0:
0681             if (reg_config->ext_control)
0682                 ops = &as3722_ldo0_extcntrl_ops;
0683             else
0684                 ops = &as3722_ldo0_ops;
0685             desc->min_uV = 825000;
0686             desc->uV_step = 25000;
0687             desc->linear_min_sel = 1;
0688             desc->enable_time = 500;
0689             desc->curr_table = as3722_ldo_current;
0690             desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current);
0691             desc->csel_reg = as3722_reg_lookup[id].vsel_reg;
0692             desc->csel_mask = AS3722_LDO_ILIMIT_MASK;
0693             break;
0694         case AS3722_REGULATOR_ID_LDO3:
0695             if (reg_config->ext_control)
0696                 ops = &as3722_ldo3_extcntrl_ops;
0697             else
0698                 ops = &as3722_ldo3_ops;
0699             desc->min_uV = 620000;
0700             desc->uV_step = 20000;
0701             desc->linear_min_sel = 1;
0702             desc->enable_time = 500;
0703             if (reg_config->enable_tracking) {
0704                 ret = as3722_ldo3_set_tracking_mode(as3722_regs,
0705                     id, AS3722_LDO3_MODE_PMOS_TRACKING);
0706                 if (ret < 0) {
0707                     dev_err(&pdev->dev,
0708                         "LDO3 tracking failed: %d\n",
0709                         ret);
0710                     return ret;
0711                 }
0712             }
0713             break;
0714         case AS3722_REGULATOR_ID_LDO6:
0715             if (reg_config->ext_control)
0716                 ops = &as3722_ldo6_extcntrl_ops;
0717             else
0718                 ops = &as3722_ldo6_ops;
0719             desc->enable_time = 500;
0720             desc->bypass_reg = AS3722_LDO6_VOLTAGE_REG;
0721             desc->bypass_mask = AS3722_LDO_VSEL_MASK;
0722             desc->bypass_val_on = AS3722_LDO6_VSEL_BYPASS;
0723             desc->bypass_val_off = AS3722_LDO6_VSEL_BYPASS;
0724             desc->linear_ranges = as3722_ldo_ranges;
0725             desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges);
0726             desc->curr_table = as3722_ldo_current;
0727             desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current);
0728             desc->csel_reg = as3722_reg_lookup[id].vsel_reg;
0729             desc->csel_mask = AS3722_LDO_ILIMIT_MASK;
0730             break;
0731         case AS3722_REGULATOR_ID_SD0:
0732         case AS3722_REGULATOR_ID_SD1:
0733         case AS3722_REGULATOR_ID_SD6:
0734             if (reg_config->ext_control)
0735                 ops = &as3722_sd016_extcntrl_ops;
0736             else
0737                 ops = &as3722_sd016_ops;
0738             if (id == AS3722_REGULATOR_ID_SD0 &&
0739                 as3722_sd0_is_low_voltage(as3722_regs)) {
0740                 as3722_regs->desc[id].n_voltages =
0741                     AS3722_SD0_VSEL_LOW_VOL_MAX + 1;
0742                 as3722_regs->desc[id].min_uV = 410000;
0743             } else {
0744                 as3722_regs->desc[id].n_voltages =
0745                     AS3722_SD0_VSEL_MAX + 1;
0746                 as3722_regs->desc[id].min_uV = 610000;
0747             }
0748             desc->uV_step = 10000;
0749             desc->linear_min_sel = 1;
0750             desc->enable_time = 600;
0751             desc->curr_table = as3722_sd016_current;
0752             desc->n_current_limits =
0753                 ARRAY_SIZE(as3722_sd016_current);
0754             if (id == AS3722_REGULATOR_ID_SD0) {
0755                 desc->csel_reg = AS3722_OVCURRENT_REG;
0756                 desc->csel_mask =
0757                     AS3722_OVCURRENT_SD0_TRIP_MASK;
0758             } else if (id == AS3722_REGULATOR_ID_SD1) {
0759                 desc->csel_reg = AS3722_OVCURRENT_REG;
0760                 desc->csel_mask =
0761                     AS3722_OVCURRENT_SD1_TRIP_MASK;
0762             } else if (id == AS3722_REGULATOR_ID_SD6) {
0763                 desc->csel_reg = AS3722_OVCURRENT_DEB_REG;
0764                 desc->csel_mask =
0765                     AS3722_OVCURRENT_SD6_TRIP_MASK;
0766             }
0767             break;
0768         case AS3722_REGULATOR_ID_SD2:
0769         case AS3722_REGULATOR_ID_SD3:
0770         case AS3722_REGULATOR_ID_SD4:
0771         case AS3722_REGULATOR_ID_SD5:
0772             if (reg_config->ext_control)
0773                 ops = &as3722_sd2345_extcntrl_ops;
0774             else
0775                 ops = &as3722_sd2345_ops;
0776             desc->linear_ranges = as3722_sd2345_ranges;
0777             desc->n_linear_ranges =
0778                     ARRAY_SIZE(as3722_sd2345_ranges);
0779             break;
0780         default:
0781             if (reg_config->ext_control)
0782                 ops = &as3722_ldo_extcntrl_ops;
0783             else
0784                 ops = &as3722_ldo_ops;
0785             desc->enable_time = 500;
0786             desc->linear_ranges = as3722_ldo_ranges;
0787             desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges);
0788             desc->curr_table = as3722_ldo_current;
0789             desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current);
0790             desc->csel_reg = as3722_reg_lookup[id].vsel_reg;
0791             desc->csel_mask = AS3722_LDO_ILIMIT_MASK;
0792             break;
0793         }
0794         desc->ops = ops;
0795         config.init_data = reg_config->reg_init;
0796         config.of_node = as3722_regulator_matches[id].of_node;
0797         rdev = devm_regulator_register(&pdev->dev, desc, &config);
0798         if (IS_ERR(rdev)) {
0799             ret = PTR_ERR(rdev);
0800             dev_err(&pdev->dev, "regulator %d register failed %d\n",
0801                 id, ret);
0802             return ret;
0803         }
0804 
0805         if (reg_config->ext_control) {
0806             ret = regulator_enable_regmap(rdev);
0807             if (ret < 0) {
0808                 dev_err(&pdev->dev,
0809                     "Regulator %d enable failed: %d\n",
0810                     id, ret);
0811                 return ret;
0812             }
0813             ret = as3722_extreg_init(as3722_regs, id,
0814                     reg_config->ext_control);
0815             if (ret < 0) {
0816                 dev_err(&pdev->dev,
0817                     "AS3722 ext control failed: %d", ret);
0818                 return ret;
0819             }
0820         }
0821     }
0822     return 0;
0823 }
0824 
0825 static const struct of_device_id of_as3722_regulator_match[] = {
0826     { .compatible = "ams,as3722-regulator", },
0827     {},
0828 };
0829 MODULE_DEVICE_TABLE(of, of_as3722_regulator_match);
0830 
0831 static struct platform_driver as3722_regulator_driver = {
0832     .driver = {
0833         .name = "as3722-regulator",
0834         .of_match_table = of_as3722_regulator_match,
0835     },
0836     .probe = as3722_regulator_probe,
0837 };
0838 
0839 module_platform_driver(as3722_regulator_driver);
0840 
0841 MODULE_ALIAS("platform:as3722-regulator");
0842 MODULE_DESCRIPTION("AS3722 regulator driver");
0843 MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>");
0844 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
0845 MODULE_LICENSE("GPL");