db8500-prcmu.c (12189B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) ST-Ericsson SA 2010 4 * 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 25static 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 44static 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 64static 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 */ 78static const 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 */ 87static bool epod_on[NUM_EPOD_ID]; 88static bool epod_ramret[NUM_EPOD_ID]; 89 90static 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 111static 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 */ 141static 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; 161out: 162 return ret; 163} 164 165static 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 = false; 185out: 186 return ret; 187} 188 189static 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 203static const 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 */ 212static struct dbx500_regulator_info 213dbx500_regulator_info[DB8500_NUM_REGULATORS] = { 214 [DB8500_REGULATOR_VAPE] = { 215 .desc = { 216 .name = "db8500-vape", 217 .of_match = of_match_ptr("db8500_vape"), 218 .id = DB8500_REGULATOR_VAPE, 219 .ops = &db8500_regulator_ops, 220 .type = REGULATOR_VOLTAGE, 221 .owner = THIS_MODULE, 222 }, 223 }, 224 [DB8500_REGULATOR_VARM] = { 225 .desc = { 226 .name = "db8500-varm", 227 .of_match = of_match_ptr("db8500_varm"), 228 .id = DB8500_REGULATOR_VARM, 229 .ops = &db8500_regulator_ops, 230 .type = REGULATOR_VOLTAGE, 231 .owner = THIS_MODULE, 232 }, 233 }, 234 [DB8500_REGULATOR_VMODEM] = { 235 .desc = { 236 .name = "db8500-vmodem", 237 .of_match = of_match_ptr("db8500_vmodem"), 238 .id = DB8500_REGULATOR_VMODEM, 239 .ops = &db8500_regulator_ops, 240 .type = REGULATOR_VOLTAGE, 241 .owner = THIS_MODULE, 242 }, 243 }, 244 [DB8500_REGULATOR_VPLL] = { 245 .desc = { 246 .name = "db8500-vpll", 247 .of_match = of_match_ptr("db8500_vpll"), 248 .id = DB8500_REGULATOR_VPLL, 249 .ops = &db8500_regulator_ops, 250 .type = REGULATOR_VOLTAGE, 251 .owner = THIS_MODULE, 252 }, 253 }, 254 [DB8500_REGULATOR_VSMPS1] = { 255 .desc = { 256 .name = "db8500-vsmps1", 257 .of_match = of_match_ptr("db8500_vsmps1"), 258 .id = DB8500_REGULATOR_VSMPS1, 259 .ops = &db8500_regulator_ops, 260 .type = REGULATOR_VOLTAGE, 261 .owner = THIS_MODULE, 262 }, 263 }, 264 [DB8500_REGULATOR_VSMPS2] = { 265 .desc = { 266 .name = "db8500-vsmps2", 267 .of_match = of_match_ptr("db8500_vsmps2"), 268 .id = DB8500_REGULATOR_VSMPS2, 269 .ops = &db8500_regulator_ops, 270 .type = REGULATOR_VOLTAGE, 271 .owner = THIS_MODULE, 272 .fixed_uV = 1800000, 273 .n_voltages = 1, 274 }, 275 .exclude_from_power_state = true, 276 }, 277 [DB8500_REGULATOR_VSMPS3] = { 278 .desc = { 279 .name = "db8500-vsmps3", 280 .of_match = of_match_ptr("db8500_vsmps3"), 281 .id = DB8500_REGULATOR_VSMPS3, 282 .ops = &db8500_regulator_ops, 283 .type = REGULATOR_VOLTAGE, 284 .owner = THIS_MODULE, 285 }, 286 }, 287 [DB8500_REGULATOR_VRF1] = { 288 .desc = { 289 .name = "db8500-vrf1", 290 .of_match = of_match_ptr("db8500_vrf1"), 291 .id = DB8500_REGULATOR_VRF1, 292 .ops = &db8500_regulator_ops, 293 .type = REGULATOR_VOLTAGE, 294 .owner = THIS_MODULE, 295 }, 296 }, 297 [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { 298 .desc = { 299 .name = "db8500-sva-mmdsp", 300 .of_match = of_match_ptr("db8500_sva_mmdsp"), 301 .id = DB8500_REGULATOR_SWITCH_SVAMMDSP, 302 .ops = &db8500_regulator_switch_ops, 303 .type = REGULATOR_VOLTAGE, 304 .owner = THIS_MODULE, 305 }, 306 .epod_id = EPOD_ID_SVAMMDSP, 307 }, 308 [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { 309 .desc = { 310 .name = "db8500-sva-mmdsp-ret", 311 .of_match = of_match_ptr("db8500_sva_mmdsp_ret"), 312 .id = DB8500_REGULATOR_SWITCH_SVAMMDSPRET, 313 .ops = &db8500_regulator_switch_ops, 314 .type = REGULATOR_VOLTAGE, 315 .owner = THIS_MODULE, 316 }, 317 .epod_id = EPOD_ID_SVAMMDSP, 318 .is_ramret = true, 319 }, 320 [DB8500_REGULATOR_SWITCH_SVAPIPE] = { 321 .desc = { 322 .name = "db8500-sva-pipe", 323 .of_match = of_match_ptr("db8500_sva_pipe"), 324 .id = DB8500_REGULATOR_SWITCH_SVAPIPE, 325 .ops = &db8500_regulator_switch_ops, 326 .type = REGULATOR_VOLTAGE, 327 .owner = THIS_MODULE, 328 }, 329 .epod_id = EPOD_ID_SVAPIPE, 330 }, 331 [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { 332 .desc = { 333 .name = "db8500-sia-mmdsp", 334 .of_match = of_match_ptr("db8500_sia_mmdsp"), 335 .id = DB8500_REGULATOR_SWITCH_SIAMMDSP, 336 .ops = &db8500_regulator_switch_ops, 337 .type = REGULATOR_VOLTAGE, 338 .owner = THIS_MODULE, 339 }, 340 .epod_id = EPOD_ID_SIAMMDSP, 341 }, 342 [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { 343 .desc = { 344 .name = "db8500-sia-mmdsp-ret", 345 .of_match = of_match_ptr("db8500_sia_mmdsp_ret"), 346 .id = DB8500_REGULATOR_SWITCH_SIAMMDSPRET, 347 .ops = &db8500_regulator_switch_ops, 348 .type = REGULATOR_VOLTAGE, 349 .owner = THIS_MODULE, 350 }, 351 .epod_id = EPOD_ID_SIAMMDSP, 352 .is_ramret = true, 353 }, 354 [DB8500_REGULATOR_SWITCH_SIAPIPE] = { 355 .desc = { 356 .name = "db8500-sia-pipe", 357 .of_match = of_match_ptr("db8500_sia_pipe"), 358 .id = DB8500_REGULATOR_SWITCH_SIAPIPE, 359 .ops = &db8500_regulator_switch_ops, 360 .type = REGULATOR_VOLTAGE, 361 .owner = THIS_MODULE, 362 }, 363 .epod_id = EPOD_ID_SIAPIPE, 364 }, 365 [DB8500_REGULATOR_SWITCH_SGA] = { 366 .desc = { 367 .name = "db8500-sga", 368 .of_match = of_match_ptr("db8500_sga"), 369 .id = DB8500_REGULATOR_SWITCH_SGA, 370 .ops = &db8500_regulator_switch_ops, 371 .type = REGULATOR_VOLTAGE, 372 .owner = THIS_MODULE, 373 }, 374 .epod_id = EPOD_ID_SGA, 375 }, 376 [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { 377 .desc = { 378 .name = "db8500-b2r2-mcde", 379 .of_match = of_match_ptr("db8500_b2r2_mcde"), 380 .id = DB8500_REGULATOR_SWITCH_B2R2_MCDE, 381 .ops = &db8500_regulator_switch_ops, 382 .type = REGULATOR_VOLTAGE, 383 .owner = THIS_MODULE, 384 }, 385 .epod_id = EPOD_ID_B2R2_MCDE, 386 }, 387 [DB8500_REGULATOR_SWITCH_ESRAM12] = { 388 .desc = { 389 .name = "db8500-esram12", 390 .of_match = of_match_ptr("db8500_esram12"), 391 .id = DB8500_REGULATOR_SWITCH_ESRAM12, 392 .ops = &db8500_regulator_switch_ops, 393 .type = REGULATOR_VOLTAGE, 394 .owner = THIS_MODULE, 395 }, 396 .epod_id = EPOD_ID_ESRAM12, 397 .is_enabled = true, 398 }, 399 [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { 400 .desc = { 401 .name = "db8500-esram12-ret", 402 .of_match = of_match_ptr("db8500_esram12_ret"), 403 .id = DB8500_REGULATOR_SWITCH_ESRAM12RET, 404 .ops = &db8500_regulator_switch_ops, 405 .type = REGULATOR_VOLTAGE, 406 .owner = THIS_MODULE, 407 }, 408 .epod_id = EPOD_ID_ESRAM12, 409 .is_ramret = true, 410 }, 411 [DB8500_REGULATOR_SWITCH_ESRAM34] = { 412 .desc = { 413 .name = "db8500-esram34", 414 .of_match = of_match_ptr("db8500_esram34"), 415 .id = DB8500_REGULATOR_SWITCH_ESRAM34, 416 .ops = &db8500_regulator_switch_ops, 417 .type = REGULATOR_VOLTAGE, 418 .owner = THIS_MODULE, 419 }, 420 .epod_id = EPOD_ID_ESRAM34, 421 .is_enabled = true, 422 }, 423 [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { 424 .desc = { 425 .name = "db8500-esram34-ret", 426 .of_match = of_match_ptr("db8500_esram34_ret"), 427 .id = DB8500_REGULATOR_SWITCH_ESRAM34RET, 428 .ops = &db8500_regulator_switch_ops, 429 .type = REGULATOR_VOLTAGE, 430 .owner = THIS_MODULE, 431 }, 432 .epod_id = EPOD_ID_ESRAM34, 433 .is_ramret = true, 434 }, 435}; 436 437static int db8500_regulator_probe(struct platform_device *pdev) 438{ 439 struct regulator_init_data *db8500_init_data; 440 struct dbx500_regulator_info *info; 441 struct regulator_config config = { }; 442 struct regulator_dev *rdev; 443 int err, i; 444 445 db8500_init_data = dev_get_platdata(&pdev->dev); 446 447 for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { 448 /* assign per-regulator data */ 449 info = &dbx500_regulator_info[i]; 450 451 config.driver_data = info; 452 config.dev = &pdev->dev; 453 if (db8500_init_data) 454 config.init_data = &db8500_init_data[i]; 455 456 rdev = devm_regulator_register(&pdev->dev, &info->desc, 457 &config); 458 if (IS_ERR(rdev)) { 459 err = PTR_ERR(rdev); 460 dev_err(&pdev->dev, "failed to register %s: err %i\n", 461 info->desc.name, err); 462 return err; 463 } 464 dev_dbg(&pdev->dev, "regulator-%s-probed\n", info->desc.name); 465 } 466 467 ux500_regulator_debug_init(pdev, dbx500_regulator_info, 468 ARRAY_SIZE(dbx500_regulator_info)); 469 return 0; 470} 471 472static int db8500_regulator_remove(struct platform_device *pdev) 473{ 474 ux500_regulator_debug_exit(); 475 476 return 0; 477} 478 479static struct platform_driver db8500_regulator_driver = { 480 .driver = { 481 .name = "db8500-prcmu-regulators", 482 }, 483 .probe = db8500_regulator_probe, 484 .remove = db8500_regulator_remove, 485}; 486 487static int __init db8500_regulator_init(void) 488{ 489 return platform_driver_register(&db8500_regulator_driver); 490} 491 492static void __exit db8500_regulator_exit(void) 493{ 494 platform_driver_unregister(&db8500_regulator_driver); 495} 496 497arch_initcall(db8500_regulator_init); 498module_exit(db8500_regulator_exit); 499 500MODULE_AUTHOR("STMicroelectronics/ST-Ericsson"); 501MODULE_DESCRIPTION("DB8500 regulator driver"); 502MODULE_LICENSE("GPL v2");