Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

regulator: pca9450: Add support for mode operations

Make the PWM mode on the buck controllers configurable from
devicetree. Some boards require forced PWM mode to keep the supply
ripple within acceptable limits under light load conditions.

Signed-off-by: Martijn de Gouw <martijn.de.gouw@prodrive-technologies.com>
Link: https://patch.msgid.link/20250525071823.819342-2-martijn.de.gouw@prodrive-technologies.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Martijn de Gouw and committed by
Mark Brown
548d770c d7181a2d

+116 -4
+116 -4
drivers/regulator/pca9450-regulator.c
··· 17 17 #include <linux/regulator/machine.h> 18 18 #include <linux/regulator/of_regulator.h> 19 19 #include <linux/regulator/pca9450.h> 20 + #include <dt-bindings/regulator/nxp,pca9450-regulator.h> 21 + 22 + static unsigned int pca9450_buck_get_mode(struct regulator_dev *rdev); 23 + static int pca9450_buck_set_mode(struct regulator_dev *rdev, unsigned int mode); 20 24 21 25 struct pc9450_dvs_config { 22 26 unsigned int run_reg; /* dvs0 */ 23 27 unsigned int run_mask; 24 28 unsigned int standby_reg; /* dvs1 */ 25 29 unsigned int standby_mask; 30 + unsigned int mode_reg; /* ctrl */ 31 + unsigned int mode_mask; 26 32 }; 27 33 28 34 struct pca9450_regulator_desc { ··· 86 80 .get_voltage_sel = regulator_get_voltage_sel_regmap, 87 81 .set_voltage_time_sel = regulator_set_voltage_time_sel, 88 82 .set_ramp_delay = regulator_set_ramp_delay_regmap, 83 + .set_mode = pca9450_buck_set_mode, 84 + .get_mode = pca9450_buck_get_mode, 89 85 }; 90 86 91 87 static const struct regulator_ops pca9450_buck_regulator_ops = { ··· 98 90 .set_voltage_sel = regulator_set_voltage_sel_regmap, 99 91 .get_voltage_sel = regulator_get_voltage_sel_regmap, 100 92 .set_voltage_time_sel = regulator_set_voltage_time_sel, 93 + .set_mode = pca9450_buck_set_mode, 94 + .get_mode = pca9450_buck_get_mode, 101 95 }; 102 96 103 97 static const struct regulator_ops pca9450_ldo_regulator_ops = { ··· 295 285 return ret; 296 286 } 297 287 298 - static const struct pca9450_regulator_desc pca9450a_regulators[] = { 288 + static inline unsigned int pca9450_map_mode(unsigned int mode) 289 + { 290 + switch (mode) { 291 + case PCA9450_BUCK_MODE_AUTO: 292 + return REGULATOR_MODE_NORMAL; 293 + case PCA9450_BUCK_MODE_FORCE_PWM: 294 + return REGULATOR_MODE_FAST; 295 + default: 296 + return REGULATOR_MODE_INVALID; 297 + } 298 + } 299 + 300 + static int pca9450_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) 301 + { 302 + struct pca9450_regulator_desc *desc = container_of(rdev->desc, 303 + struct pca9450_regulator_desc, desc); 304 + const struct pc9450_dvs_config *dvs = &desc->dvs; 305 + int val; 306 + 307 + switch (mode) { 308 + case REGULATOR_MODE_FAST: 309 + val = dvs->mode_mask; 310 + break; 311 + case REGULATOR_MODE_NORMAL: 312 + val = 0; 313 + break; 314 + default: 315 + return -EINVAL; 316 + } 317 + 318 + dev_dbg(&rdev->dev, "pca9450 buck set_mode %#x, %#x, %#x\n", 319 + dvs->mode_reg, dvs->mode_mask, val); 320 + 321 + return regmap_update_bits(rdev->regmap, dvs->mode_reg, 322 + dvs->mode_mask, val); 323 + } 324 + 325 + static unsigned int pca9450_buck_get_mode(struct regulator_dev *rdev) 326 + { 327 + struct pca9450_regulator_desc *desc = container_of(rdev->desc, 328 + struct pca9450_regulator_desc, desc); 329 + const struct pc9450_dvs_config *dvs = &desc->dvs; 330 + int ret = 0, regval; 331 + 332 + ret = regmap_read(rdev->regmap, dvs->mode_reg, &regval); 333 + if (ret != 0) { 334 + dev_err(&rdev->dev, 335 + "Failed to get pca9450 buck mode: %d\n", ret); 336 + return ret; 337 + } 338 + 339 + if ((regval & dvs->mode_mask) == dvs->mode_mask) 340 + return REGULATOR_MODE_FAST; 341 + 342 + return REGULATOR_MODE_NORMAL; 343 + } 344 + 345 + static struct pca9450_regulator_desc pca9450a_regulators[] = { 299 346 { 300 347 .desc = { 301 348 .name = "buck1", ··· 375 308 .enable_val = BUCK_ENMODE_ONREQ, 376 309 .owner = THIS_MODULE, 377 310 .of_parse_cb = pca9450_set_dvs_levels, 311 + .of_map_mode = pca9450_map_mode, 378 312 }, 379 313 .dvs = { 380 314 .run_reg = PCA9450_REG_BUCK1OUT_DVS0, 381 315 .run_mask = BUCK1OUT_DVS0_MASK, 382 316 .standby_reg = PCA9450_REG_BUCK1OUT_DVS1, 383 317 .standby_mask = BUCK1OUT_DVS1_MASK, 318 + .mode_reg = PCA9450_REG_BUCK1CTRL, 319 + .mode_mask = BUCK1_FPWM, 384 320 }, 385 321 }, 386 322 { ··· 408 338 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table), 409 339 .owner = THIS_MODULE, 410 340 .of_parse_cb = pca9450_set_dvs_levels, 341 + .of_map_mode = pca9450_map_mode, 411 342 }, 412 343 .dvs = { 413 344 .run_reg = PCA9450_REG_BUCK2OUT_DVS0, 414 345 .run_mask = BUCK2OUT_DVS0_MASK, 415 346 .standby_reg = PCA9450_REG_BUCK2OUT_DVS1, 416 347 .standby_mask = BUCK2OUT_DVS1_MASK, 348 + .mode_reg = PCA9450_REG_BUCK2CTRL, 349 + .mode_mask = BUCK2_FPWM, 417 350 }, 418 351 }, 419 352 { ··· 441 368 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table), 442 369 .owner = THIS_MODULE, 443 370 .of_parse_cb = pca9450_set_dvs_levels, 371 + .of_map_mode = pca9450_map_mode, 444 372 }, 445 373 .dvs = { 446 374 .run_reg = PCA9450_REG_BUCK3OUT_DVS0, 447 375 .run_mask = BUCK3OUT_DVS0_MASK, 448 376 .standby_reg = PCA9450_REG_BUCK3OUT_DVS1, 449 377 .standby_mask = BUCK3OUT_DVS1_MASK, 378 + .mode_reg = PCA9450_REG_BUCK3CTRL, 379 + .mode_mask = BUCK3_FPWM, 450 380 }, 451 381 }, 452 382 { ··· 469 393 .enable_mask = BUCK4_ENMODE_MASK, 470 394 .enable_val = BUCK_ENMODE_ONREQ, 471 395 .owner = THIS_MODULE, 396 + .of_map_mode = pca9450_map_mode, 397 + }, 398 + .dvs = { 399 + .mode_reg = PCA9450_REG_BUCK4CTRL, 400 + .mode_mask = BUCK4_FPWM, 472 401 }, 473 402 }, 474 403 { ··· 493 412 .enable_mask = BUCK5_ENMODE_MASK, 494 413 .enable_val = BUCK_ENMODE_ONREQ, 495 414 .owner = THIS_MODULE, 415 + .of_map_mode = pca9450_map_mode, 416 + }, 417 + .dvs = { 418 + .mode_reg = PCA9450_REG_BUCK5CTRL, 419 + .mode_mask = BUCK5_FPWM, 496 420 }, 497 421 }, 498 422 { ··· 517 431 .enable_mask = BUCK6_ENMODE_MASK, 518 432 .enable_val = BUCK_ENMODE_ONREQ, 519 433 .owner = THIS_MODULE, 434 + .of_map_mode = pca9450_map_mode, 435 + }, 436 + .dvs = { 437 + .mode_reg = PCA9450_REG_BUCK6CTRL, 438 + .mode_mask = BUCK6_FPWM, 520 439 }, 521 440 }, 522 441 { ··· 620 529 * Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase 621 530 * on PCA9450C as no Buck3. 622 531 */ 623 - static const struct pca9450_regulator_desc pca9450bc_regulators[] = { 532 + static struct pca9450_regulator_desc pca9450bc_regulators[] = { 624 533 { 625 534 .desc = { 626 535 .name = "buck1", ··· 643 552 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table), 644 553 .owner = THIS_MODULE, 645 554 .of_parse_cb = pca9450_set_dvs_levels, 555 + .of_map_mode = pca9450_map_mode, 646 556 }, 647 557 .dvs = { 648 558 .run_reg = PCA9450_REG_BUCK1OUT_DVS0, 649 559 .run_mask = BUCK1OUT_DVS0_MASK, 650 560 .standby_reg = PCA9450_REG_BUCK1OUT_DVS1, 651 561 .standby_mask = BUCK1OUT_DVS1_MASK, 562 + .mode_reg = PCA9450_REG_BUCK1CTRL, 563 + .mode_mask = BUCK1_FPWM, 652 564 }, 653 565 }, 654 566 { ··· 676 582 .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table), 677 583 .owner = THIS_MODULE, 678 584 .of_parse_cb = pca9450_set_dvs_levels, 585 + .of_map_mode = pca9450_map_mode, 679 586 }, 680 587 .dvs = { 681 588 .run_reg = PCA9450_REG_BUCK2OUT_DVS0, 682 589 .run_mask = BUCK2OUT_DVS0_MASK, 683 590 .standby_reg = PCA9450_REG_BUCK2OUT_DVS1, 684 591 .standby_mask = BUCK2OUT_DVS1_MASK, 592 + .mode_reg = PCA9450_REG_BUCK2CTRL, 593 + .mode_mask = BUCK2_FPWM, 685 594 }, 686 595 }, 687 596 { ··· 704 607 .enable_mask = BUCK4_ENMODE_MASK, 705 608 .enable_val = BUCK_ENMODE_ONREQ, 706 609 .owner = THIS_MODULE, 610 + .of_map_mode = pca9450_map_mode, 611 + }, 612 + .dvs = { 613 + .mode_reg = PCA9450_REG_BUCK4CTRL, 614 + .mode_mask = BUCK4_FPWM, 707 615 }, 708 616 }, 709 617 { ··· 728 626 .enable_mask = BUCK5_ENMODE_MASK, 729 627 .enable_val = BUCK_ENMODE_ONREQ, 730 628 .owner = THIS_MODULE, 629 + .of_map_mode = pca9450_map_mode, 630 + }, 631 + .dvs = { 632 + .mode_reg = PCA9450_REG_BUCK5CTRL, 633 + .mode_mask = BUCK5_FPWM, 731 634 }, 732 635 }, 733 636 { ··· 752 645 .enable_mask = BUCK6_ENMODE_MASK, 753 646 .enable_val = BUCK_ENMODE_ONREQ, 754 647 .owner = THIS_MODULE, 648 + .of_map_mode = pca9450_map_mode, 649 + }, 650 + .dvs = { 651 + .mode_reg = PCA9450_REG_BUCK6CTRL, 652 + .mode_mask = BUCK6_FPWM, 755 653 }, 756 654 }, 757 655 { ··· 851 739 }, 852 740 }; 853 741 854 - static const struct pca9450_regulator_desc pca9451a_regulators[] = { 742 + static struct pca9450_regulator_desc pca9451a_regulators[] = { 855 743 { 856 744 .desc = { 857 745 .name = "buck1", ··· 1102 990 { 1103 991 enum pca9450_chip_type type = (unsigned int)(uintptr_t) 1104 992 of_device_get_match_data(&i2c->dev); 1105 - const struct pca9450_regulator_desc *regulator_desc; 993 + const struct pca9450_regulator_desc *regulator_desc; 1106 994 struct regulator_config config = { }; 1107 995 struct regulator_dev *ldo5; 1108 996 struct pca9450 *pca9450;