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