1 /* 2 * tps65218-regulator.c 3 * 4 * Regulator driver for TPS65218 PMIC 5 * 6 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 13 * kind, whether expressed or implied; without even the implied warranty 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License version 2 for more details. 16 */ 17 18 #include <linux/kernel.h> 19 #include <linux/module.h> 20 #include <linux/device.h> 21 #include <linux/init.h> 22 #include <linux/err.h> 23 #include <linux/platform_device.h> 24 #include <linux/of_device.h> 25 #include <linux/regmap.h> 26 #include <linux/regulator/of_regulator.h> 27 #include <linux/regulator/driver.h> 28 #include <linux/regulator/machine.h> 29 #include <linux/mfd/tps65218.h> 30 31 #define TPS65218_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \ 32 _em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \ 33 { \ 34 .name = _name, \ 35 .of_match = _of, \ 36 .id = _id, \ 37 .ops = &_ops, \ 38 .n_voltages = _n, \ 39 .type = _type, \ 40 .owner = THIS_MODULE, \ 41 .vsel_reg = _vr, \ 42 .vsel_mask = _vm, \ 43 .csel_reg = _cr, \ 44 .csel_mask = _cm, \ 45 .enable_reg = _er, \ 46 .enable_mask = _em, \ 47 .volt_table = NULL, \ 48 .linear_ranges = _lr, \ 49 .n_linear_ranges = _nlr, \ 50 .ramp_delay = _delay, \ 51 .fixed_uV = _fuv, \ 52 .bypass_reg = _sr, \ 53 .bypass_mask = _sm, \ 54 } \ 55 56 static const struct regulator_linear_range dcdc1_dcdc2_ranges[] = { 57 REGULATOR_LINEAR_RANGE(850000, 0x0, 0x32, 10000), 58 REGULATOR_LINEAR_RANGE(1375000, 0x33, 0x3f, 25000), 59 }; 60 61 static const struct regulator_linear_range ldo1_dcdc3_ranges[] = { 62 REGULATOR_LINEAR_RANGE(900000, 0x0, 0x1a, 25000), 63 REGULATOR_LINEAR_RANGE(1600000, 0x1b, 0x3f, 50000), 64 }; 65 66 static const struct regulator_linear_range dcdc4_ranges[] = { 67 REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000), 68 REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000), 69 }; 70 71 static int tps65218_pmic_set_voltage_sel(struct regulator_dev *dev, 72 unsigned selector) 73 { 74 int ret; 75 struct tps65218 *tps = rdev_get_drvdata(dev); 76 unsigned int rid = rdev_get_id(dev); 77 78 /* Set the voltage based on vsel value and write protect level is 2 */ 79 ret = tps65218_set_bits(tps, dev->desc->vsel_reg, dev->desc->vsel_mask, 80 selector, TPS65218_PROTECT_L1); 81 82 /* Set GO bit for DCDC1/2 to initiate voltage transistion */ 83 switch (rid) { 84 case TPS65218_DCDC_1: 85 case TPS65218_DCDC_2: 86 ret = tps65218_set_bits(tps, TPS65218_REG_CONTRL_SLEW_RATE, 87 TPS65218_SLEW_RATE_GO, 88 TPS65218_SLEW_RATE_GO, 89 TPS65218_PROTECT_L1); 90 break; 91 } 92 93 return ret; 94 } 95 96 static int tps65218_pmic_enable(struct regulator_dev *dev) 97 { 98 struct tps65218 *tps = rdev_get_drvdata(dev); 99 int rid = rdev_get_id(dev); 100 101 if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) 102 return -EINVAL; 103 104 /* Enable the regulator and password protection is level 1 */ 105 return tps65218_set_bits(tps, dev->desc->enable_reg, 106 dev->desc->enable_mask, dev->desc->enable_mask, 107 TPS65218_PROTECT_L1); 108 } 109 110 static int tps65218_pmic_disable(struct regulator_dev *dev) 111 { 112 struct tps65218 *tps = rdev_get_drvdata(dev); 113 int rid = rdev_get_id(dev); 114 115 if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) 116 return -EINVAL; 117 118 /* Disable the regulator and password protection is level 1 */ 119 return tps65218_clear_bits(tps, dev->desc->enable_reg, 120 dev->desc->enable_mask, TPS65218_PROTECT_L1); 121 } 122 123 static int tps65218_pmic_set_suspend_enable(struct regulator_dev *dev) 124 { 125 struct tps65218 *tps = rdev_get_drvdata(dev); 126 unsigned int rid = rdev_get_id(dev); 127 128 if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) 129 return -EINVAL; 130 131 return tps65218_clear_bits(tps, dev->desc->bypass_reg, 132 dev->desc->bypass_mask, 133 TPS65218_PROTECT_L1); 134 } 135 136 static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev) 137 { 138 struct tps65218 *tps = rdev_get_drvdata(dev); 139 unsigned int rid = rdev_get_id(dev); 140 141 if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) 142 return -EINVAL; 143 144 /* 145 * Certain revisions of TPS65218 will need to have DCDC3 regulator 146 * enabled always, otherwise an immediate system reboot will occur 147 * during poweroff. 148 */ 149 if (rid == TPS65218_DCDC_3 && tps->rev == TPS65218_REV_2_1) 150 return 0; 151 152 if (!tps->strobes[rid]) { 153 if (rid == TPS65218_DCDC_3) 154 tps->strobes[rid] = 3; 155 else 156 return -EINVAL; 157 } 158 159 return tps65218_set_bits(tps, dev->desc->bypass_reg, 160 dev->desc->bypass_mask, 161 tps->strobes[rid], TPS65218_PROTECT_L1); 162 } 163 164 /* Operations permitted on DCDC1, DCDC2 */ 165 static struct regulator_ops tps65218_dcdc12_ops = { 166 .is_enabled = regulator_is_enabled_regmap, 167 .enable = tps65218_pmic_enable, 168 .disable = tps65218_pmic_disable, 169 .get_voltage_sel = regulator_get_voltage_sel_regmap, 170 .set_voltage_sel = tps65218_pmic_set_voltage_sel, 171 .list_voltage = regulator_list_voltage_linear_range, 172 .map_voltage = regulator_map_voltage_linear_range, 173 .set_voltage_time_sel = regulator_set_voltage_time_sel, 174 .set_suspend_enable = tps65218_pmic_set_suspend_enable, 175 .set_suspend_disable = tps65218_pmic_set_suspend_disable, 176 }; 177 178 /* Operations permitted on DCDC3, DCDC4 and LDO1 */ 179 static struct regulator_ops tps65218_ldo1_dcdc34_ops = { 180 .is_enabled = regulator_is_enabled_regmap, 181 .enable = tps65218_pmic_enable, 182 .disable = tps65218_pmic_disable, 183 .get_voltage_sel = regulator_get_voltage_sel_regmap, 184 .set_voltage_sel = tps65218_pmic_set_voltage_sel, 185 .list_voltage = regulator_list_voltage_linear_range, 186 .map_voltage = regulator_map_voltage_linear_range, 187 .set_suspend_enable = tps65218_pmic_set_suspend_enable, 188 .set_suspend_disable = tps65218_pmic_set_suspend_disable, 189 }; 190 191 static const int ls3_currents[] = { 100, 200, 500, 1000 }; 192 193 static int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev, 194 int lim_uA) 195 { 196 unsigned int index = 0; 197 unsigned int num_currents = ARRAY_SIZE(ls3_currents); 198 struct tps65218 *tps = rdev_get_drvdata(dev); 199 200 while (index < num_currents && ls3_currents[index] != lim_uA) 201 index++; 202 203 if (index == num_currents) 204 return -EINVAL; 205 206 return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, 207 index << 2, TPS65218_PROTECT_L1); 208 } 209 210 static int tps65218_pmic_set_current_limit(struct regulator_dev *dev, 211 int min_uA, int max_uA) 212 { 213 int index = 0; 214 unsigned int num_currents = ARRAY_SIZE(ls3_currents); 215 struct tps65218 *tps = rdev_get_drvdata(dev); 216 217 while (index < num_currents && ls3_currents[index] < max_uA) 218 index++; 219 220 index--; 221 222 if (index < 0 || ls3_currents[index] < min_uA) 223 return -EINVAL; 224 225 return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, 226 index << 2, TPS65218_PROTECT_L1); 227 } 228 229 static int tps65218_pmic_get_current_limit(struct regulator_dev *dev) 230 { 231 int retval; 232 unsigned int index; 233 struct tps65218 *tps = rdev_get_drvdata(dev); 234 235 retval = regmap_read(tps->regmap, dev->desc->csel_reg, &index); 236 if (retval < 0) 237 return retval; 238 239 index = (index & dev->desc->csel_mask) >> 2; 240 241 return ls3_currents[index]; 242 } 243 244 static struct regulator_ops tps65218_ls3_ops = { 245 .is_enabled = regulator_is_enabled_regmap, 246 .enable = tps65218_pmic_enable, 247 .disable = tps65218_pmic_disable, 248 .set_input_current_limit = tps65218_pmic_set_input_current_lim, 249 .set_current_limit = tps65218_pmic_set_current_limit, 250 .get_current_limit = tps65218_pmic_get_current_limit, 251 }; 252 253 /* Operations permitted on DCDC5, DCDC6 */ 254 static struct regulator_ops tps65218_dcdc56_pmic_ops = { 255 .is_enabled = regulator_is_enabled_regmap, 256 .enable = tps65218_pmic_enable, 257 .disable = tps65218_pmic_disable, 258 .set_suspend_enable = tps65218_pmic_set_suspend_enable, 259 .set_suspend_disable = tps65218_pmic_set_suspend_disable, 260 }; 261 262 static const struct regulator_desc regulators[] = { 263 TPS65218_REGULATOR("DCDC1", "regulator-dcdc1", TPS65218_DCDC_1, 264 REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64, 265 TPS65218_REG_CONTROL_DCDC1, 266 TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, 267 TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges, 268 2, 4000, 0, TPS65218_REG_SEQ3, 269 TPS65218_SEQ3_DC1_SEQ_MASK), 270 TPS65218_REGULATOR("DCDC2", "regulator-dcdc2", TPS65218_DCDC_2, 271 REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64, 272 TPS65218_REG_CONTROL_DCDC2, 273 TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, 274 TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges, 275 2, 4000, 0, TPS65218_REG_SEQ3, 276 TPS65218_SEQ3_DC2_SEQ_MASK), 277 TPS65218_REGULATOR("DCDC3", "regulator-dcdc3", TPS65218_DCDC_3, 278 REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, 279 TPS65218_REG_CONTROL_DCDC3, 280 TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, 281 TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2, 282 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK), 283 TPS65218_REGULATOR("DCDC4", "regulator-dcdc4", TPS65218_DCDC_4, 284 REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 53, 285 TPS65218_REG_CONTROL_DCDC4, 286 TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, 287 TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2, 288 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK), 289 TPS65218_REGULATOR("DCDC5", "regulator-dcdc5", TPS65218_DCDC_5, 290 REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, 291 -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 292 0, NULL, 0, 0, 1000000, TPS65218_REG_SEQ5, 293 TPS65218_SEQ5_DC5_SEQ_MASK), 294 TPS65218_REGULATOR("DCDC6", "regulator-dcdc6", TPS65218_DCDC_6, 295 REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, 296 -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 297 0, NULL, 0, 0, 1800000, TPS65218_REG_SEQ5, 298 TPS65218_SEQ5_DC6_SEQ_MASK), 299 TPS65218_REGULATOR("LDO1", "regulator-ldo1", TPS65218_LDO_1, 300 REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, 301 TPS65218_REG_CONTROL_LDO1, 302 TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, 303 TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges, 304 2, 0, 0, TPS65218_REG_SEQ6, 305 TPS65218_SEQ6_LDO1_SEQ_MASK), 306 TPS65218_REGULATOR("LS3", "regulator-ls3", TPS65218_LS_3, 307 REGULATOR_CURRENT, tps65218_ls3_ops, 0, 0, 0, 308 TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN, 309 TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS3ILIM_MASK, 310 NULL, 0, 0, 0, 0, 0), 311 }; 312 313 static int tps65218_regulator_probe(struct platform_device *pdev) 314 { 315 struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent); 316 struct regulator_dev *rdev; 317 struct regulator_config config = { }; 318 int i, ret; 319 unsigned int val; 320 321 config.dev = &pdev->dev; 322 config.dev->of_node = tps->dev->of_node; 323 config.driver_data = tps; 324 config.regmap = tps->regmap; 325 326 /* Allocate memory for strobes */ 327 tps->strobes = devm_kzalloc(&pdev->dev, sizeof(u8) * 328 TPS65218_NUM_REGULATOR, GFP_KERNEL); 329 if (!tps->strobes) 330 return -ENOMEM; 331 332 for (i = 0; i < ARRAY_SIZE(regulators); i++) { 333 rdev = devm_regulator_register(&pdev->dev, ®ulators[i], 334 &config); 335 if (IS_ERR(rdev)) { 336 dev_err(tps->dev, "failed to register %s regulator\n", 337 pdev->name); 338 return PTR_ERR(rdev); 339 } 340 341 ret = regmap_read(tps->regmap, regulators[i].bypass_reg, &val); 342 if (ret) 343 return ret; 344 345 tps->strobes[i] = val & regulators[i].bypass_mask; 346 } 347 348 return 0; 349 } 350 351 static const struct platform_device_id tps65218_regulator_id_table[] = { 352 { "tps65218-regulator", }, 353 { /* sentinel */ } 354 }; 355 MODULE_DEVICE_TABLE(platform, tps65218_regulator_id_table); 356 357 static struct platform_driver tps65218_regulator_driver = { 358 .driver = { 359 .name = "tps65218-pmic", 360 }, 361 .probe = tps65218_regulator_probe, 362 .id_table = tps65218_regulator_id_table, 363 }; 364 365 module_platform_driver(tps65218_regulator_driver); 366 367 MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); 368 MODULE_DESCRIPTION("TPS65218 voltage regulator driver"); 369 MODULE_ALIAS("platform:tps65218-pmic"); 370 MODULE_LICENSE("GPL v2"); 371