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