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