0001
0002
0003
0004
0005
0006
0007
0008
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
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");