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