1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com> 4 */ 5 6#include <dm.h> 7#include <power/pmic.h> 8#include <power/regulator.h> 9#include <power/tps65910_pmic.h> 10 11/* fist row is control registers, second is voltage registers */ 12static const char tps65911_vdd_reg[][TPS65911_VDD_NUM] = { 13 { TPS65911_REG_VDD1, TPS65911_REG_VDD2, 14 TPS65911_REG_VDDCTRL, TPS65911_REG_VIO }, 15 { TPS65911_REG_VDD1_OP, TPS65911_REG_VDD2_OP, 16 TPS65911_REG_VDDCTRL_OP, 0x00 }, 17}; 18 19static const char tps65911_ldo_reg[TPS65911_LDO_NUM] = { 20 TPS65911_REG_LDO1, TPS65911_REG_LDO2, TPS65911_REG_LDO3, 21 TPS65911_REG_LDO4, TPS65911_REG_LDO5, TPS65911_REG_LDO6, 22 TPS65911_REG_LDO7, TPS65911_REG_LDO8 23}; 24 25static int tps65911_regulator_enable(struct udevice *dev, int op, bool *enable) 26{ 27 struct dm_regulator_uclass_plat *uc_pdata = 28 dev_get_uclass_plat(dev); 29 u32 adr = uc_pdata->ctrl_reg; 30 int val, ret; 31 32 val = pmic_reg_read(dev->parent, adr); 33 if (val < 0) 34 return val; 35 36 if (op == PMIC_OP_GET) { 37 if (val & TPS65910_SUPPLY_STATE_ON) 38 *enable = true; 39 else 40 *enable = false; 41 42 return 0; 43 } else if (op == PMIC_OP_SET) { 44 val &= ~TPS65910_SUPPLY_STATE_MASK; 45 46 if (*enable) 47 val |= TPS65910_SUPPLY_STATE_ON; 48 49 ret = pmic_reg_write(dev->parent, adr, val); 50 if (ret) 51 return ret; 52 } 53 54 return 0; 55} 56 57static int tps65911_get_enable(struct udevice *dev) 58{ 59 bool enable = false; 60 int ret; 61 62 ret = tps65911_regulator_enable(dev, PMIC_OP_GET, &enable); 63 if (ret) 64 return ret; 65 66 return enable; 67} 68 69static int tps65911_set_enable(struct udevice *dev, bool enable) 70{ 71 return tps65911_regulator_enable(dev, PMIC_OP_SET, &enable); 72} 73 74/** 75 * tps65911_vdd_volt2hex() - convert voltage in uV into 76 * applicable to register hex value 77 * 78 * @uV: voltage in uV 79 * 80 * Return: voltage in hex on success, -ve on failure 81 */ 82static int tps65911_vdd_volt2hex(int uV) 83{ 84 if (uV > TPS65911_VDD_VOLT_MAX) 85 return -EINVAL; 86 87 if (uV < TPS65911_VDD_VOLT_MIN) 88 uV = TPS65911_VDD_VOLT_MIN; 89 90 return (uV - TPS65911_VDD_VOLT_BASE) / 12500; 91} 92 93/** 94 * tps65911_vdd_hex2volt() - convert register hex value into 95 * actual voltage in uV 96 * 97 * @hex: hex value of register 98 * 99 * Return: voltage in uV on success, -ve on failure 100 */ 101static int tps65911_vdd_hex2volt(int hex) 102{ 103 if (hex > TPS65910_VDD_SEL_MAX) 104 return -EINVAL; 105 106 if (hex < TPS65910_VDD_SEL_MIN) 107 hex = TPS65910_VDD_SEL_MIN; 108 109 return TPS65911_VDD_VOLT_BASE + hex * 12500; 110} 111 112static int tps65911_vio_range[4] = { 113 1500000, 1800000, 2500000, 3300000 114}; 115 116static int tps65911_vio_val(struct udevice *dev, int op, int *uV) 117{ 118 struct dm_regulator_uclass_plat *uc_pdata = 119 dev_get_uclass_plat(dev); 120 u32 adr = uc_pdata->volt_reg; 121 int i, val; 122 123 val = pmic_reg_read(dev->parent, adr); 124 if (val < 0) 125 return val; 126 127 if (op == PMIC_OP_GET) { 128 *uV = 0; 129 130 val &= TPS65910_SEL_MASK; 131 132 *uV = tps65911_vio_range[val >> 2]; 133 134 return 0; 135 } 136 137 val &= ~TPS65910_SEL_MASK; 138 139 for (i = 0; i < ARRAY_SIZE(tps65911_vio_range); i++) 140 if (*uV <= tps65911_vio_range[i]) 141 break; 142 143 return pmic_reg_write(dev->parent, adr, val | i << 2); 144} 145 146static int tps65911_vdd_val(struct udevice *dev, int op, int *uV) 147{ 148 struct dm_regulator_uclass_plat *uc_pdata = 149 dev_get_uclass_plat(dev); 150 u32 adr = uc_pdata->volt_reg; 151 int val, ret; 152 153 /* in case vdd is vio */ 154 if (!adr) 155 return tps65911_vio_val(dev, op, uV); 156 157 val = pmic_reg_read(dev->parent, adr); 158 if (val < 0) 159 return val; 160 161 if (op == PMIC_OP_GET) { 162 *uV = 0; 163 164 ret = tps65911_vdd_hex2volt(val); 165 if (ret < 0) 166 return ret; 167 168 *uV = ret; 169 return 0; 170 } 171 172 val = tps65911_vdd_volt2hex(*uV); 173 if (val < 0) 174 return val; 175 176 return pmic_reg_write(dev->parent, adr, val); 177} 178 179static int tps65911_vdd_probe(struct udevice *dev) 180{ 181 struct dm_regulator_uclass_plat *uc_pdata = 182 dev_get_uclass_plat(dev); 183 184 uc_pdata->type = REGULATOR_TYPE_BUCK; 185 186 /* check for vddctrl and vddio cases */ 187 if (!strcmp("vddctrl", dev->name)) { 188 uc_pdata->ctrl_reg = tps65911_vdd_reg[0][2]; 189 uc_pdata->volt_reg = tps65911_vdd_reg[1][2]; 190 return 0; 191 } 192 193 if (!strcmp("vddio", dev->name)) { 194 uc_pdata->ctrl_reg = tps65911_vdd_reg[0][3]; 195 uc_pdata->volt_reg = tps65911_vdd_reg[1][3]; 196 return 0; 197 } 198 199 if (dev->driver_data > 0) { 200 u8 idx = dev->driver_data - 1; 201 202 uc_pdata->ctrl_reg = tps65911_vdd_reg[0][idx]; 203 uc_pdata->volt_reg = tps65911_vdd_reg[1][idx]; 204 } 205 206 return 0; 207} 208 209static int vdd_get_value(struct udevice *dev) 210{ 211 int uV; 212 int ret; 213 214 ret = tps65911_vdd_val(dev, PMIC_OP_GET, &uV); 215 if (ret) 216 return ret; 217 218 return uV; 219} 220 221static int vdd_set_value(struct udevice *dev, int uV) 222{ 223 return tps65911_vdd_val(dev, PMIC_OP_SET, &uV); 224} 225 226static const struct dm_regulator_ops tps65911_vdd_ops = { 227 .get_value = vdd_get_value, 228 .set_value = vdd_set_value, 229 .get_enable = tps65911_get_enable, 230 .set_enable = tps65911_set_enable, 231}; 232 233U_BOOT_DRIVER(tps65911_vdd) = { 234 .name = TPS65911_VDD_DRIVER, 235 .id = UCLASS_REGULATOR, 236 .ops = &tps65911_vdd_ops, 237 .probe = tps65911_vdd_probe, 238}; 239 240/** 241 * tps65911_ldo_volt2hex() - convert voltage in uV into 242 * applicable to register hex value 243 * 244 * @idx: regulator index 245 * @uV: voltage in uV 246 * 247 * Return: voltage in hex on success, -ve on failure 248 */ 249static int tps65911_ldo_volt2hex(int idx, int uV) 250{ 251 int step; 252 253 if (uV > TPS65911_LDO_VOLT_MAX) 254 return -EINVAL; 255 256 if (uV < TPS65911_LDO_VOLT_BASE) 257 uV = TPS65911_LDO_VOLT_BASE; 258 259 switch (idx) { 260 case 1: 261 case 2: 262 case 4: 263 step = TPS65911_LDO124_VOLT_STEP; 264 break; 265 case 3: 266 case 5: 267 case 6: 268 case 7: 269 case 8: 270 step = TPS65911_LDO358_VOLT_STEP; 271 break; 272 default: 273 return -EINVAL; 274 }; 275 276 return ((uV - TPS65911_LDO_VOLT_BASE) / step) << 2; 277} 278 279/** 280 * tps65911_ldo_hex2volt() - convert register hex value into 281 * actual voltage in uV 282 * 283 * @idx: regulator index 284 * @hex: hex value of register 285 * 286 * Return: voltage in uV on success, -ve on failure 287 */ 288static int tps65911_ldo_hex2volt(int idx, int hex) 289{ 290 int step; 291 292 switch (idx) { 293 case 1: 294 case 2: 295 case 4: 296 if (hex > TPS65911_LDO124_VOLT_MAX_HEX) 297 return -EINVAL; 298 299 step = TPS65911_LDO124_VOLT_STEP; 300 break; 301 case 3: 302 case 5: 303 case 6: 304 case 7: 305 case 8: 306 if (hex > TPS65911_LDO358_VOLT_MAX_HEX) 307 return -EINVAL; 308 309 if (hex < TPS65911_LDO358_VOLT_MIN_HEX) 310 hex = TPS65911_LDO358_VOLT_MIN_HEX; 311 312 step = TPS65911_LDO358_VOLT_STEP; 313 break; 314 default: 315 return -EINVAL; 316 }; 317 318 return TPS65911_LDO_VOLT_BASE + hex * step; 319} 320 321static int tps65911_ldo_val(struct udevice *dev, int op, int *uV) 322{ 323 struct dm_regulator_uclass_plat *uc_pdata = 324 dev_get_uclass_plat(dev); 325 u32 adr = uc_pdata->ctrl_reg; 326 int idx = dev->driver_data; 327 int val, hex, ret; 328 329 val = pmic_reg_read(dev->parent, adr); 330 if (val < 0) 331 return val; 332 333 if (op == PMIC_OP_GET) { 334 *uV = 0; 335 val &= TPS65911_LDO_SEL_MASK; 336 337 ret = tps65911_ldo_hex2volt(idx, val >> 2); 338 if (ret < 0) 339 return ret; 340 341 *uV = ret; 342 return 0; 343 } 344 345 hex = tps65911_ldo_volt2hex(idx, *uV); 346 if (hex < 0) 347 return hex; 348 349 val &= ~TPS65911_LDO_SEL_MASK; 350 351 return pmic_reg_write(dev->parent, adr, val | hex); 352} 353 354static int tps65911_ldo_probe(struct udevice *dev) 355{ 356 struct dm_regulator_uclass_plat *uc_pdata = 357 dev_get_uclass_plat(dev); 358 u8 idx = dev->driver_data - 1; 359 360 uc_pdata->type = REGULATOR_TYPE_LDO; 361 uc_pdata->ctrl_reg = tps65911_ldo_reg[idx]; 362 363 return 0; 364} 365 366static int ldo_get_value(struct udevice *dev) 367{ 368 int uV; 369 int ret; 370 371 ret = tps65911_ldo_val(dev, PMIC_OP_GET, &uV); 372 if (ret) 373 return ret; 374 375 return uV; 376} 377 378static int ldo_set_value(struct udevice *dev, int uV) 379{ 380 return tps65911_ldo_val(dev, PMIC_OP_SET, &uV); 381} 382 383static const struct dm_regulator_ops tps65911_ldo_ops = { 384 .get_value = ldo_get_value, 385 .set_value = ldo_set_value, 386 .get_enable = tps65911_get_enable, 387 .set_enable = tps65911_set_enable, 388}; 389 390U_BOOT_DRIVER(tps65911_ldo) = { 391 .name = TPS65911_LDO_DRIVER, 392 .id = UCLASS_REGULATOR, 393 .ops = &tps65911_ldo_ops, 394 .probe = tps65911_ldo_probe, 395}; 396