1 /* 2 * Copyright (C) 2018 Samsung Electronics 3 * Jaehoon Chung <jh80.chung@samsung.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0 6 */ 7 8 #include <common.h> 9 #include <fdtdec.h> 10 #include <errno.h> 11 #include <dm.h> 12 #include <i2c.h> 13 #include <power/pmic.h> 14 #include <power/regulator.h> 15 #include <power/s2mps11.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 #define MODE(_id, _val, _name) { \ 20 .id = _id, \ 21 .register_value = _val, \ 22 .name = _name, \ 23 } 24 25 /* BUCK : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 */ 26 static struct dm_regulator_mode s2mps11_buck_modes[] = { 27 MODE(OP_OFF, S2MPS11_BUCK_MODE_OFF, "OFF"), 28 MODE(OP_STANDBY, S2MPS11_BUCK_MODE_STANDBY, "ON/OFF"), 29 MODE(OP_ON, S2MPS11_BUCK_MODE_STANDBY, "ON"), 30 }; 31 32 static struct dm_regulator_mode s2mps11_ldo_modes[] = { 33 MODE(OP_OFF, S2MPS11_LDO_MODE_OFF, "OFF"), 34 MODE(OP_STANDBY, S2MPS11_LDO_MODE_STANDBY, "ON/OFF"), 35 MODE(OP_STANDBY_LPM, S2MPS11_LDO_MODE_STANDBY_LPM, "ON/LPM"), 36 MODE(OP_ON, S2MPS11_LDO_MODE_ON, "ON"), 37 }; 38 39 static const char s2mps11_buck_ctrl[] = { 40 0xff, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x37, 0x39, 0x3b 41 }; 42 43 static const char s2mps11_buck_out[] = { 44 0xff, 0x26, 0x28, 0x2a, 0x2c, 0x2f, 0x34, 0x36, 0x38, 0x3a, 0x3c 45 }; 46 47 static int s2mps11_buck_hex2volt(int buck, int hex) 48 { 49 unsigned int uV = 0; 50 51 if (hex < 0) 52 goto bad; 53 54 switch (buck) { 55 case 7: 56 case 8: 57 case 10: 58 if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX) 59 goto bad; 60 61 uV = hex * S2MPS11_BUCK_HSTEP + S2MPS11_BUCK_UV_HMIN; 62 break; 63 case 9: 64 if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX) 65 goto bad; 66 uV = hex * S2MPS11_BUCK9_STEP * 2 + S2MPS11_BUCK9_UV_MIN; 67 break; 68 default: 69 if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX) 70 goto bad; 71 else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX) 72 goto bad; 73 74 uV = hex * S2MPS11_BUCK_LSTEP + S2MPS11_BUCK_UV_MIN; 75 break; 76 } 77 78 return uV; 79 bad: 80 pr_err("Value: %#x is wrong for BUCK%d", hex, buck); 81 return -EINVAL; 82 } 83 84 static int s2mps11_buck_volt2hex(int buck, int uV) 85 { 86 int hex; 87 88 switch (buck) { 89 case 7: 90 case 8: 91 case 10: 92 hex = (uV - S2MPS11_BUCK_UV_HMIN) / S2MPS11_BUCK_HSTEP; 93 if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX) 94 goto bad; 95 96 break; 97 case 9: 98 hex = (uV - S2MPS11_BUCK9_UV_MIN) / S2MPS11_BUCK9_STEP; 99 if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX) 100 goto bad; 101 break; 102 default: 103 hex = (uV - S2MPS11_BUCK_UV_MIN) / S2MPS11_BUCK_LSTEP; 104 if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX) 105 goto bad; 106 else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX) 107 goto bad; 108 break; 109 }; 110 111 if (hex >= 0) 112 return hex; 113 114 bad: 115 pr_err("Value: %d uV is wrong for BUCK%d", uV, buck); 116 return -EINVAL; 117 } 118 119 static int s2mps11_buck_val(struct udevice *dev, int op, int *uV) 120 { 121 int hex, buck, ret; 122 u32 mask, addr; 123 u8 val; 124 125 buck = dev->driver_data; 126 if (buck < 1 || buck > S2MPS11_BUCK_NUM) { 127 pr_err("Wrong buck number: %d\n", buck); 128 return -EINVAL; 129 } 130 131 if (op == PMIC_OP_GET) 132 *uV = 0; 133 134 addr = s2mps11_buck_out[buck]; 135 136 switch (buck) { 137 case 9: 138 mask = S2MPS11_BUCK9_VOLT_MASK; 139 break; 140 default: 141 mask = S2MPS11_BUCK_VOLT_MASK; 142 break; 143 } 144 145 ret = pmic_read(dev->parent, addr, &val, 1); 146 if (ret) 147 return ret; 148 149 if (op == PMIC_OP_GET) { 150 val &= mask; 151 ret = s2mps11_buck_hex2volt(buck, val); 152 if (ret < 0) 153 return ret; 154 *uV = ret; 155 return 0; 156 } 157 158 hex = s2mps11_buck_volt2hex(buck, *uV); 159 if (hex < 0) 160 return hex; 161 162 val &= ~mask; 163 val |= hex; 164 ret = pmic_write(dev->parent, addr, &val, 1); 165 166 return ret; 167 } 168 169 static int s2mps11_buck_mode(struct udevice *dev, int op, int *opmode) 170 { 171 unsigned int addr, mode; 172 unsigned char val; 173 int buck, ret; 174 175 buck = dev->driver_data; 176 if (buck < 1 || buck > S2MPS11_BUCK_NUM) { 177 pr_err("Wrong buck number: %d\n", buck); 178 return -EINVAL; 179 } 180 181 addr = s2mps11_buck_ctrl[buck]; 182 183 ret = pmic_read(dev->parent, addr, &val, 1); 184 if (ret) 185 return ret; 186 187 if (op == PMIC_OP_GET) { 188 val &= (S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT); 189 switch (val) { 190 case S2MPS11_BUCK_MODE_OFF: 191 *opmode = OP_OFF; 192 break; 193 case S2MPS11_BUCK_MODE_STANDBY: 194 *opmode = OP_STANDBY; 195 break; 196 case S2MPS11_BUCK_MODE_ON: 197 *opmode = OP_ON; 198 break; 199 default: 200 return -EINVAL; 201 } 202 return 0; 203 } 204 205 switch (*opmode) { 206 case OP_OFF: 207 mode = S2MPS11_BUCK_MODE_OFF; 208 break; 209 case OP_STANDBY: 210 mode = S2MPS11_BUCK_MODE_STANDBY; 211 break; 212 case OP_ON: 213 mode = S2MPS11_BUCK_MODE_ON; 214 break; 215 default: 216 pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck); 217 return -EINVAL; 218 } 219 220 val &= ~(S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT); 221 val |= mode; 222 ret = pmic_write(dev->parent, addr, &val, 1); 223 224 return ret; 225 } 226 227 static int s2mps11_buck_enable(struct udevice *dev, int op, bool *enable) 228 { 229 int ret, on_off; 230 231 if (op == PMIC_OP_GET) { 232 ret = s2mps11_buck_mode(dev, op, &on_off); 233 if (ret) 234 return ret; 235 switch (on_off) { 236 case OP_OFF: 237 *enable = false; 238 break; 239 case OP_ON: 240 *enable = true; 241 break; 242 default: 243 return -EINVAL; 244 } 245 } else if (op == PMIC_OP_SET) { 246 if (*enable) 247 on_off = OP_ON; 248 else 249 on_off = OP_OFF; 250 251 ret = s2mps11_buck_mode(dev, op, &on_off); 252 if (ret) 253 return ret; 254 } 255 256 return 0; 257 } 258 259 static int buck_get_value(struct udevice *dev) 260 { 261 int uV; 262 int ret; 263 264 ret = s2mps11_buck_val(dev, PMIC_OP_GET, &uV); 265 if (ret) 266 return ret; 267 return uV; 268 } 269 270 static int buck_set_value(struct udevice *dev, int uV) 271 { 272 return s2mps11_buck_val(dev, PMIC_OP_SET, &uV); 273 } 274 275 static int buck_get_enable(struct udevice *dev) 276 { 277 bool enable = false; 278 int ret; 279 280 ret = s2mps11_buck_enable(dev, PMIC_OP_GET, &enable); 281 if (ret) 282 return ret; 283 return enable; 284 } 285 286 static int buck_set_enable(struct udevice *dev, bool enable) 287 { 288 return s2mps11_buck_enable(dev, PMIC_OP_SET, &enable); 289 } 290 291 static int buck_get_mode(struct udevice *dev) 292 { 293 int mode; 294 int ret; 295 296 ret = s2mps11_buck_mode(dev, PMIC_OP_GET, &mode); 297 if (ret) 298 return ret; 299 300 return mode; 301 } 302 303 static int buck_set_mode(struct udevice *dev, int mode) 304 { 305 return s2mps11_buck_mode(dev, PMIC_OP_SET, &mode); 306 } 307 308 static int s2mps11_buck_probe(struct udevice *dev) 309 { 310 struct dm_regulator_uclass_platdata *uc_pdata; 311 312 uc_pdata = dev_get_uclass_platdata(dev); 313 314 uc_pdata->type = REGULATOR_TYPE_BUCK; 315 uc_pdata->mode = s2mps11_buck_modes; 316 uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes); 317 318 return 0; 319 } 320 321 static const struct dm_regulator_ops s2mps11_buck_ops = { 322 .get_value = buck_get_value, 323 .set_value = buck_set_value, 324 .get_enable = buck_get_enable, 325 .set_enable = buck_set_enable, 326 .get_mode = buck_get_mode, 327 .set_mode = buck_set_mode, 328 }; 329 330 U_BOOT_DRIVER(s2mps11_buck) = { 331 .name = S2MPS11_BUCK_DRIVER, 332 .id = UCLASS_REGULATOR, 333 .ops = &s2mps11_buck_ops, 334 .probe = s2mps11_buck_probe, 335 }; 336 337 static int s2mps11_ldo_hex2volt(int ldo, int hex) 338 { 339 unsigned int uV = 0; 340 341 if (hex > S2MPS11_LDO_VOLT_MAX_HEX) { 342 pr_err("Value: %#x is wrong for LDO%d", hex, ldo); 343 return -EINVAL; 344 } 345 346 switch (ldo) { 347 case 1: 348 case 6: 349 case 11: 350 case 22: 351 case 23: 352 uV = hex * S2MPS11_LDO_STEP + S2MPS11_LDO_UV_MIN; 353 break; 354 default: 355 uV = hex * S2MPS11_LDO_STEP * 2 + S2MPS11_LDO_UV_MIN; 356 break; 357 } 358 359 return uV; 360 } 361 362 static int s2mps11_ldo_volt2hex(int ldo, int uV) 363 { 364 int hex = 0; 365 366 switch (ldo) { 367 case 1: 368 case 6: 369 case 11: 370 case 22: 371 case 23: 372 hex = (uV - S2MPS11_LDO_UV_MIN) / S2MPS11_LDO_STEP; 373 break; 374 default: 375 hex = (uV - S2MPS11_LDO_UV_MIN) / (S2MPS11_LDO_STEP * 2); 376 break; 377 } 378 379 if (hex >= 0 && hex <= S2MPS11_LDO_VOLT_MAX_HEX) 380 return hex; 381 382 pr_err("Value: %d uV is wrong for LDO%d", uV, ldo); 383 return -EINVAL; 384 385 return 0; 386 } 387 388 static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV) 389 { 390 unsigned int addr; 391 unsigned char val; 392 int hex, ldo, ret; 393 394 ldo = dev->driver_data; 395 if (ldo < 1 || ldo > S2MPS11_LDO_NUM) { 396 pr_err("Wrong ldo number: %d\n", ldo); 397 return -EINVAL; 398 } 399 400 addr = S2MPS11_REG_L1CTRL + ldo - 1; 401 402 ret = pmic_read(dev->parent, addr, &val, 1); 403 if (ret) 404 return ret; 405 406 if (op == PMIC_OP_GET) { 407 *uV = 0; 408 val &= S2MPS11_LDO_VOLT_MASK; 409 ret = s2mps11_ldo_hex2volt(ldo, val); 410 if (ret < 0) 411 return ret; 412 413 *uV = ret; 414 return 0; 415 } 416 417 hex = s2mps11_ldo_volt2hex(ldo, *uV); 418 if (hex < 0) 419 return hex; 420 421 val &= ~S2MPS11_LDO_VOLT_MASK; 422 val |= hex; 423 ret = pmic_write(dev->parent, addr, &val, 1); 424 425 return ret; 426 } 427 428 static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode) 429 { 430 unsigned int addr, mode; 431 unsigned char val; 432 int ldo, ret; 433 434 ldo = dev->driver_data; 435 if (ldo < 1 || ldo > S2MPS11_LDO_NUM) { 436 pr_err("Wrong ldo number: %d\n", ldo); 437 return -EINVAL; 438 } 439 addr = S2MPS11_REG_L1CTRL + ldo - 1; 440 441 ret = pmic_read(dev->parent, addr, &val, 1); 442 if (ret) 443 return ret; 444 445 if (op == PMIC_OP_GET) { 446 val &= (S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT); 447 switch (val) { 448 case S2MPS11_LDO_MODE_OFF: 449 *opmode = OP_OFF; 450 break; 451 case S2MPS11_LDO_MODE_STANDBY: 452 *opmode = OP_STANDBY; 453 break; 454 case S2MPS11_LDO_MODE_STANDBY_LPM: 455 *opmode = OP_STANDBY_LPM; 456 break; 457 case S2MPS11_LDO_MODE_ON: 458 *opmode = OP_ON; 459 break; 460 default: 461 return -EINVAL; 462 } 463 return 0; 464 } 465 466 switch (*opmode) { 467 case OP_OFF: 468 mode = S2MPS11_LDO_MODE_OFF; 469 break; 470 case OP_STANDBY: 471 mode = S2MPS11_LDO_MODE_STANDBY; 472 break; 473 case OP_STANDBY_LPM: 474 mode = S2MPS11_LDO_MODE_STANDBY_LPM; 475 break; 476 case OP_ON: 477 mode = S2MPS11_LDO_MODE_ON; 478 break; 479 default: 480 pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo); 481 return -EINVAL; 482 } 483 484 val &= ~(S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT); 485 val |= mode; 486 ret = pmic_write(dev->parent, addr, &val, 1); 487 488 return ret; 489 } 490 491 static int s2mps11_ldo_enable(struct udevice *dev, int op, bool *enable) 492 { 493 int ret, on_off; 494 495 if (op == PMIC_OP_GET) { 496 ret = s2mps11_ldo_mode(dev, op, &on_off); 497 if (ret) 498 return ret; 499 switch (on_off) { 500 case OP_OFF: 501 *enable = false; 502 break; 503 case OP_ON: 504 *enable = true; 505 break; 506 default: 507 return -EINVAL; 508 } 509 } else if (op == PMIC_OP_SET) { 510 if (*enable) 511 on_off = OP_ON; 512 else 513 on_off = OP_OFF; 514 515 ret = s2mps11_ldo_mode(dev, op, &on_off); 516 if (ret) 517 return ret; 518 } 519 520 return 0; 521 } 522 523 static int ldo_get_value(struct udevice *dev) 524 { 525 int uV; 526 int ret; 527 528 ret = s2mps11_ldo_val(dev, PMIC_OP_GET, &uV); 529 if (ret) 530 return ret; 531 532 return uV; 533 } 534 535 static int ldo_set_value(struct udevice *dev, int uV) 536 { 537 return s2mps11_ldo_val(dev, PMIC_OP_SET, &uV); 538 } 539 540 static int ldo_get_enable(struct udevice *dev) 541 { 542 bool enable = false; 543 int ret; 544 545 ret = s2mps11_ldo_enable(dev, PMIC_OP_GET, &enable); 546 if (ret) 547 return ret; 548 return enable; 549 } 550 551 static int ldo_set_enable(struct udevice *dev, bool enable) 552 { 553 return s2mps11_ldo_enable(dev, PMIC_OP_SET, &enable); 554 } 555 556 static int ldo_get_mode(struct udevice *dev) 557 { 558 int mode, ret; 559 560 ret = s2mps11_ldo_mode(dev, PMIC_OP_GET, &mode); 561 if (ret) 562 return ret; 563 return mode; 564 } 565 566 static int ldo_set_mode(struct udevice *dev, int mode) 567 { 568 return s2mps11_ldo_mode(dev, PMIC_OP_SET, &mode); 569 } 570 571 static int s2mps11_ldo_probe(struct udevice *dev) 572 { 573 struct dm_regulator_uclass_platdata *uc_pdata; 574 575 uc_pdata = dev_get_uclass_platdata(dev); 576 uc_pdata->type = REGULATOR_TYPE_LDO; 577 uc_pdata->mode = s2mps11_ldo_modes; 578 uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes); 579 580 return 0; 581 } 582 583 static const struct dm_regulator_ops s2mps11_ldo_ops = { 584 .get_value = ldo_get_value, 585 .set_value = ldo_set_value, 586 .get_enable = ldo_get_enable, 587 .set_enable = ldo_set_enable, 588 .get_mode = ldo_get_mode, 589 .set_mode = ldo_set_mode, 590 }; 591 592 U_BOOT_DRIVER(s2mps11_ldo) = { 593 .name = S2MPS11_LDO_DRIVER, 594 .id = UCLASS_REGULATOR, 595 .ops = &s2mps11_ldo_ops, 596 .probe = s2mps11_ldo_probe, 597 }; 598