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