1 /* 2 * Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <power/pmic.h> 10 #include <power/regulator.h> 11 #include <power/tps65910_pmic.h> 12 13 #define VOUT_CHOICE_COUNT 4 14 15 /* 16 * struct regulator_props - Properties of a LDO and VIO SMPS regulator 17 * 18 * All of these regulators allow setting one out of four output voltages. 19 * These output voltages are only achievable when supplying the regulator 20 * with a minimum input voltage. 21 * 22 * @vin_min[]: minimum supply input voltage in uV required to achieve the 23 * corresponding vout[] voltage 24 * @vout[]: regulator output voltage in uV 25 * @reg: I2C register used to set regulator voltage 26 */ 27 struct regulator_props { 28 int vin_min[VOUT_CHOICE_COUNT]; 29 int vout[VOUT_CHOICE_COUNT]; 30 int reg; 31 }; 32 33 static const struct regulator_props ldo_props_vdig1 = { 34 .vin_min = { 1700000, 2100000, 2700000, 3200000 }, 35 .vout = { 1200000, 1500000, 1800000, 2700000 }, 36 .reg = TPS65910_REG_VDIG1 37 }; 38 39 static const struct regulator_props ldo_props_vdig2 = { 40 .vin_min = { 1700000, 1700000, 1700000, 2700000 }, 41 .vout = { 1000000, 1100000, 1200000, 1800000 }, 42 .reg = TPS65910_REG_VDIG2 43 }; 44 45 static const struct regulator_props ldo_props_vpll = { 46 .vin_min = { 2700000, 2700000, 2700000, 3000000 }, 47 .vout = { 1000000, 1100000, 1800000, 2500000 }, 48 .reg = TPS65910_REG_VPLL 49 }; 50 51 static const struct regulator_props ldo_props_vdac = { 52 .vin_min = { 2700000, 3000000, 3200000, 3200000 }, 53 .vout = { 1800000, 2600000, 2800000, 2850000 }, 54 .reg = TPS65910_REG_VDAC 55 }; 56 57 static const struct regulator_props ldo_props_vaux1 = { 58 .vin_min = { 2700000, 3200000, 3200000, 3200000 }, 59 .vout = { 1800000, 2500000, 2800000, 2850000 }, 60 .reg = TPS65910_REG_VAUX1 61 }; 62 63 static const struct regulator_props ldo_props_vaux2 = { 64 .vin_min = { 2700000, 3200000, 3200000, 3600000 }, 65 .vout = { 1800000, 2800000, 2900000, 3300000 }, 66 .reg = TPS65910_REG_VAUX2 67 }; 68 69 static const struct regulator_props ldo_props_vaux33 = { 70 .vin_min = { 2700000, 2700000, 3200000, 3600000 }, 71 .vout = { 1800000, 2000000, 2800000, 3300000 }, 72 .reg = TPS65910_REG_VAUX33 73 }; 74 75 static const struct regulator_props ldo_props_vmmc = { 76 .vin_min = { 2700000, 3200000, 3200000, 3600000 }, 77 .vout = { 1800000, 2800000, 3000000, 3300000 }, 78 .reg = TPS65910_REG_VMMC 79 }; 80 81 static const struct regulator_props smps_props_vio = { 82 .vin_min = { 3200000, 3200000, 4000000, 4400000 }, 83 .vout = { 1500000, 1800000, 2500000, 3300000 }, 84 .reg = TPS65910_REG_VIO 85 }; 86 87 /* lookup table of control registers indexed by regulator unit number */ 88 static const int ctrl_regs[] = { 89 TPS65910_REG_VRTC, 90 TPS65910_REG_VIO, 91 TPS65910_REG_VDD1, 92 TPS65910_REG_VDD2, 93 TPS65910_REG_VDD3, 94 TPS65910_REG_VDIG1, 95 TPS65910_REG_VDIG2, 96 TPS65910_REG_VPLL, 97 TPS65910_REG_VDAC, 98 TPS65910_REG_VAUX1, 99 TPS65910_REG_VAUX2, 100 TPS65910_REG_VAUX33, 101 TPS65910_REG_VMMC 102 }; 103 104 /* supply names as used in DT */ 105 static const char * const supply_names[] = { 106 "vccio-supply", 107 "vcc1-supply", 108 "vcc2-supply", 109 "vcc3-supply", 110 "vcc4-supply", 111 "vcc5-supply", 112 "vcc6-supply", 113 "vcc7-supply" 114 }; 115 116 /* lookup table of regulator supplies indexed by regulator unit number */ 117 static const int regulator_supplies[] = { 118 TPS65910_SUPPLY_VCC7, 119 TPS65910_SUPPLY_VCCIO, 120 TPS65910_SUPPLY_VCC1, 121 TPS65910_SUPPLY_VCC2, 122 TPS65910_SUPPLY_VCC7, 123 TPS65910_SUPPLY_VCC6, 124 TPS65910_SUPPLY_VCC6, 125 TPS65910_SUPPLY_VCC5, 126 TPS65910_SUPPLY_VCC5, 127 TPS65910_SUPPLY_VCC4, 128 TPS65910_SUPPLY_VCC4, 129 TPS65910_SUPPLY_VCC3, 130 TPS65910_SUPPLY_VCC3 131 }; 132 133 static int get_ctrl_reg_from_unit_addr(const uint unit_addr) 134 { 135 if (unit_addr < ARRAY_SIZE(ctrl_regs)) 136 return ctrl_regs[unit_addr]; 137 return -ENXIO; 138 } 139 140 static int tps65910_regulator_get_value(struct udevice *dev, 141 const struct regulator_props *rgp) 142 { 143 int sel, val, vout; 144 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 145 int vin = pdata->supply; 146 147 val = pmic_reg_read(dev->parent, rgp->reg); 148 if (val < 0) 149 return val; 150 sel = (val & TPS65910_SEL_MASK) >> 2; 151 vout = (vin >= *(rgp->vin_min + sel)) ? *(rgp->vout + sel) : 0; 152 vout = ((val & TPS65910_SUPPLY_STATE_MASK) == 1) ? vout : 0; 153 154 return vout; 155 } 156 157 static int tps65910_ldo_get_value(struct udevice *dev) 158 { 159 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 160 int vin; 161 162 if (!pdata) 163 return 0; 164 vin = pdata->supply; 165 166 switch (pdata->unit) { 167 case TPS65910_UNIT_VRTC: 168 /* VRTC is fixed and can't be turned off */ 169 return (vin >= 2500000) ? 1830000 : 0; 170 case TPS65910_UNIT_VDIG1: 171 return tps65910_regulator_get_value(dev, &ldo_props_vdig1); 172 case TPS65910_UNIT_VDIG2: 173 return tps65910_regulator_get_value(dev, &ldo_props_vdig2); 174 case TPS65910_UNIT_VPLL: 175 return tps65910_regulator_get_value(dev, &ldo_props_vpll); 176 case TPS65910_UNIT_VDAC: 177 return tps65910_regulator_get_value(dev, &ldo_props_vdac); 178 case TPS65910_UNIT_VAUX1: 179 return tps65910_regulator_get_value(dev, &ldo_props_vaux1); 180 case TPS65910_UNIT_VAUX2: 181 return tps65910_regulator_get_value(dev, &ldo_props_vaux2); 182 case TPS65910_UNIT_VAUX33: 183 return tps65910_regulator_get_value(dev, &ldo_props_vaux33); 184 case TPS65910_UNIT_VMMC: 185 return tps65910_regulator_get_value(dev, &ldo_props_vmmc); 186 default: 187 return 0; 188 } 189 } 190 191 static int tps65910_regulator_set_value(struct udevice *dev, 192 const struct regulator_props *ldo, 193 int uV) 194 { 195 int val; 196 int sel = 0; 197 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 198 199 do { 200 /* we only allow exact voltage matches */ 201 if (uV == *(ldo->vout + sel)) 202 break; 203 } while (++sel < VOUT_CHOICE_COUNT); 204 if (sel == VOUT_CHOICE_COUNT) 205 return -EINVAL; 206 if (pdata->supply < *(ldo->vin_min + sel)) 207 return -EINVAL; 208 209 val = pmic_reg_read(dev->parent, ldo->reg); 210 if (val < 0) 211 return val; 212 val &= ~TPS65910_SEL_MASK; 213 val |= sel << 2; 214 return pmic_reg_write(dev->parent, ldo->reg, val); 215 } 216 217 static int tps65910_ldo_set_value(struct udevice *dev, int uV) 218 { 219 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 220 int vin = pdata->supply; 221 222 switch (pdata->unit) { 223 case TPS65910_UNIT_VRTC: 224 /* VRTC is fixed to 1.83V and can't be turned off */ 225 if (vin < 2500000) 226 return -EINVAL; 227 return 0; 228 case TPS65910_UNIT_VDIG1: 229 return tps65910_regulator_set_value(dev, &ldo_props_vdig1, uV); 230 case TPS65910_UNIT_VDIG2: 231 return tps65910_regulator_set_value(dev, &ldo_props_vdig2, uV); 232 case TPS65910_UNIT_VPLL: 233 return tps65910_regulator_set_value(dev, &ldo_props_vpll, uV); 234 case TPS65910_UNIT_VDAC: 235 return tps65910_regulator_set_value(dev, &ldo_props_vdac, uV); 236 case TPS65910_UNIT_VAUX1: 237 return tps65910_regulator_set_value(dev, &ldo_props_vaux1, uV); 238 case TPS65910_UNIT_VAUX2: 239 return tps65910_regulator_set_value(dev, &ldo_props_vaux2, uV); 240 case TPS65910_UNIT_VAUX33: 241 return tps65910_regulator_set_value(dev, &ldo_props_vaux33, uV); 242 case TPS65910_UNIT_VMMC: 243 return tps65910_regulator_set_value(dev, &ldo_props_vmmc, uV); 244 default: 245 return 0; 246 } 247 } 248 249 static int tps65910_get_enable(struct udevice *dev) 250 { 251 int reg, val; 252 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 253 254 reg = get_ctrl_reg_from_unit_addr(pdata->unit); 255 if (reg < 0) 256 return reg; 257 258 val = pmic_reg_read(dev->parent, reg); 259 if (val < 0) 260 return val; 261 262 /* bits 1:0 of regulator control register define state */ 263 return ((val & TPS65910_SUPPLY_STATE_MASK) == 1); 264 } 265 266 static int tps65910_set_enable(struct udevice *dev, bool enable) 267 { 268 int reg; 269 uint clr, set; 270 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 271 272 reg = get_ctrl_reg_from_unit_addr(pdata->unit); 273 if (reg < 0) 274 return reg; 275 276 if (enable) { 277 clr = TPS65910_SUPPLY_STATE_MASK & ~TPS65910_SUPPLY_STATE_ON; 278 set = TPS65910_SUPPLY_STATE_MASK & TPS65910_SUPPLY_STATE_ON; 279 } else { 280 clr = TPS65910_SUPPLY_STATE_MASK & ~TPS65910_SUPPLY_STATE_OFF; 281 set = TPS65910_SUPPLY_STATE_MASK & TPS65910_SUPPLY_STATE_OFF; 282 } 283 return pmic_clrsetbits(dev->parent, reg, clr, set); 284 } 285 286 static int buck_get_vdd1_vdd2_value(struct udevice *dev, int reg_vdd) 287 { 288 int gain; 289 int val = pmic_reg_read(dev, reg_vdd); 290 291 if (val < 0) 292 return val; 293 gain = (val & TPS65910_GAIN_SEL_MASK) >> 6; 294 gain = (gain == 0) ? 1 : gain; 295 val = pmic_reg_read(dev, reg_vdd + 1); 296 if (val < 0) 297 return val; 298 if (val & TPS65910_VDD_SR_MASK) 299 /* use smart reflex value instead */ 300 val = pmic_reg_read(dev, reg_vdd + 2); 301 if (val < 0) 302 return val; 303 return (562500 + (val & TPS65910_VDD_SEL_MASK) * 12500) * gain; 304 } 305 306 static int tps65910_buck_get_value(struct udevice *dev) 307 { 308 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 309 310 switch (pdata->unit) { 311 case TPS65910_UNIT_VIO: 312 return tps65910_regulator_get_value(dev, &smps_props_vio); 313 case TPS65910_UNIT_VDD1: 314 return buck_get_vdd1_vdd2_value(dev->parent, TPS65910_REG_VDD1); 315 case TPS65910_UNIT_VDD2: 316 return buck_get_vdd1_vdd2_value(dev->parent, TPS65910_REG_VDD2); 317 default: 318 return 0; 319 } 320 } 321 322 static int buck_set_vdd1_vdd2_value(struct udevice *dev, int uV) 323 { 324 int ret, reg_vdd, gain; 325 int val; 326 struct dm_regulator_uclass_platdata *uc_pdata; 327 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 328 329 switch (pdata->unit) { 330 case TPS65910_UNIT_VDD1: 331 reg_vdd = TPS65910_REG_VDD1; 332 break; 333 case TPS65910_UNIT_VDD2: 334 reg_vdd = TPS65910_REG_VDD2; 335 break; 336 default: 337 return -EINVAL; 338 } 339 uc_pdata = dev_get_uclass_platdata(dev); 340 341 /* check setpoint is within limits */ 342 if (uV < uc_pdata->min_uV) { 343 pr_err("voltage %duV for %s too low\n", uV, dev->name); 344 return -EINVAL; 345 } 346 if (uV > uc_pdata->max_uV) { 347 pr_err("voltage %duV for %s too high\n", uV, dev->name); 348 return -EINVAL; 349 } 350 351 val = pmic_reg_read(dev->parent, reg_vdd); 352 if (val < 0) 353 return val; 354 gain = (val & TPS65910_GAIN_SEL_MASK) >> 6; 355 gain = (gain == 0) ? 1 : gain; 356 val = ((uV / gain) - 562500) / 12500; 357 if (val < TPS65910_VDD_SEL_MIN || val > TPS65910_VDD_SEL_MAX) 358 /* 359 * Neither do we change the gain, nor do we allow shutdown or 360 * any approximate value (for now) 361 */ 362 return -EPERM; 363 val &= TPS65910_VDD_SEL_MASK; 364 ret = pmic_reg_write(dev->parent, reg_vdd + 1, val); 365 if (ret) 366 return ret; 367 return 0; 368 } 369 370 static int tps65910_buck_set_value(struct udevice *dev, int uV) 371 { 372 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 373 374 if (pdata->unit == TPS65910_UNIT_VIO) 375 return tps65910_regulator_set_value(dev, &smps_props_vio, uV); 376 377 return buck_set_vdd1_vdd2_value(dev, uV); 378 } 379 380 static int tps65910_boost_get_value(struct udevice *dev) 381 { 382 int vout; 383 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 384 385 vout = (pdata->supply >= 3000000) ? 5000000 : 0; 386 return vout; 387 } 388 389 static int tps65910_regulator_ofdata_to_platdata(struct udevice *dev) 390 { 391 struct udevice *supply; 392 int ret; 393 const char *supply_name; 394 struct tps65910_regulator_pdata *pdata = dev_get_platdata(dev); 395 396 pdata->unit = dev_get_driver_data(dev); 397 if (pdata->unit > TPS65910_UNIT_VMMC) 398 return -EINVAL; 399 supply_name = supply_names[regulator_supplies[pdata->unit]]; 400 401 debug("Looking up supply power %s\n", supply_name); 402 ret = device_get_supply_regulator(dev->parent, supply_name, &supply); 403 if (ret) { 404 debug(" missing supply power %s\n", supply_name); 405 return ret; 406 } 407 pdata->supply = regulator_get_value(supply); 408 if (pdata->supply < 0) { 409 debug(" invalid supply voltage for regulator %s\n", 410 supply->name); 411 return -EINVAL; 412 } 413 414 return 0; 415 } 416 417 static const struct dm_regulator_ops tps65910_boost_ops = { 418 .get_value = tps65910_boost_get_value, 419 .get_enable = tps65910_get_enable, 420 .set_enable = tps65910_set_enable, 421 }; 422 423 U_BOOT_DRIVER(tps65910_boost) = { 424 .name = TPS65910_BOOST_DRIVER, 425 .id = UCLASS_REGULATOR, 426 .ops = &tps65910_boost_ops, 427 .platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata), 428 .ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata, 429 }; 430 431 static const struct dm_regulator_ops tps65910_buck_ops = { 432 .get_value = tps65910_buck_get_value, 433 .set_value = tps65910_buck_set_value, 434 .get_enable = tps65910_get_enable, 435 .set_enable = tps65910_set_enable, 436 }; 437 438 U_BOOT_DRIVER(tps65910_buck) = { 439 .name = TPS65910_BUCK_DRIVER, 440 .id = UCLASS_REGULATOR, 441 .ops = &tps65910_buck_ops, 442 .platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata), 443 .ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata, 444 }; 445 446 static const struct dm_regulator_ops tps65910_ldo_ops = { 447 .get_value = tps65910_ldo_get_value, 448 .set_value = tps65910_ldo_set_value, 449 .get_enable = tps65910_get_enable, 450 .set_enable = tps65910_set_enable, 451 }; 452 453 U_BOOT_DRIVER(tps65910_ldo) = { 454 .name = TPS65910_LDO_DRIVER, 455 .id = UCLASS_REGULATOR, 456 .ops = &tps65910_ldo_ops, 457 .platdata_auto_alloc_size = sizeof(struct tps65910_regulator_pdata), 458 .ofdata_to_platdata = tps65910_regulator_ofdata_to_platdata, 459 }; 460