1 /* 2 * (C) Copyright 2016 3 * Texas Instruments Incorporated, <www.ti.com> 4 * 5 * Keerthy <j-keerthy@ti.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <fdtdec.h> 12 #include <errno.h> 13 #include <dm.h> 14 #include <i2c.h> 15 #include <power/pmic.h> 16 #include <power/regulator.h> 17 #include <power/palmas.h> 18 19 #define REGULATOR_ON 0x1 20 #define REGULATOR_OFF 0x0 21 22 #define SMPS_MODE_MASK 0x3 23 #define SMPS_MODE_SHIFT 0x0 24 #define LDO_MODE_MASK 0x1 25 #define LDO_MODE_SHIFT 0x0 26 27 static const char palmas_smps_ctrl[][PALMAS_SMPS_NUM] = { 28 {0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c}, 29 {0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38}, 30 {0x20, 0x24, 0x2c, 0x30, 0x38}, 31 }; 32 33 static const char palmas_smps_volt[][PALMAS_SMPS_NUM] = { 34 {0x23, 0x27, 0x2b, 0x2f, 0x33, 0x37, 0x3b, 0x3c}, 35 {0x23, 0x27, 0x2b, 0x2f, 0x33, 0x37, 0x3b}, 36 {0x23, 0x27, 0x2f, 0x33, 0x3B} 37 }; 38 39 static const char palmas_ldo_ctrl[][PALMAS_LDO_NUM] = { 40 {0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64}, 41 {0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64}, 42 {0x50, 0x52, 0x54, 0x5e, 0x62} 43 }; 44 45 static const char palmas_ldo_volt[][PALMAS_LDO_NUM] = { 46 {0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f, 0x61, 0x63, 0x65}, 47 {0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f, 0x61, 0x63, 0x65}, 48 {0x51, 0x53, 0x55, 0x5f, 0x63} 49 }; 50 51 static int palmas_smps_enable(struct udevice *dev, int op, bool *enable) 52 { 53 int ret; 54 unsigned int adr; 55 struct dm_regulator_uclass_platdata *uc_pdata; 56 57 uc_pdata = dev_get_uclass_platdata(dev); 58 adr = uc_pdata->ctrl_reg; 59 60 ret = pmic_reg_read(dev->parent, adr); 61 if (ret < 0) 62 return ret; 63 64 if (op == PMIC_OP_GET) { 65 ret &= PALMAS_SMPS_STATUS_MASK; 66 67 if (ret) 68 *enable = true; 69 else 70 *enable = false; 71 72 return 0; 73 } else if (op == PMIC_OP_SET) { 74 if (*enable) 75 ret |= PALMAS_SMPS_MODE_MASK; 76 else 77 ret &= ~(PALMAS_SMPS_MODE_MASK); 78 79 ret = pmic_reg_write(dev->parent, adr, ret); 80 if (ret) 81 return ret; 82 } 83 84 return 0; 85 } 86 87 static int palmas_smps_volt2hex(int uV) 88 { 89 if (uV > PALMAS_LDO_VOLT_MAX) 90 return -EINVAL; 91 92 if (uV > 1650000) 93 return (uV - 1000000) / 20000 + 0x6; 94 95 if (uV == 500000) 96 return 0x6; 97 else 98 return 0x6 + ((uV - 500000) / 10000); 99 } 100 101 static int palmas_smps_hex2volt(int hex, bool range) 102 { 103 unsigned int uV = 0; 104 105 if (hex > PALMAS_SMPS_VOLT_MAX_HEX) 106 return -EINVAL; 107 108 if (hex < 0x7) 109 uV = 500000; 110 else 111 uV = 500000 + (hex - 0x6) * 10000; 112 113 if (range) 114 uV *= 2; 115 116 return uV; 117 } 118 119 static int palmas_smps_val(struct udevice *dev, int op, int *uV) 120 { 121 unsigned int hex, adr; 122 int ret; 123 bool range; 124 struct dm_regulator_uclass_platdata *uc_pdata; 125 126 uc_pdata = dev_get_uclass_platdata(dev); 127 128 if (op == PMIC_OP_GET) 129 *uV = 0; 130 131 adr = uc_pdata->volt_reg; 132 133 ret = pmic_reg_read(dev->parent, adr); 134 if (ret < 0) 135 return ret; 136 137 if (op == PMIC_OP_GET) { 138 if (ret & PALMAS_SMPS_RANGE_MASK) 139 range = true; 140 else 141 range = false; 142 143 ret &= PALMAS_SMPS_VOLT_MASK; 144 ret = palmas_smps_hex2volt(ret, range); 145 if (ret < 0) 146 return ret; 147 *uV = ret; 148 149 return 0; 150 } 151 152 hex = palmas_smps_volt2hex(*uV); 153 if (hex < 0) 154 return hex; 155 156 ret &= ~PALMAS_SMPS_VOLT_MASK; 157 ret |= hex; 158 if (*uV > 1650000) 159 ret |= PALMAS_SMPS_RANGE_MASK; 160 161 return pmic_reg_write(dev->parent, adr, ret); 162 } 163 164 static int palmas_ldo_bypass_enable(struct udevice *dev, bool enabled) 165 { 166 int type = dev_get_driver_data(dev_get_parent(dev)); 167 struct dm_regulator_uclass_platdata *p; 168 unsigned int adr; 169 int reg; 170 171 if (type == TPS65917) { 172 /* bypass available only on LDO1 and LDO2 */ 173 if (dev->driver_data > 2) 174 return -ENOTSUPP; 175 } else if (type == TPS659038) { 176 /* bypass available only on LDO9 */ 177 if (dev->driver_data != 9) 178 return -ENOTSUPP; 179 } 180 181 p = dev_get_uclass_platdata(dev); 182 adr = p->ctrl_reg; 183 184 reg = pmic_reg_read(dev->parent, adr); 185 if (reg < 0) 186 return reg; 187 188 if (enabled) 189 reg |= PALMAS_LDO_BYPASS_EN; 190 else 191 reg &= ~PALMAS_LDO_BYPASS_EN; 192 193 return pmic_reg_write(dev->parent, adr, reg); 194 } 195 196 static int palmas_ldo_enable(struct udevice *dev, int op, bool *enable) 197 { 198 int ret; 199 unsigned int adr; 200 struct dm_regulator_uclass_platdata *uc_pdata; 201 202 uc_pdata = dev_get_uclass_platdata(dev); 203 adr = uc_pdata->ctrl_reg; 204 205 ret = pmic_reg_read(dev->parent, adr); 206 if (ret < 0) 207 return ret; 208 209 if (op == PMIC_OP_GET) { 210 ret &= PALMAS_LDO_STATUS_MASK; 211 212 if (ret) 213 *enable = true; 214 else 215 *enable = false; 216 217 return 0; 218 } else if (op == PMIC_OP_SET) { 219 if (*enable) 220 ret |= PALMAS_LDO_MODE_MASK; 221 else 222 ret &= ~(PALMAS_LDO_MODE_MASK); 223 224 ret = pmic_reg_write(dev->parent, adr, ret); 225 if (ret) 226 return ret; 227 228 ret = palmas_ldo_bypass_enable(dev, false); 229 if (ret && (ret != -ENOTSUPP)) 230 return ret; 231 } 232 233 return 0; 234 } 235 236 static int palmas_ldo_volt2hex(int uV) 237 { 238 if (uV > PALMAS_LDO_VOLT_MAX) 239 return -EINVAL; 240 241 return (uV - 850000) / 50000; 242 } 243 244 static int palmas_ldo_hex2volt(int hex) 245 { 246 if (hex > PALMAS_LDO_VOLT_MAX_HEX) 247 return -EINVAL; 248 249 if (!hex) 250 return 0; 251 252 return (hex * 50000) + 850000; 253 } 254 255 static int palmas_ldo_val(struct udevice *dev, int op, int *uV) 256 { 257 unsigned int hex, adr; 258 int ret; 259 260 struct dm_regulator_uclass_platdata *uc_pdata; 261 262 if (op == PMIC_OP_GET) 263 *uV = 0; 264 265 uc_pdata = dev_get_uclass_platdata(dev); 266 267 adr = uc_pdata->volt_reg; 268 269 ret = pmic_reg_read(dev->parent, adr); 270 if (ret < 0) 271 return ret; 272 273 if (op == PMIC_OP_GET) { 274 ret &= PALMAS_LDO_VOLT_MASK; 275 ret = palmas_ldo_hex2volt(ret); 276 if (ret < 0) 277 return ret; 278 *uV = ret; 279 return 0; 280 } 281 282 hex = palmas_ldo_volt2hex(*uV); 283 if (hex < 0) 284 return hex; 285 286 ret &= ~PALMAS_LDO_VOLT_MASK; 287 ret |= hex; 288 if (*uV > 1650000) 289 ret |= 0x80; 290 291 return pmic_reg_write(dev->parent, adr, ret); 292 } 293 294 static int palmas_ldo_probe(struct udevice *dev) 295 { 296 struct dm_regulator_uclass_platdata *uc_pdata; 297 struct udevice *parent; 298 299 uc_pdata = dev_get_uclass_platdata(dev); 300 301 parent = dev_get_parent(dev); 302 int type = dev_get_driver_data(parent); 303 304 uc_pdata->type = REGULATOR_TYPE_LDO; 305 306 if (dev->driver_data) { 307 u8 idx = dev->driver_data - 1; 308 uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][idx]; 309 uc_pdata->volt_reg = palmas_ldo_volt[type][idx]; 310 } else { 311 /* check for ldoln and ldousb cases */ 312 if (!strcmp("ldoln", dev->name)) { 313 uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][9]; 314 uc_pdata->volt_reg = palmas_ldo_volt[type][9]; 315 } else if (!strcmp("ldousb", dev->name)) { 316 uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][10]; 317 uc_pdata->volt_reg = palmas_ldo_volt[type][10]; 318 } 319 } 320 321 return 0; 322 } 323 324 static int ldo_get_value(struct udevice *dev) 325 { 326 int uV; 327 int ret; 328 329 ret = palmas_ldo_val(dev, PMIC_OP_GET, &uV); 330 if (ret) 331 return ret; 332 333 return uV; 334 } 335 336 static int ldo_set_value(struct udevice *dev, int uV) 337 { 338 return palmas_ldo_val(dev, PMIC_OP_SET, &uV); 339 } 340 341 static int ldo_get_enable(struct udevice *dev) 342 { 343 bool enable = false; 344 int ret; 345 346 ret = palmas_ldo_enable(dev, PMIC_OP_GET, &enable); 347 if (ret) 348 return ret; 349 350 return enable; 351 } 352 353 static int ldo_set_enable(struct udevice *dev, bool enable) 354 { 355 return palmas_ldo_enable(dev, PMIC_OP_SET, &enable); 356 } 357 358 static int palmas_smps_probe(struct udevice *dev) 359 { 360 struct dm_regulator_uclass_platdata *uc_pdata; 361 struct udevice *parent; 362 int idx; 363 364 uc_pdata = dev_get_uclass_platdata(dev); 365 366 parent = dev_get_parent(dev); 367 int type = dev_get_driver_data(parent); 368 369 uc_pdata->type = REGULATOR_TYPE_BUCK; 370 371 switch (type) { 372 case PALMAS: 373 case TPS659038: 374 switch (dev->driver_data) { 375 case 123: 376 case 12: 377 uc_pdata->ctrl_reg = palmas_smps_ctrl[type][0]; 378 uc_pdata->volt_reg = palmas_smps_volt[type][0]; 379 break; 380 case 3: 381 uc_pdata->ctrl_reg = palmas_smps_ctrl[type][1]; 382 uc_pdata->volt_reg = palmas_smps_volt[type][1]; 383 break; 384 case 45: 385 uc_pdata->ctrl_reg = palmas_smps_ctrl[type][2]; 386 uc_pdata->volt_reg = palmas_smps_volt[type][2]; 387 break; 388 case 6: 389 case 7: 390 case 8: 391 case 9: 392 case 10: 393 idx = dev->driver_data - 3; 394 uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx]; 395 uc_pdata->volt_reg = palmas_smps_volt[type][idx]; 396 break; 397 398 default: 399 printf("Wrong ID for regulator\n"); 400 } 401 break; 402 403 case TPS65917: 404 switch (dev->driver_data) { 405 case 1: 406 case 2: 407 case 3: 408 case 4: 409 case 5: 410 idx = dev->driver_data - 1; 411 uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx]; 412 uc_pdata->volt_reg = palmas_smps_volt[type][idx]; 413 break; 414 case 12: 415 idx = 0; 416 uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx]; 417 uc_pdata->volt_reg = palmas_smps_volt[type][idx]; 418 break; 419 default: 420 printf("Wrong ID for regulator\n"); 421 } 422 break; 423 424 default: 425 printf("Invalid PMIC ID\n"); 426 } 427 428 return 0; 429 } 430 431 static int smps_get_value(struct udevice *dev) 432 { 433 int uV; 434 int ret; 435 436 ret = palmas_smps_val(dev, PMIC_OP_GET, &uV); 437 if (ret) 438 return ret; 439 440 return uV; 441 } 442 443 static int smps_set_value(struct udevice *dev, int uV) 444 { 445 return palmas_smps_val(dev, PMIC_OP_SET, &uV); 446 } 447 448 static int smps_get_enable(struct udevice *dev) 449 { 450 bool enable = false; 451 int ret; 452 453 ret = palmas_smps_enable(dev, PMIC_OP_GET, &enable); 454 if (ret) 455 return ret; 456 457 return enable; 458 } 459 460 static int smps_set_enable(struct udevice *dev, bool enable) 461 { 462 return palmas_smps_enable(dev, PMIC_OP_SET, &enable); 463 } 464 465 static const struct dm_regulator_ops palmas_ldo_ops = { 466 .get_value = ldo_get_value, 467 .set_value = ldo_set_value, 468 .get_enable = ldo_get_enable, 469 .set_enable = ldo_set_enable, 470 }; 471 472 U_BOOT_DRIVER(palmas_ldo) = { 473 .name = PALMAS_LDO_DRIVER, 474 .id = UCLASS_REGULATOR, 475 .ops = &palmas_ldo_ops, 476 .probe = palmas_ldo_probe, 477 }; 478 479 static const struct dm_regulator_ops palmas_smps_ops = { 480 .get_value = smps_get_value, 481 .set_value = smps_set_value, 482 .get_enable = smps_get_enable, 483 .set_enable = smps_set_enable, 484 }; 485 486 U_BOOT_DRIVER(palmas_smps) = { 487 .name = PALMAS_SMPS_DRIVER, 488 .id = UCLASS_REGULATOR, 489 .ops = &palmas_smps_ops, 490 .probe = palmas_smps_probe, 491 }; 492