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