12ece646cSMatti Vaittinen // SPDX-License-Identifier: GPL-2.0 22ece646cSMatti Vaittinen // Copyright (C) 2018 ROHM Semiconductors 32ece646cSMatti Vaittinen // bd71837-regulator.c ROHM BD71837MWV/BD71847MWV regulator driver 42ece646cSMatti Vaittinen 52ece646cSMatti Vaittinen #include <linux/delay.h> 62ece646cSMatti Vaittinen #include <linux/err.h> 72ece646cSMatti Vaittinen #include <linux/interrupt.h> 82ece646cSMatti Vaittinen #include <linux/kernel.h> 92ece646cSMatti Vaittinen #include <linux/mfd/rohm-bd718x7.h> 102ece646cSMatti Vaittinen #include <linux/module.h> 119cce7244SMatti Vaittinen #include <linux/of.h> 122ece646cSMatti Vaittinen #include <linux/platform_device.h> 132ece646cSMatti Vaittinen #include <linux/regulator/driver.h> 142ece646cSMatti Vaittinen #include <linux/regulator/machine.h> 152ece646cSMatti Vaittinen #include <linux/regulator/of_regulator.h> 162ece646cSMatti Vaittinen #include <linux/slab.h> 172ece646cSMatti Vaittinen 18*3b66e4a8SGuido Günther /* Typical regulator startup times as per data sheet in uS */ 19*3b66e4a8SGuido Günther #define BD71847_BUCK1_STARTUP_TIME 144 20*3b66e4a8SGuido Günther #define BD71847_BUCK2_STARTUP_TIME 162 21*3b66e4a8SGuido Günther #define BD71847_BUCK3_STARTUP_TIME 162 22*3b66e4a8SGuido Günther #define BD71847_BUCK4_STARTUP_TIME 240 23*3b66e4a8SGuido Günther #define BD71847_BUCK5_STARTUP_TIME 270 24*3b66e4a8SGuido Günther #define BD71847_BUCK6_STARTUP_TIME 200 25*3b66e4a8SGuido Günther #define BD71847_LDO1_STARTUP_TIME 440 26*3b66e4a8SGuido Günther #define BD71847_LDO2_STARTUP_TIME 370 27*3b66e4a8SGuido Günther #define BD71847_LDO3_STARTUP_TIME 310 28*3b66e4a8SGuido Günther #define BD71847_LDO4_STARTUP_TIME 400 29*3b66e4a8SGuido Günther #define BD71847_LDO5_STARTUP_TIME 530 30*3b66e4a8SGuido Günther #define BD71847_LDO6_STARTUP_TIME 400 31*3b66e4a8SGuido Günther 32*3b66e4a8SGuido Günther #define BD71837_BUCK1_STARTUP_TIME 160 33*3b66e4a8SGuido Günther #define BD71837_BUCK2_STARTUP_TIME 180 34*3b66e4a8SGuido Günther #define BD71837_BUCK3_STARTUP_TIME 180 35*3b66e4a8SGuido Günther #define BD71837_BUCK4_STARTUP_TIME 180 36*3b66e4a8SGuido Günther #define BD71837_BUCK5_STARTUP_TIME 160 37*3b66e4a8SGuido Günther #define BD71837_BUCK6_STARTUP_TIME 240 38*3b66e4a8SGuido Günther #define BD71837_BUCK7_STARTUP_TIME 220 39*3b66e4a8SGuido Günther #define BD71837_BUCK8_STARTUP_TIME 200 40*3b66e4a8SGuido Günther #define BD71837_LDO1_STARTUP_TIME 440 41*3b66e4a8SGuido Günther #define BD71837_LDO2_STARTUP_TIME 370 42*3b66e4a8SGuido Günther #define BD71837_LDO3_STARTUP_TIME 310 43*3b66e4a8SGuido Günther #define BD71837_LDO4_STARTUP_TIME 400 44*3b66e4a8SGuido Günther #define BD71837_LDO5_STARTUP_TIME 310 45*3b66e4a8SGuido Günther #define BD71837_LDO6_STARTUP_TIME 400 46*3b66e4a8SGuido Günther #define BD71837_LDO7_STARTUP_TIME 530 47*3b66e4a8SGuido Günther 482ece646cSMatti Vaittinen /* 491d848d68SMatti Vaittinen * BD718(37/47/50) have two "enable control modes". ON/OFF can either be 501d848d68SMatti Vaittinen * controlled by software - or by PMIC internal HW state machine. Whether 511d848d68SMatti Vaittinen * regulator should be under SW or HW control can be defined from device-tree. 521d848d68SMatti Vaittinen * Let's provide separate ops for regulators to use depending on the "enable 531d848d68SMatti Vaittinen * control mode". 541d848d68SMatti Vaittinen */ 551d848d68SMatti Vaittinen #define BD718XX_HWOPNAME(swopname) swopname##_hwcontrol 561d848d68SMatti Vaittinen 571d848d68SMatti Vaittinen #define BD718XX_OPS(name, _list_voltage, _map_voltage, _set_voltage_sel, \ 581d848d68SMatti Vaittinen _get_voltage_sel, _set_voltage_time_sel, _set_ramp_delay) \ 591d848d68SMatti Vaittinen static const struct regulator_ops name = { \ 601d848d68SMatti Vaittinen .enable = regulator_enable_regmap, \ 611d848d68SMatti Vaittinen .disable = regulator_disable_regmap, \ 621d848d68SMatti Vaittinen .is_enabled = regulator_is_enabled_regmap, \ 631d848d68SMatti Vaittinen .list_voltage = (_list_voltage), \ 641d848d68SMatti Vaittinen .map_voltage = (_map_voltage), \ 651d848d68SMatti Vaittinen .set_voltage_sel = (_set_voltage_sel), \ 661d848d68SMatti Vaittinen .get_voltage_sel = (_get_voltage_sel), \ 671d848d68SMatti Vaittinen .set_voltage_time_sel = (_set_voltage_time_sel), \ 681d848d68SMatti Vaittinen .set_ramp_delay = (_set_ramp_delay), \ 691d848d68SMatti Vaittinen }; \ 701d848d68SMatti Vaittinen \ 711d848d68SMatti Vaittinen static const struct regulator_ops BD718XX_HWOPNAME(name) = { \ 721d848d68SMatti Vaittinen .is_enabled = always_enabled_by_hwstate, \ 731d848d68SMatti Vaittinen .list_voltage = (_list_voltage), \ 741d848d68SMatti Vaittinen .map_voltage = (_map_voltage), \ 751d848d68SMatti Vaittinen .set_voltage_sel = (_set_voltage_sel), \ 761d848d68SMatti Vaittinen .get_voltage_sel = (_get_voltage_sel), \ 771d848d68SMatti Vaittinen .set_voltage_time_sel = (_set_voltage_time_sel), \ 781d848d68SMatti Vaittinen .set_ramp_delay = (_set_ramp_delay), \ 791d848d68SMatti Vaittinen } \ 801d848d68SMatti Vaittinen 811d848d68SMatti Vaittinen /* 822ece646cSMatti Vaittinen * BUCK1/2/3/4 832ece646cSMatti Vaittinen * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting 842ece646cSMatti Vaittinen * 00: 10.00mV/usec 10mV 1uS 852ece646cSMatti Vaittinen * 01: 5.00mV/usec 10mV 2uS 862ece646cSMatti Vaittinen * 10: 2.50mV/usec 10mV 4uS 872ece646cSMatti Vaittinen * 11: 1.25mV/usec 10mV 8uS 882ece646cSMatti Vaittinen */ 892ece646cSMatti Vaittinen static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev, 902ece646cSMatti Vaittinen int ramp_delay) 912ece646cSMatti Vaittinen { 920a245f0eSAxel Lin int id = rdev_get_id(rdev); 930a245f0eSAxel Lin unsigned int ramp_value; 942ece646cSMatti Vaittinen 95bcb047ebSAxel Lin dev_dbg(&rdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1, 962ece646cSMatti Vaittinen ramp_delay); 972ece646cSMatti Vaittinen switch (ramp_delay) { 982ece646cSMatti Vaittinen case 1 ... 1250: 992ece646cSMatti Vaittinen ramp_value = BUCK_RAMPRATE_1P25MV; 1002ece646cSMatti Vaittinen break; 1012ece646cSMatti Vaittinen case 1251 ... 2500: 1022ece646cSMatti Vaittinen ramp_value = BUCK_RAMPRATE_2P50MV; 1032ece646cSMatti Vaittinen break; 1042ece646cSMatti Vaittinen case 2501 ... 5000: 1052ece646cSMatti Vaittinen ramp_value = BUCK_RAMPRATE_5P00MV; 1062ece646cSMatti Vaittinen break; 1072ece646cSMatti Vaittinen case 5001 ... 10000: 1082ece646cSMatti Vaittinen ramp_value = BUCK_RAMPRATE_10P00MV; 1092ece646cSMatti Vaittinen break; 1102ece646cSMatti Vaittinen default: 1112ece646cSMatti Vaittinen ramp_value = BUCK_RAMPRATE_10P00MV; 112bcb047ebSAxel Lin dev_err(&rdev->dev, 1132ece646cSMatti Vaittinen "%s: ramp_delay: %d not supported, setting 10000mV//us\n", 1142ece646cSMatti Vaittinen rdev->desc->name, ramp_delay); 1152ece646cSMatti Vaittinen } 1162ece646cSMatti Vaittinen 117bcb047ebSAxel Lin return regmap_update_bits(rdev->regmap, BD718XX_REG_BUCK1_CTRL + id, 1182ece646cSMatti Vaittinen BUCK_RAMPRATE_MASK, ramp_value << 6); 1192ece646cSMatti Vaittinen } 1202ece646cSMatti Vaittinen 1211d848d68SMatti Vaittinen /* These functions are used when regulators are under HW state machine control. 1221d848d68SMatti Vaittinen * We assume PMIC is in RUN state because SW running and able to query the 1231d848d68SMatti Vaittinen * status. Most of the regulators have fixed ON or OFF state at RUN/IDLE so for 1241d848d68SMatti Vaittinen * them we just return a constant. BD71837 BUCK3 and BUCK4 are exceptions as 1251d848d68SMatti Vaittinen * they support configuring the ON/OFF state for RUN. 1261d848d68SMatti Vaittinen * 1271d848d68SMatti Vaittinen * Note for next hacker - these PMICs have a register where the HW state can be 1281d848d68SMatti Vaittinen * read. If assuming RUN appears to be false in your use-case - you can 1291d848d68SMatti Vaittinen * implement state reading (although that is not going to be atomic) before 1301d848d68SMatti Vaittinen * returning the enable state. 1311d848d68SMatti Vaittinen */ 1321d848d68SMatti Vaittinen static int always_enabled_by_hwstate(struct regulator_dev *rdev) 1331d848d68SMatti Vaittinen { 1341d848d68SMatti Vaittinen return 1; 1351d848d68SMatti Vaittinen } 1361d848d68SMatti Vaittinen 1371d848d68SMatti Vaittinen static int never_enabled_by_hwstate(struct regulator_dev *rdev) 1381d848d68SMatti Vaittinen { 1391d848d68SMatti Vaittinen return 0; 1401d848d68SMatti Vaittinen } 1411d848d68SMatti Vaittinen 1421d848d68SMatti Vaittinen static int bd71837_get_buck34_enable_hwctrl(struct regulator_dev *rdev) 1431d848d68SMatti Vaittinen { 1441d848d68SMatti Vaittinen int ret; 1451d848d68SMatti Vaittinen unsigned int val; 1461d848d68SMatti Vaittinen 1471d848d68SMatti Vaittinen ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); 1481d848d68SMatti Vaittinen if (ret) 1491d848d68SMatti Vaittinen return ret; 1501d848d68SMatti Vaittinen 1511d848d68SMatti Vaittinen return !!(BD718XX_BUCK_RUN_ON & val); 1521d848d68SMatti Vaittinen } 153f0ca7b24SMatti Vaittinen /* 154f0ca7b24SMatti Vaittinen * On BD71837 (not on BD71847, BD71850, ...) 155f0ca7b24SMatti Vaittinen * Bucks 1 to 4 support DVS. PWM mode is used when voltage is changed. 1562ece646cSMatti Vaittinen * Bucks 5 to 8 and LDOs can use PFM and must be disabled when voltage 1572ece646cSMatti Vaittinen * is changed. Hence we return -EBUSY for these if voltage is changed 1582ece646cSMatti Vaittinen * when BUCK/LDO is enabled. 159f0ca7b24SMatti Vaittinen * 1609bcbabafSMatti Vaittinen * On BD71847, BD71850, ... The LDO voltage can be changed when LDO is 1619bcbabafSMatti Vaittinen * enabled. But if voltage is increased the LDO power-good monitoring 1629bcbabafSMatti Vaittinen * must be disabled for the duration of changing + 1mS to ensure voltage 1639bcbabafSMatti Vaittinen * has reached the higher level before HW does next under voltage detection 1649bcbabafSMatti Vaittinen * cycle. 1652ece646cSMatti Vaittinen */ 1669bcbabafSMatti Vaittinen static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev, 1672ece646cSMatti Vaittinen unsigned int sel) 1682ece646cSMatti Vaittinen { 1691d848d68SMatti Vaittinen if (rdev->desc->ops->is_enabled(rdev)) 1702ece646cSMatti Vaittinen return -EBUSY; 1712ece646cSMatti Vaittinen 1722ece646cSMatti Vaittinen return regulator_set_voltage_sel_regmap(rdev, sel); 1732ece646cSMatti Vaittinen } 1742ece646cSMatti Vaittinen 1759bcbabafSMatti Vaittinen static void voltage_change_done(struct regulator_dev *rdev, unsigned int sel, 1769bcbabafSMatti Vaittinen unsigned int *mask) 1779bcbabafSMatti Vaittinen { 1789bcbabafSMatti Vaittinen int ret; 1799bcbabafSMatti Vaittinen 1809bcbabafSMatti Vaittinen if (*mask) { 1819bcbabafSMatti Vaittinen /* 1829bcbabafSMatti Vaittinen * Let's allow scheduling as we use I2C anyways. We just need to 1839bcbabafSMatti Vaittinen * guarantee minimum of 1ms sleep - it shouldn't matter if we 1849bcbabafSMatti Vaittinen * exceed it due to the scheduling. 1859bcbabafSMatti Vaittinen */ 1869bcbabafSMatti Vaittinen msleep(1); 1879bcbabafSMatti Vaittinen /* 1889bcbabafSMatti Vaittinen * Note for next hacker. The PWRGOOD should not be masked on 1899bcbabafSMatti Vaittinen * BD71847 so we will just unconditionally enable detection 1909bcbabafSMatti Vaittinen * when voltage is set. 1919bcbabafSMatti Vaittinen * If someone want's to disable PWRGOOD he must implement 1929bcbabafSMatti Vaittinen * caching and restoring the old value here. I am not 1939bcbabafSMatti Vaittinen * aware of such use-cases so for the sake of the simplicity 1949bcbabafSMatti Vaittinen * we just always enable PWRGOOD here. 1959bcbabafSMatti Vaittinen */ 1969bcbabafSMatti Vaittinen ret = regmap_update_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2, 1979bcbabafSMatti Vaittinen *mask, 0); 1989bcbabafSMatti Vaittinen if (ret) 1999bcbabafSMatti Vaittinen dev_err(&rdev->dev, 2009bcbabafSMatti Vaittinen "Failed to re-enable voltage monitoring (%d)\n", 2019bcbabafSMatti Vaittinen ret); 2029bcbabafSMatti Vaittinen } 2039bcbabafSMatti Vaittinen } 2049bcbabafSMatti Vaittinen 2059bcbabafSMatti Vaittinen static int voltage_change_prepare(struct regulator_dev *rdev, unsigned int sel, 2069bcbabafSMatti Vaittinen unsigned int *mask) 2079bcbabafSMatti Vaittinen { 2089bcbabafSMatti Vaittinen int ret; 2099bcbabafSMatti Vaittinen 2109bcbabafSMatti Vaittinen *mask = 0; 2111d848d68SMatti Vaittinen if (rdev->desc->ops->is_enabled(rdev)) { 2129bcbabafSMatti Vaittinen int now, new; 2139bcbabafSMatti Vaittinen 2149bcbabafSMatti Vaittinen now = rdev->desc->ops->get_voltage_sel(rdev); 2159bcbabafSMatti Vaittinen if (now < 0) 2169bcbabafSMatti Vaittinen return now; 2179bcbabafSMatti Vaittinen 2189bcbabafSMatti Vaittinen now = rdev->desc->ops->list_voltage(rdev, now); 2199bcbabafSMatti Vaittinen if (now < 0) 2209bcbabafSMatti Vaittinen return now; 2219bcbabafSMatti Vaittinen 2229bcbabafSMatti Vaittinen new = rdev->desc->ops->list_voltage(rdev, sel); 2239bcbabafSMatti Vaittinen if (new < 0) 2249bcbabafSMatti Vaittinen return new; 2259bcbabafSMatti Vaittinen 2269bcbabafSMatti Vaittinen /* 2279bcbabafSMatti Vaittinen * If we increase LDO voltage when LDO is enabled we need to 2289bcbabafSMatti Vaittinen * disable the power-good detection until voltage has reached 2299bcbabafSMatti Vaittinen * the new level. According to HW colleagues the maximum time 2309bcbabafSMatti Vaittinen * it takes is 1000us. I assume that on systems with light load 2319bcbabafSMatti Vaittinen * this might be less - and we could probably use DT to give 2329bcbabafSMatti Vaittinen * system specific delay value if performance matters. 2339bcbabafSMatti Vaittinen * 2349bcbabafSMatti Vaittinen * Well, knowing we use I2C here and can add scheduling delays 2359bcbabafSMatti Vaittinen * I don't think it is worth the hassle and I just add fixed 2369bcbabafSMatti Vaittinen * 1ms sleep here (and allow scheduling). If this turns out to 2379bcbabafSMatti Vaittinen * be a problem we can change it to delay and make the delay 2389bcbabafSMatti Vaittinen * time configurable. 2399bcbabafSMatti Vaittinen */ 2409bcbabafSMatti Vaittinen if (new > now) { 2419bcbabafSMatti Vaittinen int ldo_offset = rdev->desc->id - BD718XX_LDO1; 2429bcbabafSMatti Vaittinen 2439bcbabafSMatti Vaittinen *mask = BD718XX_LDO1_VRMON80 << ldo_offset; 2449bcbabafSMatti Vaittinen ret = regmap_update_bits(rdev->regmap, 2459bcbabafSMatti Vaittinen BD718XX_REG_MVRFLTMASK2, 2469bcbabafSMatti Vaittinen *mask, *mask); 2479bcbabafSMatti Vaittinen if (ret) { 2489bcbabafSMatti Vaittinen dev_err(&rdev->dev, 2499bcbabafSMatti Vaittinen "Failed to stop voltage monitoring\n"); 2509bcbabafSMatti Vaittinen return ret; 2519bcbabafSMatti Vaittinen } 2529bcbabafSMatti Vaittinen } 2539bcbabafSMatti Vaittinen } 2549bcbabafSMatti Vaittinen 2559bcbabafSMatti Vaittinen return 0; 2569bcbabafSMatti Vaittinen } 2579bcbabafSMatti Vaittinen 2589bcbabafSMatti Vaittinen static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev, 2599bcbabafSMatti Vaittinen unsigned int sel) 2609bcbabafSMatti Vaittinen { 2619bcbabafSMatti Vaittinen int ret; 2629bcbabafSMatti Vaittinen int mask; 2639bcbabafSMatti Vaittinen 2649bcbabafSMatti Vaittinen ret = voltage_change_prepare(rdev, sel, &mask); 2659bcbabafSMatti Vaittinen if (ret) 2669bcbabafSMatti Vaittinen return ret; 2679bcbabafSMatti Vaittinen 2689bcbabafSMatti Vaittinen ret = regulator_set_voltage_sel_regmap(rdev, sel); 2699bcbabafSMatti Vaittinen voltage_change_done(rdev, sel, &mask); 2709bcbabafSMatti Vaittinen 2719bcbabafSMatti Vaittinen return ret; 2729bcbabafSMatti Vaittinen } 2739bcbabafSMatti Vaittinen 2742ece646cSMatti Vaittinen static int bd718xx_set_voltage_sel_pickable_restricted( 2752ece646cSMatti Vaittinen struct regulator_dev *rdev, unsigned int sel) 2762ece646cSMatti Vaittinen { 2779bcbabafSMatti Vaittinen int ret; 2789bcbabafSMatti Vaittinen int mask; 2799bcbabafSMatti Vaittinen 2809bcbabafSMatti Vaittinen ret = voltage_change_prepare(rdev, sel, &mask); 2819bcbabafSMatti Vaittinen if (ret) 2829bcbabafSMatti Vaittinen return ret; 2839bcbabafSMatti Vaittinen 2849bcbabafSMatti Vaittinen ret = regulator_set_voltage_sel_pickable_regmap(rdev, sel); 2859bcbabafSMatti Vaittinen voltage_change_done(rdev, sel, &mask); 2869bcbabafSMatti Vaittinen 2879bcbabafSMatti Vaittinen return ret; 2889bcbabafSMatti Vaittinen } 2899bcbabafSMatti Vaittinen 2909bcbabafSMatti Vaittinen static int bd71837_set_voltage_sel_pickable_restricted( 2919bcbabafSMatti Vaittinen struct regulator_dev *rdev, unsigned int sel) 2929bcbabafSMatti Vaittinen { 2931d848d68SMatti Vaittinen if (rdev->desc->ops->is_enabled(rdev)) 2942ece646cSMatti Vaittinen return -EBUSY; 2952ece646cSMatti Vaittinen 2962ece646cSMatti Vaittinen return regulator_set_voltage_sel_pickable_regmap(rdev, sel); 2972ece646cSMatti Vaittinen } 2982ece646cSMatti Vaittinen 2991d848d68SMatti Vaittinen /* 3001d848d68SMatti Vaittinen * OPS common for BD71847 and BD71850 3011d848d68SMatti Vaittinen */ 3021d848d68SMatti Vaittinen BD718XX_OPS(bd718xx_pickable_range_ldo_ops, 3031d848d68SMatti Vaittinen regulator_list_voltage_pickable_linear_range, NULL, 3041d848d68SMatti Vaittinen bd718xx_set_voltage_sel_pickable_restricted, 3051d848d68SMatti Vaittinen regulator_get_voltage_sel_pickable_regmap, NULL, NULL); 3061d848d68SMatti Vaittinen 3071d848d68SMatti Vaittinen /* BD71847 and BD71850 LDO 5 is by default OFF at RUN state */ 3081d848d68SMatti Vaittinen static const struct regulator_ops bd718xx_ldo5_ops_hwstate = { 3091d848d68SMatti Vaittinen .is_enabled = never_enabled_by_hwstate, 3102ece646cSMatti Vaittinen .list_voltage = regulator_list_voltage_pickable_linear_range, 3112ece646cSMatti Vaittinen .set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted, 3122ece646cSMatti Vaittinen .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, 3139bcbabafSMatti Vaittinen }; 3149bcbabafSMatti Vaittinen 3151d848d68SMatti Vaittinen BD718XX_OPS(bd718xx_pickable_range_buck_ops, 3161d848d68SMatti Vaittinen regulator_list_voltage_pickable_linear_range, NULL, 3171d848d68SMatti Vaittinen regulator_set_voltage_sel_pickable_regmap, 3181d848d68SMatti Vaittinen regulator_get_voltage_sel_pickable_regmap, 3191d848d68SMatti Vaittinen regulator_set_voltage_time_sel, NULL); 3202ece646cSMatti Vaittinen 3211d848d68SMatti Vaittinen BD718XX_OPS(bd718xx_ldo_regulator_ops, regulator_list_voltage_linear_range, 3221d848d68SMatti Vaittinen NULL, bd718xx_set_voltage_sel_restricted, 3231d848d68SMatti Vaittinen regulator_get_voltage_sel_regmap, NULL, NULL); 324f0ca7b24SMatti Vaittinen 3251d848d68SMatti Vaittinen BD718XX_OPS(bd718xx_ldo_regulator_nolinear_ops, regulator_list_voltage_table, 3261d848d68SMatti Vaittinen NULL, bd718xx_set_voltage_sel_restricted, 3271d848d68SMatti Vaittinen regulator_get_voltage_sel_regmap, NULL, NULL); 3282ece646cSMatti Vaittinen 3291d848d68SMatti Vaittinen BD718XX_OPS(bd718xx_buck_regulator_ops, regulator_list_voltage_linear_range, 3301d848d68SMatti Vaittinen NULL, regulator_set_voltage_sel_regmap, 3311d848d68SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 3321d848d68SMatti Vaittinen NULL); 3339bcbabafSMatti Vaittinen 3341d848d68SMatti Vaittinen BD718XX_OPS(bd718xx_buck_regulator_nolinear_ops, regulator_list_voltage_table, 3351d848d68SMatti Vaittinen regulator_map_voltage_ascend, regulator_set_voltage_sel_regmap, 3361d848d68SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 3371d848d68SMatti Vaittinen NULL); 3382ece646cSMatti Vaittinen 3391d848d68SMatti Vaittinen /* 3401d848d68SMatti Vaittinen * OPS for BD71837 3411d848d68SMatti Vaittinen */ 3421d848d68SMatti Vaittinen BD718XX_OPS(bd71837_pickable_range_ldo_ops, 3431d848d68SMatti Vaittinen regulator_list_voltage_pickable_linear_range, NULL, 3441d848d68SMatti Vaittinen bd71837_set_voltage_sel_pickable_restricted, 3451d848d68SMatti Vaittinen regulator_get_voltage_sel_pickable_regmap, NULL, NULL); 3469bcbabafSMatti Vaittinen 3471d848d68SMatti Vaittinen BD718XX_OPS(bd71837_pickable_range_buck_ops, 3481d848d68SMatti Vaittinen regulator_list_voltage_pickable_linear_range, NULL, 3491d848d68SMatti Vaittinen bd71837_set_voltage_sel_pickable_restricted, 3501d848d68SMatti Vaittinen regulator_get_voltage_sel_pickable_regmap, 3511d848d68SMatti Vaittinen regulator_set_voltage_time_sel, NULL); 3522ece646cSMatti Vaittinen 3531d848d68SMatti Vaittinen BD718XX_OPS(bd71837_ldo_regulator_ops, regulator_list_voltage_linear_range, 3541d848d68SMatti Vaittinen NULL, bd71837_set_voltage_sel_restricted, 3551d848d68SMatti Vaittinen regulator_get_voltage_sel_regmap, NULL, NULL); 356f0ca7b24SMatti Vaittinen 3571d848d68SMatti Vaittinen BD718XX_OPS(bd71837_ldo_regulator_nolinear_ops, regulator_list_voltage_table, 3581d848d68SMatti Vaittinen NULL, bd71837_set_voltage_sel_restricted, 3591d848d68SMatti Vaittinen regulator_get_voltage_sel_regmap, NULL, NULL); 3602ece646cSMatti Vaittinen 3611d848d68SMatti Vaittinen BD718XX_OPS(bd71837_buck_regulator_ops, regulator_list_voltage_linear_range, 3621d848d68SMatti Vaittinen NULL, bd71837_set_voltage_sel_restricted, 3631d848d68SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 3641d848d68SMatti Vaittinen NULL); 365f0ca7b24SMatti Vaittinen 3661d848d68SMatti Vaittinen BD718XX_OPS(bd71837_buck_regulator_nolinear_ops, regulator_list_voltage_table, 3671d848d68SMatti Vaittinen regulator_map_voltage_ascend, bd718xx_set_voltage_sel_restricted, 3681d848d68SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 3691d848d68SMatti Vaittinen NULL); 3701d848d68SMatti Vaittinen /* 3711d848d68SMatti Vaittinen * BD71837 bucks 3 and 4 support defining their enable/disable state also 3721d848d68SMatti Vaittinen * when buck enable state is under HW state machine control. In that case the 3731d848d68SMatti Vaittinen * bit [2] in CTRL register is used to indicate if regulator should be ON. 3741d848d68SMatti Vaittinen */ 3751d848d68SMatti Vaittinen static const struct regulator_ops bd71837_buck34_ops_hwctrl = { 3761d848d68SMatti Vaittinen .is_enabled = bd71837_get_buck34_enable_hwctrl, 3772ece646cSMatti Vaittinen .list_voltage = regulator_list_voltage_linear_range, 3782ece646cSMatti Vaittinen .set_voltage_sel = regulator_set_voltage_sel_regmap, 3792ece646cSMatti Vaittinen .get_voltage_sel = regulator_get_voltage_sel_regmap, 3802ece646cSMatti Vaittinen .set_voltage_time_sel = regulator_set_voltage_time_sel, 3812ece646cSMatti Vaittinen .set_ramp_delay = bd718xx_buck1234_set_ramp_delay, 3822ece646cSMatti Vaittinen }; 3832ece646cSMatti Vaittinen 3842ece646cSMatti Vaittinen /* 3851d848d68SMatti Vaittinen * OPS for all of the ICs - BD718(37/47/50) 3861d848d68SMatti Vaittinen */ 3871d848d68SMatti Vaittinen BD718XX_OPS(bd718xx_dvs_buck_regulator_ops, regulator_list_voltage_linear_range, 3881d848d68SMatti Vaittinen NULL, regulator_set_voltage_sel_regmap, 3891d848d68SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 3901d848d68SMatti Vaittinen bd718xx_buck1234_set_ramp_delay); 3911d848d68SMatti Vaittinen 3921d848d68SMatti Vaittinen /* 3932ece646cSMatti Vaittinen * BD71837 BUCK1/2/3/4 3942ece646cSMatti Vaittinen * BD71847 BUCK1/2 3952ece646cSMatti Vaittinen * 0.70 to 1.30V (10mV step) 3962ece646cSMatti Vaittinen */ 39760ab7f41SMatti Vaittinen static const struct linear_range bd718xx_dvs_buck_volts[] = { 3982ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000), 3992ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0), 4002ece646cSMatti Vaittinen }; 4012ece646cSMatti Vaittinen 4022ece646cSMatti Vaittinen /* 4032ece646cSMatti Vaittinen * BD71837 BUCK5 4042ece646cSMatti Vaittinen * 0.7V to 1.35V (range 0) 4052ece646cSMatti Vaittinen * and 4062ece646cSMatti Vaittinen * 0.675 to 1.325 (range 1) 4072ece646cSMatti Vaittinen */ 40860ab7f41SMatti Vaittinen static const struct linear_range bd71837_buck5_volts[] = { 4092ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bit is 0 */ 4102ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000), 4112ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000), 4122ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000), 4132ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bit is 1 */ 4142ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000), 4152ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000), 4162ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000), 4172ece646cSMatti Vaittinen }; 4182ece646cSMatti Vaittinen 4192ece646cSMatti Vaittinen /* 4202ece646cSMatti Vaittinen * Range selector for first 3 linear ranges is 0x0 4212ece646cSMatti Vaittinen * and 0x1 for last 3 ranges. 4222ece646cSMatti Vaittinen */ 4232ece646cSMatti Vaittinen static const unsigned int bd71837_buck5_volt_range_sel[] = { 4242ece646cSMatti Vaittinen 0x0, 0x0, 0x0, 0x80, 0x80, 0x80 4252ece646cSMatti Vaittinen }; 4262ece646cSMatti Vaittinen 4272ece646cSMatti Vaittinen /* 4282ece646cSMatti Vaittinen * BD71847 BUCK3 4292ece646cSMatti Vaittinen */ 43060ab7f41SMatti Vaittinen static const struct linear_range bd71847_buck3_volts[] = { 4312ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bits are 00 */ 4322ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000), 4332ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000), 4342ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000), 4352ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bits are 01 */ 4362ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(550000, 0x0, 0x7, 50000), 4372ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bits are 11 */ 4382ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000), 4392ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000), 4402ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000), 4412ece646cSMatti Vaittinen }; 4422ece646cSMatti Vaittinen 4432ece646cSMatti Vaittinen static const unsigned int bd71847_buck3_volt_range_sel[] = { 4442ece646cSMatti Vaittinen 0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80 4452ece646cSMatti Vaittinen }; 4462ece646cSMatti Vaittinen 44760ab7f41SMatti Vaittinen static const struct linear_range bd71847_buck4_volts[] = { 4482ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), 4492ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000), 4502ece646cSMatti Vaittinen }; 4512ece646cSMatti Vaittinen 4522ece646cSMatti Vaittinen static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 }; 4532ece646cSMatti Vaittinen 4542ece646cSMatti Vaittinen /* 4552ece646cSMatti Vaittinen * BUCK6 4562ece646cSMatti Vaittinen * 3.0V to 3.3V (step 100mV) 4572ece646cSMatti Vaittinen */ 45860ab7f41SMatti Vaittinen static const struct linear_range bd71837_buck6_volts[] = { 4592ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), 4602ece646cSMatti Vaittinen }; 4612ece646cSMatti Vaittinen 4622ece646cSMatti Vaittinen /* 4632ece646cSMatti Vaittinen * BD71837 BUCK7 4642ece646cSMatti Vaittinen * BD71847 BUCK5 4652ece646cSMatti Vaittinen * 000 = 1.605V 4662ece646cSMatti Vaittinen * 001 = 1.695V 4672ece646cSMatti Vaittinen * 010 = 1.755V 4682ece646cSMatti Vaittinen * 011 = 1.8V (Initial) 4692ece646cSMatti Vaittinen * 100 = 1.845V 4702ece646cSMatti Vaittinen * 101 = 1.905V 4712ece646cSMatti Vaittinen * 110 = 1.95V 4722ece646cSMatti Vaittinen * 111 = 1.995V 4732ece646cSMatti Vaittinen */ 4742ece646cSMatti Vaittinen static const unsigned int bd718xx_3rd_nodvs_buck_volts[] = { 4752ece646cSMatti Vaittinen 1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000 4762ece646cSMatti Vaittinen }; 4772ece646cSMatti Vaittinen 4782ece646cSMatti Vaittinen /* 4792ece646cSMatti Vaittinen * BUCK8 4802ece646cSMatti Vaittinen * 0.8V to 1.40V (step 10mV) 4812ece646cSMatti Vaittinen */ 48260ab7f41SMatti Vaittinen static const struct linear_range bd718xx_4th_nodvs_buck_volts[] = { 4832ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000), 4842ece646cSMatti Vaittinen }; 4852ece646cSMatti Vaittinen 4862ece646cSMatti Vaittinen /* 4872ece646cSMatti Vaittinen * LDO1 4882ece646cSMatti Vaittinen * 3.0 to 3.3V (100mV step) 4892ece646cSMatti Vaittinen */ 49060ab7f41SMatti Vaittinen static const struct linear_range bd718xx_ldo1_volts[] = { 4912ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), 4922ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000), 4932ece646cSMatti Vaittinen }; 4942ece646cSMatti Vaittinen 4952ece646cSMatti Vaittinen static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x20 }; 4962ece646cSMatti Vaittinen 4972ece646cSMatti Vaittinen /* 4982ece646cSMatti Vaittinen * LDO2 4992ece646cSMatti Vaittinen * 0.8 or 0.9V 5002ece646cSMatti Vaittinen */ 5012ece646cSMatti Vaittinen static const unsigned int ldo_2_volts[] = { 5022ece646cSMatti Vaittinen 900000, 800000 5032ece646cSMatti Vaittinen }; 5042ece646cSMatti Vaittinen 5052ece646cSMatti Vaittinen /* 5062ece646cSMatti Vaittinen * LDO3 5072ece646cSMatti Vaittinen * 1.8 to 3.3V (100mV step) 5082ece646cSMatti Vaittinen */ 50960ab7f41SMatti Vaittinen static const struct linear_range bd718xx_ldo3_volts[] = { 5102ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 5112ece646cSMatti Vaittinen }; 5122ece646cSMatti Vaittinen 5132ece646cSMatti Vaittinen /* 5142ece646cSMatti Vaittinen * LDO4 5152ece646cSMatti Vaittinen * 0.9 to 1.8V (100mV step) 5162ece646cSMatti Vaittinen */ 51760ab7f41SMatti Vaittinen static const struct linear_range bd718xx_ldo4_volts[] = { 5182ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000), 5192ece646cSMatti Vaittinen }; 5202ece646cSMatti Vaittinen 5212ece646cSMatti Vaittinen /* 5222ece646cSMatti Vaittinen * LDO5 for BD71837 5232ece646cSMatti Vaittinen * 1.8 to 3.3V (100mV step) 5242ece646cSMatti Vaittinen */ 52560ab7f41SMatti Vaittinen static const struct linear_range bd71837_ldo5_volts[] = { 5262ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 5272ece646cSMatti Vaittinen }; 5282ece646cSMatti Vaittinen 5292ece646cSMatti Vaittinen /* 5302ece646cSMatti Vaittinen * LDO5 for BD71837 5312ece646cSMatti Vaittinen * 1.8 to 3.3V (100mV step) 5322ece646cSMatti Vaittinen */ 53360ab7f41SMatti Vaittinen static const struct linear_range bd71847_ldo5_volts[] = { 5342ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 5352ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000), 5362ece646cSMatti Vaittinen }; 5372ece646cSMatti Vaittinen 5382ece646cSMatti Vaittinen static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 }; 5392ece646cSMatti Vaittinen 5402ece646cSMatti Vaittinen /* 5412ece646cSMatti Vaittinen * LDO6 5422ece646cSMatti Vaittinen * 0.9 to 1.8V (100mV step) 5432ece646cSMatti Vaittinen */ 54460ab7f41SMatti Vaittinen static const struct linear_range bd718xx_ldo6_volts[] = { 5452ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000), 5462ece646cSMatti Vaittinen }; 5472ece646cSMatti Vaittinen 5482ece646cSMatti Vaittinen /* 5492ece646cSMatti Vaittinen * LDO7 5502ece646cSMatti Vaittinen * 1.8 to 3.3V (100mV step) 5512ece646cSMatti Vaittinen */ 55260ab7f41SMatti Vaittinen static const struct linear_range bd71837_ldo7_volts[] = { 5532ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 5542ece646cSMatti Vaittinen }; 5552ece646cSMatti Vaittinen 5562ece646cSMatti Vaittinen struct reg_init { 5572ece646cSMatti Vaittinen unsigned int reg; 5582ece646cSMatti Vaittinen unsigned int mask; 5592ece646cSMatti Vaittinen unsigned int val; 5602ece646cSMatti Vaittinen }; 5612ece646cSMatti Vaittinen struct bd718xx_regulator_data { 5622ece646cSMatti Vaittinen struct regulator_desc desc; 56321b72156SMatti Vaittinen const struct rohm_dvs_config dvs; 5642ece646cSMatti Vaittinen const struct reg_init init; 5652ece646cSMatti Vaittinen const struct reg_init *additional_inits; 5662ece646cSMatti Vaittinen int additional_init_amnt; 5672ece646cSMatti Vaittinen }; 5682ece646cSMatti Vaittinen 5692ece646cSMatti Vaittinen /* 5702ece646cSMatti Vaittinen * There is a HW quirk in BD71837. The shutdown sequence timings for 5712ece646cSMatti Vaittinen * bucks/LDOs which are controlled via register interface are changed. 5722ece646cSMatti Vaittinen * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the 5732ece646cSMatti Vaittinen * beginning of shut-down sequence. As bucks 6 and 7 are parent 5742ece646cSMatti Vaittinen * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage 5752ece646cSMatti Vaittinen * monitoring to errorneously detect under voltage and force PMIC to 5762ece646cSMatti Vaittinen * emergency state instead of poweroff. In order to avoid this we 5772ece646cSMatti Vaittinen * disable voltage monitoring for LDO5 and LDO6 5782ece646cSMatti Vaittinen */ 5792ece646cSMatti Vaittinen static const struct reg_init bd71837_ldo5_inits[] = { 5802ece646cSMatti Vaittinen { 5812ece646cSMatti Vaittinen .reg = BD718XX_REG_MVRFLTMASK2, 5822ece646cSMatti Vaittinen .mask = BD718XX_LDO5_VRMON80, 5832ece646cSMatti Vaittinen .val = BD718XX_LDO5_VRMON80, 5842ece646cSMatti Vaittinen }, 5852ece646cSMatti Vaittinen }; 5862ece646cSMatti Vaittinen 5872ece646cSMatti Vaittinen static const struct reg_init bd71837_ldo6_inits[] = { 5882ece646cSMatti Vaittinen { 5892ece646cSMatti Vaittinen .reg = BD718XX_REG_MVRFLTMASK2, 5902ece646cSMatti Vaittinen .mask = BD718XX_LDO6_VRMON80, 5912ece646cSMatti Vaittinen .val = BD718XX_LDO6_VRMON80, 5922ece646cSMatti Vaittinen }, 5932ece646cSMatti Vaittinen }; 5942ece646cSMatti Vaittinen 59521b72156SMatti Vaittinen static int buck_set_hw_dvs_levels(struct device_node *np, 596049369d4SMatti Vaittinen const struct regulator_desc *desc, 597049369d4SMatti Vaittinen struct regulator_config *cfg) 598049369d4SMatti Vaittinen { 59921b72156SMatti Vaittinen struct bd718xx_regulator_data *data; 600049369d4SMatti Vaittinen 60121b72156SMatti Vaittinen data = container_of(desc, struct bd718xx_regulator_data, desc); 602049369d4SMatti Vaittinen 60321b72156SMatti Vaittinen return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap); 604049369d4SMatti Vaittinen } 605049369d4SMatti Vaittinen 60602f8eaabSYueHaibing static const struct regulator_ops *bd71847_swcontrol_ops[] = { 6071d848d68SMatti Vaittinen &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, 6081d848d68SMatti Vaittinen &bd718xx_pickable_range_buck_ops, &bd718xx_pickable_range_buck_ops, 6091d848d68SMatti Vaittinen &bd718xx_buck_regulator_nolinear_ops, &bd718xx_buck_regulator_ops, 6101d848d68SMatti Vaittinen &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_nolinear_ops, 6111d848d68SMatti Vaittinen &bd718xx_ldo_regulator_ops, &bd718xx_ldo_regulator_ops, 6121d848d68SMatti Vaittinen &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_ops, 6131d848d68SMatti Vaittinen }; 6141d848d68SMatti Vaittinen 61502f8eaabSYueHaibing static const struct regulator_ops *bd71847_hwcontrol_ops[] = { 6161d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 6171d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 6181d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops), 6191d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops), 6201d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_buck_regulator_nolinear_ops), 6211d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_buck_regulator_ops), 6221d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_pickable_range_ldo_ops), 6231d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_ldo_regulator_nolinear_ops), 6241d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), 6251d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), 6261d848d68SMatti Vaittinen &bd718xx_ldo5_ops_hwstate, 6271d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), 6281d848d68SMatti Vaittinen }; 6291d848d68SMatti Vaittinen 6301d848d68SMatti Vaittinen static struct bd718xx_regulator_data bd71847_regulators[] = { 6312ece646cSMatti Vaittinen { 6322ece646cSMatti Vaittinen .desc = { 6332ece646cSMatti Vaittinen .name = "buck1", 6342ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK1"), 6352ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 6362ece646cSMatti Vaittinen .id = BD718XX_BUCK1, 6372ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 6382ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 6392ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 6402ece646cSMatti Vaittinen .n_linear_ranges = 6412ece646cSMatti Vaittinen ARRAY_SIZE(bd718xx_dvs_buck_volts), 6422ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN, 6432ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 6442ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_BUCK1_CTRL, 6452ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 646*3b66e4a8SGuido Günther .enable_time = BD71847_BUCK1_STARTUP_TIME, 6472ece646cSMatti Vaittinen .owner = THIS_MODULE, 64821b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 64921b72156SMatti Vaittinen }, 65021b72156SMatti Vaittinen .dvs = { 65121b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | 65221b72156SMatti Vaittinen ROHM_DVS_LEVEL_SUSPEND, 65321b72156SMatti Vaittinen .run_reg = BD718XX_REG_BUCK1_VOLT_RUN, 65421b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 65521b72156SMatti Vaittinen .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE, 65621b72156SMatti Vaittinen .idle_mask = DVS_BUCK_RUN_MASK, 65721b72156SMatti Vaittinen .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP, 65821b72156SMatti Vaittinen .suspend_mask = DVS_BUCK_RUN_MASK, 6592ece646cSMatti Vaittinen }, 6602ece646cSMatti Vaittinen .init = { 6612ece646cSMatti Vaittinen .reg = BD718XX_REG_BUCK1_CTRL, 6622ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 6632ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 6642ece646cSMatti Vaittinen }, 6652ece646cSMatti Vaittinen }, 6662ece646cSMatti Vaittinen { 6672ece646cSMatti Vaittinen .desc = { 6682ece646cSMatti Vaittinen .name = "buck2", 6692ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK2"), 6702ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 6712ece646cSMatti Vaittinen .id = BD718XX_BUCK2, 6722ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 6732ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 6742ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 6752ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 6762ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN, 6772ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 6782ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_BUCK2_CTRL, 6792ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 680*3b66e4a8SGuido Günther .enable_time = BD71847_BUCK2_STARTUP_TIME, 6812ece646cSMatti Vaittinen .owner = THIS_MODULE, 68221b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 68321b72156SMatti Vaittinen }, 68421b72156SMatti Vaittinen .dvs = { 68521b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE, 68621b72156SMatti Vaittinen .run_reg = BD718XX_REG_BUCK2_VOLT_RUN, 68721b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 68821b72156SMatti Vaittinen .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE, 68921b72156SMatti Vaittinen .idle_mask = DVS_BUCK_RUN_MASK, 6902ece646cSMatti Vaittinen }, 6912ece646cSMatti Vaittinen .init = { 6922ece646cSMatti Vaittinen .reg = BD718XX_REG_BUCK2_CTRL, 6932ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 6942ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 6952ece646cSMatti Vaittinen }, 6962ece646cSMatti Vaittinen }, 6972ece646cSMatti Vaittinen { 6982ece646cSMatti Vaittinen .desc = { 6992ece646cSMatti Vaittinen .name = "buck3", 7002ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK3"), 7012ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 7022ece646cSMatti Vaittinen .id = BD718XX_BUCK3, 7032ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 7042ece646cSMatti Vaittinen .n_voltages = BD71847_BUCK3_VOLTAGE_NUM, 7052ece646cSMatti Vaittinen .linear_ranges = bd71847_buck3_volts, 7062ece646cSMatti Vaittinen .n_linear_ranges = 7072ece646cSMatti Vaittinen ARRAY_SIZE(bd71847_buck3_volts), 7082ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 7092ece646cSMatti Vaittinen .vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK, 7102ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 7112ece646cSMatti Vaittinen .vsel_range_mask = BD71847_BUCK3_RANGE_MASK, 7122ece646cSMatti Vaittinen .linear_range_selectors = bd71847_buck3_volt_range_sel, 7132ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 7142ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 715*3b66e4a8SGuido Günther .enable_time = BD71847_BUCK3_STARTUP_TIME, 7162ece646cSMatti Vaittinen .owner = THIS_MODULE, 7172ece646cSMatti Vaittinen }, 7182ece646cSMatti Vaittinen .init = { 7192ece646cSMatti Vaittinen .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 7202ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 7212ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 7222ece646cSMatti Vaittinen }, 7232ece646cSMatti Vaittinen }, 7242ece646cSMatti Vaittinen { 7252ece646cSMatti Vaittinen .desc = { 7262ece646cSMatti Vaittinen .name = "buck4", 7272ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK4"), 7282ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 7292ece646cSMatti Vaittinen .id = BD718XX_BUCK4, 7302ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 7312ece646cSMatti Vaittinen .n_voltages = BD71847_BUCK4_VOLTAGE_NUM, 7322ece646cSMatti Vaittinen .linear_ranges = bd71847_buck4_volts, 7332ece646cSMatti Vaittinen .n_linear_ranges = 7342ece646cSMatti Vaittinen ARRAY_SIZE(bd71847_buck4_volts), 7352ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 7362ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, 7372ece646cSMatti Vaittinen .vsel_mask = BD71847_BUCK4_MASK, 7382ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, 7392ece646cSMatti Vaittinen .vsel_range_mask = BD71847_BUCK4_RANGE_MASK, 7402ece646cSMatti Vaittinen .linear_range_selectors = bd71847_buck4_volt_range_sel, 7412ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 742*3b66e4a8SGuido Günther .enable_time = BD71847_BUCK4_STARTUP_TIME, 7432ece646cSMatti Vaittinen .owner = THIS_MODULE, 7442ece646cSMatti Vaittinen }, 7452ece646cSMatti Vaittinen .init = { 7462ece646cSMatti Vaittinen .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 7472ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 7482ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 7492ece646cSMatti Vaittinen }, 7502ece646cSMatti Vaittinen }, 7512ece646cSMatti Vaittinen { 7522ece646cSMatti Vaittinen .desc = { 7532ece646cSMatti Vaittinen .name = "buck5", 7542ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK5"), 7552ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 7562ece646cSMatti Vaittinen .id = BD718XX_BUCK5, 7572ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 7582ece646cSMatti Vaittinen .volt_table = &bd718xx_3rd_nodvs_buck_volts[0], 7592ece646cSMatti Vaittinen .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts), 7602ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT, 7612ece646cSMatti Vaittinen .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, 7622ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 7632ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 764*3b66e4a8SGuido Günther .enable_time = BD71847_BUCK5_STARTUP_TIME, 7652ece646cSMatti Vaittinen .owner = THIS_MODULE, 7662ece646cSMatti Vaittinen }, 7672ece646cSMatti Vaittinen .init = { 7682ece646cSMatti Vaittinen .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 7692ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 7702ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 7712ece646cSMatti Vaittinen }, 7722ece646cSMatti Vaittinen }, 7732ece646cSMatti Vaittinen { 7742ece646cSMatti Vaittinen .desc = { 7752ece646cSMatti Vaittinen .name = "buck6", 7762ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK6"), 7772ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 7782ece646cSMatti Vaittinen .id = BD718XX_BUCK6, 7792ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 7802ece646cSMatti Vaittinen .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM, 7812ece646cSMatti Vaittinen .linear_ranges = bd718xx_4th_nodvs_buck_volts, 7822ece646cSMatti Vaittinen .n_linear_ranges = 7832ece646cSMatti Vaittinen ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts), 7842ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT, 7852ece646cSMatti Vaittinen .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, 7862ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 7872ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 788*3b66e4a8SGuido Günther .enable_time = BD71847_BUCK6_STARTUP_TIME, 7892ece646cSMatti Vaittinen .owner = THIS_MODULE, 7902ece646cSMatti Vaittinen }, 7912ece646cSMatti Vaittinen .init = { 7922ece646cSMatti Vaittinen .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 7932ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 7942ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 7952ece646cSMatti Vaittinen }, 7962ece646cSMatti Vaittinen }, 7972ece646cSMatti Vaittinen { 7982ece646cSMatti Vaittinen .desc = { 7992ece646cSMatti Vaittinen .name = "ldo1", 8002ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO1"), 8012ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 8022ece646cSMatti Vaittinen .id = BD718XX_LDO1, 8032ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 8042ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO1_VOLTAGE_NUM, 8052ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo1_volts, 8062ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts), 8072ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO1_VOLT, 8082ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO1_MASK, 8092ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_LDO1_VOLT, 8102ece646cSMatti Vaittinen .vsel_range_mask = BD718XX_LDO1_RANGE_MASK, 8112ece646cSMatti Vaittinen .linear_range_selectors = bd718xx_ldo1_volt_range_sel, 8122ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO1_VOLT, 8132ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 814*3b66e4a8SGuido Günther .enable_time = BD71847_LDO1_STARTUP_TIME, 8152ece646cSMatti Vaittinen .owner = THIS_MODULE, 8162ece646cSMatti Vaittinen }, 8172ece646cSMatti Vaittinen .init = { 8182ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO1_VOLT, 8192ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 8202ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 8212ece646cSMatti Vaittinen }, 8222ece646cSMatti Vaittinen }, 8232ece646cSMatti Vaittinen { 8242ece646cSMatti Vaittinen .desc = { 8252ece646cSMatti Vaittinen .name = "ldo2", 8262ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO2"), 8272ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 8282ece646cSMatti Vaittinen .id = BD718XX_LDO2, 8292ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 8302ece646cSMatti Vaittinen .volt_table = &ldo_2_volts[0], 8312ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO2_VOLT, 8322ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO2_MASK, 8332ece646cSMatti Vaittinen .n_voltages = ARRAY_SIZE(ldo_2_volts), 8342ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO2_VOLT, 8352ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 836*3b66e4a8SGuido Günther .enable_time = BD71847_LDO2_STARTUP_TIME, 8372ece646cSMatti Vaittinen .owner = THIS_MODULE, 8382ece646cSMatti Vaittinen }, 8392ece646cSMatti Vaittinen .init = { 8402ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO2_VOLT, 8412ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 8422ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 8432ece646cSMatti Vaittinen }, 8442ece646cSMatti Vaittinen }, 8452ece646cSMatti Vaittinen { 8462ece646cSMatti Vaittinen .desc = { 8472ece646cSMatti Vaittinen .name = "ldo3", 8482ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO3"), 8492ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 8502ece646cSMatti Vaittinen .id = BD718XX_LDO3, 8512ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 8522ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO3_VOLTAGE_NUM, 8532ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo3_volts, 8542ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts), 8552ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO3_VOLT, 8562ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO3_MASK, 8572ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO3_VOLT, 8582ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 859*3b66e4a8SGuido Günther .enable_time = BD71847_LDO3_STARTUP_TIME, 8602ece646cSMatti Vaittinen .owner = THIS_MODULE, 8612ece646cSMatti Vaittinen }, 8622ece646cSMatti Vaittinen .init = { 8632ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO3_VOLT, 8642ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 8652ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 8662ece646cSMatti Vaittinen }, 8672ece646cSMatti Vaittinen }, 8682ece646cSMatti Vaittinen { 8692ece646cSMatti Vaittinen .desc = { 8702ece646cSMatti Vaittinen .name = "ldo4", 8712ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO4"), 8722ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 8732ece646cSMatti Vaittinen .id = BD718XX_LDO4, 8742ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 8752ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO4_VOLTAGE_NUM, 8762ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo4_volts, 8772ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts), 8782ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO4_VOLT, 8792ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO4_MASK, 8802ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO4_VOLT, 8812ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 882*3b66e4a8SGuido Günther .enable_time = BD71847_LDO4_STARTUP_TIME, 8832ece646cSMatti Vaittinen .owner = THIS_MODULE, 8842ece646cSMatti Vaittinen }, 8852ece646cSMatti Vaittinen .init = { 8862ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO4_VOLT, 8872ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 8882ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 8892ece646cSMatti Vaittinen }, 8902ece646cSMatti Vaittinen }, 8912ece646cSMatti Vaittinen { 8922ece646cSMatti Vaittinen .desc = { 8932ece646cSMatti Vaittinen .name = "ldo5", 8942ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO5"), 8952ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 8962ece646cSMatti Vaittinen .id = BD718XX_LDO5, 8972ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 8982ece646cSMatti Vaittinen .n_voltages = BD71847_LDO5_VOLTAGE_NUM, 8992ece646cSMatti Vaittinen .linear_ranges = bd71847_ldo5_volts, 9002ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd71847_ldo5_volts), 9012ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO5_VOLT, 9022ece646cSMatti Vaittinen .vsel_mask = BD71847_LDO5_MASK, 9032ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_LDO5_VOLT, 9042ece646cSMatti Vaittinen .vsel_range_mask = BD71847_LDO5_RANGE_MASK, 9052ece646cSMatti Vaittinen .linear_range_selectors = bd71847_ldo5_volt_range_sel, 9062ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO5_VOLT, 9072ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 908*3b66e4a8SGuido Günther .enable_time = BD71847_LDO5_STARTUP_TIME, 9092ece646cSMatti Vaittinen .owner = THIS_MODULE, 9102ece646cSMatti Vaittinen }, 9112ece646cSMatti Vaittinen .init = { 9122ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO5_VOLT, 9132ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 9142ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 9152ece646cSMatti Vaittinen }, 9162ece646cSMatti Vaittinen }, 9172ece646cSMatti Vaittinen { 9182ece646cSMatti Vaittinen .desc = { 9192ece646cSMatti Vaittinen .name = "ldo6", 9202ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO6"), 9212ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 9222ece646cSMatti Vaittinen .id = BD718XX_LDO6, 9232ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 9242ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO6_VOLTAGE_NUM, 9252ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo6_volts, 9262ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts), 9272ece646cSMatti Vaittinen /* LDO6 is supplied by buck5 */ 9282ece646cSMatti Vaittinen .supply_name = "buck5", 9292ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO6_VOLT, 9302ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO6_MASK, 9312ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO6_VOLT, 9322ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 933*3b66e4a8SGuido Günther .enable_time = BD71847_LDO6_STARTUP_TIME, 9342ece646cSMatti Vaittinen .owner = THIS_MODULE, 9352ece646cSMatti Vaittinen }, 9362ece646cSMatti Vaittinen .init = { 9372ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO6_VOLT, 9382ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 9392ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 9402ece646cSMatti Vaittinen }, 9412ece646cSMatti Vaittinen }, 9422ece646cSMatti Vaittinen }; 9432ece646cSMatti Vaittinen 94402f8eaabSYueHaibing static const struct regulator_ops *bd71837_swcontrol_ops[] = { 9451d848d68SMatti Vaittinen &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, 9461d848d68SMatti Vaittinen &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, 9471d848d68SMatti Vaittinen &bd71837_pickable_range_buck_ops, &bd71837_buck_regulator_ops, 9481d848d68SMatti Vaittinen &bd71837_buck_regulator_nolinear_ops, &bd71837_buck_regulator_ops, 9491d848d68SMatti Vaittinen &bd71837_pickable_range_ldo_ops, &bd71837_ldo_regulator_nolinear_ops, 9501d848d68SMatti Vaittinen &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops, 9511d848d68SMatti Vaittinen &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops, 9521d848d68SMatti Vaittinen &bd71837_ldo_regulator_ops, 9531d848d68SMatti Vaittinen }; 9541d848d68SMatti Vaittinen 95502f8eaabSYueHaibing static const struct regulator_ops *bd71837_hwcontrol_ops[] = { 9561d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 9571d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 9581d848d68SMatti Vaittinen &bd71837_buck34_ops_hwctrl, &bd71837_buck34_ops_hwctrl, 9591d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_pickable_range_buck_ops), 9601d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_buck_regulator_ops), 9611d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_buck_regulator_nolinear_ops), 9621d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_buck_regulator_ops), 9631d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_pickable_range_ldo_ops), 9641d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_nolinear_ops), 9651d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 9661d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 9671d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 9681d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 9691d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 9701d848d68SMatti Vaittinen }; 9711d848d68SMatti Vaittinen 9721d848d68SMatti Vaittinen static struct bd718xx_regulator_data bd71837_regulators[] = { 9732ece646cSMatti Vaittinen { 9742ece646cSMatti Vaittinen .desc = { 9752ece646cSMatti Vaittinen .name = "buck1", 9762ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK1"), 9772ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 9782ece646cSMatti Vaittinen .id = BD718XX_BUCK1, 9792ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 9802ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 9812ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 9822ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 9832ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN, 9842ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 9852ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_BUCK1_CTRL, 9862ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 987*3b66e4a8SGuido Günther .enable_time = BD71837_BUCK1_STARTUP_TIME, 9882ece646cSMatti Vaittinen .owner = THIS_MODULE, 98921b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 99021b72156SMatti Vaittinen }, 99121b72156SMatti Vaittinen .dvs = { 99221b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | 99321b72156SMatti Vaittinen ROHM_DVS_LEVEL_SUSPEND, 99421b72156SMatti Vaittinen .run_reg = BD718XX_REG_BUCK1_VOLT_RUN, 99521b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 99621b72156SMatti Vaittinen .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE, 99721b72156SMatti Vaittinen .idle_mask = DVS_BUCK_RUN_MASK, 99821b72156SMatti Vaittinen .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP, 99921b72156SMatti Vaittinen .suspend_mask = DVS_BUCK_RUN_MASK, 10002ece646cSMatti Vaittinen }, 10012ece646cSMatti Vaittinen .init = { 10022ece646cSMatti Vaittinen .reg = BD718XX_REG_BUCK1_CTRL, 10032ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 10042ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 10052ece646cSMatti Vaittinen }, 10062ece646cSMatti Vaittinen }, 10072ece646cSMatti Vaittinen { 10082ece646cSMatti Vaittinen .desc = { 10092ece646cSMatti Vaittinen .name = "buck2", 10102ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK2"), 10112ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 10122ece646cSMatti Vaittinen .id = BD718XX_BUCK2, 10132ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 10142ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 10152ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 10162ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 10172ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN, 10182ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 10192ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_BUCK2_CTRL, 10202ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 1021*3b66e4a8SGuido Günther .enable_time = BD71837_BUCK2_STARTUP_TIME, 10222ece646cSMatti Vaittinen .owner = THIS_MODULE, 102321b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 102421b72156SMatti Vaittinen }, 102521b72156SMatti Vaittinen .dvs = { 102621b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE, 102721b72156SMatti Vaittinen .run_reg = BD718XX_REG_BUCK2_VOLT_RUN, 102821b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 102921b72156SMatti Vaittinen .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE, 103021b72156SMatti Vaittinen .idle_mask = DVS_BUCK_RUN_MASK, 10312ece646cSMatti Vaittinen }, 10322ece646cSMatti Vaittinen .init = { 10332ece646cSMatti Vaittinen .reg = BD718XX_REG_BUCK2_CTRL, 10342ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 10352ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 10362ece646cSMatti Vaittinen }, 10372ece646cSMatti Vaittinen }, 10382ece646cSMatti Vaittinen { 10392ece646cSMatti Vaittinen .desc = { 10402ece646cSMatti Vaittinen .name = "buck3", 10412ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK3"), 10422ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 10432ece646cSMatti Vaittinen .id = BD718XX_BUCK3, 10442ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 10452ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 10462ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 10472ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 10482ece646cSMatti Vaittinen .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN, 10492ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 10502ece646cSMatti Vaittinen .enable_reg = BD71837_REG_BUCK3_CTRL, 10512ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 1052*3b66e4a8SGuido Günther .enable_time = BD71837_BUCK3_STARTUP_TIME, 10532ece646cSMatti Vaittinen .owner = THIS_MODULE, 105421b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 105521b72156SMatti Vaittinen }, 105621b72156SMatti Vaittinen .dvs = { 105721b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN, 105821b72156SMatti Vaittinen .run_reg = BD71837_REG_BUCK3_VOLT_RUN, 105921b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 10602ece646cSMatti Vaittinen }, 10612ece646cSMatti Vaittinen .init = { 10622ece646cSMatti Vaittinen .reg = BD71837_REG_BUCK3_CTRL, 10632ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 10642ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 10652ece646cSMatti Vaittinen }, 10662ece646cSMatti Vaittinen }, 10672ece646cSMatti Vaittinen { 10682ece646cSMatti Vaittinen .desc = { 10692ece646cSMatti Vaittinen .name = "buck4", 10702ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK4"), 10712ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 10722ece646cSMatti Vaittinen .id = BD718XX_BUCK4, 10732ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 10742ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 10752ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 10762ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 10772ece646cSMatti Vaittinen .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN, 10782ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 10792ece646cSMatti Vaittinen .enable_reg = BD71837_REG_BUCK4_CTRL, 10802ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 1081*3b66e4a8SGuido Günther .enable_time = BD71837_BUCK4_STARTUP_TIME, 10822ece646cSMatti Vaittinen .owner = THIS_MODULE, 108321b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 108421b72156SMatti Vaittinen }, 108521b72156SMatti Vaittinen .dvs = { 108621b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN, 108721b72156SMatti Vaittinen .run_reg = BD71837_REG_BUCK4_VOLT_RUN, 108821b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 10892ece646cSMatti Vaittinen }, 10902ece646cSMatti Vaittinen .init = { 10912ece646cSMatti Vaittinen .reg = BD71837_REG_BUCK4_CTRL, 10922ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 10932ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 10942ece646cSMatti Vaittinen }, 10952ece646cSMatti Vaittinen }, 10962ece646cSMatti Vaittinen { 10972ece646cSMatti Vaittinen .desc = { 10982ece646cSMatti Vaittinen .name = "buck5", 10992ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK5"), 11002ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 11012ece646cSMatti Vaittinen .id = BD718XX_BUCK5, 11022ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 11032ece646cSMatti Vaittinen .n_voltages = BD71837_BUCK5_VOLTAGE_NUM, 11042ece646cSMatti Vaittinen .linear_ranges = bd71837_buck5_volts, 11052ece646cSMatti Vaittinen .n_linear_ranges = 11062ece646cSMatti Vaittinen ARRAY_SIZE(bd71837_buck5_volts), 11072ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 11082ece646cSMatti Vaittinen .vsel_mask = BD71837_BUCK5_MASK, 11092ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 11102ece646cSMatti Vaittinen .vsel_range_mask = BD71837_BUCK5_RANGE_MASK, 11112ece646cSMatti Vaittinen .linear_range_selectors = bd71837_buck5_volt_range_sel, 11122ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 11132ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 1114*3b66e4a8SGuido Günther .enable_time = BD71837_BUCK5_STARTUP_TIME, 11152ece646cSMatti Vaittinen .owner = THIS_MODULE, 11162ece646cSMatti Vaittinen }, 11172ece646cSMatti Vaittinen .init = { 11182ece646cSMatti Vaittinen .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 11192ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 11202ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 11212ece646cSMatti Vaittinen }, 11222ece646cSMatti Vaittinen }, 11232ece646cSMatti Vaittinen { 11242ece646cSMatti Vaittinen .desc = { 11252ece646cSMatti Vaittinen .name = "buck6", 11262ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK6"), 11272ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 11282ece646cSMatti Vaittinen .id = BD718XX_BUCK6, 11292ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 11302ece646cSMatti Vaittinen .n_voltages = BD71837_BUCK6_VOLTAGE_NUM, 11312ece646cSMatti Vaittinen .linear_ranges = bd71837_buck6_volts, 11322ece646cSMatti Vaittinen .n_linear_ranges = 11332ece646cSMatti Vaittinen ARRAY_SIZE(bd71837_buck6_volts), 11342ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, 11352ece646cSMatti Vaittinen .vsel_mask = BD71837_BUCK6_MASK, 11362ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 11372ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 1138*3b66e4a8SGuido Günther .enable_time = BD71837_BUCK6_STARTUP_TIME, 11392ece646cSMatti Vaittinen .owner = THIS_MODULE, 11402ece646cSMatti Vaittinen }, 11412ece646cSMatti Vaittinen .init = { 11422ece646cSMatti Vaittinen .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 11432ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 11442ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 11452ece646cSMatti Vaittinen }, 11462ece646cSMatti Vaittinen }, 11472ece646cSMatti Vaittinen { 11482ece646cSMatti Vaittinen .desc = { 11492ece646cSMatti Vaittinen .name = "buck7", 11502ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK7"), 11512ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 11522ece646cSMatti Vaittinen .id = BD718XX_BUCK7, 11532ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 11542ece646cSMatti Vaittinen .volt_table = &bd718xx_3rd_nodvs_buck_volts[0], 11552ece646cSMatti Vaittinen .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts), 11562ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT, 11572ece646cSMatti Vaittinen .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, 11582ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 11592ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 1160*3b66e4a8SGuido Günther .enable_time = BD71837_BUCK7_STARTUP_TIME, 11612ece646cSMatti Vaittinen .owner = THIS_MODULE, 11622ece646cSMatti Vaittinen }, 11632ece646cSMatti Vaittinen .init = { 11642ece646cSMatti Vaittinen .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 11652ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 11662ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 11672ece646cSMatti Vaittinen }, 11682ece646cSMatti Vaittinen }, 11692ece646cSMatti Vaittinen { 11702ece646cSMatti Vaittinen .desc = { 11712ece646cSMatti Vaittinen .name = "buck8", 11722ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK8"), 11732ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 11742ece646cSMatti Vaittinen .id = BD718XX_BUCK8, 11752ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 11762ece646cSMatti Vaittinen .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM, 11772ece646cSMatti Vaittinen .linear_ranges = bd718xx_4th_nodvs_buck_volts, 11782ece646cSMatti Vaittinen .n_linear_ranges = 11792ece646cSMatti Vaittinen ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts), 11802ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT, 11812ece646cSMatti Vaittinen .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, 11822ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 11832ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 1184*3b66e4a8SGuido Günther .enable_time = BD71837_BUCK8_STARTUP_TIME, 11852ece646cSMatti Vaittinen .owner = THIS_MODULE, 11862ece646cSMatti Vaittinen }, 11872ece646cSMatti Vaittinen .init = { 11882ece646cSMatti Vaittinen .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 11892ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 11902ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 11912ece646cSMatti Vaittinen }, 11922ece646cSMatti Vaittinen }, 11932ece646cSMatti Vaittinen { 11942ece646cSMatti Vaittinen .desc = { 11952ece646cSMatti Vaittinen .name = "ldo1", 11962ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO1"), 11972ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 11982ece646cSMatti Vaittinen .id = BD718XX_LDO1, 11992ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 12002ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO1_VOLTAGE_NUM, 12012ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo1_volts, 12022ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts), 12032ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO1_VOLT, 12042ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO1_MASK, 12052ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_LDO1_VOLT, 12062ece646cSMatti Vaittinen .vsel_range_mask = BD718XX_LDO1_RANGE_MASK, 12072ece646cSMatti Vaittinen .linear_range_selectors = bd718xx_ldo1_volt_range_sel, 12082ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO1_VOLT, 12092ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 1210*3b66e4a8SGuido Günther .enable_time = BD71837_LDO1_STARTUP_TIME, 12112ece646cSMatti Vaittinen .owner = THIS_MODULE, 12122ece646cSMatti Vaittinen }, 12132ece646cSMatti Vaittinen .init = { 12142ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO1_VOLT, 12152ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 12162ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 12172ece646cSMatti Vaittinen }, 12182ece646cSMatti Vaittinen }, 12192ece646cSMatti Vaittinen { 12202ece646cSMatti Vaittinen .desc = { 12212ece646cSMatti Vaittinen .name = "ldo2", 12222ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO2"), 12232ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 12242ece646cSMatti Vaittinen .id = BD718XX_LDO2, 12252ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 12262ece646cSMatti Vaittinen .volt_table = &ldo_2_volts[0], 12272ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO2_VOLT, 12282ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO2_MASK, 12292ece646cSMatti Vaittinen .n_voltages = ARRAY_SIZE(ldo_2_volts), 12302ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO2_VOLT, 12312ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 1232*3b66e4a8SGuido Günther .enable_time = BD71837_LDO2_STARTUP_TIME, 12332ece646cSMatti Vaittinen .owner = THIS_MODULE, 12342ece646cSMatti Vaittinen }, 12352ece646cSMatti Vaittinen .init = { 12362ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO2_VOLT, 12372ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 12382ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 12392ece646cSMatti Vaittinen }, 12402ece646cSMatti Vaittinen }, 12412ece646cSMatti Vaittinen { 12422ece646cSMatti Vaittinen .desc = { 12432ece646cSMatti Vaittinen .name = "ldo3", 12442ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO3"), 12452ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 12462ece646cSMatti Vaittinen .id = BD718XX_LDO3, 12472ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 12482ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO3_VOLTAGE_NUM, 12492ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo3_volts, 12502ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts), 12512ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO3_VOLT, 12522ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO3_MASK, 12532ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO3_VOLT, 12542ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 1255*3b66e4a8SGuido Günther .enable_time = BD71837_LDO3_STARTUP_TIME, 12562ece646cSMatti Vaittinen .owner = THIS_MODULE, 12572ece646cSMatti Vaittinen }, 12582ece646cSMatti Vaittinen .init = { 12592ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO3_VOLT, 12602ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 12612ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 12622ece646cSMatti Vaittinen }, 12632ece646cSMatti Vaittinen }, 12642ece646cSMatti Vaittinen { 12652ece646cSMatti Vaittinen .desc = { 12662ece646cSMatti Vaittinen .name = "ldo4", 12672ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO4"), 12682ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 12692ece646cSMatti Vaittinen .id = BD718XX_LDO4, 12702ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 12712ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO4_VOLTAGE_NUM, 12722ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo4_volts, 12732ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts), 12742ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO4_VOLT, 12752ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO4_MASK, 12762ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO4_VOLT, 12772ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 1278*3b66e4a8SGuido Günther .enable_time = BD71837_LDO4_STARTUP_TIME, 12792ece646cSMatti Vaittinen .owner = THIS_MODULE, 12802ece646cSMatti Vaittinen }, 12812ece646cSMatti Vaittinen .init = { 12822ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO4_VOLT, 12832ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 12842ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 12852ece646cSMatti Vaittinen }, 12862ece646cSMatti Vaittinen }, 12872ece646cSMatti Vaittinen { 12882ece646cSMatti Vaittinen .desc = { 12892ece646cSMatti Vaittinen .name = "ldo5", 12902ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO5"), 12912ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 12922ece646cSMatti Vaittinen .id = BD718XX_LDO5, 12932ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 12942ece646cSMatti Vaittinen .n_voltages = BD71837_LDO5_VOLTAGE_NUM, 12952ece646cSMatti Vaittinen .linear_ranges = bd71837_ldo5_volts, 12962ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_volts), 12972ece646cSMatti Vaittinen /* LDO5 is supplied by buck6 */ 12982ece646cSMatti Vaittinen .supply_name = "buck6", 12992ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO5_VOLT, 13002ece646cSMatti Vaittinen .vsel_mask = BD71837_LDO5_MASK, 13012ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO5_VOLT, 13022ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 1303*3b66e4a8SGuido Günther .enable_time = BD71837_LDO5_STARTUP_TIME, 13042ece646cSMatti Vaittinen .owner = THIS_MODULE, 13052ece646cSMatti Vaittinen }, 13062ece646cSMatti Vaittinen .init = { 13072ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO5_VOLT, 13082ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 13092ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 13102ece646cSMatti Vaittinen }, 13112ece646cSMatti Vaittinen .additional_inits = bd71837_ldo5_inits, 13122ece646cSMatti Vaittinen .additional_init_amnt = ARRAY_SIZE(bd71837_ldo5_inits), 13132ece646cSMatti Vaittinen }, 13142ece646cSMatti Vaittinen { 13152ece646cSMatti Vaittinen .desc = { 13162ece646cSMatti Vaittinen .name = "ldo6", 13172ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO6"), 13182ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 13192ece646cSMatti Vaittinen .id = BD718XX_LDO6, 13202ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 13212ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO6_VOLTAGE_NUM, 13222ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo6_volts, 13232ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts), 13242ece646cSMatti Vaittinen /* LDO6 is supplied by buck7 */ 13252ece646cSMatti Vaittinen .supply_name = "buck7", 13262ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO6_VOLT, 13272ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO6_MASK, 13282ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO6_VOLT, 13292ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 1330*3b66e4a8SGuido Günther .enable_time = BD71837_LDO6_STARTUP_TIME, 13312ece646cSMatti Vaittinen .owner = THIS_MODULE, 13322ece646cSMatti Vaittinen }, 13332ece646cSMatti Vaittinen .init = { 13342ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO6_VOLT, 13352ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 13362ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 13372ece646cSMatti Vaittinen }, 13382ece646cSMatti Vaittinen .additional_inits = bd71837_ldo6_inits, 13392ece646cSMatti Vaittinen .additional_init_amnt = ARRAY_SIZE(bd71837_ldo6_inits), 13402ece646cSMatti Vaittinen }, 13412ece646cSMatti Vaittinen { 13422ece646cSMatti Vaittinen .desc = { 13432ece646cSMatti Vaittinen .name = "ldo7", 13442ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO7"), 13452ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 13462ece646cSMatti Vaittinen .id = BD718XX_LDO7, 13472ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 13482ece646cSMatti Vaittinen .n_voltages = BD71837_LDO7_VOLTAGE_NUM, 13492ece646cSMatti Vaittinen .linear_ranges = bd71837_ldo7_volts, 13502ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_volts), 13512ece646cSMatti Vaittinen .vsel_reg = BD71837_REG_LDO7_VOLT, 13522ece646cSMatti Vaittinen .vsel_mask = BD71837_LDO7_MASK, 13532ece646cSMatti Vaittinen .enable_reg = BD71837_REG_LDO7_VOLT, 13542ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 1355*3b66e4a8SGuido Günther .enable_time = BD71837_LDO7_STARTUP_TIME, 13562ece646cSMatti Vaittinen .owner = THIS_MODULE, 13572ece646cSMatti Vaittinen }, 13582ece646cSMatti Vaittinen .init = { 13592ece646cSMatti Vaittinen .reg = BD71837_REG_LDO7_VOLT, 13602ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 13612ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 13622ece646cSMatti Vaittinen }, 13632ece646cSMatti Vaittinen }, 13642ece646cSMatti Vaittinen }; 13652ece646cSMatti Vaittinen 13661d848d68SMatti Vaittinen static void mark_hw_controlled(struct device *dev, struct device_node *np, 13671d848d68SMatti Vaittinen struct bd718xx_regulator_data *reg_data, 13681d848d68SMatti Vaittinen unsigned int num_reg_data, int *info) 13691d848d68SMatti Vaittinen { 13701d848d68SMatti Vaittinen int i; 13711d848d68SMatti Vaittinen 13721d848d68SMatti Vaittinen for (i = 1; i <= num_reg_data; i++) { 13731d848d68SMatti Vaittinen if (!of_node_name_eq(np, reg_data[i-1].desc.of_match)) 13741d848d68SMatti Vaittinen continue; 13751d848d68SMatti Vaittinen 13761d848d68SMatti Vaittinen *info |= 1 << (i - 1); 13771d848d68SMatti Vaittinen dev_dbg(dev, "regulator %d runlevel controlled\n", i); 13781d848d68SMatti Vaittinen return; 13791d848d68SMatti Vaittinen } 13801d848d68SMatti Vaittinen dev_warn(dev, "Bad regulator node\n"); 13811d848d68SMatti Vaittinen } 13821d848d68SMatti Vaittinen 1383d2ad9811SMatti Vaittinen /* 1384d2ad9811SMatti Vaittinen * Setups where regulator (especially the buck8) output voltage is scaled 1385d2ad9811SMatti Vaittinen * by adding external connection where some other regulator output is connected 1386d2ad9811SMatti Vaittinen * to feedback-pin (over suitable resistors) is getting popular amongst users 1387d2ad9811SMatti Vaittinen * of BD71837. (This allows for example scaling down the buck8 voltages to suit 1388d2ad9811SMatti Vaittinen * lover GPU voltages for projects where buck8 is (ab)used to supply power 1389d2ad9811SMatti Vaittinen * for GPU. Additionally some setups do allow DVS for buck8 but as this do 1390d2ad9811SMatti Vaittinen * produce voltage spikes the HW must be evaluated to be able to survive this 1391d2ad9811SMatti Vaittinen * - hence I keep the DVS disabled for non DVS bucks by default. I don't want 1392d2ad9811SMatti Vaittinen * to help you burn your proto board) 1393d2ad9811SMatti Vaittinen * 1394d2ad9811SMatti Vaittinen * So we allow describing this external connection from DT and scale the 1395d2ad9811SMatti Vaittinen * voltages accordingly. This is what the connection should look like: 1396d2ad9811SMatti Vaittinen * 1397d2ad9811SMatti Vaittinen * |------------| 1398d2ad9811SMatti Vaittinen * | buck 8 |-------+----->Vout 1399d2ad9811SMatti Vaittinen * | | | 1400d2ad9811SMatti Vaittinen * |------------| | 1401d2ad9811SMatti Vaittinen * | FB pin | 1402d2ad9811SMatti Vaittinen * | | 1403d2ad9811SMatti Vaittinen * +-------+--R2---+ 1404d2ad9811SMatti Vaittinen * | 1405d2ad9811SMatti Vaittinen * R1 1406d2ad9811SMatti Vaittinen * | 1407d2ad9811SMatti Vaittinen * V FB-pull-up 1408d2ad9811SMatti Vaittinen * 1409d2ad9811SMatti Vaittinen * Here the buck output is sifted according to formula: 1410d2ad9811SMatti Vaittinen * 1411d2ad9811SMatti Vaittinen * Vout_o = Vo - (Vpu - Vo)*R2/R1 1412d2ad9811SMatti Vaittinen * Linear_step = step_orig*(R1+R2)/R1 1413d2ad9811SMatti Vaittinen * 1414d2ad9811SMatti Vaittinen * where: 1415d2ad9811SMatti Vaittinen * Vout_o is adjusted voltage output at vsel reg value 0 1416d2ad9811SMatti Vaittinen * Vo is original voltage output at vsel reg value 0 1417d2ad9811SMatti Vaittinen * Vpu is the pull-up voltage V FB-pull-up in the picture 1418d2ad9811SMatti Vaittinen * R1 and R2 are resistor values. 1419d2ad9811SMatti Vaittinen * 1420d2ad9811SMatti Vaittinen * As a real world example for buck8 and a specific GPU: 1421d2ad9811SMatti Vaittinen * VLDO = 1.6V (used as FB-pull-up) 1422d2ad9811SMatti Vaittinen * R1 = 1000ohms 1423d2ad9811SMatti Vaittinen * R2 = 150ohms 1424d2ad9811SMatti Vaittinen * VSEL 0x0 => 0.8V – (VLDO – 0.8) * R2 / R1 = 0.68V 1425d2ad9811SMatti Vaittinen * Linear Step = 10mV * (R1 + R2) / R1 = 11.5mV 1426d2ad9811SMatti Vaittinen */ 1427d2ad9811SMatti Vaittinen static int setup_feedback_loop(struct device *dev, struct device_node *np, 1428d2ad9811SMatti Vaittinen struct bd718xx_regulator_data *reg_data, 1429d2ad9811SMatti Vaittinen unsigned int num_reg_data, int fb_uv) 1430d2ad9811SMatti Vaittinen { 1431d2ad9811SMatti Vaittinen int i, r1, r2, ret; 1432d2ad9811SMatti Vaittinen 1433d2ad9811SMatti Vaittinen /* 1434d2ad9811SMatti Vaittinen * We do adjust the values in the global desc based on DT settings. 1435d2ad9811SMatti Vaittinen * This may not be best approach as it can cause problems if more than 1436d2ad9811SMatti Vaittinen * one PMIC is controlled from same processor. I don't see such use-case 1437d2ad9811SMatti Vaittinen * for BD718x7 now - so we spare some bits. 1438d2ad9811SMatti Vaittinen * 1439d2ad9811SMatti Vaittinen * If this will point out to be a problem - then we can allocate new 1440d2ad9811SMatti Vaittinen * bd718xx_regulator_data array at probe and just use the global 1441d2ad9811SMatti Vaittinen * array as a template where we copy initial values. Then we can 1442d2ad9811SMatti Vaittinen * use allocated descs for regultor registration and do IC specific 1443d2ad9811SMatti Vaittinen * modifications to this copy while leaving other PMICs untouched. But 1444d2ad9811SMatti Vaittinen * that means allocating new array for each PMIC - and currently I see 1445d2ad9811SMatti Vaittinen * no need for that. 1446d2ad9811SMatti Vaittinen */ 1447d2ad9811SMatti Vaittinen 1448d2ad9811SMatti Vaittinen for (i = 0; i < num_reg_data; i++) { 1449d2ad9811SMatti Vaittinen struct regulator_desc *desc = ®_data[i].desc; 1450d2ad9811SMatti Vaittinen int j; 1451d2ad9811SMatti Vaittinen 1452d2ad9811SMatti Vaittinen if (!of_node_name_eq(np, desc->of_match)) 1453d2ad9811SMatti Vaittinen continue; 1454d2ad9811SMatti Vaittinen 1455d2ad9811SMatti Vaittinen pr_info("Looking at node '%s'\n", desc->of_match); 1456d2ad9811SMatti Vaittinen 1457d2ad9811SMatti Vaittinen /* The feedback loop connection does not make sense for LDOs */ 1458d2ad9811SMatti Vaittinen if (desc->id >= BD718XX_LDO1) 1459d2ad9811SMatti Vaittinen return -EINVAL; 1460d2ad9811SMatti Vaittinen 1461d2ad9811SMatti Vaittinen ret = of_property_read_u32(np, "rohm,feedback-pull-up-r1-ohms", 1462d2ad9811SMatti Vaittinen &r1); 1463d2ad9811SMatti Vaittinen if (ret) 1464d2ad9811SMatti Vaittinen return ret; 1465d2ad9811SMatti Vaittinen 1466d2ad9811SMatti Vaittinen if (!r1) 1467d2ad9811SMatti Vaittinen return -EINVAL; 1468d2ad9811SMatti Vaittinen 1469d2ad9811SMatti Vaittinen ret = of_property_read_u32(np, "rohm,feedback-pull-up-r2-ohms", 1470d2ad9811SMatti Vaittinen &r2); 1471d2ad9811SMatti Vaittinen if (ret) 1472d2ad9811SMatti Vaittinen return ret; 1473d2ad9811SMatti Vaittinen 1474d2ad9811SMatti Vaittinen if (desc->n_linear_ranges && desc->linear_ranges) { 1475d2ad9811SMatti Vaittinen struct linear_range *new; 1476d2ad9811SMatti Vaittinen 1477d2ad9811SMatti Vaittinen new = devm_kzalloc(dev, desc->n_linear_ranges * 1478d2ad9811SMatti Vaittinen sizeof(struct linear_range), 1479d2ad9811SMatti Vaittinen GFP_KERNEL); 1480d2ad9811SMatti Vaittinen if (!new) 1481d2ad9811SMatti Vaittinen return -ENOMEM; 1482d2ad9811SMatti Vaittinen 1483d2ad9811SMatti Vaittinen for (j = 0; j < desc->n_linear_ranges; j++) { 1484d2ad9811SMatti Vaittinen int min = desc->linear_ranges[j].min; 1485d2ad9811SMatti Vaittinen int step = desc->linear_ranges[j].step; 1486d2ad9811SMatti Vaittinen 1487d2ad9811SMatti Vaittinen min -= (fb_uv - min)*r2/r1; 1488d2ad9811SMatti Vaittinen step = step * (r1 + r2); 1489d2ad9811SMatti Vaittinen step /= r1; 1490d2ad9811SMatti Vaittinen 1491d2ad9811SMatti Vaittinen new[j].min = min; 1492d2ad9811SMatti Vaittinen new[j].step = step; 1493d2ad9811SMatti Vaittinen 1494d2ad9811SMatti Vaittinen dev_dbg(dev, "%s: old range min %d, step %d\n", 1495d2ad9811SMatti Vaittinen desc->name, desc->linear_ranges[j].min, 1496d2ad9811SMatti Vaittinen desc->linear_ranges[j].step); 1497d2ad9811SMatti Vaittinen dev_dbg(dev, "new range min %d, step %d\n", min, 1498d2ad9811SMatti Vaittinen step); 1499d2ad9811SMatti Vaittinen } 1500d2ad9811SMatti Vaittinen desc->linear_ranges = new; 1501d2ad9811SMatti Vaittinen } 1502d2ad9811SMatti Vaittinen dev_dbg(dev, "regulator '%s' has FB pull-up configured\n", 1503d2ad9811SMatti Vaittinen desc->name); 1504d2ad9811SMatti Vaittinen 1505d2ad9811SMatti Vaittinen return 0; 1506d2ad9811SMatti Vaittinen } 1507d2ad9811SMatti Vaittinen 1508d2ad9811SMatti Vaittinen return -ENODEV; 1509d2ad9811SMatti Vaittinen } 1510d2ad9811SMatti Vaittinen 1511d2ad9811SMatti Vaittinen static int get_special_regulators(struct device *dev, 15121d848d68SMatti Vaittinen struct bd718xx_regulator_data *reg_data, 15131d848d68SMatti Vaittinen unsigned int num_reg_data, int *info) 15141d848d68SMatti Vaittinen { 1515d2ad9811SMatti Vaittinen int ret; 15161d848d68SMatti Vaittinen struct device_node *np; 15171d848d68SMatti Vaittinen struct device_node *nproot = dev->of_node; 1518d2ad9811SMatti Vaittinen int uv; 15191d848d68SMatti Vaittinen 15201d848d68SMatti Vaittinen *info = 0; 15211d848d68SMatti Vaittinen 15221d848d68SMatti Vaittinen nproot = of_get_child_by_name(nproot, "regulators"); 15231d848d68SMatti Vaittinen if (!nproot) { 15241d848d68SMatti Vaittinen dev_err(dev, "failed to find regulators node\n"); 15251d848d68SMatti Vaittinen return -ENODEV; 15261d848d68SMatti Vaittinen } 1527d2ad9811SMatti Vaittinen for_each_child_of_node(nproot, np) { 1528d2ad9811SMatti Vaittinen if (of_property_read_bool(np, "rohm,no-regulator-enable-control")) 15291d848d68SMatti Vaittinen mark_hw_controlled(dev, np, reg_data, num_reg_data, 15301d848d68SMatti Vaittinen info); 1531d2ad9811SMatti Vaittinen ret = of_property_read_u32(np, "rohm,fb-pull-up-microvolt", 1532d2ad9811SMatti Vaittinen &uv); 1533d2ad9811SMatti Vaittinen if (ret) { 1534d2ad9811SMatti Vaittinen if (ret == -EINVAL) 1535d2ad9811SMatti Vaittinen continue; 1536d2ad9811SMatti Vaittinen else 1537d2ad9811SMatti Vaittinen goto err_out; 1538d2ad9811SMatti Vaittinen } 1539d2ad9811SMatti Vaittinen 1540d2ad9811SMatti Vaittinen ret = setup_feedback_loop(dev, np, reg_data, num_reg_data, uv); 1541d2ad9811SMatti Vaittinen if (ret) 1542d2ad9811SMatti Vaittinen goto err_out; 1543d2ad9811SMatti Vaittinen } 15441d848d68SMatti Vaittinen 15451d848d68SMatti Vaittinen of_node_put(nproot); 15461d848d68SMatti Vaittinen return 0; 1547d2ad9811SMatti Vaittinen 1548d2ad9811SMatti Vaittinen err_out: 1549d2ad9811SMatti Vaittinen of_node_put(np); 1550d2ad9811SMatti Vaittinen of_node_put(nproot); 1551d2ad9811SMatti Vaittinen 1552d2ad9811SMatti Vaittinen return ret; 15531d848d68SMatti Vaittinen } 15541d848d68SMatti Vaittinen 15552ece646cSMatti Vaittinen static int bd718xx_probe(struct platform_device *pdev) 15562ece646cSMatti Vaittinen { 1557bcb047ebSAxel Lin struct bd718xx *mfd; 15582ece646cSMatti Vaittinen struct regulator_config config = { 0 }; 15591d848d68SMatti Vaittinen int i, j, err, omit_enable; 1560049369d4SMatti Vaittinen bool use_snvs; 15611d848d68SMatti Vaittinen struct bd718xx_regulator_data *reg_data; 1562b389ceaeSAxel Lin unsigned int num_reg_data; 15631b1c26b2SMatti Vaittinen enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; 15641d848d68SMatti Vaittinen const struct regulator_ops **swops, **hwops; 15652ece646cSMatti Vaittinen 1566bcb047ebSAxel Lin mfd = dev_get_drvdata(pdev->dev.parent); 1567bcb047ebSAxel Lin if (!mfd) { 15682ece646cSMatti Vaittinen dev_err(&pdev->dev, "No MFD driver data\n"); 15692ece646cSMatti Vaittinen err = -EINVAL; 15702ece646cSMatti Vaittinen goto err; 15712ece646cSMatti Vaittinen } 1572bcb047ebSAxel Lin 1573af32f3a4SLinus Torvalds switch (chip) { 1574b389ceaeSAxel Lin case ROHM_CHIP_TYPE_BD71837: 1575b389ceaeSAxel Lin reg_data = bd71837_regulators; 1576b389ceaeSAxel Lin num_reg_data = ARRAY_SIZE(bd71837_regulators); 15771d848d68SMatti Vaittinen swops = &bd71837_swcontrol_ops[0]; 15781d848d68SMatti Vaittinen hwops = &bd71837_hwcontrol_ops[0]; 1579b389ceaeSAxel Lin break; 1580b389ceaeSAxel Lin case ROHM_CHIP_TYPE_BD71847: 1581b389ceaeSAxel Lin reg_data = bd71847_regulators; 1582b389ceaeSAxel Lin num_reg_data = ARRAY_SIZE(bd71847_regulators); 15831d848d68SMatti Vaittinen swops = &bd71847_swcontrol_ops[0]; 15841d848d68SMatti Vaittinen hwops = &bd71847_hwcontrol_ops[0]; 1585b389ceaeSAxel Lin break; 1586b389ceaeSAxel Lin default: 15872ece646cSMatti Vaittinen dev_err(&pdev->dev, "Unsupported chip type\n"); 15882ece646cSMatti Vaittinen err = -EINVAL; 15892ece646cSMatti Vaittinen goto err; 15902ece646cSMatti Vaittinen } 15912ece646cSMatti Vaittinen 15922ece646cSMatti Vaittinen /* Register LOCK release */ 15932a6a7aacSMatti Vaittinen err = regmap_update_bits(mfd->chip.regmap, BD718XX_REG_REGLOCK, 15942ece646cSMatti Vaittinen (REGLOCK_PWRSEQ | REGLOCK_VREG), 0); 15952ece646cSMatti Vaittinen if (err) { 1596bcb047ebSAxel Lin dev_err(&pdev->dev, "Failed to unlock PMIC (%d)\n", err); 15972ece646cSMatti Vaittinen goto err; 15982ece646cSMatti Vaittinen } else { 1599bcb047ebSAxel Lin dev_dbg(&pdev->dev, "Unlocked lock register 0x%x\n", 16002ece646cSMatti Vaittinen BD718XX_REG_REGLOCK); 16012ece646cSMatti Vaittinen } 16022ece646cSMatti Vaittinen 1603049369d4SMatti Vaittinen use_snvs = of_property_read_bool(pdev->dev.parent->of_node, 1604049369d4SMatti Vaittinen "rohm,reset-snvs-powered"); 1605049369d4SMatti Vaittinen 1606049369d4SMatti Vaittinen /* 1607e770b18bSMatti Vaittinen * Change the next stage from poweroff to be READY instead of SNVS 1608e770b18bSMatti Vaittinen * for all reset types because OTP loading at READY will clear SEL 1609e770b18bSMatti Vaittinen * bit allowing HW defaults for power rails to be used 1610e770b18bSMatti Vaittinen */ 1611049369d4SMatti Vaittinen if (!use_snvs) { 16122a6a7aacSMatti Vaittinen err = regmap_update_bits(mfd->chip.regmap, 16132a6a7aacSMatti Vaittinen BD718XX_REG_TRANS_COND1, 1614e770b18bSMatti Vaittinen BD718XX_ON_REQ_POWEROFF_MASK | 1615e770b18bSMatti Vaittinen BD718XX_SWRESET_POWEROFF_MASK | 1616e770b18bSMatti Vaittinen BD718XX_WDOG_POWEROFF_MASK | 1617e770b18bSMatti Vaittinen BD718XX_KEY_L_POWEROFF_MASK, 1618e770b18bSMatti Vaittinen BD718XX_POWOFF_TO_RDY); 1619e770b18bSMatti Vaittinen if (err) { 1620e770b18bSMatti Vaittinen dev_err(&pdev->dev, "Failed to change reset target\n"); 1621e770b18bSMatti Vaittinen goto err; 1622e770b18bSMatti Vaittinen } else { 1623049369d4SMatti Vaittinen dev_dbg(&pdev->dev, 1624049369d4SMatti Vaittinen "Changed all resets from SVNS to READY\n"); 1625049369d4SMatti Vaittinen } 1626e770b18bSMatti Vaittinen } 1627e770b18bSMatti Vaittinen 1628df9db254SMatti Vaittinen config.dev = pdev->dev.parent; 1629df9db254SMatti Vaittinen config.regmap = mfd->chip.regmap; 16301d848d68SMatti Vaittinen /* 16311d848d68SMatti Vaittinen * There are cases when we want to leave the enable-control for 16321d848d68SMatti Vaittinen * the HW state machine and use this driver only for voltage control. 16331d848d68SMatti Vaittinen * One special case is when we use PMIC_STBY_REQ line from SoC to PMIC 16341d848d68SMatti Vaittinen * in order to set the system to SUSPEND state. 16351d848d68SMatti Vaittinen * 16361d848d68SMatti Vaittinen * If regulator is taken under SW control the regulator state will not 16371d848d68SMatti Vaittinen * be affected by PMIC state machine - Eg. regulator is likely to stay 16381d848d68SMatti Vaittinen * on even in SUSPEND 16391d848d68SMatti Vaittinen */ 1640d2ad9811SMatti Vaittinen err = get_special_regulators(pdev->dev.parent, reg_data, num_reg_data, 16411d848d68SMatti Vaittinen &omit_enable); 1642d2ad9811SMatti Vaittinen if (err) 1643d2ad9811SMatti Vaittinen return err; 1644df9db254SMatti Vaittinen 1645b389ceaeSAxel Lin for (i = 0; i < num_reg_data; i++) { 16462ece646cSMatti Vaittinen 16471d848d68SMatti Vaittinen struct regulator_desc *desc; 16482ece646cSMatti Vaittinen struct regulator_dev *rdev; 16491d848d68SMatti Vaittinen struct bd718xx_regulator_data *r; 16501d848d68SMatti Vaittinen int no_enable_control = omit_enable & (1 << i); 16512ece646cSMatti Vaittinen 1652b389ceaeSAxel Lin r = ®_data[i]; 16532ece646cSMatti Vaittinen desc = &r->desc; 16542ece646cSMatti Vaittinen 16551d848d68SMatti Vaittinen if (no_enable_control) 16561d848d68SMatti Vaittinen desc->ops = hwops[i]; 16571d848d68SMatti Vaittinen else 16581d848d68SMatti Vaittinen desc->ops = swops[i]; 16592ece646cSMatti Vaittinen 16602ece646cSMatti Vaittinen rdev = devm_regulator_register(&pdev->dev, desc, &config); 16612ece646cSMatti Vaittinen if (IS_ERR(rdev)) { 1662bcb047ebSAxel Lin dev_err(&pdev->dev, 16632ece646cSMatti Vaittinen "failed to register %s regulator\n", 16642ece646cSMatti Vaittinen desc->name); 16652ece646cSMatti Vaittinen err = PTR_ERR(rdev); 16662ece646cSMatti Vaittinen goto err; 16672ece646cSMatti Vaittinen } 1668049369d4SMatti Vaittinen 1669049369d4SMatti Vaittinen /* 1670049369d4SMatti Vaittinen * Regulator register gets the regulator constraints and 16712ece646cSMatti Vaittinen * applies them (set_machine_constraints). This should have 16722ece646cSMatti Vaittinen * turned the control register(s) to correct values and we 16732ece646cSMatti Vaittinen * can now switch the control from PMIC state machine to the 16742ece646cSMatti Vaittinen * register interface 1675049369d4SMatti Vaittinen * 1676049369d4SMatti Vaittinen * At poweroff transition PMIC HW disables EN bit for 1677049369d4SMatti Vaittinen * regulators but leaves SEL bit untouched. So if state 1678049369d4SMatti Vaittinen * transition from POWEROFF is done to SNVS - then all power 1679049369d4SMatti Vaittinen * rails controlled by SW (having SEL bit set) stay disabled 1680049369d4SMatti Vaittinen * as EN is cleared. This will result boot failure if any 1681049369d4SMatti Vaittinen * crucial systems are powered by these rails. We don't 1682049369d4SMatti Vaittinen * enable SW control for crucial regulators if snvs state is 1683049369d4SMatti Vaittinen * used 16842ece646cSMatti Vaittinen */ 16851d848d68SMatti Vaittinen if (!no_enable_control && (!use_snvs || 16861d848d68SMatti Vaittinen !rdev->constraints->always_on || 16871d848d68SMatti Vaittinen !rdev->constraints->boot_on)) { 16882a6a7aacSMatti Vaittinen err = regmap_update_bits(mfd->chip.regmap, r->init.reg, 16892ece646cSMatti Vaittinen r->init.mask, r->init.val); 16902ece646cSMatti Vaittinen if (err) { 1691bcb047ebSAxel Lin dev_err(&pdev->dev, 1692049369d4SMatti Vaittinen "Failed to take control for (%s)\n", 16932ece646cSMatti Vaittinen desc->name); 16942ece646cSMatti Vaittinen goto err; 16952ece646cSMatti Vaittinen } 1696049369d4SMatti Vaittinen } 16972ece646cSMatti Vaittinen for (j = 0; j < r->additional_init_amnt; j++) { 16982a6a7aacSMatti Vaittinen err = regmap_update_bits(mfd->chip.regmap, 16992ece646cSMatti Vaittinen r->additional_inits[j].reg, 17002ece646cSMatti Vaittinen r->additional_inits[j].mask, 17012ece646cSMatti Vaittinen r->additional_inits[j].val); 17022ece646cSMatti Vaittinen if (err) { 1703bcb047ebSAxel Lin dev_err(&pdev->dev, 17042ece646cSMatti Vaittinen "Buck (%s) initialization failed\n", 17052ece646cSMatti Vaittinen desc->name); 17062ece646cSMatti Vaittinen goto err; 17072ece646cSMatti Vaittinen } 17082ece646cSMatti Vaittinen } 17092ece646cSMatti Vaittinen } 17102ece646cSMatti Vaittinen 17112ece646cSMatti Vaittinen err: 17122ece646cSMatti Vaittinen return err; 17132ece646cSMatti Vaittinen } 17142ece646cSMatti Vaittinen 17151b1c26b2SMatti Vaittinen static const struct platform_device_id bd718x7_pmic_id[] = { 17161b1c26b2SMatti Vaittinen { "bd71837-pmic", ROHM_CHIP_TYPE_BD71837 }, 17171b1c26b2SMatti Vaittinen { "bd71847-pmic", ROHM_CHIP_TYPE_BD71847 }, 17181b1c26b2SMatti Vaittinen { }, 17191b1c26b2SMatti Vaittinen }; 17201b1c26b2SMatti Vaittinen MODULE_DEVICE_TABLE(platform, bd718x7_pmic_id); 17211b1c26b2SMatti Vaittinen 17222ece646cSMatti Vaittinen static struct platform_driver bd718xx_regulator = { 17232ece646cSMatti Vaittinen .driver = { 17242ece646cSMatti Vaittinen .name = "bd718xx-pmic", 17252ece646cSMatti Vaittinen }, 17262ece646cSMatti Vaittinen .probe = bd718xx_probe, 17271b1c26b2SMatti Vaittinen .id_table = bd718x7_pmic_id, 17282ece646cSMatti Vaittinen }; 17292ece646cSMatti Vaittinen 17302ece646cSMatti Vaittinen module_platform_driver(bd718xx_regulator); 17312ece646cSMatti Vaittinen 17322ece646cSMatti Vaittinen MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 17332ece646cSMatti Vaittinen MODULE_DESCRIPTION("BD71837/BD71847 voltage regulator driver"); 17342ece646cSMatti Vaittinen MODULE_LICENSE("GPL"); 173595bddd8bSGuido Günther MODULE_ALIAS("platform:bd718xx-pmic"); 1736