1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP29502) 4 */ 5 6 #include <linux/bitfield.h> 7 #include <linux/i2c.h> 8 #include <linux/module.h> 9 #include <linux/of_device.h> 10 #include "pmbus.h" 11 12 #define MFR_VOUT_SCALE_LOOP 0x29 13 #define MFR_SVI3_IOUT_PRT 0x67 14 #define MFR_READ_PIN_EST 0x94 15 #define MFR_READ_IIN_EST 0x95 16 #define MFR_VOUT_PROT1 0x3D 17 #define MFR_VOUT_PROT2 0x51 18 #define MFR_SLOPE_CNT_SET 0xA8 19 #define MFR_TSNS_FLT_SET 0xBB 20 21 #define MP29502_VIN_OV_GAIN 4 22 #define MP29502_TEMP_LIMIT_OFFSET 40 23 #define MP29502_READ_VOUT_DIV 1024 24 #define MP29502_READ_IOUT_DIV 32 25 #define MP29502_IOUT_LIMIT_UINT 8 26 #define MP29502_OVUV_LIMIT_SCALE 10 27 #define MP28502_VOUT_OV_GAIN 512 28 #define MP28502_VOUT_OV_SCALE 40 29 #define MP29502_VOUT_UV_OFFSET 36 30 #define MP29502_PIN_GAIN 2 31 #define MP29502_IIN_DIV 2 32 33 #define MP29502_PAGE_NUM 1 34 35 #define MP29502_RAIL_FUNC (PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | \ 36 PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | \ 37 PMBUS_HAVE_TEMP | PMBUS_HAVE_PIN | \ 38 PMBUS_HAVE_IIN | \ 39 PMBUS_HAVE_STATUS_VOUT | \ 40 PMBUS_HAVE_STATUS_IOUT | \ 41 PMBUS_HAVE_STATUS_TEMP | \ 42 PMBUS_HAVE_STATUS_INPUT) 43 44 struct mp29502_data { 45 struct pmbus_driver_info info; 46 int vout_scale; 47 int vout_bottom_div; 48 int vout_top_div; 49 int ovp_div; 50 int iout_scale; 51 }; 52 53 #define to_mp29502_data(x) container_of(x, struct mp29502_data, info) 54 55 static u16 mp29502_reg2data_linear11(u16 word) 56 { 57 s16 exponent; 58 s32 mantissa; 59 s64 val; 60 61 exponent = ((s16)word) >> 11; 62 mantissa = ((s16)((word & 0x7ff) << 5)) >> 5; 63 val = mantissa; 64 65 if (exponent >= 0) 66 val <<= exponent; 67 else 68 val >>= -exponent; 69 70 return val; 71 } 72 73 static int 74 mp29502_identify_vout_scale(struct i2c_client *client, struct pmbus_driver_info *info, 75 int page) 76 { 77 struct mp29502_data *data = to_mp29502_data(info); 78 int ret; 79 80 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); 81 if (ret < 0) 82 return ret; 83 84 ret = i2c_smbus_read_word_data(client, MFR_VOUT_SCALE_LOOP); 85 if (ret < 0) 86 return ret; 87 88 switch (FIELD_GET(GENMASK(12, 10), ret)) { 89 case 0: 90 data->vout_scale = 6400; 91 break; 92 case 1: 93 data->vout_scale = 5120; 94 break; 95 case 2: 96 data->vout_scale = 2560; 97 break; 98 case 3: 99 data->vout_scale = 2048; 100 break; 101 case 4: 102 data->vout_scale = 1024; 103 break; 104 case 5: 105 data->vout_scale = 4; 106 break; 107 case 6: 108 data->vout_scale = 2; 109 break; 110 case 7: 111 data->vout_scale = 1; 112 break; 113 default: 114 data->vout_scale = 1; 115 break; 116 } 117 118 return 0; 119 } 120 121 static int 122 mp29502_identify_vout_divider(struct i2c_client *client, struct pmbus_driver_info *info, 123 int page) 124 { 125 struct mp29502_data *data = to_mp29502_data(info); 126 int ret; 127 128 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); 129 if (ret < 0) 130 return ret; 131 132 ret = i2c_smbus_read_word_data(client, MFR_VOUT_PROT1); 133 if (ret < 0) 134 return ret; 135 136 data->vout_bottom_div = FIELD_GET(GENMASK(11, 0), ret); 137 138 ret = i2c_smbus_read_word_data(client, MFR_VOUT_PROT2); 139 if (ret < 0) 140 return ret; 141 142 data->vout_top_div = FIELD_GET(GENMASK(14, 0), ret); 143 144 return 0; 145 } 146 147 static int 148 mp29502_identify_ovp_divider(struct i2c_client *client, struct pmbus_driver_info *info, 149 int page) 150 { 151 struct mp29502_data *data = to_mp29502_data(info); 152 int ret; 153 154 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); 155 if (ret < 0) 156 return ret; 157 158 ret = i2c_smbus_read_word_data(client, MFR_SLOPE_CNT_SET); 159 if (ret < 0) 160 return ret; 161 162 data->ovp_div = FIELD_GET(GENMASK(9, 0), ret); 163 164 return 0; 165 } 166 167 static int 168 mp29502_identify_iout_scale(struct i2c_client *client, struct pmbus_driver_info *info, 169 int page) 170 { 171 struct mp29502_data *data = to_mp29502_data(info); 172 int ret; 173 174 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); 175 if (ret < 0) 176 return ret; 177 178 ret = i2c_smbus_read_word_data(client, MFR_SVI3_IOUT_PRT); 179 if (ret < 0) 180 return ret; 181 182 switch (ret & GENMASK(2, 0)) { 183 case 0: 184 case 6: 185 data->iout_scale = 32; 186 break; 187 case 1: 188 data->iout_scale = 1; 189 break; 190 case 2: 191 data->iout_scale = 2; 192 break; 193 case 3: 194 data->iout_scale = 4; 195 break; 196 case 4: 197 data->iout_scale = 8; 198 break; 199 case 5: 200 data->iout_scale = 16; 201 break; 202 default: 203 data->iout_scale = 64; 204 break; 205 } 206 207 return 0; 208 } 209 210 static int mp29502_read_vout_ov_limit(struct i2c_client *client, struct mp29502_data *data) 211 { 212 int ret; 213 int ov_value; 214 215 /* 216 * This is because the vout ov fault limit value comes from 217 * page1 MFR_TSNS_FLT_SET reg, and other telemetry and limit 218 * value comes from page0 reg. So the page should be set to 219 * 0 after the reading of vout ov limit. 220 */ 221 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 1); 222 if (ret < 0) 223 return ret; 224 225 ret = i2c_smbus_read_word_data(client, MFR_TSNS_FLT_SET); 226 if (ret < 0) 227 return ret; 228 229 ov_value = DIV_ROUND_CLOSEST(FIELD_GET(GENMASK(12, 7), ret) * 230 MP28502_VOUT_OV_GAIN * MP28502_VOUT_OV_SCALE, 231 data->ovp_div); 232 233 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); 234 if (ret < 0) 235 return ret; 236 237 return ov_value; 238 } 239 240 static int mp29502_write_vout_ov_limit(struct i2c_client *client, u16 word, 241 struct mp29502_data *data) 242 { 243 int ret; 244 245 /* 246 * This is because the vout ov fault limit value comes from 247 * page1 MFR_TSNS_FLT_SET reg, and other telemetry and limit 248 * value comes from page0 reg. So the page should be set to 249 * 0 after the writing of vout ov limit. 250 */ 251 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 1); 252 if (ret < 0) 253 return ret; 254 255 ret = i2c_smbus_read_word_data(client, MFR_TSNS_FLT_SET); 256 if (ret < 0) 257 return ret; 258 259 ret = i2c_smbus_write_word_data(client, MFR_TSNS_FLT_SET, 260 (ret & ~GENMASK(12, 7)) | 261 FIELD_PREP(GENMASK(12, 7), 262 DIV_ROUND_CLOSEST(word * data->ovp_div, 263 MP28502_VOUT_OV_GAIN * MP28502_VOUT_OV_SCALE))); 264 265 return i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); 266 } 267 268 static int mp29502_read_byte_data(struct i2c_client *client, int page, int reg) 269 { 270 int ret; 271 272 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); 273 if (ret < 0) 274 return ret; 275 276 switch (reg) { 277 case PMBUS_VOUT_MODE: 278 ret = PB_VOUT_MODE_DIRECT; 279 break; 280 default: 281 ret = -ENODATA; 282 break; 283 } 284 285 return ret; 286 } 287 288 static int mp29502_read_word_data(struct i2c_client *client, int page, 289 int phase, int reg) 290 { 291 const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 292 struct mp29502_data *data = to_mp29502_data(info); 293 int ret; 294 295 switch (reg) { 296 case PMBUS_STATUS_WORD: 297 ret = -ENODATA; 298 break; 299 case PMBUS_READ_VIN: 300 /* 301 * The MP29502 PMBUS_READ_VIN[10:0] is the vin value, the vin scale is 302 * 125mV/LSB. And the vin scale is set to 125mV/Lsb(using r/m/b scale) 303 * in MP29502 pmbus_driver_info struct, so the word data bit0-bit10 can 304 * be returned to pmbus core directly. 305 */ 306 ret = pmbus_read_word_data(client, page, phase, reg); 307 if (ret < 0) 308 return ret; 309 310 ret = FIELD_GET(GENMASK(10, 0), ret); 311 break; 312 case PMBUS_READ_VOUT: 313 /* 314 * The MP29502 PMBUS_READ_VOUT[11:0] is the vout value, and vout 315 * value is calculated based on vout scale and vout divider. 316 */ 317 ret = pmbus_read_word_data(client, page, phase, reg); 318 if (ret < 0) 319 return ret; 320 321 ret = DIV_ROUND_CLOSEST((ret & GENMASK(11, 0)) * 322 data->vout_scale * 323 (data->vout_bottom_div + 324 4 * data->vout_top_div), 325 MP29502_READ_VOUT_DIV * 326 data->vout_bottom_div); 327 break; 328 case PMBUS_READ_IIN: 329 /* 330 * The MP29502 MFR_READ_IIN_EST register is linear11 format, and the 331 * exponent is not a constant value. But the iin scale is set to 332 * 1A/Lsb(using r/m/b scale). As a result, the iin read from MP29502 333 * should be calculated to A, then return the result to pmbus core. 334 */ 335 ret = pmbus_read_word_data(client, page, phase, MFR_READ_IIN_EST); 336 if (ret < 0) 337 return ret; 338 339 ret = DIV_ROUND_CLOSEST(mp29502_reg2data_linear11(ret), 340 MP29502_IIN_DIV); 341 break; 342 case PMBUS_READ_PIN: 343 /* 344 * The MP29502 MFR_READ_PIN_EST register is linear11 format, and the 345 * exponent is not a constant value. But the pin scale is set to 346 * 1W/Lsb(using r/m/b scale). As a result, the pout read from MP29502 347 * should be calculated to W, then return the result to pmbus core. 348 */ 349 ret = pmbus_read_word_data(client, page, phase, MFR_READ_PIN_EST); 350 if (ret < 0) 351 return ret; 352 353 ret = mp29502_reg2data_linear11(ret) * MP29502_PIN_GAIN; 354 break; 355 case PMBUS_READ_POUT: 356 /* 357 * The MP29502 PMBUS_READ_POUT register is linear11 format, and the 358 * exponent is not a constant value. But the pout scale is set to 359 * 1W/Lsb(using r/m/b scale). As a result, the pout read from MP29502 360 * should be calculated to W, then return the result to pmbus core. 361 * And the pout is calculated based on vout divider. 362 */ 363 ret = pmbus_read_word_data(client, page, phase, reg); 364 if (ret < 0) 365 return ret; 366 367 ret = DIV_ROUND_CLOSEST(mp29502_reg2data_linear11(ret) * 368 (data->vout_bottom_div + 369 4 * data->vout_top_div), 370 data->vout_bottom_div); 371 break; 372 case PMBUS_READ_IOUT: 373 ret = pmbus_read_word_data(client, page, phase, reg); 374 if (ret < 0) 375 return ret; 376 377 ret = DIV_ROUND_CLOSEST((ret & GENMASK(10, 0)) * data->iout_scale, 378 MP29502_READ_IOUT_DIV); 379 break; 380 case PMBUS_READ_TEMPERATURE_1: 381 ret = pmbus_read_word_data(client, page, phase, reg); 382 if (ret < 0) 383 return ret; 384 385 ret = FIELD_GET(GENMASK(10, 0), ret); 386 break; 387 case PMBUS_VIN_OV_FAULT_LIMIT: 388 /* 389 * The MP29502 PMBUS_VIN_OV_FAULT_LIMIT is 500mV/Lsb, but 390 * the vin scale is set to 125mV/Lsb(using r/m/b scale), 391 * so the word data should multiply by 4. 392 */ 393 ret = pmbus_read_word_data(client, page, phase, reg); 394 if (ret < 0) 395 return ret; 396 397 ret = FIELD_GET(GENMASK(7, 0), ret) * MP29502_VIN_OV_GAIN; 398 break; 399 case PMBUS_VIN_UV_WARN_LIMIT: 400 case PMBUS_VIN_UV_FAULT_LIMIT: 401 /* 402 * The MP29502 PMBUS_VIN_UV_WARN_LIMIT and PMBUS_VIN_UV_FAULT_LIMIT 403 * scale is 125mV/Lsb, but the vin scale is set to 125mV/Lsb(using 404 * r/m/b scale), so the word data bit0-bit9 can be returned to pmbus 405 * core directly. 406 */ 407 ret = pmbus_read_word_data(client, page, phase, reg); 408 if (ret < 0) 409 return ret; 410 411 ret = FIELD_GET(GENMASK(9, 0), ret); 412 break; 413 case PMBUS_VOUT_OV_FAULT_LIMIT: 414 /* 415 * The MP29502 vout ov fault limit value comes from 416 * page1 MFR_TSNS_FLT_SET[12:7]. 417 */ 418 ret = mp29502_read_vout_ov_limit(client, data); 419 if (ret < 0) 420 return ret; 421 422 break; 423 case PMBUS_VOUT_UV_FAULT_LIMIT: 424 ret = pmbus_read_word_data(client, page, phase, reg); 425 if (ret < 0) 426 return ret; 427 428 ret = DIV_ROUND_CLOSEST((FIELD_GET(GENMASK(8, 0), ret) * 429 MP29502_OVUV_LIMIT_SCALE - 430 MP29502_VOUT_UV_OFFSET) * 431 (data->vout_bottom_div + 432 4 * data->vout_top_div), 433 data->vout_bottom_div); 434 break; 435 case PMBUS_IOUT_OC_FAULT_LIMIT: 436 case PMBUS_IOUT_OC_WARN_LIMIT: 437 ret = pmbus_read_word_data(client, page, phase, reg); 438 if (ret < 0) 439 return ret; 440 441 ret = DIV_ROUND_CLOSEST((ret & GENMASK(7, 0)) * 442 data->iout_scale * 443 MP29502_IOUT_LIMIT_UINT, 444 MP29502_READ_IOUT_DIV); 445 break; 446 case PMBUS_OT_FAULT_LIMIT: 447 case PMBUS_OT_WARN_LIMIT: 448 /* 449 * The scale of MP29502 PMBUS_OT_FAULT_LIMIT and PMBUS_OT_WARN_LIMIT 450 * is 1°C/LSB and they have 40°C offset. 451 */ 452 ret = pmbus_read_word_data(client, page, phase, reg); 453 if (ret < 0) 454 return ret; 455 456 ret = (ret & GENMASK(7, 0)) - MP29502_TEMP_LIMIT_OFFSET; 457 break; 458 default: 459 ret = -EINVAL; 460 break; 461 } 462 463 return ret; 464 } 465 466 static int mp29502_write_word_data(struct i2c_client *client, int page, int reg, 467 u16 word) 468 { 469 const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 470 struct mp29502_data *data = to_mp29502_data(info); 471 int ret; 472 473 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); 474 if (ret < 0) 475 return ret; 476 477 switch (reg) { 478 case PMBUS_VIN_OV_FAULT_LIMIT: 479 /* 480 * The PMBUS_VIN_OV_FAULT_LIMIT[7:0] is the limit value, 481 * and bit8-bit15 should not be changed. The scale of 482 * PMBUS_VIN_OV_FAULT_LIMIT is 500mV/Lsb, but the vin 483 * scale is set to 125mV/Lsb(using r/m/b scale), so 484 * the word data should divide by 4. 485 */ 486 ret = pmbus_read_word_data(client, page, 0xff, reg); 487 if (ret < 0) 488 return ret; 489 490 ret = pmbus_write_word_data(client, page, reg, 491 (ret & ~GENMASK(7, 0)) | 492 FIELD_PREP(GENMASK(7, 0), 493 DIV_ROUND_CLOSEST(word, 494 MP29502_VIN_OV_GAIN))); 495 break; 496 case PMBUS_VIN_UV_WARN_LIMIT: 497 case PMBUS_VIN_UV_FAULT_LIMIT: 498 /* 499 * The PMBUS_VIN_UV_WARN_LIMIT[9:0] and PMBUS_VIN_UV_FAULT_LIMIT[9:0] 500 * are the limit value, and bit10-bit15 should not be changed. 501 */ 502 ret = pmbus_read_word_data(client, page, 0xff, reg); 503 if (ret < 0) 504 return ret; 505 506 ret = pmbus_write_word_data(client, page, reg, 507 (ret & ~GENMASK(9, 0)) | 508 FIELD_PREP(GENMASK(9, 0), 509 word)); 510 break; 511 case PMBUS_VOUT_OV_FAULT_LIMIT: 512 ret = mp29502_write_vout_ov_limit(client, word, data); 513 if (ret < 0) 514 return ret; 515 516 break; 517 case PMBUS_VOUT_UV_FAULT_LIMIT: 518 ret = pmbus_read_word_data(client, page, 0xff, reg); 519 if (ret < 0) 520 return ret; 521 522 ret = pmbus_write_word_data(client, page, reg, 523 (ret & ~GENMASK(8, 0)) | 524 FIELD_PREP(GENMASK(8, 0), 525 DIV_ROUND_CLOSEST(word * 526 data->vout_bottom_div + 527 MP29502_VOUT_UV_OFFSET * 528 (data->vout_bottom_div + 529 4 * data->vout_top_div), 530 MP29502_OVUV_LIMIT_SCALE * 531 (data->vout_bottom_div + 532 4 * data->vout_top_div)))); 533 break; 534 case PMBUS_IOUT_OC_FAULT_LIMIT: 535 case PMBUS_IOUT_OC_WARN_LIMIT: 536 ret = pmbus_write_word_data(client, page, reg, 537 DIV_ROUND_CLOSEST(word * 538 MP29502_READ_IOUT_DIV, 539 MP29502_IOUT_LIMIT_UINT * 540 data->iout_scale)); 541 break; 542 case PMBUS_OT_FAULT_LIMIT: 543 case PMBUS_OT_WARN_LIMIT: 544 /* 545 * The PMBUS_OT_FAULT_LIMIT[7:0] and PMBUS_OT_WARN_LIMIT[7:0] 546 * are the limit value, and bit8-bit15 should not be changed. 547 */ 548 ret = pmbus_read_word_data(client, page, 0xff, reg); 549 if (ret < 0) 550 return ret; 551 552 ret = pmbus_write_word_data(client, page, reg, 553 (ret & ~GENMASK(7, 0)) | 554 FIELD_PREP(GENMASK(7, 0), 555 word + MP29502_TEMP_LIMIT_OFFSET)); 556 break; 557 default: 558 ret = -EINVAL; 559 break; 560 } 561 562 return ret; 563 } 564 565 static int mp29502_identify(struct i2c_client *client, struct pmbus_driver_info *info) 566 { 567 int ret; 568 569 /* Identify vout scale */ 570 ret = mp29502_identify_vout_scale(client, info, 0); 571 if (ret < 0) 572 return ret; 573 574 /* Identify vout divider. */ 575 ret = mp29502_identify_vout_divider(client, info, 1); 576 if (ret < 0) 577 return ret; 578 579 /* Identify ovp divider. */ 580 ret = mp29502_identify_ovp_divider(client, info, 1); 581 if (ret < 0) 582 return ret; 583 584 /* Identify iout scale */ 585 return mp29502_identify_iout_scale(client, info, 0); 586 } 587 588 static const struct pmbus_driver_info mp29502_info = { 589 .pages = MP29502_PAGE_NUM, 590 .format[PSC_VOLTAGE_IN] = direct, 591 .format[PSC_TEMPERATURE] = direct, 592 .format[PSC_CURRENT_IN] = direct, 593 .format[PSC_CURRENT_OUT] = direct, 594 .format[PSC_VOLTAGE_OUT] = direct, 595 .format[PSC_POWER] = direct, 596 597 .m[PSC_VOLTAGE_IN] = 8, 598 .R[PSC_VOLTAGE_IN] = 0, 599 .b[PSC_VOLTAGE_IN] = 0, 600 601 .m[PSC_VOLTAGE_OUT] = 1, 602 .R[PSC_VOLTAGE_OUT] = 3, 603 .b[PSC_VOLTAGE_OUT] = 0, 604 605 .m[PSC_TEMPERATURE] = 1, 606 .R[PSC_TEMPERATURE] = 0, 607 .b[PSC_TEMPERATURE] = 0, 608 609 .m[PSC_CURRENT_IN] = 1, 610 .R[PSC_CURRENT_IN] = 0, 611 .b[PSC_CURRENT_IN] = 0, 612 613 .m[PSC_CURRENT_OUT] = 1, 614 .R[PSC_CURRENT_OUT] = 0, 615 .b[PSC_CURRENT_OUT] = 0, 616 617 .m[PSC_POWER] = 1, 618 .R[PSC_POWER] = 0, 619 .b[PSC_POWER] = 0, 620 621 .func[0] = MP29502_RAIL_FUNC, 622 .read_word_data = mp29502_read_word_data, 623 .read_byte_data = mp29502_read_byte_data, 624 .write_word_data = mp29502_write_word_data, 625 .identify = mp29502_identify, 626 }; 627 628 static int mp29502_probe(struct i2c_client *client) 629 { 630 struct pmbus_driver_info *info; 631 struct mp29502_data *data; 632 633 data = devm_kzalloc(&client->dev, sizeof(struct mp29502_data), 634 GFP_KERNEL); 635 if (!data) 636 return -ENOMEM; 637 638 memcpy(&data->info, &mp29502_info, sizeof(*info)); 639 info = &data->info; 640 641 return pmbus_do_probe(client, info); 642 } 643 644 static const struct i2c_device_id mp29502_id[] = { 645 {"mp29502", 0}, 646 {} 647 }; 648 MODULE_DEVICE_TABLE(i2c, mp29502_id); 649 650 static const struct of_device_id __maybe_unused mp29502_of_match[] = { 651 {.compatible = "mps,mp29502"}, 652 {} 653 }; 654 MODULE_DEVICE_TABLE(of, mp29502_of_match); 655 656 static struct i2c_driver mp29502_driver = { 657 .driver = { 658 .name = "mp29502", 659 .of_match_table = mp29502_of_match, 660 }, 661 .probe = mp29502_probe, 662 .id_table = mp29502_id, 663 }; 664 665 module_i2c_driver(mp29502_driver); 666 667 MODULE_AUTHOR("Wensheng Wang <wenswang@yeah.net"); 668 MODULE_DESCRIPTION("PMBus driver for MPS MP29502"); 669 MODULE_LICENSE("GPL"); 670 MODULE_IMPORT_NS("PMBUS"); 671