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