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: bd96801: Support ROHM BD96802

The ROHM BD96802 PMIC is primarily intended to be used as a companion
PMIC extending the capabilities of the BD96802 but it can be used on
it's own as well. When used as a companion PMIC, the start-up and
shut-down sequences are usually intitiated by the master PMIC using IF
pins.

The BD96802 looks from the digital interface point of view pretty much
like a reduced version of BD96801. It includes only 2 BUCKs and provides
the same error protection/detection mechanisms as the BD96801. Also, the
voltage control logic is same up to the register addresses.

Add support for controlling BD96802 using the BD96801 driver.

Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/2fb2d0d4997c32d18bfa32cea4564352c00eebc8.1744090658.git.mazziesaccount@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Matti Vaittinen and committed by
Lee Jones
55606b9b 4094040b

+86 -9
+86 -9
drivers/regulator/bd96801-regulator.c
··· 160 160 REGULATOR_LINEAR_RANGE(3300000 - 150000, 0xed, 0xff, 0), 161 161 }; 162 162 163 + /* BD96802 uses same voltage ranges for bucks as BD96801 */ 164 + #define bd96802_tune_volts bd96801_tune_volts 165 + #define bd96802_buck_init_volts bd96801_buck_init_volts 163 166 static const struct linear_range bd96801_ldo_int_volts[] = { 164 167 REGULATOR_LINEAR_RANGE(300000, 0x00, 0x78, 25000), 165 168 REGULATOR_LINEAR_RANGE(3300000, 0x79, 0xff, 0), ··· 305 302 struct bd96801_regulator_data regulator_data[BD96801_NUM_REGULATORS]; 306 303 struct regmap *regmap; 307 304 int fatal_ind; 305 + int num_regulators; 308 306 }; 309 307 310 308 static int ldo_map_notif(int irq, struct regulator_irq_data *rid, ··· 507 503 * case later. What we can easly do for preparing is to not use static global 508 504 * data for regulators though. 509 505 */ 506 + static const struct bd96801_pmic_data bd96802_data = { 507 + .regulator_data = { 508 + { 509 + .desc = { 510 + .name = "buck1", 511 + .of_match = of_match_ptr("buck1"), 512 + .regulators_node = of_match_ptr("regulators"), 513 + .id = BD96801_BUCK1, 514 + .ops = &bd96801_buck_ops, 515 + .type = REGULATOR_VOLTAGE, 516 + .linear_ranges = bd96802_tune_volts, 517 + .n_linear_ranges = ARRAY_SIZE(bd96802_tune_volts), 518 + .n_voltages = BD96801_BUCK_VOLTS, 519 + .enable_reg = BD96801_REG_ENABLE, 520 + .enable_mask = BD96801_BUCK1_EN_MASK, 521 + .enable_is_inverted = true, 522 + .vsel_reg = BD96801_BUCK1_VSEL_REG, 523 + .vsel_mask = BD96801_BUCK_VSEL_MASK, 524 + .ramp_reg = BD96801_BUCK1_VSEL_REG, 525 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 526 + .ramp_delay_table = &buck_ramp_table[0], 527 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 528 + .owner = THIS_MODULE, 529 + }, 530 + .init_ranges = bd96802_buck_init_volts, 531 + .num_ranges = ARRAY_SIZE(bd96802_buck_init_volts), 532 + .irq_desc = { 533 + .irqinfo = (struct bd96801_irqinfo *)&buck1_irqinfo[0], 534 + .num_irqs = ARRAY_SIZE(buck1_irqinfo), 535 + }, 536 + }, 537 + { 538 + .desc = { 539 + .name = "buck2", 540 + .of_match = of_match_ptr("buck2"), 541 + .regulators_node = of_match_ptr("regulators"), 542 + .id = BD96801_BUCK2, 543 + .ops = &bd96801_buck_ops, 544 + .type = REGULATOR_VOLTAGE, 545 + .linear_ranges = bd96802_tune_volts, 546 + .n_linear_ranges = ARRAY_SIZE(bd96802_tune_volts), 547 + .n_voltages = BD96801_BUCK_VOLTS, 548 + .enable_reg = BD96801_REG_ENABLE, 549 + .enable_mask = BD96801_BUCK2_EN_MASK, 550 + .enable_is_inverted = true, 551 + .vsel_reg = BD96801_BUCK2_VSEL_REG, 552 + .vsel_mask = BD96801_BUCK_VSEL_MASK, 553 + .ramp_reg = BD96801_BUCK2_VSEL_REG, 554 + .ramp_mask = BD96801_MASK_RAMP_DELAY, 555 + .ramp_delay_table = &buck_ramp_table[0], 556 + .n_ramp_values = ARRAY_SIZE(buck_ramp_table), 557 + .owner = THIS_MODULE, 558 + }, 559 + .irq_desc = { 560 + .irqinfo = (struct bd96801_irqinfo *)&buck2_irqinfo[0], 561 + .num_irqs = ARRAY_SIZE(buck2_irqinfo), 562 + }, 563 + .init_ranges = bd96802_buck_init_volts, 564 + .num_ranges = ARRAY_SIZE(bd96802_buck_init_volts), 565 + }, 566 + }, 567 + .num_regulators = 2, 568 + }; 569 + 510 570 static const struct bd96801_pmic_data bd96801_data = { 511 571 .regulator_data = { 512 572 { ··· 756 688 .ldo_vol_lvl = BD96801_LDO7_VOL_LVL_REG, 757 689 }, 758 690 }, 691 + .num_regulators = 7, 759 692 }; 760 693 761 - static int initialize_pmic_data(struct device *dev, 694 + static int initialize_pmic_data(struct platform_device *pdev, 762 695 struct bd96801_pmic_data *pdata) 763 696 { 697 + struct device *dev = &pdev->dev; 764 698 int r, i; 765 699 766 700 /* ··· 770 700 * wish to modify IRQ information independently for each driver 771 701 * instance. 772 702 */ 773 - for (r = 0; r < BD96801_NUM_REGULATORS; r++) { 703 + for (r = 0; r < pdata->num_regulators; r++) { 774 704 const struct bd96801_irqinfo *template; 775 705 struct bd96801_irqinfo *new; 776 706 int num_infos; ··· 936 866 { 937 867 struct regulator_dev *ldo_errs_rdev_arr[BD96801_NUM_LDOS]; 938 868 struct regulator_dev *all_rdevs[BD96801_NUM_REGULATORS]; 869 + struct bd96801_pmic_data *pdata_template; 939 870 struct bd96801_regulator_data *rdesc; 940 871 struct regulator_config config = {}; 941 872 int ldo_errs_arr[BD96801_NUM_LDOS]; ··· 949 878 950 879 parent = pdev->dev.parent; 951 880 952 - pdata = devm_kmemdup(&pdev->dev, &bd96801_data, sizeof(bd96801_data), 881 + pdata_template = (struct bd96801_pmic_data *)platform_get_device_id(pdev)->driver_data; 882 + if (!pdata_template) 883 + return -ENODEV; 884 + 885 + pdata = devm_kmemdup(&pdev->dev, pdata_template, sizeof(bd96801_data), 953 886 GFP_KERNEL); 954 887 if (!pdata) 955 888 return -ENOMEM; 956 889 957 - if (initialize_pmic_data(&pdev->dev, pdata)) 890 + if (initialize_pmic_data(pdev, pdata)) 958 891 return -ENOMEM; 959 892 960 893 pdata->regmap = dev_get_regmap(parent, NULL); ··· 981 906 use_errb = true; 982 907 983 908 ret = bd96801_walk_regulator_dt(&pdev->dev, pdata->regmap, rdesc, 984 - BD96801_NUM_REGULATORS); 909 + pdata->num_regulators); 985 910 if (ret) 986 911 return ret; 987 912 988 - for (i = 0; i < ARRAY_SIZE(pdata->regulator_data); i++) { 913 + for (i = 0; i < pdata->num_regulators; i++) { 989 914 struct regulator_dev *rdev; 990 915 struct bd96801_irq_desc *idesc = &rdesc[i].irq_desc; 991 916 int j; ··· 998 923 rdesc[i].desc.name); 999 924 return PTR_ERR(rdev); 1000 925 } 926 + 1001 927 all_rdevs[i] = rdev; 1002 928 /* 1003 929 * LDOs don't have own temperature monitoring. If temperature ··· 1048 972 1049 973 if (use_errb) 1050 974 return bd96801_global_errb_irqs(pdev, all_rdevs, 1051 - ARRAY_SIZE(all_rdevs)); 975 + pdata->num_regulators); 1052 976 1053 977 return 0; 1054 978 } 1055 979 1056 980 static const struct platform_device_id bd96801_pmic_id[] = { 1057 - { "bd96801-regulator", }, 1058 - { } 981 + { "bd96801-regulator", (kernel_ulong_t)&bd96801_data }, 982 + { "bd96802-regulator", (kernel_ulong_t)&bd96802_data }, 983 + { }, 1059 984 }; 1060 985 MODULE_DEVICE_TABLE(platform, bd96801_pmic_id); 1061 986