1 /* 2 * Copyright (C) ST-Ericsson SA 2010 3 * 4 * License Terms: GNU General Public License v2 5 * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson 6 * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson 7 * 8 * Power domain regulators on DB8500 9 */ 10 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <linux/err.h> 14 #include <linux/spinlock.h> 15 #include <linux/platform_device.h> 16 #include <linux/mfd/dbx500-prcmu.h> 17 #include <linux/regulator/driver.h> 18 #include <linux/regulator/machine.h> 19 #include <linux/regulator/db8500-prcmu.h> 20 #include <linux/regulator/of_regulator.h> 21 #include <linux/of.h> 22 #include <linux/module.h> 23 #include "dbx500-prcmu.h" 24 25 static int db8500_regulator_enable(struct regulator_dev *rdev) 26 { 27 struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); 28 29 if (info == NULL) 30 return -EINVAL; 31 32 dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", 33 info->desc.name); 34 35 if (!info->is_enabled) { 36 info->is_enabled = true; 37 if (!info->exclude_from_power_state) 38 power_state_active_enable(); 39 } 40 41 return 0; 42 } 43 44 static int db8500_regulator_disable(struct regulator_dev *rdev) 45 { 46 struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); 47 int ret = 0; 48 49 if (info == NULL) 50 return -EINVAL; 51 52 dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", 53 info->desc.name); 54 55 if (info->is_enabled) { 56 info->is_enabled = false; 57 if (!info->exclude_from_power_state) 58 ret = power_state_active_disable(); 59 } 60 61 return ret; 62 } 63 64 static int db8500_regulator_is_enabled(struct regulator_dev *rdev) 65 { 66 struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); 67 68 if (info == NULL) 69 return -EINVAL; 70 71 dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):" 72 " %i\n", info->desc.name, info->is_enabled); 73 74 return info->is_enabled; 75 } 76 77 /* db8500 regulator operations */ 78 static struct regulator_ops db8500_regulator_ops = { 79 .enable = db8500_regulator_enable, 80 .disable = db8500_regulator_disable, 81 .is_enabled = db8500_regulator_is_enabled, 82 }; 83 84 /* 85 * EPOD control 86 */ 87 static bool epod_on[NUM_EPOD_ID]; 88 static bool epod_ramret[NUM_EPOD_ID]; 89 90 static int enable_epod(u16 epod_id, bool ramret) 91 { 92 int ret; 93 94 if (ramret) { 95 if (!epod_on[epod_id]) { 96 ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET); 97 if (ret < 0) 98 return ret; 99 } 100 epod_ramret[epod_id] = true; 101 } else { 102 ret = prcmu_set_epod(epod_id, EPOD_STATE_ON); 103 if (ret < 0) 104 return ret; 105 epod_on[epod_id] = true; 106 } 107 108 return 0; 109 } 110 111 static int disable_epod(u16 epod_id, bool ramret) 112 { 113 int ret; 114 115 if (ramret) { 116 if (!epod_on[epod_id]) { 117 ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF); 118 if (ret < 0) 119 return ret; 120 } 121 epod_ramret[epod_id] = false; 122 } else { 123 if (epod_ramret[epod_id]) { 124 ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET); 125 if (ret < 0) 126 return ret; 127 } else { 128 ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF); 129 if (ret < 0) 130 return ret; 131 } 132 epod_on[epod_id] = false; 133 } 134 135 return 0; 136 } 137 138 /* 139 * Regulator switch 140 */ 141 static int db8500_regulator_switch_enable(struct regulator_dev *rdev) 142 { 143 struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); 144 int ret; 145 146 if (info == NULL) 147 return -EINVAL; 148 149 dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n", 150 info->desc.name); 151 152 ret = enable_epod(info->epod_id, info->is_ramret); 153 if (ret < 0) { 154 dev_err(rdev_get_dev(rdev), 155 "regulator-switch-%s-enable: prcmu call failed\n", 156 info->desc.name); 157 goto out; 158 } 159 160 info->is_enabled = true; 161 out: 162 return ret; 163 } 164 165 static int db8500_regulator_switch_disable(struct regulator_dev *rdev) 166 { 167 struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); 168 int ret; 169 170 if (info == NULL) 171 return -EINVAL; 172 173 dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n", 174 info->desc.name); 175 176 ret = disable_epod(info->epod_id, info->is_ramret); 177 if (ret < 0) { 178 dev_err(rdev_get_dev(rdev), 179 "regulator_switch-%s-disable: prcmu call failed\n", 180 info->desc.name); 181 goto out; 182 } 183 184 info->is_enabled = 0; 185 out: 186 return ret; 187 } 188 189 static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) 190 { 191 struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); 192 193 if (info == NULL) 194 return -EINVAL; 195 196 dev_vdbg(rdev_get_dev(rdev), 197 "regulator-switch-%s-is_enabled (is_enabled): %i\n", 198 info->desc.name, info->is_enabled); 199 200 return info->is_enabled; 201 } 202 203 static struct regulator_ops db8500_regulator_switch_ops = { 204 .enable = db8500_regulator_switch_enable, 205 .disable = db8500_regulator_switch_disable, 206 .is_enabled = db8500_regulator_switch_is_enabled, 207 }; 208 209 /* 210 * Regulator information 211 */ 212 static struct dbx500_regulator_info 213 dbx500_regulator_info[DB8500_NUM_REGULATORS] = { 214 [DB8500_REGULATOR_VAPE] = { 215 .desc = { 216 .name = "db8500-vape", 217 .id = DB8500_REGULATOR_VAPE, 218 .ops = &db8500_regulator_ops, 219 .type = REGULATOR_VOLTAGE, 220 .owner = THIS_MODULE, 221 }, 222 }, 223 [DB8500_REGULATOR_VARM] = { 224 .desc = { 225 .name = "db8500-varm", 226 .id = DB8500_REGULATOR_VARM, 227 .ops = &db8500_regulator_ops, 228 .type = REGULATOR_VOLTAGE, 229 .owner = THIS_MODULE, 230 }, 231 }, 232 [DB8500_REGULATOR_VMODEM] = { 233 .desc = { 234 .name = "db8500-vmodem", 235 .id = DB8500_REGULATOR_VMODEM, 236 .ops = &db8500_regulator_ops, 237 .type = REGULATOR_VOLTAGE, 238 .owner = THIS_MODULE, 239 }, 240 }, 241 [DB8500_REGULATOR_VPLL] = { 242 .desc = { 243 .name = "db8500-vpll", 244 .id = DB8500_REGULATOR_VPLL, 245 .ops = &db8500_regulator_ops, 246 .type = REGULATOR_VOLTAGE, 247 .owner = THIS_MODULE, 248 }, 249 }, 250 [DB8500_REGULATOR_VSMPS1] = { 251 .desc = { 252 .name = "db8500-vsmps1", 253 .id = DB8500_REGULATOR_VSMPS1, 254 .ops = &db8500_regulator_ops, 255 .type = REGULATOR_VOLTAGE, 256 .owner = THIS_MODULE, 257 }, 258 }, 259 [DB8500_REGULATOR_VSMPS2] = { 260 .desc = { 261 .name = "db8500-vsmps2", 262 .id = DB8500_REGULATOR_VSMPS2, 263 .ops = &db8500_regulator_ops, 264 .type = REGULATOR_VOLTAGE, 265 .owner = THIS_MODULE, 266 }, 267 .exclude_from_power_state = true, 268 }, 269 [DB8500_REGULATOR_VSMPS3] = { 270 .desc = { 271 .name = "db8500-vsmps3", 272 .id = DB8500_REGULATOR_VSMPS3, 273 .ops = &db8500_regulator_ops, 274 .type = REGULATOR_VOLTAGE, 275 .owner = THIS_MODULE, 276 }, 277 }, 278 [DB8500_REGULATOR_VRF1] = { 279 .desc = { 280 .name = "db8500-vrf1", 281 .id = DB8500_REGULATOR_VRF1, 282 .ops = &db8500_regulator_ops, 283 .type = REGULATOR_VOLTAGE, 284 .owner = THIS_MODULE, 285 }, 286 }, 287 [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { 288 .desc = { 289 .name = "db8500-sva-mmdsp", 290 .id = DB8500_REGULATOR_SWITCH_SVAMMDSP, 291 .ops = &db8500_regulator_switch_ops, 292 .type = REGULATOR_VOLTAGE, 293 .owner = THIS_MODULE, 294 }, 295 .epod_id = EPOD_ID_SVAMMDSP, 296 }, 297 [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { 298 .desc = { 299 .name = "db8500-sva-mmdsp-ret", 300 .id = DB8500_REGULATOR_SWITCH_SVAMMDSPRET, 301 .ops = &db8500_regulator_switch_ops, 302 .type = REGULATOR_VOLTAGE, 303 .owner = THIS_MODULE, 304 }, 305 .epod_id = EPOD_ID_SVAMMDSP, 306 .is_ramret = true, 307 }, 308 [DB8500_REGULATOR_SWITCH_SVAPIPE] = { 309 .desc = { 310 .name = "db8500-sva-pipe", 311 .id = DB8500_REGULATOR_SWITCH_SVAPIPE, 312 .ops = &db8500_regulator_switch_ops, 313 .type = REGULATOR_VOLTAGE, 314 .owner = THIS_MODULE, 315 }, 316 .epod_id = EPOD_ID_SVAPIPE, 317 }, 318 [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { 319 .desc = { 320 .name = "db8500-sia-mmdsp", 321 .id = DB8500_REGULATOR_SWITCH_SIAMMDSP, 322 .ops = &db8500_regulator_switch_ops, 323 .type = REGULATOR_VOLTAGE, 324 .owner = THIS_MODULE, 325 }, 326 .epod_id = EPOD_ID_SIAMMDSP, 327 }, 328 [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { 329 .desc = { 330 .name = "db8500-sia-mmdsp-ret", 331 .id = DB8500_REGULATOR_SWITCH_SIAMMDSPRET, 332 .ops = &db8500_regulator_switch_ops, 333 .type = REGULATOR_VOLTAGE, 334 .owner = THIS_MODULE, 335 }, 336 .epod_id = EPOD_ID_SIAMMDSP, 337 .is_ramret = true, 338 }, 339 [DB8500_REGULATOR_SWITCH_SIAPIPE] = { 340 .desc = { 341 .name = "db8500-sia-pipe", 342 .id = DB8500_REGULATOR_SWITCH_SIAPIPE, 343 .ops = &db8500_regulator_switch_ops, 344 .type = REGULATOR_VOLTAGE, 345 .owner = THIS_MODULE, 346 }, 347 .epod_id = EPOD_ID_SIAPIPE, 348 }, 349 [DB8500_REGULATOR_SWITCH_SGA] = { 350 .desc = { 351 .name = "db8500-sga", 352 .id = DB8500_REGULATOR_SWITCH_SGA, 353 .ops = &db8500_regulator_switch_ops, 354 .type = REGULATOR_VOLTAGE, 355 .owner = THIS_MODULE, 356 }, 357 .epod_id = EPOD_ID_SGA, 358 }, 359 [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { 360 .desc = { 361 .name = "db8500-b2r2-mcde", 362 .id = DB8500_REGULATOR_SWITCH_B2R2_MCDE, 363 .ops = &db8500_regulator_switch_ops, 364 .type = REGULATOR_VOLTAGE, 365 .owner = THIS_MODULE, 366 }, 367 .epod_id = EPOD_ID_B2R2_MCDE, 368 }, 369 [DB8500_REGULATOR_SWITCH_ESRAM12] = { 370 .desc = { 371 .name = "db8500-esram12", 372 .id = DB8500_REGULATOR_SWITCH_ESRAM12, 373 .ops = &db8500_regulator_switch_ops, 374 .type = REGULATOR_VOLTAGE, 375 .owner = THIS_MODULE, 376 }, 377 .epod_id = EPOD_ID_ESRAM12, 378 .is_enabled = true, 379 }, 380 [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { 381 .desc = { 382 .name = "db8500-esram12-ret", 383 .id = DB8500_REGULATOR_SWITCH_ESRAM12RET, 384 .ops = &db8500_regulator_switch_ops, 385 .type = REGULATOR_VOLTAGE, 386 .owner = THIS_MODULE, 387 }, 388 .epod_id = EPOD_ID_ESRAM12, 389 .is_ramret = true, 390 }, 391 [DB8500_REGULATOR_SWITCH_ESRAM34] = { 392 .desc = { 393 .name = "db8500-esram34", 394 .id = DB8500_REGULATOR_SWITCH_ESRAM34, 395 .ops = &db8500_regulator_switch_ops, 396 .type = REGULATOR_VOLTAGE, 397 .owner = THIS_MODULE, 398 }, 399 .epod_id = EPOD_ID_ESRAM34, 400 .is_enabled = true, 401 }, 402 [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { 403 .desc = { 404 .name = "db8500-esram34-ret", 405 .id = DB8500_REGULATOR_SWITCH_ESRAM34RET, 406 .ops = &db8500_regulator_switch_ops, 407 .type = REGULATOR_VOLTAGE, 408 .owner = THIS_MODULE, 409 }, 410 .epod_id = EPOD_ID_ESRAM34, 411 .is_ramret = true, 412 }, 413 }; 414 415 static int db8500_regulator_register(struct platform_device *pdev, 416 struct regulator_init_data *init_data, 417 int id, 418 struct device_node *np) 419 { 420 struct dbx500_regulator_info *info; 421 struct regulator_config config = { }; 422 int err; 423 424 /* assign per-regulator data */ 425 info = &dbx500_regulator_info[id]; 426 info->dev = &pdev->dev; 427 428 config.dev = &pdev->dev; 429 config.init_data = init_data; 430 config.driver_data = info; 431 config.of_node = np; 432 433 /* register with the regulator framework */ 434 info->rdev = regulator_register(&info->desc, &config); 435 if (IS_ERR(info->rdev)) { 436 err = PTR_ERR(info->rdev); 437 dev_err(&pdev->dev, "failed to register %s: err %i\n", 438 info->desc.name, err); 439 440 /* if failing, unregister all earlier regulators */ 441 while (--id >= 0) { 442 info = &dbx500_regulator_info[id]; 443 regulator_unregister(info->rdev); 444 } 445 return err; 446 } 447 448 dev_dbg(rdev_get_dev(info->rdev), 449 "regulator-%s-probed\n", info->desc.name); 450 451 return 0; 452 } 453 454 static struct of_regulator_match db8500_regulator_matches[] = { 455 { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, 456 { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, 457 { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, 458 { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, 459 { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, 460 { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, 461 { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, 462 { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, 463 { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, 464 { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, 465 { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, 466 { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, 467 { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, 468 { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, 469 { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, 470 { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, 471 { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, 472 { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, 473 { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, 474 { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, 475 }; 476 477 static int 478 db8500_regulator_of_probe(struct platform_device *pdev, 479 struct device_node *np) 480 { 481 int i, err; 482 483 for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { 484 err = db8500_regulator_register( 485 pdev, db8500_regulator_matches[i].init_data, 486 i, db8500_regulator_matches[i].of_node); 487 if (err) 488 return err; 489 } 490 491 return 0; 492 } 493 494 static int db8500_regulator_probe(struct platform_device *pdev) 495 { 496 struct regulator_init_data *db8500_init_data = 497 dev_get_platdata(&pdev->dev); 498 struct device_node *np = pdev->dev.of_node; 499 int i, err; 500 501 /* register all regulators */ 502 if (np) { 503 err = of_regulator_match(&pdev->dev, np, 504 db8500_regulator_matches, 505 ARRAY_SIZE(db8500_regulator_matches)); 506 if (err < 0) { 507 dev_err(&pdev->dev, 508 "Error parsing regulator init data: %d\n", err); 509 return err; 510 } 511 512 err = db8500_regulator_of_probe(pdev, np); 513 if (err) 514 return err; 515 } else { 516 for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { 517 err = db8500_regulator_register(pdev, 518 &db8500_init_data[i], 519 i, NULL); 520 if (err) 521 return err; 522 } 523 } 524 525 err = ux500_regulator_debug_init(pdev, 526 dbx500_regulator_info, 527 ARRAY_SIZE(dbx500_regulator_info)); 528 return 0; 529 } 530 531 static int __exit db8500_regulator_remove(struct platform_device *pdev) 532 { 533 int i; 534 535 ux500_regulator_debug_exit(); 536 537 for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { 538 struct dbx500_regulator_info *info; 539 info = &dbx500_regulator_info[i]; 540 541 dev_vdbg(rdev_get_dev(info->rdev), 542 "regulator-%s-remove\n", info->desc.name); 543 544 regulator_unregister(info->rdev); 545 } 546 547 return 0; 548 } 549 550 static struct platform_driver db8500_regulator_driver = { 551 .driver = { 552 .name = "db8500-prcmu-regulators", 553 .owner = THIS_MODULE, 554 }, 555 .probe = db8500_regulator_probe, 556 .remove = __exit_p(db8500_regulator_remove), 557 }; 558 559 static int __init db8500_regulator_init(void) 560 { 561 return platform_driver_register(&db8500_regulator_driver); 562 } 563 564 static void __exit db8500_regulator_exit(void) 565 { 566 platform_driver_unregister(&db8500_regulator_driver); 567 } 568 569 arch_initcall(db8500_regulator_init); 570 module_exit(db8500_regulator_exit); 571 572 MODULE_AUTHOR("STMicroelectronics/ST-Ericsson"); 573 MODULE_DESCRIPTION("DB8500 regulator driver"); 574 MODULE_LICENSE("GPL v2"); 575