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