1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Voltage regulator support for AMS AS3722 PMIC 4 * 5 * Copyright (C) 2013 ams 6 * 7 * Author: Florian Lobmaier <florian.lobmaier@ams.com> 8 * Author: Laxman Dewangan <ldewangan@nvidia.com> 9 */ 10 11 #include <linux/err.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/mfd/as3722.h> 15 #include <linux/of.h> 16 #include <linux/of_platform.h> 17 #include <linux/platform_device.h> 18 #include <linux/regulator/driver.h> 19 #include <linux/regulator/machine.h> 20 #include <linux/regulator/of_regulator.h> 21 #include <linux/slab.h> 22 23 /* Regulator IDs */ 24 enum as3722_regulators_id { 25 AS3722_REGULATOR_ID_SD0, 26 AS3722_REGULATOR_ID_SD1, 27 AS3722_REGULATOR_ID_SD2, 28 AS3722_REGULATOR_ID_SD3, 29 AS3722_REGULATOR_ID_SD4, 30 AS3722_REGULATOR_ID_SD5, 31 AS3722_REGULATOR_ID_SD6, 32 AS3722_REGULATOR_ID_LDO0, 33 AS3722_REGULATOR_ID_LDO1, 34 AS3722_REGULATOR_ID_LDO2, 35 AS3722_REGULATOR_ID_LDO3, 36 AS3722_REGULATOR_ID_LDO4, 37 AS3722_REGULATOR_ID_LDO5, 38 AS3722_REGULATOR_ID_LDO6, 39 AS3722_REGULATOR_ID_LDO7, 40 AS3722_REGULATOR_ID_LDO9, 41 AS3722_REGULATOR_ID_LDO10, 42 AS3722_REGULATOR_ID_LDO11, 43 AS3722_REGULATOR_ID_MAX, 44 }; 45 46 struct as3722_register_mapping { 47 u8 regulator_id; 48 const char *name; 49 const char *sname; 50 u8 vsel_reg; 51 u8 vsel_mask; 52 int n_voltages; 53 u32 enable_reg; 54 u8 enable_mask; 55 u32 control_reg; 56 u8 mode_mask; 57 u32 sleep_ctrl_reg; 58 u8 sleep_ctrl_mask; 59 }; 60 61 struct as3722_regulator_config_data { 62 struct regulator_init_data *reg_init; 63 bool enable_tracking; 64 int ext_control; 65 }; 66 67 struct as3722_regulators { 68 struct device *dev; 69 struct as3722 *as3722; 70 struct regulator_desc desc[AS3722_REGULATOR_ID_MAX]; 71 struct as3722_regulator_config_data 72 reg_config_data[AS3722_REGULATOR_ID_MAX]; 73 }; 74 75 static const struct as3722_register_mapping as3722_reg_lookup[] = { 76 { 77 .regulator_id = AS3722_REGULATOR_ID_SD0, 78 .name = "as3722-sd0", 79 .vsel_reg = AS3722_SD0_VOLTAGE_REG, 80 .vsel_mask = AS3722_SD_VSEL_MASK, 81 .enable_reg = AS3722_SD_CONTROL_REG, 82 .enable_mask = AS3722_SDn_CTRL(0), 83 .sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG, 84 .sleep_ctrl_mask = AS3722_SD0_EXT_ENABLE_MASK, 85 .control_reg = AS3722_SD0_CONTROL_REG, 86 .mode_mask = AS3722_SD0_MODE_FAST, 87 }, 88 { 89 .regulator_id = AS3722_REGULATOR_ID_SD1, 90 .name = "as3722-sd1", 91 .vsel_reg = AS3722_SD1_VOLTAGE_REG, 92 .vsel_mask = AS3722_SD_VSEL_MASK, 93 .enable_reg = AS3722_SD_CONTROL_REG, 94 .enable_mask = AS3722_SDn_CTRL(1), 95 .sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG, 96 .sleep_ctrl_mask = AS3722_SD1_EXT_ENABLE_MASK, 97 .control_reg = AS3722_SD1_CONTROL_REG, 98 .mode_mask = AS3722_SD1_MODE_FAST, 99 }, 100 { 101 .regulator_id = AS3722_REGULATOR_ID_SD2, 102 .name = "as3722-sd2", 103 .sname = "vsup-sd2", 104 .vsel_reg = AS3722_SD2_VOLTAGE_REG, 105 .vsel_mask = AS3722_SD_VSEL_MASK, 106 .enable_reg = AS3722_SD_CONTROL_REG, 107 .enable_mask = AS3722_SDn_CTRL(2), 108 .sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG, 109 .sleep_ctrl_mask = AS3722_SD2_EXT_ENABLE_MASK, 110 .control_reg = AS3722_SD23_CONTROL_REG, 111 .mode_mask = AS3722_SD2_MODE_FAST, 112 .n_voltages = AS3722_SD2_VSEL_MAX + 1, 113 }, 114 { 115 .regulator_id = AS3722_REGULATOR_ID_SD3, 116 .name = "as3722-sd3", 117 .sname = "vsup-sd3", 118 .vsel_reg = AS3722_SD3_VOLTAGE_REG, 119 .vsel_mask = AS3722_SD_VSEL_MASK, 120 .enable_reg = AS3722_SD_CONTROL_REG, 121 .enable_mask = AS3722_SDn_CTRL(3), 122 .sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG, 123 .sleep_ctrl_mask = AS3722_SD3_EXT_ENABLE_MASK, 124 .control_reg = AS3722_SD23_CONTROL_REG, 125 .mode_mask = AS3722_SD3_MODE_FAST, 126 .n_voltages = AS3722_SD2_VSEL_MAX + 1, 127 }, 128 { 129 .regulator_id = AS3722_REGULATOR_ID_SD4, 130 .name = "as3722-sd4", 131 .sname = "vsup-sd4", 132 .vsel_reg = AS3722_SD4_VOLTAGE_REG, 133 .vsel_mask = AS3722_SD_VSEL_MASK, 134 .enable_reg = AS3722_SD_CONTROL_REG, 135 .enable_mask = AS3722_SDn_CTRL(4), 136 .sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG, 137 .sleep_ctrl_mask = AS3722_SD4_EXT_ENABLE_MASK, 138 .control_reg = AS3722_SD4_CONTROL_REG, 139 .mode_mask = AS3722_SD4_MODE_FAST, 140 .n_voltages = AS3722_SD2_VSEL_MAX + 1, 141 }, 142 { 143 .regulator_id = AS3722_REGULATOR_ID_SD5, 144 .name = "as3722-sd5", 145 .sname = "vsup-sd5", 146 .vsel_reg = AS3722_SD5_VOLTAGE_REG, 147 .vsel_mask = AS3722_SD_VSEL_MASK, 148 .enable_reg = AS3722_SD_CONTROL_REG, 149 .enable_mask = AS3722_SDn_CTRL(5), 150 .sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG, 151 .sleep_ctrl_mask = AS3722_SD5_EXT_ENABLE_MASK, 152 .control_reg = AS3722_SD5_CONTROL_REG, 153 .mode_mask = AS3722_SD5_MODE_FAST, 154 .n_voltages = AS3722_SD2_VSEL_MAX + 1, 155 }, 156 { 157 .regulator_id = AS3722_REGULATOR_ID_SD6, 158 .name = "as3722-sd6", 159 .vsel_reg = AS3722_SD6_VOLTAGE_REG, 160 .vsel_mask = AS3722_SD_VSEL_MASK, 161 .enable_reg = AS3722_SD_CONTROL_REG, 162 .enable_mask = AS3722_SDn_CTRL(6), 163 .sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG, 164 .sleep_ctrl_mask = AS3722_SD6_EXT_ENABLE_MASK, 165 .control_reg = AS3722_SD6_CONTROL_REG, 166 .mode_mask = AS3722_SD6_MODE_FAST, 167 }, 168 { 169 .regulator_id = AS3722_REGULATOR_ID_LDO0, 170 .name = "as3722-ldo0", 171 .sname = "vin-ldo0", 172 .vsel_reg = AS3722_LDO0_VOLTAGE_REG, 173 .vsel_mask = AS3722_LDO0_VSEL_MASK, 174 .enable_reg = AS3722_LDOCONTROL0_REG, 175 .enable_mask = AS3722_LDO0_CTRL, 176 .sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG, 177 .sleep_ctrl_mask = AS3722_LDO0_EXT_ENABLE_MASK, 178 .n_voltages = AS3722_LDO0_NUM_VOLT, 179 }, 180 { 181 .regulator_id = AS3722_REGULATOR_ID_LDO1, 182 .name = "as3722-ldo1", 183 .sname = "vin-ldo1-6", 184 .vsel_reg = AS3722_LDO1_VOLTAGE_REG, 185 .vsel_mask = AS3722_LDO_VSEL_MASK, 186 .enable_reg = AS3722_LDOCONTROL0_REG, 187 .enable_mask = AS3722_LDO1_CTRL, 188 .sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG, 189 .sleep_ctrl_mask = AS3722_LDO1_EXT_ENABLE_MASK, 190 .n_voltages = AS3722_LDO_NUM_VOLT, 191 }, 192 { 193 .regulator_id = AS3722_REGULATOR_ID_LDO2, 194 .name = "as3722-ldo2", 195 .sname = "vin-ldo2-5-7", 196 .vsel_reg = AS3722_LDO2_VOLTAGE_REG, 197 .vsel_mask = AS3722_LDO_VSEL_MASK, 198 .enable_reg = AS3722_LDOCONTROL0_REG, 199 .enable_mask = AS3722_LDO2_CTRL, 200 .sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG, 201 .sleep_ctrl_mask = AS3722_LDO2_EXT_ENABLE_MASK, 202 .n_voltages = AS3722_LDO_NUM_VOLT, 203 }, 204 { 205 .regulator_id = AS3722_REGULATOR_ID_LDO3, 206 .name = "as3722-ldo3", 207 .sname = "vin-ldo3-4", 208 .vsel_reg = AS3722_LDO3_VOLTAGE_REG, 209 .vsel_mask = AS3722_LDO3_VSEL_MASK, 210 .enable_reg = AS3722_LDOCONTROL0_REG, 211 .enable_mask = AS3722_LDO3_CTRL, 212 .sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG, 213 .sleep_ctrl_mask = AS3722_LDO3_EXT_ENABLE_MASK, 214 .n_voltages = AS3722_LDO3_NUM_VOLT, 215 }, 216 { 217 .regulator_id = AS3722_REGULATOR_ID_LDO4, 218 .name = "as3722-ldo4", 219 .sname = "vin-ldo3-4", 220 .vsel_reg = AS3722_LDO4_VOLTAGE_REG, 221 .vsel_mask = AS3722_LDO_VSEL_MASK, 222 .enable_reg = AS3722_LDOCONTROL0_REG, 223 .enable_mask = AS3722_LDO4_CTRL, 224 .sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG, 225 .sleep_ctrl_mask = AS3722_LDO4_EXT_ENABLE_MASK, 226 .n_voltages = AS3722_LDO_NUM_VOLT, 227 }, 228 { 229 .regulator_id = AS3722_REGULATOR_ID_LDO5, 230 .name = "as3722-ldo5", 231 .sname = "vin-ldo2-5-7", 232 .vsel_reg = AS3722_LDO5_VOLTAGE_REG, 233 .vsel_mask = AS3722_LDO_VSEL_MASK, 234 .enable_reg = AS3722_LDOCONTROL0_REG, 235 .enable_mask = AS3722_LDO5_CTRL, 236 .sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG, 237 .sleep_ctrl_mask = AS3722_LDO5_EXT_ENABLE_MASK, 238 .n_voltages = AS3722_LDO_NUM_VOLT, 239 }, 240 { 241 .regulator_id = AS3722_REGULATOR_ID_LDO6, 242 .name = "as3722-ldo6", 243 .sname = "vin-ldo1-6", 244 .vsel_reg = AS3722_LDO6_VOLTAGE_REG, 245 .vsel_mask = AS3722_LDO_VSEL_MASK, 246 .enable_reg = AS3722_LDOCONTROL0_REG, 247 .enable_mask = AS3722_LDO6_CTRL, 248 .sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG, 249 .sleep_ctrl_mask = AS3722_LDO6_EXT_ENABLE_MASK, 250 .n_voltages = AS3722_LDO_NUM_VOLT, 251 }, 252 { 253 .regulator_id = AS3722_REGULATOR_ID_LDO7, 254 .name = "as3722-ldo7", 255 .sname = "vin-ldo2-5-7", 256 .vsel_reg = AS3722_LDO7_VOLTAGE_REG, 257 .vsel_mask = AS3722_LDO_VSEL_MASK, 258 .enable_reg = AS3722_LDOCONTROL0_REG, 259 .enable_mask = AS3722_LDO7_CTRL, 260 .sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG, 261 .sleep_ctrl_mask = AS3722_LDO7_EXT_ENABLE_MASK, 262 .n_voltages = AS3722_LDO_NUM_VOLT, 263 }, 264 { 265 .regulator_id = AS3722_REGULATOR_ID_LDO9, 266 .name = "as3722-ldo9", 267 .sname = "vin-ldo9-10", 268 .vsel_reg = AS3722_LDO9_VOLTAGE_REG, 269 .vsel_mask = AS3722_LDO_VSEL_MASK, 270 .enable_reg = AS3722_LDOCONTROL1_REG, 271 .enable_mask = AS3722_LDO9_CTRL, 272 .sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG, 273 .sleep_ctrl_mask = AS3722_LDO9_EXT_ENABLE_MASK, 274 .n_voltages = AS3722_LDO_NUM_VOLT, 275 }, 276 { 277 .regulator_id = AS3722_REGULATOR_ID_LDO10, 278 .name = "as3722-ldo10", 279 .sname = "vin-ldo9-10", 280 .vsel_reg = AS3722_LDO10_VOLTAGE_REG, 281 .vsel_mask = AS3722_LDO_VSEL_MASK, 282 .enable_reg = AS3722_LDOCONTROL1_REG, 283 .enable_mask = AS3722_LDO10_CTRL, 284 .sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG, 285 .sleep_ctrl_mask = AS3722_LDO10_EXT_ENABLE_MASK, 286 .n_voltages = AS3722_LDO_NUM_VOLT, 287 }, 288 { 289 .regulator_id = AS3722_REGULATOR_ID_LDO11, 290 .name = "as3722-ldo11", 291 .sname = "vin-ldo11", 292 .vsel_reg = AS3722_LDO11_VOLTAGE_REG, 293 .vsel_mask = AS3722_LDO_VSEL_MASK, 294 .enable_reg = AS3722_LDOCONTROL1_REG, 295 .enable_mask = AS3722_LDO11_CTRL, 296 .sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG, 297 .sleep_ctrl_mask = AS3722_LDO11_EXT_ENABLE_MASK, 298 .n_voltages = AS3722_LDO_NUM_VOLT, 299 }, 300 }; 301 302 static const unsigned int as3722_ldo_current[] = { 150000, 300000 }; 303 static const unsigned int as3722_sd016_current[] = { 304 2500000, 3000000, 3500000 305 }; 306 307 static const struct regulator_ops as3722_ldo0_ops = { 308 .is_enabled = regulator_is_enabled_regmap, 309 .enable = regulator_enable_regmap, 310 .disable = regulator_disable_regmap, 311 .list_voltage = regulator_list_voltage_linear, 312 .get_voltage_sel = regulator_get_voltage_sel_regmap, 313 .set_voltage_sel = regulator_set_voltage_sel_regmap, 314 .get_current_limit = regulator_get_current_limit_regmap, 315 .set_current_limit = regulator_set_current_limit_regmap, 316 }; 317 318 static const struct regulator_ops as3722_ldo0_extcntrl_ops = { 319 .list_voltage = regulator_list_voltage_linear, 320 .get_voltage_sel = regulator_get_voltage_sel_regmap, 321 .set_voltage_sel = regulator_set_voltage_sel_regmap, 322 .get_current_limit = regulator_get_current_limit_regmap, 323 .set_current_limit = regulator_set_current_limit_regmap, 324 }; 325 326 static int as3722_ldo3_set_tracking_mode(struct as3722_regulators *as3722_reg, 327 int id, u8 mode) 328 { 329 struct as3722 *as3722 = as3722_reg->as3722; 330 331 switch (mode) { 332 case AS3722_LDO3_MODE_PMOS: 333 case AS3722_LDO3_MODE_PMOS_TRACKING: 334 case AS3722_LDO3_MODE_NMOS: 335 case AS3722_LDO3_MODE_SWITCH: 336 return as3722_update_bits(as3722, 337 as3722_reg_lookup[id].vsel_reg, 338 AS3722_LDO3_MODE_MASK, mode); 339 340 default: 341 return -EINVAL; 342 } 343 } 344 345 static int as3722_ldo3_get_current_limit(struct regulator_dev *rdev) 346 { 347 return 150000; 348 } 349 350 static const struct regulator_ops as3722_ldo3_ops = { 351 .is_enabled = regulator_is_enabled_regmap, 352 .enable = regulator_enable_regmap, 353 .disable = regulator_disable_regmap, 354 .list_voltage = regulator_list_voltage_linear, 355 .get_voltage_sel = regulator_get_voltage_sel_regmap, 356 .set_voltage_sel = regulator_set_voltage_sel_regmap, 357 .get_current_limit = as3722_ldo3_get_current_limit, 358 }; 359 360 static const struct regulator_ops as3722_ldo3_extcntrl_ops = { 361 .list_voltage = regulator_list_voltage_linear, 362 .get_voltage_sel = regulator_get_voltage_sel_regmap, 363 .set_voltage_sel = regulator_set_voltage_sel_regmap, 364 .get_current_limit = as3722_ldo3_get_current_limit, 365 }; 366 367 static const struct regulator_ops as3722_ldo6_ops = { 368 .is_enabled = regulator_is_enabled_regmap, 369 .enable = regulator_enable_regmap, 370 .disable = regulator_disable_regmap, 371 .map_voltage = regulator_map_voltage_linear_range, 372 .set_voltage_sel = regulator_set_voltage_sel_regmap, 373 .get_voltage_sel = regulator_get_voltage_sel_regmap, 374 .list_voltage = regulator_list_voltage_linear_range, 375 .get_current_limit = regulator_get_current_limit_regmap, 376 .set_current_limit = regulator_set_current_limit_regmap, 377 .get_bypass = regulator_get_bypass_regmap, 378 .set_bypass = regulator_set_bypass_regmap, 379 }; 380 381 static const struct regulator_ops as3722_ldo6_extcntrl_ops = { 382 .map_voltage = regulator_map_voltage_linear_range, 383 .set_voltage_sel = regulator_set_voltage_sel_regmap, 384 .get_voltage_sel = regulator_get_voltage_sel_regmap, 385 .list_voltage = regulator_list_voltage_linear_range, 386 .get_current_limit = regulator_get_current_limit_regmap, 387 .set_current_limit = regulator_set_current_limit_regmap, 388 .get_bypass = regulator_get_bypass_regmap, 389 .set_bypass = regulator_set_bypass_regmap, 390 }; 391 392 static const struct linear_range as3722_ldo_ranges[] = { 393 REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0), 394 REGULATOR_LINEAR_RANGE(825000, 0x01, 0x24, 25000), 395 REGULATOR_LINEAR_RANGE(1725000, 0x40, 0x7F, 25000), 396 }; 397 398 static const struct regulator_ops as3722_ldo_ops = { 399 .is_enabled = regulator_is_enabled_regmap, 400 .enable = regulator_enable_regmap, 401 .disable = regulator_disable_regmap, 402 .map_voltage = regulator_map_voltage_linear_range, 403 .set_voltage_sel = regulator_set_voltage_sel_regmap, 404 .get_voltage_sel = regulator_get_voltage_sel_regmap, 405 .list_voltage = regulator_list_voltage_linear_range, 406 .get_current_limit = regulator_get_current_limit_regmap, 407 .set_current_limit = regulator_set_current_limit_regmap, 408 }; 409 410 static const struct regulator_ops as3722_ldo_extcntrl_ops = { 411 .map_voltage = regulator_map_voltage_linear_range, 412 .set_voltage_sel = regulator_set_voltage_sel_regmap, 413 .get_voltage_sel = regulator_get_voltage_sel_regmap, 414 .list_voltage = regulator_list_voltage_linear_range, 415 .get_current_limit = regulator_get_current_limit_regmap, 416 .set_current_limit = regulator_set_current_limit_regmap, 417 }; 418 419 static unsigned int as3722_sd_get_mode(struct regulator_dev *rdev) 420 { 421 struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); 422 struct as3722 *as3722 = as3722_regs->as3722; 423 int id = rdev_get_id(rdev); 424 u32 val; 425 int ret; 426 427 if (!as3722_reg_lookup[id].control_reg) 428 return -ENOTSUPP; 429 430 ret = as3722_read(as3722, as3722_reg_lookup[id].control_reg, &val); 431 if (ret < 0) { 432 dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n", 433 as3722_reg_lookup[id].control_reg, ret); 434 return ret; 435 } 436 437 if (val & as3722_reg_lookup[id].mode_mask) 438 return REGULATOR_MODE_FAST; 439 else 440 return REGULATOR_MODE_NORMAL; 441 } 442 443 static int as3722_sd_set_mode(struct regulator_dev *rdev, 444 unsigned int mode) 445 { 446 struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); 447 struct as3722 *as3722 = as3722_regs->as3722; 448 u8 id = rdev_get_id(rdev); 449 u8 val = 0; 450 int ret; 451 452 if (!as3722_reg_lookup[id].control_reg) 453 return -ERANGE; 454 455 switch (mode) { 456 case REGULATOR_MODE_FAST: 457 val = as3722_reg_lookup[id].mode_mask; 458 case REGULATOR_MODE_NORMAL: /* fall down */ 459 break; 460 default: 461 return -EINVAL; 462 } 463 464 ret = as3722_update_bits(as3722, as3722_reg_lookup[id].control_reg, 465 as3722_reg_lookup[id].mode_mask, val); 466 if (ret < 0) { 467 dev_err(as3722_regs->dev, "Reg 0x%02x update failed: %d\n", 468 as3722_reg_lookup[id].control_reg, ret); 469 return ret; 470 } 471 return ret; 472 } 473 474 static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs) 475 { 476 int err; 477 unsigned val; 478 479 err = as3722_read(as3722_regs->as3722, AS3722_FUSE7_REG, &val); 480 if (err < 0) { 481 dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n", 482 AS3722_FUSE7_REG, err); 483 return false; 484 } 485 if (val & AS3722_FUSE7_SD0_LOW_VOLTAGE) 486 return true; 487 return false; 488 } 489 490 static const struct linear_range as3722_sd2345_ranges[] = { 491 REGULATOR_LINEAR_RANGE(0, 0x00, 0x00, 0), 492 REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500), 493 REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000), 494 REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7F, 50000), 495 }; 496 497 static const struct regulator_ops as3722_sd016_ops = { 498 .is_enabled = regulator_is_enabled_regmap, 499 .enable = regulator_enable_regmap, 500 .disable = regulator_disable_regmap, 501 .list_voltage = regulator_list_voltage_linear, 502 .map_voltage = regulator_map_voltage_linear, 503 .get_voltage_sel = regulator_get_voltage_sel_regmap, 504 .set_voltage_sel = regulator_set_voltage_sel_regmap, 505 .get_current_limit = regulator_get_current_limit_regmap, 506 .set_current_limit = regulator_set_current_limit_regmap, 507 .get_mode = as3722_sd_get_mode, 508 .set_mode = as3722_sd_set_mode, 509 }; 510 511 static const struct regulator_ops as3722_sd016_extcntrl_ops = { 512 .list_voltage = regulator_list_voltage_linear, 513 .map_voltage = regulator_map_voltage_linear, 514 .get_voltage_sel = regulator_get_voltage_sel_regmap, 515 .set_voltage_sel = regulator_set_voltage_sel_regmap, 516 .get_current_limit = regulator_get_current_limit_regmap, 517 .set_current_limit = regulator_set_current_limit_regmap, 518 .get_mode = as3722_sd_get_mode, 519 .set_mode = as3722_sd_set_mode, 520 }; 521 522 static const struct regulator_ops as3722_sd2345_ops = { 523 .is_enabled = regulator_is_enabled_regmap, 524 .enable = regulator_enable_regmap, 525 .disable = regulator_disable_regmap, 526 .list_voltage = regulator_list_voltage_linear_range, 527 .map_voltage = regulator_map_voltage_linear_range, 528 .set_voltage_sel = regulator_set_voltage_sel_regmap, 529 .get_voltage_sel = regulator_get_voltage_sel_regmap, 530 .get_mode = as3722_sd_get_mode, 531 .set_mode = as3722_sd_set_mode, 532 }; 533 534 static const struct regulator_ops as3722_sd2345_extcntrl_ops = { 535 .list_voltage = regulator_list_voltage_linear_range, 536 .map_voltage = regulator_map_voltage_linear_range, 537 .set_voltage_sel = regulator_set_voltage_sel_regmap, 538 .get_voltage_sel = regulator_get_voltage_sel_regmap, 539 .get_mode = as3722_sd_get_mode, 540 .set_mode = as3722_sd_set_mode, 541 }; 542 543 static int as3722_extreg_init(struct as3722_regulators *as3722_regs, int id, 544 int ext_pwr_ctrl) 545 { 546 int ret; 547 unsigned int val; 548 549 if ((ext_pwr_ctrl < AS3722_EXT_CONTROL_ENABLE1) || 550 (ext_pwr_ctrl > AS3722_EXT_CONTROL_ENABLE3)) 551 return -EINVAL; 552 553 val = ext_pwr_ctrl << (ffs(as3722_reg_lookup[id].sleep_ctrl_mask) - 1); 554 ret = as3722_update_bits(as3722_regs->as3722, 555 as3722_reg_lookup[id].sleep_ctrl_reg, 556 as3722_reg_lookup[id].sleep_ctrl_mask, val); 557 if (ret < 0) 558 dev_err(as3722_regs->dev, "Reg 0x%02x update failed: %d\n", 559 as3722_reg_lookup[id].sleep_ctrl_reg, ret); 560 return ret; 561 } 562 563 static struct of_regulator_match as3722_regulator_matches[] = { 564 { .name = "sd0", }, 565 { .name = "sd1", }, 566 { .name = "sd2", }, 567 { .name = "sd3", }, 568 { .name = "sd4", }, 569 { .name = "sd5", }, 570 { .name = "sd6", }, 571 { .name = "ldo0", }, 572 { .name = "ldo1", }, 573 { .name = "ldo2", }, 574 { .name = "ldo3", }, 575 { .name = "ldo4", }, 576 { .name = "ldo5", }, 577 { .name = "ldo6", }, 578 { .name = "ldo7", }, 579 { .name = "ldo9", }, 580 { .name = "ldo10", }, 581 { .name = "ldo11", }, 582 }; 583 584 static int as3722_get_regulator_dt_data(struct platform_device *pdev, 585 struct as3722_regulators *as3722_regs) 586 { 587 struct device_node *np; 588 struct as3722_regulator_config_data *reg_config; 589 u32 prop; 590 int id; 591 int ret; 592 593 np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); 594 if (!np) { 595 dev_err(&pdev->dev, "Device is not having regulators node\n"); 596 return -ENODEV; 597 } 598 pdev->dev.of_node = np; 599 600 ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches, 601 ARRAY_SIZE(as3722_regulator_matches)); 602 of_node_put(np); 603 if (ret < 0) { 604 dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n", 605 ret); 606 return ret; 607 } 608 609 for (id = 0; id < ARRAY_SIZE(as3722_regulator_matches); ++id) { 610 struct device_node *reg_node; 611 612 reg_config = &as3722_regs->reg_config_data[id]; 613 reg_config->reg_init = as3722_regulator_matches[id].init_data; 614 reg_node = as3722_regulator_matches[id].of_node; 615 616 if (!reg_config->reg_init || !reg_node) 617 continue; 618 619 ret = of_property_read_u32(reg_node, "ams,ext-control", &prop); 620 if (!ret) { 621 if (prop < 3) 622 reg_config->ext_control = prop; 623 else 624 dev_warn(&pdev->dev, 625 "ext-control have invalid option: %u\n", 626 prop); 627 } 628 reg_config->enable_tracking = 629 of_property_read_bool(reg_node, "ams,enable-tracking"); 630 } 631 return 0; 632 } 633 634 static int as3722_regulator_probe(struct platform_device *pdev) 635 { 636 struct as3722 *as3722 = dev_get_drvdata(pdev->dev.parent); 637 struct as3722_regulators *as3722_regs; 638 struct as3722_regulator_config_data *reg_config; 639 struct regulator_dev *rdev; 640 struct regulator_config config = { }; 641 const struct regulator_ops *ops; 642 int id; 643 int ret; 644 645 as3722_regs = devm_kzalloc(&pdev->dev, sizeof(*as3722_regs), 646 GFP_KERNEL); 647 if (!as3722_regs) 648 return -ENOMEM; 649 650 as3722_regs->dev = &pdev->dev; 651 as3722_regs->as3722 = as3722; 652 platform_set_drvdata(pdev, as3722_regs); 653 654 ret = as3722_get_regulator_dt_data(pdev, as3722_regs); 655 if (ret < 0) 656 return ret; 657 658 config.dev = &pdev->dev; 659 config.driver_data = as3722_regs; 660 config.regmap = as3722->regmap; 661 662 for (id = 0; id < AS3722_REGULATOR_ID_MAX; id++) { 663 struct regulator_desc *desc; 664 665 desc = &as3722_regs->desc[id]; 666 reg_config = &as3722_regs->reg_config_data[id]; 667 668 desc->name = as3722_reg_lookup[id].name; 669 desc->supply_name = as3722_reg_lookup[id].sname; 670 desc->id = as3722_reg_lookup[id].regulator_id; 671 desc->n_voltages = as3722_reg_lookup[id].n_voltages; 672 desc->type = REGULATOR_VOLTAGE; 673 desc->owner = THIS_MODULE; 674 desc->enable_reg = as3722_reg_lookup[id].enable_reg; 675 desc->enable_mask = as3722_reg_lookup[id].enable_mask; 676 desc->vsel_reg = as3722_reg_lookup[id].vsel_reg; 677 desc->vsel_mask = as3722_reg_lookup[id].vsel_mask; 678 switch (id) { 679 case AS3722_REGULATOR_ID_LDO0: 680 if (reg_config->ext_control) 681 ops = &as3722_ldo0_extcntrl_ops; 682 else 683 ops = &as3722_ldo0_ops; 684 desc->min_uV = 825000; 685 desc->uV_step = 25000; 686 desc->linear_min_sel = 1; 687 desc->enable_time = 500; 688 desc->curr_table = as3722_ldo_current; 689 desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current); 690 desc->csel_reg = as3722_reg_lookup[id].vsel_reg; 691 desc->csel_mask = AS3722_LDO_ILIMIT_MASK; 692 break; 693 case AS3722_REGULATOR_ID_LDO3: 694 if (reg_config->ext_control) 695 ops = &as3722_ldo3_extcntrl_ops; 696 else 697 ops = &as3722_ldo3_ops; 698 desc->min_uV = 620000; 699 desc->uV_step = 20000; 700 desc->linear_min_sel = 1; 701 desc->enable_time = 500; 702 if (reg_config->enable_tracking) { 703 ret = as3722_ldo3_set_tracking_mode(as3722_regs, 704 id, AS3722_LDO3_MODE_PMOS_TRACKING); 705 if (ret < 0) { 706 dev_err(&pdev->dev, 707 "LDO3 tracking failed: %d\n", 708 ret); 709 return ret; 710 } 711 } 712 break; 713 case AS3722_REGULATOR_ID_LDO6: 714 if (reg_config->ext_control) 715 ops = &as3722_ldo6_extcntrl_ops; 716 else 717 ops = &as3722_ldo6_ops; 718 desc->enable_time = 500; 719 desc->bypass_reg = AS3722_LDO6_VOLTAGE_REG; 720 desc->bypass_mask = AS3722_LDO_VSEL_MASK; 721 desc->bypass_val_on = AS3722_LDO6_VSEL_BYPASS; 722 desc->bypass_val_off = AS3722_LDO6_VSEL_BYPASS; 723 desc->linear_ranges = as3722_ldo_ranges; 724 desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges); 725 desc->curr_table = as3722_ldo_current; 726 desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current); 727 desc->csel_reg = as3722_reg_lookup[id].vsel_reg; 728 desc->csel_mask = AS3722_LDO_ILIMIT_MASK; 729 break; 730 case AS3722_REGULATOR_ID_SD0: 731 case AS3722_REGULATOR_ID_SD1: 732 case AS3722_REGULATOR_ID_SD6: 733 if (reg_config->ext_control) 734 ops = &as3722_sd016_extcntrl_ops; 735 else 736 ops = &as3722_sd016_ops; 737 if (id == AS3722_REGULATOR_ID_SD0 && 738 as3722_sd0_is_low_voltage(as3722_regs)) { 739 as3722_regs->desc[id].n_voltages = 740 AS3722_SD0_VSEL_LOW_VOL_MAX + 1; 741 as3722_regs->desc[id].min_uV = 410000; 742 } else { 743 as3722_regs->desc[id].n_voltages = 744 AS3722_SD0_VSEL_MAX + 1; 745 as3722_regs->desc[id].min_uV = 610000; 746 } 747 desc->uV_step = 10000; 748 desc->linear_min_sel = 1; 749 desc->enable_time = 600; 750 desc->curr_table = as3722_sd016_current; 751 desc->n_current_limits = 752 ARRAY_SIZE(as3722_sd016_current); 753 if (id == AS3722_REGULATOR_ID_SD0) { 754 desc->csel_reg = AS3722_OVCURRENT_REG; 755 desc->csel_mask = 756 AS3722_OVCURRENT_SD0_TRIP_MASK; 757 } else if (id == AS3722_REGULATOR_ID_SD1) { 758 desc->csel_reg = AS3722_OVCURRENT_REG; 759 desc->csel_mask = 760 AS3722_OVCURRENT_SD1_TRIP_MASK; 761 } else if (id == AS3722_REGULATOR_ID_SD6) { 762 desc->csel_reg = AS3722_OVCURRENT_DEB_REG; 763 desc->csel_mask = 764 AS3722_OVCURRENT_SD6_TRIP_MASK; 765 } 766 break; 767 case AS3722_REGULATOR_ID_SD2: 768 case AS3722_REGULATOR_ID_SD3: 769 case AS3722_REGULATOR_ID_SD4: 770 case AS3722_REGULATOR_ID_SD5: 771 if (reg_config->ext_control) 772 ops = &as3722_sd2345_extcntrl_ops; 773 else 774 ops = &as3722_sd2345_ops; 775 desc->linear_ranges = as3722_sd2345_ranges; 776 desc->n_linear_ranges = 777 ARRAY_SIZE(as3722_sd2345_ranges); 778 break; 779 default: 780 if (reg_config->ext_control) 781 ops = &as3722_ldo_extcntrl_ops; 782 else 783 ops = &as3722_ldo_ops; 784 desc->enable_time = 500; 785 desc->linear_ranges = as3722_ldo_ranges; 786 desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges); 787 desc->curr_table = as3722_ldo_current; 788 desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current); 789 desc->csel_reg = as3722_reg_lookup[id].vsel_reg; 790 desc->csel_mask = AS3722_LDO_ILIMIT_MASK; 791 break; 792 } 793 desc->ops = ops; 794 config.init_data = reg_config->reg_init; 795 config.of_node = as3722_regulator_matches[id].of_node; 796 rdev = devm_regulator_register(&pdev->dev, desc, &config); 797 if (IS_ERR(rdev)) { 798 ret = PTR_ERR(rdev); 799 dev_err(&pdev->dev, "regulator %d register failed %d\n", 800 id, ret); 801 return ret; 802 } 803 804 if (reg_config->ext_control) { 805 ret = regulator_enable_regmap(rdev); 806 if (ret < 0) { 807 dev_err(&pdev->dev, 808 "Regulator %d enable failed: %d\n", 809 id, ret); 810 return ret; 811 } 812 ret = as3722_extreg_init(as3722_regs, id, 813 reg_config->ext_control); 814 if (ret < 0) { 815 dev_err(&pdev->dev, 816 "AS3722 ext control failed: %d", ret); 817 return ret; 818 } 819 } 820 } 821 return 0; 822 } 823 824 static const struct of_device_id of_as3722_regulator_match[] = { 825 { .compatible = "ams,as3722-regulator", }, 826 {}, 827 }; 828 MODULE_DEVICE_TABLE(of, of_as3722_regulator_match); 829 830 static struct platform_driver as3722_regulator_driver = { 831 .driver = { 832 .name = "as3722-regulator", 833 .of_match_table = of_as3722_regulator_match, 834 }, 835 .probe = as3722_regulator_probe, 836 }; 837 838 module_platform_driver(as3722_regulator_driver); 839 840 MODULE_ALIAS("platform:as3722-regulator"); 841 MODULE_DESCRIPTION("AS3722 regulator driver"); 842 MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>"); 843 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 844 MODULE_LICENSE("GPL"); 845