ab8500-ext.c (12377B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) ST-Ericsson SA 2010 4 * 5 * Authors: Bengt Jonsson <bengt.g.jonsson@stericsson.com> 6 * 7 * This file is based on drivers/regulator/ab8500.c 8 * 9 * AB8500 external regulators 10 * 11 * ab8500-ext supports the following regulators: 12 * - VextSupply3 13 */ 14#include <linux/init.h> 15#include <linux/kernel.h> 16#include <linux/err.h> 17#include <linux/module.h> 18#include <linux/of.h> 19#include <linux/platform_device.h> 20#include <linux/regulator/driver.h> 21#include <linux/regulator/machine.h> 22#include <linux/regulator/of_regulator.h> 23#include <linux/mfd/abx500.h> 24#include <linux/mfd/abx500/ab8500.h> 25 26/* AB8500 external regulators */ 27enum ab8500_ext_regulator_id { 28 AB8500_EXT_SUPPLY1, 29 AB8500_EXT_SUPPLY2, 30 AB8500_EXT_SUPPLY3, 31 AB8500_NUM_EXT_REGULATORS, 32}; 33 34struct ab8500_ext_regulator_cfg { 35 bool hwreq; /* requires hw mode or high power mode */ 36}; 37 38/* supply for VextSupply3 */ 39static struct regulator_consumer_supply ab8500_ext_supply3_consumers[] = { 40 /* SIM supply for 3 V SIM cards */ 41 REGULATOR_SUPPLY("vinvsim", "sim-detect.0"), 42}; 43 44/* 45 * AB8500 external regulators 46 */ 47static struct regulator_init_data ab8500_ext_regulators[] = { 48 /* fixed Vbat supplies VSMPS1_EXT_1V8 */ 49 [AB8500_EXT_SUPPLY1] = { 50 .constraints = { 51 .name = "ab8500-ext-supply1", 52 .min_uV = 1800000, 53 .max_uV = 1800000, 54 .initial_mode = REGULATOR_MODE_IDLE, 55 .boot_on = 1, 56 .always_on = 1, 57 }, 58 }, 59 /* fixed Vbat supplies VSMPS2_EXT_1V36 and VSMPS5_EXT_1V15 */ 60 [AB8500_EXT_SUPPLY2] = { 61 .constraints = { 62 .name = "ab8500-ext-supply2", 63 .min_uV = 1360000, 64 .max_uV = 1360000, 65 }, 66 }, 67 /* fixed Vbat supplies VSMPS3_EXT_3V4 and VSMPS4_EXT_3V4 */ 68 [AB8500_EXT_SUPPLY3] = { 69 .constraints = { 70 .name = "ab8500-ext-supply3", 71 .min_uV = 3400000, 72 .max_uV = 3400000, 73 .valid_ops_mask = REGULATOR_CHANGE_STATUS, 74 .boot_on = 1, 75 }, 76 .num_consumer_supplies = 77 ARRAY_SIZE(ab8500_ext_supply3_consumers), 78 .consumer_supplies = ab8500_ext_supply3_consumers, 79 }, 80}; 81 82/** 83 * struct ab8500_ext_regulator_info - ab8500 regulator information 84 * @dev: device pointer 85 * @desc: regulator description 86 * @cfg: regulator configuration (extension of regulator FW configuration) 87 * @update_bank: bank to control on/off 88 * @update_reg: register to control on/off 89 * @update_mask: mask to enable/disable and set mode of regulator 90 * @update_val: bits holding the regulator current mode 91 * @update_val_hp: bits to set EN pin active (LPn pin deactive) 92 * normally this means high power mode 93 * @update_val_lp: bits to set EN pin active and LPn pin active 94 * normally this means low power mode 95 * @update_val_hw: bits to set regulator pins in HW control 96 * SysClkReq pins and logic will choose mode 97 */ 98struct ab8500_ext_regulator_info { 99 struct device *dev; 100 struct regulator_desc desc; 101 struct ab8500_ext_regulator_cfg *cfg; 102 u8 update_bank; 103 u8 update_reg; 104 u8 update_mask; 105 u8 update_val; 106 u8 update_val_hp; 107 u8 update_val_lp; 108 u8 update_val_hw; 109}; 110 111static int ab8500_ext_regulator_enable(struct regulator_dev *rdev) 112{ 113 int ret; 114 struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); 115 u8 regval; 116 117 if (info == NULL) { 118 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); 119 return -EINVAL; 120 } 121 122 /* 123 * To satisfy both HW high power request and SW request, the regulator 124 * must be on in high power. 125 */ 126 if (info->cfg && info->cfg->hwreq) 127 regval = info->update_val_hp; 128 else 129 regval = info->update_val; 130 131 ret = abx500_mask_and_set_register_interruptible(info->dev, 132 info->update_bank, info->update_reg, 133 info->update_mask, regval); 134 if (ret < 0) { 135 dev_err(rdev_get_dev(rdev), 136 "couldn't set enable bits for regulator\n"); 137 return ret; 138 } 139 140 dev_dbg(rdev_get_dev(rdev), 141 "%s-enable (bank, reg, mask, value): 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", 142 info->desc.name, info->update_bank, info->update_reg, 143 info->update_mask, regval); 144 145 return 0; 146} 147 148static int ab8500_ext_regulator_disable(struct regulator_dev *rdev) 149{ 150 int ret; 151 struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); 152 u8 regval; 153 154 if (info == NULL) { 155 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); 156 return -EINVAL; 157 } 158 159 /* 160 * Set the regulator in HW request mode if configured 161 */ 162 if (info->cfg && info->cfg->hwreq) 163 regval = info->update_val_hw; 164 else 165 regval = 0; 166 167 ret = abx500_mask_and_set_register_interruptible(info->dev, 168 info->update_bank, info->update_reg, 169 info->update_mask, regval); 170 if (ret < 0) { 171 dev_err(rdev_get_dev(rdev), 172 "couldn't set disable bits for regulator\n"); 173 return ret; 174 } 175 176 dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):" 177 " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", 178 info->desc.name, info->update_bank, info->update_reg, 179 info->update_mask, regval); 180 181 return 0; 182} 183 184static int ab8500_ext_regulator_is_enabled(struct regulator_dev *rdev) 185{ 186 int ret; 187 struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); 188 u8 regval; 189 190 if (info == NULL) { 191 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); 192 return -EINVAL; 193 } 194 195 ret = abx500_get_register_interruptible(info->dev, 196 info->update_bank, info->update_reg, ®val); 197 if (ret < 0) { 198 dev_err(rdev_get_dev(rdev), 199 "couldn't read 0x%x register\n", info->update_reg); 200 return ret; 201 } 202 203 dev_dbg(rdev_get_dev(rdev), "%s-is_enabled (bank, reg, mask, value):" 204 " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", 205 info->desc.name, info->update_bank, info->update_reg, 206 info->update_mask, regval); 207 208 if (((regval & info->update_mask) == info->update_val_lp) || 209 ((regval & info->update_mask) == info->update_val_hp)) 210 return 1; 211 else 212 return 0; 213} 214 215static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev, 216 unsigned int mode) 217{ 218 int ret = 0; 219 struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); 220 u8 regval; 221 222 if (info == NULL) { 223 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); 224 return -EINVAL; 225 } 226 227 switch (mode) { 228 case REGULATOR_MODE_NORMAL: 229 regval = info->update_val_hp; 230 break; 231 case REGULATOR_MODE_IDLE: 232 regval = info->update_val_lp; 233 break; 234 235 default: 236 return -EINVAL; 237 } 238 239 /* If regulator is enabled and info->cfg->hwreq is set, the regulator 240 must be on in high power, so we don't need to write the register with 241 the same value. 242 */ 243 if (ab8500_ext_regulator_is_enabled(rdev) && 244 !(info->cfg && info->cfg->hwreq)) { 245 ret = abx500_mask_and_set_register_interruptible(info->dev, 246 info->update_bank, info->update_reg, 247 info->update_mask, regval); 248 if (ret < 0) { 249 dev_err(rdev_get_dev(rdev), 250 "Could not set regulator mode.\n"); 251 return ret; 252 } 253 254 dev_dbg(rdev_get_dev(rdev), 255 "%s-set_mode (bank, reg, mask, value): " 256 "0x%x, 0x%x, 0x%x, 0x%x\n", 257 info->desc.name, info->update_bank, info->update_reg, 258 info->update_mask, regval); 259 } 260 261 info->update_val = regval; 262 263 return 0; 264} 265 266static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev) 267{ 268 struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); 269 int ret; 270 271 if (info == NULL) { 272 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); 273 return -EINVAL; 274 } 275 276 if (info->update_val == info->update_val_hp) 277 ret = REGULATOR_MODE_NORMAL; 278 else if (info->update_val == info->update_val_lp) 279 ret = REGULATOR_MODE_IDLE; 280 else 281 ret = -EINVAL; 282 283 return ret; 284} 285 286static int ab8500_ext_set_voltage(struct regulator_dev *rdev, int min_uV, 287 int max_uV, unsigned *selector) 288{ 289 struct regulation_constraints *regu_constraints = rdev->constraints; 290 291 if (!regu_constraints) { 292 dev_err(rdev_get_dev(rdev), "No regulator constraints\n"); 293 return -EINVAL; 294 } 295 296 if (regu_constraints->min_uV == min_uV && 297 regu_constraints->max_uV == max_uV) 298 return 0; 299 300 dev_err(rdev_get_dev(rdev), 301 "Requested min %duV max %duV != constrained min %duV max %duV\n", 302 min_uV, max_uV, 303 regu_constraints->min_uV, regu_constraints->max_uV); 304 305 return -EINVAL; 306} 307 308static int ab8500_ext_list_voltage(struct regulator_dev *rdev, 309 unsigned selector) 310{ 311 struct regulation_constraints *regu_constraints = rdev->constraints; 312 313 if (regu_constraints == NULL) { 314 dev_err(rdev_get_dev(rdev), "regulator constraints null pointer\n"); 315 return -EINVAL; 316 } 317 /* return the uV for the fixed regulators */ 318 if (regu_constraints->min_uV && regu_constraints->max_uV) { 319 if (regu_constraints->min_uV == regu_constraints->max_uV) 320 return regu_constraints->min_uV; 321 } 322 return -EINVAL; 323} 324 325static const struct regulator_ops ab8500_ext_regulator_ops = { 326 .enable = ab8500_ext_regulator_enable, 327 .disable = ab8500_ext_regulator_disable, 328 .is_enabled = ab8500_ext_regulator_is_enabled, 329 .set_mode = ab8500_ext_regulator_set_mode, 330 .get_mode = ab8500_ext_regulator_get_mode, 331 .set_voltage = ab8500_ext_set_voltage, 332 .list_voltage = ab8500_ext_list_voltage, 333}; 334 335static struct ab8500_ext_regulator_info 336 ab8500_ext_regulator_info[AB8500_NUM_EXT_REGULATORS] = { 337 [AB8500_EXT_SUPPLY1] = { 338 .desc = { 339 .name = "VEXTSUPPLY1", 340 .of_match = of_match_ptr("ab8500_ext1"), 341 .ops = &ab8500_ext_regulator_ops, 342 .type = REGULATOR_VOLTAGE, 343 .id = AB8500_EXT_SUPPLY1, 344 .owner = THIS_MODULE, 345 .n_voltages = 1, 346 }, 347 .update_bank = 0x04, 348 .update_reg = 0x08, 349 .update_mask = 0x03, 350 .update_val = 0x01, 351 .update_val_hp = 0x01, 352 .update_val_lp = 0x03, 353 .update_val_hw = 0x02, 354 }, 355 [AB8500_EXT_SUPPLY2] = { 356 .desc = { 357 .name = "VEXTSUPPLY2", 358 .of_match = of_match_ptr("ab8500_ext2"), 359 .ops = &ab8500_ext_regulator_ops, 360 .type = REGULATOR_VOLTAGE, 361 .id = AB8500_EXT_SUPPLY2, 362 .owner = THIS_MODULE, 363 .n_voltages = 1, 364 }, 365 .update_bank = 0x04, 366 .update_reg = 0x08, 367 .update_mask = 0x0c, 368 .update_val = 0x04, 369 .update_val_hp = 0x04, 370 .update_val_lp = 0x0c, 371 .update_val_hw = 0x08, 372 }, 373 [AB8500_EXT_SUPPLY3] = { 374 .desc = { 375 .name = "VEXTSUPPLY3", 376 .of_match = of_match_ptr("ab8500_ext3"), 377 .ops = &ab8500_ext_regulator_ops, 378 .type = REGULATOR_VOLTAGE, 379 .id = AB8500_EXT_SUPPLY3, 380 .owner = THIS_MODULE, 381 .n_voltages = 1, 382 }, 383 .update_bank = 0x04, 384 .update_reg = 0x08, 385 .update_mask = 0x30, 386 .update_val = 0x10, 387 .update_val_hp = 0x10, 388 .update_val_lp = 0x30, 389 .update_val_hw = 0x20, 390 }, 391}; 392 393static int ab8500_ext_regulator_probe(struct platform_device *pdev) 394{ 395 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); 396 struct regulator_config config = { }; 397 struct regulator_dev *rdev; 398 int i; 399 400 if (!ab8500) { 401 dev_err(&pdev->dev, "null mfd parent\n"); 402 return -EINVAL; 403 } 404 405 /* check for AB8500 2.x */ 406 if (is_ab8500_2p0_or_earlier(ab8500)) { 407 struct ab8500_ext_regulator_info *info; 408 409 /* VextSupply3LPn is inverted on AB8500 2.x */ 410 info = &ab8500_ext_regulator_info[AB8500_EXT_SUPPLY3]; 411 info->update_val = 0x30; 412 info->update_val_hp = 0x30; 413 info->update_val_lp = 0x10; 414 } 415 416 /* register all regulators */ 417 for (i = 0; i < ARRAY_SIZE(ab8500_ext_regulator_info); i++) { 418 struct ab8500_ext_regulator_info *info = NULL; 419 420 /* assign per-regulator data */ 421 info = &ab8500_ext_regulator_info[i]; 422 info->dev = &pdev->dev; 423 info->cfg = (struct ab8500_ext_regulator_cfg *) 424 ab8500_ext_regulators[i].driver_data; 425 426 config.dev = &pdev->dev; 427 config.driver_data = info; 428 config.init_data = &ab8500_ext_regulators[i]; 429 430 /* register regulator with framework */ 431 rdev = devm_regulator_register(&pdev->dev, &info->desc, 432 &config); 433 if (IS_ERR(rdev)) { 434 dev_err(&pdev->dev, "failed to register regulator %s\n", 435 info->desc.name); 436 return PTR_ERR(rdev); 437 } 438 439 dev_dbg(&pdev->dev, "%s-probed\n", info->desc.name); 440 } 441 442 return 0; 443} 444 445static struct platform_driver ab8500_ext_regulator_driver = { 446 .probe = ab8500_ext_regulator_probe, 447 .driver = { 448 .name = "ab8500-ext-regulator", 449 }, 450}; 451 452static int __init ab8500_ext_regulator_init(void) 453{ 454 int ret; 455 456 ret = platform_driver_register(&ab8500_ext_regulator_driver); 457 if (ret) 458 pr_err("Failed to register ab8500 ext regulator: %d\n", ret); 459 460 return ret; 461} 462subsys_initcall(ab8500_ext_regulator_init); 463 464static void __exit ab8500_ext_regulator_exit(void) 465{ 466 platform_driver_unregister(&ab8500_ext_regulator_driver); 467} 468module_exit(ab8500_ext_regulator_exit); 469 470MODULE_LICENSE("GPL v2"); 471MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>"); 472MODULE_DESCRIPTION("AB8500 external regulator driver"); 473MODULE_ALIAS("platform:ab8500-ext-regulator");