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 183b66e4a8SGuido Günther /* Typical regulator startup times as per data sheet in uS */ 193b66e4a8SGuido Günther #define BD71847_BUCK1_STARTUP_TIME 144 203b66e4a8SGuido Günther #define BD71847_BUCK2_STARTUP_TIME 162 213b66e4a8SGuido Günther #define BD71847_BUCK3_STARTUP_TIME 162 223b66e4a8SGuido Günther #define BD71847_BUCK4_STARTUP_TIME 240 233b66e4a8SGuido Günther #define BD71847_BUCK5_STARTUP_TIME 270 243b66e4a8SGuido Günther #define BD71847_BUCK6_STARTUP_TIME 200 253b66e4a8SGuido Günther #define BD71847_LDO1_STARTUP_TIME 440 263b66e4a8SGuido Günther #define BD71847_LDO2_STARTUP_TIME 370 273b66e4a8SGuido Günther #define BD71847_LDO3_STARTUP_TIME 310 283b66e4a8SGuido Günther #define BD71847_LDO4_STARTUP_TIME 400 293b66e4a8SGuido Günther #define BD71847_LDO5_STARTUP_TIME 530 303b66e4a8SGuido Günther #define BD71847_LDO6_STARTUP_TIME 400 313b66e4a8SGuido Günther 323b66e4a8SGuido Günther #define BD71837_BUCK1_STARTUP_TIME 160 333b66e4a8SGuido Günther #define BD71837_BUCK2_STARTUP_TIME 180 343b66e4a8SGuido Günther #define BD71837_BUCK3_STARTUP_TIME 180 353b66e4a8SGuido Günther #define BD71837_BUCK4_STARTUP_TIME 180 363b66e4a8SGuido Günther #define BD71837_BUCK5_STARTUP_TIME 160 373b66e4a8SGuido Günther #define BD71837_BUCK6_STARTUP_TIME 240 383b66e4a8SGuido Günther #define BD71837_BUCK7_STARTUP_TIME 220 393b66e4a8SGuido Günther #define BD71837_BUCK8_STARTUP_TIME 200 403b66e4a8SGuido Günther #define BD71837_LDO1_STARTUP_TIME 440 413b66e4a8SGuido Günther #define BD71837_LDO2_STARTUP_TIME 370 423b66e4a8SGuido Günther #define BD71837_LDO3_STARTUP_TIME 310 433b66e4a8SGuido Günther #define BD71837_LDO4_STARTUP_TIME 400 443b66e4a8SGuido Günther #define BD71837_LDO5_STARTUP_TIME 310 453b66e4a8SGuido Günther #define BD71837_LDO6_STARTUP_TIME 400 463b66e4a8SGuido Günther #define BD71837_LDO7_STARTUP_TIME 530 473b66e4a8SGuido 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, \ 58fedbfea1SMatti Vaittinen _get_voltage_sel, _set_voltage_time_sel, _set_ramp_delay, \ 59fedbfea1SMatti Vaittinen _set_uvp, _set_ovp) \ 601d848d68SMatti Vaittinen static const struct regulator_ops name = { \ 611d848d68SMatti Vaittinen .enable = regulator_enable_regmap, \ 621d848d68SMatti Vaittinen .disable = regulator_disable_regmap, \ 631d848d68SMatti Vaittinen .is_enabled = regulator_is_enabled_regmap, \ 641d848d68SMatti Vaittinen .list_voltage = (_list_voltage), \ 651d848d68SMatti Vaittinen .map_voltage = (_map_voltage), \ 661d848d68SMatti Vaittinen .set_voltage_sel = (_set_voltage_sel), \ 671d848d68SMatti Vaittinen .get_voltage_sel = (_get_voltage_sel), \ 681d848d68SMatti Vaittinen .set_voltage_time_sel = (_set_voltage_time_sel), \ 691d848d68SMatti Vaittinen .set_ramp_delay = (_set_ramp_delay), \ 70fedbfea1SMatti Vaittinen .set_under_voltage_protection = (_set_uvp), \ 71fedbfea1SMatti Vaittinen .set_over_voltage_protection = (_set_ovp), \ 721d848d68SMatti Vaittinen }; \ 731d848d68SMatti Vaittinen \ 741d848d68SMatti Vaittinen static const struct regulator_ops BD718XX_HWOPNAME(name) = { \ 751d848d68SMatti Vaittinen .is_enabled = always_enabled_by_hwstate, \ 761d848d68SMatti Vaittinen .list_voltage = (_list_voltage), \ 771d848d68SMatti Vaittinen .map_voltage = (_map_voltage), \ 781d848d68SMatti Vaittinen .set_voltage_sel = (_set_voltage_sel), \ 791d848d68SMatti Vaittinen .get_voltage_sel = (_get_voltage_sel), \ 801d848d68SMatti Vaittinen .set_voltage_time_sel = (_set_voltage_time_sel), \ 811d848d68SMatti Vaittinen .set_ramp_delay = (_set_ramp_delay), \ 82fedbfea1SMatti Vaittinen .set_under_voltage_protection = (_set_uvp), \ 83fedbfea1SMatti Vaittinen .set_over_voltage_protection = (_set_ovp), \ 841d848d68SMatti Vaittinen } \ 851d848d68SMatti Vaittinen 861d848d68SMatti Vaittinen /* 872ece646cSMatti Vaittinen * BUCK1/2/3/4 882ece646cSMatti Vaittinen * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting 892ece646cSMatti Vaittinen * 00: 10.00mV/usec 10mV 1uS 902ece646cSMatti Vaittinen * 01: 5.00mV/usec 10mV 2uS 912ece646cSMatti Vaittinen * 10: 2.50mV/usec 10mV 4uS 922ece646cSMatti Vaittinen * 11: 1.25mV/usec 10mV 8uS 932ece646cSMatti Vaittinen */ 9418f3c625SMatti Vaittinen static const unsigned int bd718xx_ramp_delay[] = { 10000, 5000, 2500, 1250 }; 952ece646cSMatti Vaittinen 961d848d68SMatti Vaittinen /* These functions are used when regulators are under HW state machine control. 971d848d68SMatti Vaittinen * We assume PMIC is in RUN state because SW running and able to query the 981d848d68SMatti Vaittinen * status. Most of the regulators have fixed ON or OFF state at RUN/IDLE so for 991d848d68SMatti Vaittinen * them we just return a constant. BD71837 BUCK3 and BUCK4 are exceptions as 1001d848d68SMatti Vaittinen * they support configuring the ON/OFF state for RUN. 1011d848d68SMatti Vaittinen * 1021d848d68SMatti Vaittinen * Note for next hacker - these PMICs have a register where the HW state can be 1031d848d68SMatti Vaittinen * read. If assuming RUN appears to be false in your use-case - you can 1041d848d68SMatti Vaittinen * implement state reading (although that is not going to be atomic) before 1051d848d68SMatti Vaittinen * returning the enable state. 1061d848d68SMatti Vaittinen */ 1071d848d68SMatti Vaittinen static int always_enabled_by_hwstate(struct regulator_dev *rdev) 1081d848d68SMatti Vaittinen { 1091d848d68SMatti Vaittinen return 1; 1101d848d68SMatti Vaittinen } 1111d848d68SMatti Vaittinen 1121d848d68SMatti Vaittinen static int never_enabled_by_hwstate(struct regulator_dev *rdev) 1131d848d68SMatti Vaittinen { 1141d848d68SMatti Vaittinen return 0; 1151d848d68SMatti Vaittinen } 1161d848d68SMatti Vaittinen 1171d848d68SMatti Vaittinen static int bd71837_get_buck34_enable_hwctrl(struct regulator_dev *rdev) 1181d848d68SMatti Vaittinen { 1191d848d68SMatti Vaittinen int ret; 1201d848d68SMatti Vaittinen unsigned int val; 1211d848d68SMatti Vaittinen 1221d848d68SMatti Vaittinen ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); 1231d848d68SMatti Vaittinen if (ret) 1241d848d68SMatti Vaittinen return ret; 1251d848d68SMatti Vaittinen 1261d848d68SMatti Vaittinen return !!(BD718XX_BUCK_RUN_ON & val); 1271d848d68SMatti Vaittinen } 1282ece646cSMatti Vaittinen 1299bcbabafSMatti Vaittinen static void voltage_change_done(struct regulator_dev *rdev, unsigned int sel, 1309bcbabafSMatti Vaittinen unsigned int *mask) 1319bcbabafSMatti Vaittinen { 1329bcbabafSMatti Vaittinen int ret; 1339bcbabafSMatti Vaittinen 1349bcbabafSMatti Vaittinen if (*mask) { 1359bcbabafSMatti Vaittinen /* 1369bcbabafSMatti Vaittinen * Let's allow scheduling as we use I2C anyways. We just need to 1379bcbabafSMatti Vaittinen * guarantee minimum of 1ms sleep - it shouldn't matter if we 1389bcbabafSMatti Vaittinen * exceed it due to the scheduling. 1399bcbabafSMatti Vaittinen */ 1409bcbabafSMatti Vaittinen msleep(1); 141fedbfea1SMatti Vaittinen 142fedbfea1SMatti Vaittinen ret = regmap_clear_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2, 143fedbfea1SMatti Vaittinen *mask); 1449bcbabafSMatti Vaittinen if (ret) 1459bcbabafSMatti Vaittinen dev_err(&rdev->dev, 1469bcbabafSMatti Vaittinen "Failed to re-enable voltage monitoring (%d)\n", 1479bcbabafSMatti Vaittinen ret); 1489bcbabafSMatti Vaittinen } 1499bcbabafSMatti Vaittinen } 1509bcbabafSMatti Vaittinen 1519bcbabafSMatti Vaittinen static int voltage_change_prepare(struct regulator_dev *rdev, unsigned int sel, 1529bcbabafSMatti Vaittinen unsigned int *mask) 1539bcbabafSMatti Vaittinen { 1549bcbabafSMatti Vaittinen int ret; 1559bcbabafSMatti Vaittinen 1569bcbabafSMatti Vaittinen *mask = 0; 1571d848d68SMatti Vaittinen if (rdev->desc->ops->is_enabled(rdev)) { 1589bcbabafSMatti Vaittinen int now, new; 1599bcbabafSMatti Vaittinen 1609bcbabafSMatti Vaittinen now = rdev->desc->ops->get_voltage_sel(rdev); 1619bcbabafSMatti Vaittinen if (now < 0) 1629bcbabafSMatti Vaittinen return now; 1639bcbabafSMatti Vaittinen 1649bcbabafSMatti Vaittinen now = rdev->desc->ops->list_voltage(rdev, now); 1659bcbabafSMatti Vaittinen if (now < 0) 1669bcbabafSMatti Vaittinen return now; 1679bcbabafSMatti Vaittinen 1689bcbabafSMatti Vaittinen new = rdev->desc->ops->list_voltage(rdev, sel); 1699bcbabafSMatti Vaittinen if (new < 0) 1709bcbabafSMatti Vaittinen return new; 1719bcbabafSMatti Vaittinen 1729bcbabafSMatti Vaittinen /* 1739bcbabafSMatti Vaittinen * If we increase LDO voltage when LDO is enabled we need to 1749bcbabafSMatti Vaittinen * disable the power-good detection until voltage has reached 1759bcbabafSMatti Vaittinen * the new level. According to HW colleagues the maximum time 1769bcbabafSMatti Vaittinen * it takes is 1000us. I assume that on systems with light load 1779bcbabafSMatti Vaittinen * this might be less - and we could probably use DT to give 1789bcbabafSMatti Vaittinen * system specific delay value if performance matters. 1799bcbabafSMatti Vaittinen * 1809bcbabafSMatti Vaittinen * Well, knowing we use I2C here and can add scheduling delays 1819bcbabafSMatti Vaittinen * I don't think it is worth the hassle and I just add fixed 1829bcbabafSMatti Vaittinen * 1ms sleep here (and allow scheduling). If this turns out to 1839bcbabafSMatti Vaittinen * be a problem we can change it to delay and make the delay 1849bcbabafSMatti Vaittinen * time configurable. 1859bcbabafSMatti Vaittinen */ 1869bcbabafSMatti Vaittinen if (new > now) { 187fedbfea1SMatti Vaittinen int tmp; 188fedbfea1SMatti Vaittinen int prot_bit; 1899bcbabafSMatti Vaittinen int ldo_offset = rdev->desc->id - BD718XX_LDO1; 1909bcbabafSMatti Vaittinen 191fedbfea1SMatti Vaittinen prot_bit = BD718XX_LDO1_VRMON80 << ldo_offset; 192fedbfea1SMatti Vaittinen ret = regmap_read(rdev->regmap, BD718XX_REG_MVRFLTMASK2, 193fedbfea1SMatti Vaittinen &tmp); 194fedbfea1SMatti Vaittinen if (ret) { 195fedbfea1SMatti Vaittinen dev_err(&rdev->dev, 196fedbfea1SMatti Vaittinen "Failed to read voltage monitoring state\n"); 197fedbfea1SMatti Vaittinen return ret; 198fedbfea1SMatti Vaittinen } 199fedbfea1SMatti Vaittinen 200fedbfea1SMatti Vaittinen if (!(tmp & prot_bit)) { 201fedbfea1SMatti Vaittinen /* We disable protection if it was enabled... */ 202fedbfea1SMatti Vaittinen ret = regmap_set_bits(rdev->regmap, 2039bcbabafSMatti Vaittinen BD718XX_REG_MVRFLTMASK2, 204fedbfea1SMatti Vaittinen prot_bit); 205fedbfea1SMatti Vaittinen /* ...and we also want to re-enable it */ 206fedbfea1SMatti Vaittinen *mask = prot_bit; 207fedbfea1SMatti Vaittinen } 2089bcbabafSMatti Vaittinen if (ret) { 2099bcbabafSMatti Vaittinen dev_err(&rdev->dev, 2109bcbabafSMatti Vaittinen "Failed to stop voltage monitoring\n"); 2119bcbabafSMatti Vaittinen return ret; 2129bcbabafSMatti Vaittinen } 2139bcbabafSMatti Vaittinen } 2149bcbabafSMatti Vaittinen } 2159bcbabafSMatti Vaittinen 2169bcbabafSMatti Vaittinen return 0; 2179bcbabafSMatti Vaittinen } 2189bcbabafSMatti Vaittinen 2199bcbabafSMatti Vaittinen static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev, 2209bcbabafSMatti Vaittinen unsigned int sel) 2219bcbabafSMatti Vaittinen { 2229bcbabafSMatti Vaittinen int ret; 2239bcbabafSMatti Vaittinen int mask; 2249bcbabafSMatti Vaittinen 2259bcbabafSMatti Vaittinen ret = voltage_change_prepare(rdev, sel, &mask); 2269bcbabafSMatti Vaittinen if (ret) 2279bcbabafSMatti Vaittinen return ret; 2289bcbabafSMatti Vaittinen 2299bcbabafSMatti Vaittinen ret = regulator_set_voltage_sel_regmap(rdev, sel); 2309bcbabafSMatti Vaittinen voltage_change_done(rdev, sel, &mask); 2319bcbabafSMatti Vaittinen 2329bcbabafSMatti Vaittinen return ret; 2339bcbabafSMatti Vaittinen } 2349bcbabafSMatti Vaittinen 2352ece646cSMatti Vaittinen static int bd718xx_set_voltage_sel_pickable_restricted( 2362ece646cSMatti Vaittinen struct regulator_dev *rdev, unsigned int sel) 2372ece646cSMatti Vaittinen { 2389bcbabafSMatti Vaittinen int ret; 2399bcbabafSMatti Vaittinen int mask; 2409bcbabafSMatti Vaittinen 2419bcbabafSMatti Vaittinen ret = voltage_change_prepare(rdev, sel, &mask); 2429bcbabafSMatti Vaittinen if (ret) 2439bcbabafSMatti Vaittinen return ret; 2449bcbabafSMatti Vaittinen 2459bcbabafSMatti Vaittinen ret = regulator_set_voltage_sel_pickable_regmap(rdev, sel); 2469bcbabafSMatti Vaittinen voltage_change_done(rdev, sel, &mask); 2479bcbabafSMatti Vaittinen 2489bcbabafSMatti Vaittinen return ret; 2499bcbabafSMatti Vaittinen } 2509bcbabafSMatti Vaittinen 2519bcbabafSMatti Vaittinen static int bd71837_set_voltage_sel_pickable_restricted( 2529bcbabafSMatti Vaittinen struct regulator_dev *rdev, unsigned int sel) 2539bcbabafSMatti Vaittinen { 2541d848d68SMatti Vaittinen if (rdev->desc->ops->is_enabled(rdev)) 2552ece646cSMatti Vaittinen return -EBUSY; 2562ece646cSMatti Vaittinen 2572ece646cSMatti Vaittinen return regulator_set_voltage_sel_pickable_regmap(rdev, sel); 2582ece646cSMatti Vaittinen } 2592ece646cSMatti Vaittinen 2601d848d68SMatti Vaittinen /* 2612ece646cSMatti Vaittinen * BD71837 BUCK1/2/3/4 2622ece646cSMatti Vaittinen * BD71847 BUCK1/2 2632ece646cSMatti Vaittinen * 0.70 to 1.30V (10mV step) 2642ece646cSMatti Vaittinen */ 26560ab7f41SMatti Vaittinen static const struct linear_range bd718xx_dvs_buck_volts[] = { 2662ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000), 2672ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0), 2682ece646cSMatti Vaittinen }; 2692ece646cSMatti Vaittinen 2702ece646cSMatti Vaittinen /* 2712ece646cSMatti Vaittinen * BD71837 BUCK5 2722ece646cSMatti Vaittinen * 0.7V to 1.35V (range 0) 2732ece646cSMatti Vaittinen * and 2742ece646cSMatti Vaittinen * 0.675 to 1.325 (range 1) 2752ece646cSMatti Vaittinen */ 27660ab7f41SMatti Vaittinen static const struct linear_range bd71837_buck5_volts[] = { 2772ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bit is 0 */ 2782ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000), 2792ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000), 2802ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000), 2812ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bit is 1 */ 2822ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000), 2832ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000), 2842ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000), 2852ece646cSMatti Vaittinen }; 2862ece646cSMatti Vaittinen 2872ece646cSMatti Vaittinen /* 2882ece646cSMatti Vaittinen * Range selector for first 3 linear ranges is 0x0 2892ece646cSMatti Vaittinen * and 0x1 for last 3 ranges. 2902ece646cSMatti Vaittinen */ 2912ece646cSMatti Vaittinen static const unsigned int bd71837_buck5_volt_range_sel[] = { 2922ece646cSMatti Vaittinen 0x0, 0x0, 0x0, 0x80, 0x80, 0x80 2932ece646cSMatti Vaittinen }; 2942ece646cSMatti Vaittinen 2952ece646cSMatti Vaittinen /* 2962ece646cSMatti Vaittinen * BD71847 BUCK3 2972ece646cSMatti Vaittinen */ 29860ab7f41SMatti Vaittinen static const struct linear_range bd71847_buck3_volts[] = { 2992ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bits are 00 */ 3002ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000), 3012ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000), 3022ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000), 3032ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bits are 01 */ 3042ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(550000, 0x0, 0x7, 50000), 3052ece646cSMatti Vaittinen /* Ranges when VOLT_SEL bits are 11 */ 3062ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000), 3072ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000), 3082ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000), 3092ece646cSMatti Vaittinen }; 3102ece646cSMatti Vaittinen 3112ece646cSMatti Vaittinen static const unsigned int bd71847_buck3_volt_range_sel[] = { 3122ece646cSMatti Vaittinen 0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80 3132ece646cSMatti Vaittinen }; 3142ece646cSMatti Vaittinen 31560ab7f41SMatti Vaittinen static const struct linear_range bd71847_buck4_volts[] = { 3162ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), 3172ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000), 3182ece646cSMatti Vaittinen }; 3192ece646cSMatti Vaittinen 3202ece646cSMatti Vaittinen static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 }; 3212ece646cSMatti Vaittinen 3222ece646cSMatti Vaittinen /* 3232ece646cSMatti Vaittinen * BUCK6 3242ece646cSMatti Vaittinen * 3.0V to 3.3V (step 100mV) 3252ece646cSMatti Vaittinen */ 32660ab7f41SMatti Vaittinen static const struct linear_range bd71837_buck6_volts[] = { 3272ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), 3282ece646cSMatti Vaittinen }; 3292ece646cSMatti Vaittinen 3302ece646cSMatti Vaittinen /* 3312ece646cSMatti Vaittinen * BD71837 BUCK7 3322ece646cSMatti Vaittinen * BD71847 BUCK5 3332ece646cSMatti Vaittinen * 000 = 1.605V 3342ece646cSMatti Vaittinen * 001 = 1.695V 3352ece646cSMatti Vaittinen * 010 = 1.755V 3362ece646cSMatti Vaittinen * 011 = 1.8V (Initial) 3372ece646cSMatti Vaittinen * 100 = 1.845V 3382ece646cSMatti Vaittinen * 101 = 1.905V 3392ece646cSMatti Vaittinen * 110 = 1.95V 3402ece646cSMatti Vaittinen * 111 = 1.995V 3412ece646cSMatti Vaittinen */ 3422ece646cSMatti Vaittinen static const unsigned int bd718xx_3rd_nodvs_buck_volts[] = { 3432ece646cSMatti Vaittinen 1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000 3442ece646cSMatti Vaittinen }; 3452ece646cSMatti Vaittinen 3462ece646cSMatti Vaittinen /* 3472ece646cSMatti Vaittinen * BUCK8 3482ece646cSMatti Vaittinen * 0.8V to 1.40V (step 10mV) 3492ece646cSMatti Vaittinen */ 35060ab7f41SMatti Vaittinen static const struct linear_range bd718xx_4th_nodvs_buck_volts[] = { 3512ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000), 3522ece646cSMatti Vaittinen }; 3532ece646cSMatti Vaittinen 3542ece646cSMatti Vaittinen /* 3552ece646cSMatti Vaittinen * LDO1 3562ece646cSMatti Vaittinen * 3.0 to 3.3V (100mV step) 3572ece646cSMatti Vaittinen */ 35860ab7f41SMatti Vaittinen static const struct linear_range bd718xx_ldo1_volts[] = { 3592ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000), 3602ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000), 3612ece646cSMatti Vaittinen }; 3622ece646cSMatti Vaittinen 3632ece646cSMatti Vaittinen static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x20 }; 3642ece646cSMatti Vaittinen 3652ece646cSMatti Vaittinen /* 3662ece646cSMatti Vaittinen * LDO2 3672ece646cSMatti Vaittinen * 0.8 or 0.9V 3682ece646cSMatti Vaittinen */ 3692ece646cSMatti Vaittinen static const unsigned int ldo_2_volts[] = { 3702ece646cSMatti Vaittinen 900000, 800000 3712ece646cSMatti Vaittinen }; 3722ece646cSMatti Vaittinen 3732ece646cSMatti Vaittinen /* 3742ece646cSMatti Vaittinen * LDO3 3752ece646cSMatti Vaittinen * 1.8 to 3.3V (100mV step) 3762ece646cSMatti Vaittinen */ 37760ab7f41SMatti Vaittinen static const struct linear_range bd718xx_ldo3_volts[] = { 3782ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 3792ece646cSMatti Vaittinen }; 3802ece646cSMatti Vaittinen 3812ece646cSMatti Vaittinen /* 3822ece646cSMatti Vaittinen * LDO4 3832ece646cSMatti Vaittinen * 0.9 to 1.8V (100mV step) 3842ece646cSMatti Vaittinen */ 38560ab7f41SMatti Vaittinen static const struct linear_range bd718xx_ldo4_volts[] = { 3862ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000), 3872ece646cSMatti Vaittinen }; 3882ece646cSMatti Vaittinen 3892ece646cSMatti Vaittinen /* 3902ece646cSMatti Vaittinen * LDO5 for BD71837 3912ece646cSMatti Vaittinen * 1.8 to 3.3V (100mV step) 3922ece646cSMatti Vaittinen */ 39360ab7f41SMatti Vaittinen static const struct linear_range bd71837_ldo5_volts[] = { 3942ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 3952ece646cSMatti Vaittinen }; 3962ece646cSMatti Vaittinen 3972ece646cSMatti Vaittinen /* 3982ece646cSMatti Vaittinen * LDO5 for BD71837 3992ece646cSMatti Vaittinen * 1.8 to 3.3V (100mV step) 4002ece646cSMatti Vaittinen */ 40160ab7f41SMatti Vaittinen static const struct linear_range bd71847_ldo5_volts[] = { 4022ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 4032ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000), 4042ece646cSMatti Vaittinen }; 4052ece646cSMatti Vaittinen 4062ece646cSMatti Vaittinen static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 }; 4072ece646cSMatti Vaittinen 4082ece646cSMatti Vaittinen /* 4092ece646cSMatti Vaittinen * LDO6 4102ece646cSMatti Vaittinen * 0.9 to 1.8V (100mV step) 4112ece646cSMatti Vaittinen */ 41260ab7f41SMatti Vaittinen static const struct linear_range bd718xx_ldo6_volts[] = { 4132ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000), 4142ece646cSMatti Vaittinen }; 4152ece646cSMatti Vaittinen 4162ece646cSMatti Vaittinen /* 4172ece646cSMatti Vaittinen * LDO7 4182ece646cSMatti Vaittinen * 1.8 to 3.3V (100mV step) 4192ece646cSMatti Vaittinen */ 42060ab7f41SMatti Vaittinen static const struct linear_range bd71837_ldo7_volts[] = { 4212ece646cSMatti Vaittinen REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), 4222ece646cSMatti Vaittinen }; 4232ece646cSMatti Vaittinen 4242ece646cSMatti Vaittinen struct reg_init { 4252ece646cSMatti Vaittinen unsigned int reg; 4262ece646cSMatti Vaittinen unsigned int mask; 4272ece646cSMatti Vaittinen unsigned int val; 4282ece646cSMatti Vaittinen }; 4292ece646cSMatti Vaittinen struct bd718xx_regulator_data { 4302ece646cSMatti Vaittinen struct regulator_desc desc; 43121b72156SMatti Vaittinen const struct rohm_dvs_config dvs; 4322ece646cSMatti Vaittinen const struct reg_init init; 4332ece646cSMatti Vaittinen const struct reg_init *additional_inits; 4342ece646cSMatti Vaittinen int additional_init_amnt; 4352ece646cSMatti Vaittinen }; 4362ece646cSMatti Vaittinen 437fedbfea1SMatti Vaittinen static int bd718x7_xvp_sanity_check(struct regulator_dev *rdev, int lim_uV, 438fedbfea1SMatti Vaittinen int severity) 439fedbfea1SMatti Vaittinen { 440fedbfea1SMatti Vaittinen /* 441fedbfea1SMatti Vaittinen * BD71837/47/50 ... (ICs supported by this driver) do not provide 442fedbfea1SMatti Vaittinen * warnings, only protection 443fedbfea1SMatti Vaittinen */ 444fedbfea1SMatti Vaittinen if (severity != REGULATOR_SEVERITY_PROT) { 445fedbfea1SMatti Vaittinen dev_err(&rdev->dev, 446fedbfea1SMatti Vaittinen "Unsupported Under Voltage protection level\n"); 447fedbfea1SMatti Vaittinen return -EINVAL; 448fedbfea1SMatti Vaittinen } 449fedbfea1SMatti Vaittinen 450fedbfea1SMatti Vaittinen /* 451fedbfea1SMatti Vaittinen * And protection limit is not changeable. It can only be enabled 452fedbfea1SMatti Vaittinen * or disabled 453fedbfea1SMatti Vaittinen */ 454fedbfea1SMatti Vaittinen if (lim_uV) 455fedbfea1SMatti Vaittinen return -EINVAL; 456fedbfea1SMatti Vaittinen 457fedbfea1SMatti Vaittinen return 0; 458fedbfea1SMatti Vaittinen } 459fedbfea1SMatti Vaittinen 460fedbfea1SMatti Vaittinen static int bd718x7_set_ldo_uvp(struct regulator_dev *rdev, int lim_uV, 461fedbfea1SMatti Vaittinen int severity, bool enable) 462fedbfea1SMatti Vaittinen { 463fedbfea1SMatti Vaittinen int ldo_offset = rdev->desc->id - BD718XX_LDO1; 464fedbfea1SMatti Vaittinen int prot_bit, ret; 465fedbfea1SMatti Vaittinen 466fedbfea1SMatti Vaittinen ret = bd718x7_xvp_sanity_check(rdev, lim_uV, severity); 467fedbfea1SMatti Vaittinen if (ret) 468fedbfea1SMatti Vaittinen return ret; 469fedbfea1SMatti Vaittinen 470fedbfea1SMatti Vaittinen prot_bit = BD718XX_LDO1_VRMON80 << ldo_offset; 471fedbfea1SMatti Vaittinen 472fedbfea1SMatti Vaittinen if (enable) 473fedbfea1SMatti Vaittinen return regmap_clear_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2, 474fedbfea1SMatti Vaittinen prot_bit); 475fedbfea1SMatti Vaittinen 476fedbfea1SMatti Vaittinen return regmap_set_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2, 477fedbfea1SMatti Vaittinen prot_bit); 478fedbfea1SMatti Vaittinen } 479fedbfea1SMatti Vaittinen 480fedbfea1SMatti Vaittinen static int bd718x7_get_buck_prot_reg(int id, int *reg) 481fedbfea1SMatti Vaittinen { 482fedbfea1SMatti Vaittinen 483fedbfea1SMatti Vaittinen if (id > BD718XX_BUCK8) { 484fedbfea1SMatti Vaittinen WARN_ON(id > BD718XX_BUCK8); 485fedbfea1SMatti Vaittinen return -EINVAL; 486fedbfea1SMatti Vaittinen } 487fedbfea1SMatti Vaittinen 488fedbfea1SMatti Vaittinen if (id > BD718XX_BUCK4) 489fedbfea1SMatti Vaittinen *reg = BD718XX_REG_MVRFLTMASK0; 490fedbfea1SMatti Vaittinen else 491fedbfea1SMatti Vaittinen *reg = BD718XX_REG_MVRFLTMASK1; 492fedbfea1SMatti Vaittinen 493fedbfea1SMatti Vaittinen return 0; 494fedbfea1SMatti Vaittinen } 495fedbfea1SMatti Vaittinen 496fedbfea1SMatti Vaittinen static int bd718x7_get_buck_ovp_info(int id, int *reg, int *bit) 497fedbfea1SMatti Vaittinen { 498fedbfea1SMatti Vaittinen int ret; 499fedbfea1SMatti Vaittinen 500fedbfea1SMatti Vaittinen ret = bd718x7_get_buck_prot_reg(id, reg); 501fedbfea1SMatti Vaittinen if (ret) 502fedbfea1SMatti Vaittinen return ret; 503fedbfea1SMatti Vaittinen 504fedbfea1SMatti Vaittinen *bit = BIT((id % 4) * 2 + 1); 505fedbfea1SMatti Vaittinen 506fedbfea1SMatti Vaittinen return 0; 507fedbfea1SMatti Vaittinen } 508fedbfea1SMatti Vaittinen 509fedbfea1SMatti Vaittinen static int bd718x7_get_buck_uvp_info(int id, int *reg, int *bit) 510fedbfea1SMatti Vaittinen { 511fedbfea1SMatti Vaittinen int ret; 512fedbfea1SMatti Vaittinen 513fedbfea1SMatti Vaittinen ret = bd718x7_get_buck_prot_reg(id, reg); 514fedbfea1SMatti Vaittinen if (ret) 515fedbfea1SMatti Vaittinen return ret; 516fedbfea1SMatti Vaittinen 517fedbfea1SMatti Vaittinen *bit = BIT((id % 4) * 2); 518fedbfea1SMatti Vaittinen 519fedbfea1SMatti Vaittinen return 0; 520fedbfea1SMatti Vaittinen } 521fedbfea1SMatti Vaittinen 522fedbfea1SMatti Vaittinen static int bd718x7_set_buck_uvp(struct regulator_dev *rdev, int lim_uV, 523fedbfea1SMatti Vaittinen int severity, bool enable) 524fedbfea1SMatti Vaittinen { 525fedbfea1SMatti Vaittinen int bit, reg, ret; 526fedbfea1SMatti Vaittinen 527fedbfea1SMatti Vaittinen ret = bd718x7_xvp_sanity_check(rdev, lim_uV, severity); 528fedbfea1SMatti Vaittinen if (ret) 529fedbfea1SMatti Vaittinen return ret; 530fedbfea1SMatti Vaittinen 531fedbfea1SMatti Vaittinen ret = bd718x7_get_buck_uvp_info(rdev->desc->id, ®, &bit); 532fedbfea1SMatti Vaittinen if (ret) 533fedbfea1SMatti Vaittinen return ret; 534fedbfea1SMatti Vaittinen 535fedbfea1SMatti Vaittinen if (enable) 536fedbfea1SMatti Vaittinen return regmap_clear_bits(rdev->regmap, reg, bit); 537fedbfea1SMatti Vaittinen 538fedbfea1SMatti Vaittinen return regmap_set_bits(rdev->regmap, reg, bit); 539fedbfea1SMatti Vaittinen 540fedbfea1SMatti Vaittinen } 541fedbfea1SMatti Vaittinen 542fedbfea1SMatti Vaittinen static int bd718x7_set_buck_ovp(struct regulator_dev *rdev, int lim_uV, 543fedbfea1SMatti Vaittinen int severity, 544fedbfea1SMatti Vaittinen bool enable) 545fedbfea1SMatti Vaittinen { 546fedbfea1SMatti Vaittinen int bit, reg, ret; 547fedbfea1SMatti Vaittinen 548fedbfea1SMatti Vaittinen ret = bd718x7_xvp_sanity_check(rdev, lim_uV, severity); 549fedbfea1SMatti Vaittinen if (ret) 550fedbfea1SMatti Vaittinen return ret; 551fedbfea1SMatti Vaittinen 552fedbfea1SMatti Vaittinen ret = bd718x7_get_buck_ovp_info(rdev->desc->id, ®, &bit); 553fedbfea1SMatti Vaittinen if (ret) 554fedbfea1SMatti Vaittinen return ret; 555fedbfea1SMatti Vaittinen 556fedbfea1SMatti Vaittinen if (enable) 557fedbfea1SMatti Vaittinen return regmap_clear_bits(rdev->regmap, reg, bit); 558fedbfea1SMatti Vaittinen 559fedbfea1SMatti Vaittinen return regmap_set_bits(rdev->regmap, reg, bit); 560fedbfea1SMatti Vaittinen } 561fedbfea1SMatti Vaittinen 562fedbfea1SMatti Vaittinen /* 563fedbfea1SMatti Vaittinen * OPS common for BD71847 and BD71850 564fedbfea1SMatti Vaittinen */ 565fedbfea1SMatti Vaittinen BD718XX_OPS(bd718xx_pickable_range_ldo_ops, 566fedbfea1SMatti Vaittinen regulator_list_voltage_pickable_linear_range, NULL, 567fedbfea1SMatti Vaittinen bd718xx_set_voltage_sel_pickable_restricted, 568fedbfea1SMatti Vaittinen regulator_get_voltage_sel_pickable_regmap, NULL, NULL, 569fedbfea1SMatti Vaittinen bd718x7_set_ldo_uvp, NULL); 570fedbfea1SMatti Vaittinen 571fedbfea1SMatti Vaittinen /* BD71847 and BD71850 LDO 5 is by default OFF at RUN state */ 572fedbfea1SMatti Vaittinen static const struct regulator_ops bd718xx_ldo5_ops_hwstate = { 573fedbfea1SMatti Vaittinen .is_enabled = never_enabled_by_hwstate, 574fedbfea1SMatti Vaittinen .list_voltage = regulator_list_voltage_pickable_linear_range, 575fedbfea1SMatti Vaittinen .set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted, 576fedbfea1SMatti Vaittinen .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, 577fedbfea1SMatti Vaittinen .set_under_voltage_protection = bd718x7_set_ldo_uvp, 578fedbfea1SMatti Vaittinen }; 579fedbfea1SMatti Vaittinen 580fedbfea1SMatti Vaittinen BD718XX_OPS(bd718xx_pickable_range_buck_ops, 581fedbfea1SMatti Vaittinen regulator_list_voltage_pickable_linear_range, NULL, 582fedbfea1SMatti Vaittinen regulator_set_voltage_sel_pickable_regmap, 583fedbfea1SMatti Vaittinen regulator_get_voltage_sel_pickable_regmap, 584fedbfea1SMatti Vaittinen regulator_set_voltage_time_sel, NULL, bd718x7_set_buck_uvp, 585fedbfea1SMatti Vaittinen bd718x7_set_buck_ovp); 586fedbfea1SMatti Vaittinen 587fedbfea1SMatti Vaittinen BD718XX_OPS(bd718xx_ldo_regulator_ops, regulator_list_voltage_linear_range, 588fedbfea1SMatti Vaittinen NULL, bd718xx_set_voltage_sel_restricted, 589fedbfea1SMatti Vaittinen regulator_get_voltage_sel_regmap, NULL, NULL, bd718x7_set_ldo_uvp, 590fedbfea1SMatti Vaittinen NULL); 591fedbfea1SMatti Vaittinen 592fedbfea1SMatti Vaittinen BD718XX_OPS(bd718xx_ldo_regulator_nolinear_ops, regulator_list_voltage_table, 593fedbfea1SMatti Vaittinen NULL, bd718xx_set_voltage_sel_restricted, 594fedbfea1SMatti Vaittinen regulator_get_voltage_sel_regmap, NULL, NULL, bd718x7_set_ldo_uvp, 595fedbfea1SMatti Vaittinen NULL); 596fedbfea1SMatti Vaittinen 597fedbfea1SMatti Vaittinen BD718XX_OPS(bd718xx_buck_regulator_ops, regulator_list_voltage_linear_range, 598fedbfea1SMatti Vaittinen NULL, regulator_set_voltage_sel_regmap, 599fedbfea1SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 600fedbfea1SMatti Vaittinen NULL, bd718x7_set_buck_uvp, bd718x7_set_buck_ovp); 601fedbfea1SMatti Vaittinen 602fedbfea1SMatti Vaittinen BD718XX_OPS(bd718xx_buck_regulator_nolinear_ops, regulator_list_voltage_table, 603fedbfea1SMatti Vaittinen regulator_map_voltage_ascend, regulator_set_voltage_sel_regmap, 604fedbfea1SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 605fedbfea1SMatti Vaittinen NULL, bd718x7_set_buck_uvp, bd718x7_set_buck_ovp); 606fedbfea1SMatti Vaittinen 607fedbfea1SMatti Vaittinen /* 608fedbfea1SMatti Vaittinen * OPS for BD71837 609fedbfea1SMatti Vaittinen */ 610fedbfea1SMatti Vaittinen BD718XX_OPS(bd71837_pickable_range_ldo_ops, 611fedbfea1SMatti Vaittinen regulator_list_voltage_pickable_linear_range, NULL, 612fedbfea1SMatti Vaittinen bd71837_set_voltage_sel_pickable_restricted, 613fedbfea1SMatti Vaittinen regulator_get_voltage_sel_pickable_regmap, NULL, NULL, 614fedbfea1SMatti Vaittinen bd718x7_set_ldo_uvp, NULL); 615fedbfea1SMatti Vaittinen 616fedbfea1SMatti Vaittinen BD718XX_OPS(bd71837_pickable_range_buck_ops, 617fedbfea1SMatti Vaittinen regulator_list_voltage_pickable_linear_range, NULL, 618fedbfea1SMatti Vaittinen bd71837_set_voltage_sel_pickable_restricted, 619fedbfea1SMatti Vaittinen regulator_get_voltage_sel_pickable_regmap, 620fedbfea1SMatti Vaittinen regulator_set_voltage_time_sel, NULL, bd718x7_set_buck_uvp, 621fedbfea1SMatti Vaittinen bd718x7_set_buck_ovp); 622fedbfea1SMatti Vaittinen 623fedbfea1SMatti Vaittinen BD718XX_OPS(bd71837_ldo_regulator_ops, regulator_list_voltage_linear_range, 624e7543e19SMatti Vaittinen NULL, rohm_regulator_set_voltage_sel_restricted, 625fedbfea1SMatti Vaittinen regulator_get_voltage_sel_regmap, NULL, NULL, bd718x7_set_ldo_uvp, 626fedbfea1SMatti Vaittinen NULL); 627fedbfea1SMatti Vaittinen 628fedbfea1SMatti Vaittinen BD718XX_OPS(bd71837_ldo_regulator_nolinear_ops, regulator_list_voltage_table, 629e7543e19SMatti Vaittinen NULL, rohm_regulator_set_voltage_sel_restricted, 630fedbfea1SMatti Vaittinen regulator_get_voltage_sel_regmap, NULL, NULL, bd718x7_set_ldo_uvp, 631fedbfea1SMatti Vaittinen NULL); 632fedbfea1SMatti Vaittinen 633fedbfea1SMatti Vaittinen BD718XX_OPS(bd71837_buck_regulator_ops, regulator_list_voltage_linear_range, 634e7543e19SMatti Vaittinen NULL, rohm_regulator_set_voltage_sel_restricted, 635fedbfea1SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 636fedbfea1SMatti Vaittinen NULL, bd718x7_set_buck_uvp, bd718x7_set_buck_ovp); 637fedbfea1SMatti Vaittinen 638fedbfea1SMatti Vaittinen BD718XX_OPS(bd71837_buck_regulator_nolinear_ops, regulator_list_voltage_table, 639e7543e19SMatti Vaittinen regulator_map_voltage_ascend, rohm_regulator_set_voltage_sel_restricted, 640fedbfea1SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 641fedbfea1SMatti Vaittinen NULL, bd718x7_set_buck_uvp, bd718x7_set_buck_ovp); 642fedbfea1SMatti Vaittinen /* 643fedbfea1SMatti Vaittinen * BD71837 bucks 3 and 4 support defining their enable/disable state also 644fedbfea1SMatti Vaittinen * when buck enable state is under HW state machine control. In that case the 645fedbfea1SMatti Vaittinen * bit [2] in CTRL register is used to indicate if regulator should be ON. 646fedbfea1SMatti Vaittinen */ 647fedbfea1SMatti Vaittinen static const struct regulator_ops bd71837_buck34_ops_hwctrl = { 648fedbfea1SMatti Vaittinen .is_enabled = bd71837_get_buck34_enable_hwctrl, 649fedbfea1SMatti Vaittinen .list_voltage = regulator_list_voltage_linear_range, 650fedbfea1SMatti Vaittinen .set_voltage_sel = regulator_set_voltage_sel_regmap, 651fedbfea1SMatti Vaittinen .get_voltage_sel = regulator_get_voltage_sel_regmap, 652fedbfea1SMatti Vaittinen .set_voltage_time_sel = regulator_set_voltage_time_sel, 653fedbfea1SMatti Vaittinen .set_ramp_delay = regulator_set_ramp_delay_regmap, 654fedbfea1SMatti Vaittinen .set_under_voltage_protection = bd718x7_set_buck_uvp, 655fedbfea1SMatti Vaittinen .set_over_voltage_protection = bd718x7_set_buck_ovp, 656fedbfea1SMatti Vaittinen }; 657fedbfea1SMatti Vaittinen 658fedbfea1SMatti Vaittinen /* 659fedbfea1SMatti Vaittinen * OPS for all of the ICs - BD718(37/47/50) 660fedbfea1SMatti Vaittinen */ 661fedbfea1SMatti Vaittinen BD718XX_OPS(bd718xx_dvs_buck_regulator_ops, regulator_list_voltage_linear_range, 662fedbfea1SMatti Vaittinen NULL, regulator_set_voltage_sel_regmap, 663fedbfea1SMatti Vaittinen regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, 664fedbfea1SMatti Vaittinen regulator_set_ramp_delay_regmap, bd718x7_set_buck_uvp, 665fedbfea1SMatti Vaittinen bd718x7_set_buck_ovp); 666fedbfea1SMatti Vaittinen 667fedbfea1SMatti Vaittinen 668fedbfea1SMatti Vaittinen 6692ece646cSMatti Vaittinen /* 6702ece646cSMatti Vaittinen * There is a HW quirk in BD71837. The shutdown sequence timings for 6712ece646cSMatti Vaittinen * bucks/LDOs which are controlled via register interface are changed. 6722ece646cSMatti Vaittinen * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the 6732ece646cSMatti Vaittinen * beginning of shut-down sequence. As bucks 6 and 7 are parent 6742ece646cSMatti Vaittinen * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage 6752ece646cSMatti Vaittinen * monitoring to errorneously detect under voltage and force PMIC to 6762ece646cSMatti Vaittinen * emergency state instead of poweroff. In order to avoid this we 6772ece646cSMatti Vaittinen * disable voltage monitoring for LDO5 and LDO6 6782ece646cSMatti Vaittinen */ 6792ece646cSMatti Vaittinen static const struct reg_init bd71837_ldo5_inits[] = { 6802ece646cSMatti Vaittinen { 6812ece646cSMatti Vaittinen .reg = BD718XX_REG_MVRFLTMASK2, 6822ece646cSMatti Vaittinen .mask = BD718XX_LDO5_VRMON80, 6832ece646cSMatti Vaittinen .val = BD718XX_LDO5_VRMON80, 6842ece646cSMatti Vaittinen }, 6852ece646cSMatti Vaittinen }; 6862ece646cSMatti Vaittinen 6872ece646cSMatti Vaittinen static const struct reg_init bd71837_ldo6_inits[] = { 6882ece646cSMatti Vaittinen { 6892ece646cSMatti Vaittinen .reg = BD718XX_REG_MVRFLTMASK2, 6902ece646cSMatti Vaittinen .mask = BD718XX_LDO6_VRMON80, 6912ece646cSMatti Vaittinen .val = BD718XX_LDO6_VRMON80, 6922ece646cSMatti Vaittinen }, 6932ece646cSMatti Vaittinen }; 6942ece646cSMatti Vaittinen 69521b72156SMatti Vaittinen static int buck_set_hw_dvs_levels(struct device_node *np, 696049369d4SMatti Vaittinen const struct regulator_desc *desc, 697049369d4SMatti Vaittinen struct regulator_config *cfg) 698049369d4SMatti Vaittinen { 69921b72156SMatti Vaittinen struct bd718xx_regulator_data *data; 700049369d4SMatti Vaittinen 70121b72156SMatti Vaittinen data = container_of(desc, struct bd718xx_regulator_data, desc); 702049369d4SMatti Vaittinen 70321b72156SMatti Vaittinen return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap); 704049369d4SMatti Vaittinen } 705049369d4SMatti Vaittinen 70602f8eaabSYueHaibing static const struct regulator_ops *bd71847_swcontrol_ops[] = { 7071d848d68SMatti Vaittinen &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, 7081d848d68SMatti Vaittinen &bd718xx_pickable_range_buck_ops, &bd718xx_pickable_range_buck_ops, 7091d848d68SMatti Vaittinen &bd718xx_buck_regulator_nolinear_ops, &bd718xx_buck_regulator_ops, 7101d848d68SMatti Vaittinen &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_nolinear_ops, 7111d848d68SMatti Vaittinen &bd718xx_ldo_regulator_ops, &bd718xx_ldo_regulator_ops, 7121d848d68SMatti Vaittinen &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_ops, 7131d848d68SMatti Vaittinen }; 7141d848d68SMatti Vaittinen 71502f8eaabSYueHaibing static const struct regulator_ops *bd71847_hwcontrol_ops[] = { 7161d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 7171d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 7181d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops), 7191d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops), 7201d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_buck_regulator_nolinear_ops), 7211d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_buck_regulator_ops), 7221d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_pickable_range_ldo_ops), 7231d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_ldo_regulator_nolinear_ops), 7241d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), 7251d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), 7261d848d68SMatti Vaittinen &bd718xx_ldo5_ops_hwstate, 7271d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), 7281d848d68SMatti Vaittinen }; 7291d848d68SMatti Vaittinen 7301d848d68SMatti Vaittinen static struct bd718xx_regulator_data bd71847_regulators[] = { 7312ece646cSMatti Vaittinen { 7322ece646cSMatti Vaittinen .desc = { 7332ece646cSMatti Vaittinen .name = "buck1", 7342ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK1"), 7352ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 7362ece646cSMatti Vaittinen .id = BD718XX_BUCK1, 7372ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 7382ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 7392ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 7402ece646cSMatti Vaittinen .n_linear_ranges = 7412ece646cSMatti Vaittinen ARRAY_SIZE(bd718xx_dvs_buck_volts), 7422ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN, 7432ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 7442ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_BUCK1_CTRL, 7452ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 7463b66e4a8SGuido Günther .enable_time = BD71847_BUCK1_STARTUP_TIME, 7472ece646cSMatti Vaittinen .owner = THIS_MODULE, 74818f3c625SMatti Vaittinen .ramp_delay_table = bd718xx_ramp_delay, 74918f3c625SMatti Vaittinen .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 75018f3c625SMatti Vaittinen .ramp_reg = BD718XX_REG_BUCK1_CTRL, 75118f3c625SMatti Vaittinen .ramp_mask = BUCK_RAMPRATE_MASK, 75221b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 75321b72156SMatti Vaittinen }, 75421b72156SMatti Vaittinen .dvs = { 75521b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | 75621b72156SMatti Vaittinen ROHM_DVS_LEVEL_SUSPEND, 75721b72156SMatti Vaittinen .run_reg = BD718XX_REG_BUCK1_VOLT_RUN, 75821b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 75921b72156SMatti Vaittinen .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE, 76021b72156SMatti Vaittinen .idle_mask = DVS_BUCK_RUN_MASK, 76121b72156SMatti Vaittinen .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP, 76221b72156SMatti Vaittinen .suspend_mask = DVS_BUCK_RUN_MASK, 7632ece646cSMatti Vaittinen }, 7642ece646cSMatti Vaittinen .init = { 7652ece646cSMatti Vaittinen .reg = BD718XX_REG_BUCK1_CTRL, 7662ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 7672ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 7682ece646cSMatti Vaittinen }, 7692ece646cSMatti Vaittinen }, 7702ece646cSMatti Vaittinen { 7712ece646cSMatti Vaittinen .desc = { 7722ece646cSMatti Vaittinen .name = "buck2", 7732ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK2"), 7742ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 7752ece646cSMatti Vaittinen .id = BD718XX_BUCK2, 7762ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 7772ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 7782ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 7792ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 7802ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN, 7812ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 7822ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_BUCK2_CTRL, 7832ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 7843b66e4a8SGuido Günther .enable_time = BD71847_BUCK2_STARTUP_TIME, 78518f3c625SMatti Vaittinen .ramp_delay_table = bd718xx_ramp_delay, 78618f3c625SMatti Vaittinen .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 78718f3c625SMatti Vaittinen .ramp_reg = BD718XX_REG_BUCK2_CTRL, 78818f3c625SMatti Vaittinen .ramp_mask = BUCK_RAMPRATE_MASK, 7892ece646cSMatti Vaittinen .owner = THIS_MODULE, 79021b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 79121b72156SMatti Vaittinen }, 79221b72156SMatti Vaittinen .dvs = { 79321b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE, 79421b72156SMatti Vaittinen .run_reg = BD718XX_REG_BUCK2_VOLT_RUN, 79521b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 79621b72156SMatti Vaittinen .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE, 79721b72156SMatti Vaittinen .idle_mask = DVS_BUCK_RUN_MASK, 7982ece646cSMatti Vaittinen }, 7992ece646cSMatti Vaittinen .init = { 8002ece646cSMatti Vaittinen .reg = BD718XX_REG_BUCK2_CTRL, 8012ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 8022ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 8032ece646cSMatti Vaittinen }, 8042ece646cSMatti Vaittinen }, 8052ece646cSMatti Vaittinen { 8062ece646cSMatti Vaittinen .desc = { 8072ece646cSMatti Vaittinen .name = "buck3", 8082ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK3"), 8092ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 8102ece646cSMatti Vaittinen .id = BD718XX_BUCK3, 8112ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 8122ece646cSMatti Vaittinen .n_voltages = BD71847_BUCK3_VOLTAGE_NUM, 8132ece646cSMatti Vaittinen .linear_ranges = bd71847_buck3_volts, 8142ece646cSMatti Vaittinen .n_linear_ranges = 8152ece646cSMatti Vaittinen ARRAY_SIZE(bd71847_buck3_volts), 8162ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 8172ece646cSMatti Vaittinen .vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK, 8182ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 8192ece646cSMatti Vaittinen .vsel_range_mask = BD71847_BUCK3_RANGE_MASK, 8202ece646cSMatti Vaittinen .linear_range_selectors = bd71847_buck3_volt_range_sel, 8212ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 8222ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 8233b66e4a8SGuido Günther .enable_time = BD71847_BUCK3_STARTUP_TIME, 8242ece646cSMatti Vaittinen .owner = THIS_MODULE, 8252ece646cSMatti Vaittinen }, 8262ece646cSMatti Vaittinen .init = { 8272ece646cSMatti Vaittinen .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 8282ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 8292ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 8302ece646cSMatti Vaittinen }, 8312ece646cSMatti Vaittinen }, 8322ece646cSMatti Vaittinen { 8332ece646cSMatti Vaittinen .desc = { 8342ece646cSMatti Vaittinen .name = "buck4", 8352ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK4"), 8362ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 8372ece646cSMatti Vaittinen .id = BD718XX_BUCK4, 8382ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 8392ece646cSMatti Vaittinen .n_voltages = BD71847_BUCK4_VOLTAGE_NUM, 8402ece646cSMatti Vaittinen .linear_ranges = bd71847_buck4_volts, 8412ece646cSMatti Vaittinen .n_linear_ranges = 8422ece646cSMatti Vaittinen ARRAY_SIZE(bd71847_buck4_volts), 8432ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 8442ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, 8452ece646cSMatti Vaittinen .vsel_mask = BD71847_BUCK4_MASK, 8462ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, 8472ece646cSMatti Vaittinen .vsel_range_mask = BD71847_BUCK4_RANGE_MASK, 8482ece646cSMatti Vaittinen .linear_range_selectors = bd71847_buck4_volt_range_sel, 8492ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 8503b66e4a8SGuido Günther .enable_time = BD71847_BUCK4_STARTUP_TIME, 8512ece646cSMatti Vaittinen .owner = THIS_MODULE, 8522ece646cSMatti Vaittinen }, 8532ece646cSMatti Vaittinen .init = { 8542ece646cSMatti Vaittinen .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 8552ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 8562ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 8572ece646cSMatti Vaittinen }, 8582ece646cSMatti Vaittinen }, 8592ece646cSMatti Vaittinen { 8602ece646cSMatti Vaittinen .desc = { 8612ece646cSMatti Vaittinen .name = "buck5", 8622ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK5"), 8632ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 8642ece646cSMatti Vaittinen .id = BD718XX_BUCK5, 8652ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 8662ece646cSMatti Vaittinen .volt_table = &bd718xx_3rd_nodvs_buck_volts[0], 8672ece646cSMatti Vaittinen .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts), 8682ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT, 8692ece646cSMatti Vaittinen .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, 8702ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 8712ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 8723b66e4a8SGuido Günther .enable_time = BD71847_BUCK5_STARTUP_TIME, 8732ece646cSMatti Vaittinen .owner = THIS_MODULE, 8742ece646cSMatti Vaittinen }, 8752ece646cSMatti Vaittinen .init = { 8762ece646cSMatti Vaittinen .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 8772ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 8782ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 8792ece646cSMatti Vaittinen }, 8802ece646cSMatti Vaittinen }, 8812ece646cSMatti Vaittinen { 8822ece646cSMatti Vaittinen .desc = { 8832ece646cSMatti Vaittinen .name = "buck6", 8842ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK6"), 8852ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 8862ece646cSMatti Vaittinen .id = BD718XX_BUCK6, 8872ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 8882ece646cSMatti Vaittinen .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM, 8892ece646cSMatti Vaittinen .linear_ranges = bd718xx_4th_nodvs_buck_volts, 8902ece646cSMatti Vaittinen .n_linear_ranges = 8912ece646cSMatti Vaittinen ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts), 8922ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT, 8932ece646cSMatti Vaittinen .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, 8942ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 8952ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 8963b66e4a8SGuido Günther .enable_time = BD71847_BUCK6_STARTUP_TIME, 8972ece646cSMatti Vaittinen .owner = THIS_MODULE, 8982ece646cSMatti Vaittinen }, 8992ece646cSMatti Vaittinen .init = { 9002ece646cSMatti Vaittinen .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 9012ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 9022ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 9032ece646cSMatti Vaittinen }, 9042ece646cSMatti Vaittinen }, 9052ece646cSMatti Vaittinen { 9062ece646cSMatti Vaittinen .desc = { 9072ece646cSMatti Vaittinen .name = "ldo1", 9082ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO1"), 9092ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 9102ece646cSMatti Vaittinen .id = BD718XX_LDO1, 9112ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 9122ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO1_VOLTAGE_NUM, 9132ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo1_volts, 9142ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts), 9152ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO1_VOLT, 9162ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO1_MASK, 9172ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_LDO1_VOLT, 9182ece646cSMatti Vaittinen .vsel_range_mask = BD718XX_LDO1_RANGE_MASK, 9192ece646cSMatti Vaittinen .linear_range_selectors = bd718xx_ldo1_volt_range_sel, 9202ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO1_VOLT, 9212ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 9223b66e4a8SGuido Günther .enable_time = BD71847_LDO1_STARTUP_TIME, 9232ece646cSMatti Vaittinen .owner = THIS_MODULE, 9242ece646cSMatti Vaittinen }, 9252ece646cSMatti Vaittinen .init = { 9262ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO1_VOLT, 9272ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 9282ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 9292ece646cSMatti Vaittinen }, 9302ece646cSMatti Vaittinen }, 9312ece646cSMatti Vaittinen { 9322ece646cSMatti Vaittinen .desc = { 9332ece646cSMatti Vaittinen .name = "ldo2", 9342ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO2"), 9352ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 9362ece646cSMatti Vaittinen .id = BD718XX_LDO2, 9372ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 9382ece646cSMatti Vaittinen .volt_table = &ldo_2_volts[0], 9392ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO2_VOLT, 9402ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO2_MASK, 9412ece646cSMatti Vaittinen .n_voltages = ARRAY_SIZE(ldo_2_volts), 9422ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO2_VOLT, 9432ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 9443b66e4a8SGuido Günther .enable_time = BD71847_LDO2_STARTUP_TIME, 9452ece646cSMatti Vaittinen .owner = THIS_MODULE, 9462ece646cSMatti Vaittinen }, 9472ece646cSMatti Vaittinen .init = { 9482ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO2_VOLT, 9492ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 9502ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 9512ece646cSMatti Vaittinen }, 9522ece646cSMatti Vaittinen }, 9532ece646cSMatti Vaittinen { 9542ece646cSMatti Vaittinen .desc = { 9552ece646cSMatti Vaittinen .name = "ldo3", 9562ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO3"), 9572ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 9582ece646cSMatti Vaittinen .id = BD718XX_LDO3, 9592ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 9602ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO3_VOLTAGE_NUM, 9612ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo3_volts, 9622ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts), 9632ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO3_VOLT, 9642ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO3_MASK, 9652ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO3_VOLT, 9662ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 9673b66e4a8SGuido Günther .enable_time = BD71847_LDO3_STARTUP_TIME, 9682ece646cSMatti Vaittinen .owner = THIS_MODULE, 9692ece646cSMatti Vaittinen }, 9702ece646cSMatti Vaittinen .init = { 9712ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO3_VOLT, 9722ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 9732ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 9742ece646cSMatti Vaittinen }, 9752ece646cSMatti Vaittinen }, 9762ece646cSMatti Vaittinen { 9772ece646cSMatti Vaittinen .desc = { 9782ece646cSMatti Vaittinen .name = "ldo4", 9792ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO4"), 9802ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 9812ece646cSMatti Vaittinen .id = BD718XX_LDO4, 9822ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 9832ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO4_VOLTAGE_NUM, 9842ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo4_volts, 9852ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts), 9862ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO4_VOLT, 9872ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO4_MASK, 9882ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO4_VOLT, 9892ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 9903b66e4a8SGuido Günther .enable_time = BD71847_LDO4_STARTUP_TIME, 9912ece646cSMatti Vaittinen .owner = THIS_MODULE, 9922ece646cSMatti Vaittinen }, 9932ece646cSMatti Vaittinen .init = { 9942ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO4_VOLT, 9952ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 9962ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 9972ece646cSMatti Vaittinen }, 9982ece646cSMatti Vaittinen }, 9992ece646cSMatti Vaittinen { 10002ece646cSMatti Vaittinen .desc = { 10012ece646cSMatti Vaittinen .name = "ldo5", 10022ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO5"), 10032ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 10042ece646cSMatti Vaittinen .id = BD718XX_LDO5, 10052ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 10062ece646cSMatti Vaittinen .n_voltages = BD71847_LDO5_VOLTAGE_NUM, 10072ece646cSMatti Vaittinen .linear_ranges = bd71847_ldo5_volts, 10082ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd71847_ldo5_volts), 10092ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO5_VOLT, 10102ece646cSMatti Vaittinen .vsel_mask = BD71847_LDO5_MASK, 10112ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_LDO5_VOLT, 10122ece646cSMatti Vaittinen .vsel_range_mask = BD71847_LDO5_RANGE_MASK, 10132ece646cSMatti Vaittinen .linear_range_selectors = bd71847_ldo5_volt_range_sel, 10142ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO5_VOLT, 10152ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 10163b66e4a8SGuido Günther .enable_time = BD71847_LDO5_STARTUP_TIME, 10172ece646cSMatti Vaittinen .owner = THIS_MODULE, 10182ece646cSMatti Vaittinen }, 10192ece646cSMatti Vaittinen .init = { 10202ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO5_VOLT, 10212ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 10222ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 10232ece646cSMatti Vaittinen }, 10242ece646cSMatti Vaittinen }, 10252ece646cSMatti Vaittinen { 10262ece646cSMatti Vaittinen .desc = { 10272ece646cSMatti Vaittinen .name = "ldo6", 10282ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO6"), 10292ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 10302ece646cSMatti Vaittinen .id = BD718XX_LDO6, 10312ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 10322ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO6_VOLTAGE_NUM, 10332ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo6_volts, 10342ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts), 10352ece646cSMatti Vaittinen /* LDO6 is supplied by buck5 */ 10362ece646cSMatti Vaittinen .supply_name = "buck5", 10372ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO6_VOLT, 10382ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO6_MASK, 10392ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO6_VOLT, 10402ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 10413b66e4a8SGuido Günther .enable_time = BD71847_LDO6_STARTUP_TIME, 10422ece646cSMatti Vaittinen .owner = THIS_MODULE, 10432ece646cSMatti Vaittinen }, 10442ece646cSMatti Vaittinen .init = { 10452ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO6_VOLT, 10462ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 10472ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 10482ece646cSMatti Vaittinen }, 10492ece646cSMatti Vaittinen }, 10502ece646cSMatti Vaittinen }; 10512ece646cSMatti Vaittinen 105202f8eaabSYueHaibing static const struct regulator_ops *bd71837_swcontrol_ops[] = { 10531d848d68SMatti Vaittinen &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, 10541d848d68SMatti Vaittinen &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, 10551d848d68SMatti Vaittinen &bd71837_pickable_range_buck_ops, &bd71837_buck_regulator_ops, 10561d848d68SMatti Vaittinen &bd71837_buck_regulator_nolinear_ops, &bd71837_buck_regulator_ops, 10571d848d68SMatti Vaittinen &bd71837_pickable_range_ldo_ops, &bd71837_ldo_regulator_nolinear_ops, 10581d848d68SMatti Vaittinen &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops, 10591d848d68SMatti Vaittinen &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops, 10601d848d68SMatti Vaittinen &bd71837_ldo_regulator_ops, 10611d848d68SMatti Vaittinen }; 10621d848d68SMatti Vaittinen 106302f8eaabSYueHaibing static const struct regulator_ops *bd71837_hwcontrol_ops[] = { 10641d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 10651d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), 10661d848d68SMatti Vaittinen &bd71837_buck34_ops_hwctrl, &bd71837_buck34_ops_hwctrl, 10671d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_pickable_range_buck_ops), 10681d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_buck_regulator_ops), 10691d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_buck_regulator_nolinear_ops), 10701d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_buck_regulator_ops), 10711d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_pickable_range_ldo_ops), 10721d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_nolinear_ops), 10731d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 10741d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 10751d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 10761d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 10771d848d68SMatti Vaittinen &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), 10781d848d68SMatti Vaittinen }; 10791d848d68SMatti Vaittinen 10801d848d68SMatti Vaittinen static struct bd718xx_regulator_data bd71837_regulators[] = { 10812ece646cSMatti Vaittinen { 10822ece646cSMatti Vaittinen .desc = { 10832ece646cSMatti Vaittinen .name = "buck1", 10842ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK1"), 10852ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 10862ece646cSMatti Vaittinen .id = BD718XX_BUCK1, 10872ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 10882ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 10892ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 10902ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 10912ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN, 10922ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 10932ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_BUCK1_CTRL, 10942ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 10953b66e4a8SGuido Günther .enable_time = BD71837_BUCK1_STARTUP_TIME, 109618f3c625SMatti Vaittinen .ramp_delay_table = bd718xx_ramp_delay, 109718f3c625SMatti Vaittinen .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 109818f3c625SMatti Vaittinen .ramp_reg = BD718XX_REG_BUCK1_CTRL, 109918f3c625SMatti Vaittinen .ramp_mask = BUCK_RAMPRATE_MASK, 11002ece646cSMatti Vaittinen .owner = THIS_MODULE, 110121b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 110221b72156SMatti Vaittinen }, 110321b72156SMatti Vaittinen .dvs = { 110421b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | 110521b72156SMatti Vaittinen ROHM_DVS_LEVEL_SUSPEND, 110621b72156SMatti Vaittinen .run_reg = BD718XX_REG_BUCK1_VOLT_RUN, 110721b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 110821b72156SMatti Vaittinen .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE, 110921b72156SMatti Vaittinen .idle_mask = DVS_BUCK_RUN_MASK, 111021b72156SMatti Vaittinen .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP, 111121b72156SMatti Vaittinen .suspend_mask = DVS_BUCK_RUN_MASK, 11122ece646cSMatti Vaittinen }, 11132ece646cSMatti Vaittinen .init = { 11142ece646cSMatti Vaittinen .reg = BD718XX_REG_BUCK1_CTRL, 11152ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 11162ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 11172ece646cSMatti Vaittinen }, 11182ece646cSMatti Vaittinen }, 11192ece646cSMatti Vaittinen { 11202ece646cSMatti Vaittinen .desc = { 11212ece646cSMatti Vaittinen .name = "buck2", 11222ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK2"), 11232ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 11242ece646cSMatti Vaittinen .id = BD718XX_BUCK2, 11252ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 11262ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 11272ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 11282ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 11292ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN, 11302ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 11312ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_BUCK2_CTRL, 11322ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 11333b66e4a8SGuido Günther .enable_time = BD71837_BUCK2_STARTUP_TIME, 113418f3c625SMatti Vaittinen .ramp_delay_table = bd718xx_ramp_delay, 113518f3c625SMatti Vaittinen .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 113618f3c625SMatti Vaittinen .ramp_reg = BD718XX_REG_BUCK2_CTRL, 113718f3c625SMatti Vaittinen .ramp_mask = BUCK_RAMPRATE_MASK, 11382ece646cSMatti Vaittinen .owner = THIS_MODULE, 113921b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 114021b72156SMatti Vaittinen }, 114121b72156SMatti Vaittinen .dvs = { 114221b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE, 114321b72156SMatti Vaittinen .run_reg = BD718XX_REG_BUCK2_VOLT_RUN, 114421b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 114521b72156SMatti Vaittinen .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE, 114621b72156SMatti Vaittinen .idle_mask = DVS_BUCK_RUN_MASK, 11472ece646cSMatti Vaittinen }, 11482ece646cSMatti Vaittinen .init = { 11492ece646cSMatti Vaittinen .reg = BD718XX_REG_BUCK2_CTRL, 11502ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 11512ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 11522ece646cSMatti Vaittinen }, 11532ece646cSMatti Vaittinen }, 11542ece646cSMatti Vaittinen { 11552ece646cSMatti Vaittinen .desc = { 11562ece646cSMatti Vaittinen .name = "buck3", 11572ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK3"), 11582ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 11592ece646cSMatti Vaittinen .id = BD718XX_BUCK3, 11602ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 11612ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 11622ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 11632ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 11642ece646cSMatti Vaittinen .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN, 11652ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 11662ece646cSMatti Vaittinen .enable_reg = BD71837_REG_BUCK3_CTRL, 11672ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 11683b66e4a8SGuido Günther .enable_time = BD71837_BUCK3_STARTUP_TIME, 116918f3c625SMatti Vaittinen .ramp_delay_table = bd718xx_ramp_delay, 117018f3c625SMatti Vaittinen .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 117118f3c625SMatti Vaittinen .ramp_reg = BD71837_REG_BUCK3_CTRL, 117218f3c625SMatti Vaittinen .ramp_mask = BUCK_RAMPRATE_MASK, 11732ece646cSMatti Vaittinen .owner = THIS_MODULE, 117421b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 117521b72156SMatti Vaittinen }, 117621b72156SMatti Vaittinen .dvs = { 117721b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN, 117821b72156SMatti Vaittinen .run_reg = BD71837_REG_BUCK3_VOLT_RUN, 117921b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 11802ece646cSMatti Vaittinen }, 11812ece646cSMatti Vaittinen .init = { 11822ece646cSMatti Vaittinen .reg = BD71837_REG_BUCK3_CTRL, 11832ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 11842ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 11852ece646cSMatti Vaittinen }, 11862ece646cSMatti Vaittinen }, 11872ece646cSMatti Vaittinen { 11882ece646cSMatti Vaittinen .desc = { 11892ece646cSMatti Vaittinen .name = "buck4", 11902ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK4"), 11912ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 11922ece646cSMatti Vaittinen .id = BD718XX_BUCK4, 11932ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 11942ece646cSMatti Vaittinen .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, 11952ece646cSMatti Vaittinen .linear_ranges = bd718xx_dvs_buck_volts, 11962ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts), 11972ece646cSMatti Vaittinen .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN, 11982ece646cSMatti Vaittinen .vsel_mask = DVS_BUCK_RUN_MASK, 11992ece646cSMatti Vaittinen .enable_reg = BD71837_REG_BUCK4_CTRL, 12002ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 12013b66e4a8SGuido Günther .enable_time = BD71837_BUCK4_STARTUP_TIME, 120218f3c625SMatti Vaittinen .ramp_delay_table = bd718xx_ramp_delay, 120318f3c625SMatti Vaittinen .n_ramp_values = ARRAY_SIZE(bd718xx_ramp_delay), 120418f3c625SMatti Vaittinen .ramp_reg = BD71837_REG_BUCK4_CTRL, 120518f3c625SMatti Vaittinen .ramp_mask = BUCK_RAMPRATE_MASK, 12062ece646cSMatti Vaittinen .owner = THIS_MODULE, 120721b72156SMatti Vaittinen .of_parse_cb = buck_set_hw_dvs_levels, 120821b72156SMatti Vaittinen }, 120921b72156SMatti Vaittinen .dvs = { 121021b72156SMatti Vaittinen .level_map = ROHM_DVS_LEVEL_RUN, 121121b72156SMatti Vaittinen .run_reg = BD71837_REG_BUCK4_VOLT_RUN, 121221b72156SMatti Vaittinen .run_mask = DVS_BUCK_RUN_MASK, 12132ece646cSMatti Vaittinen }, 12142ece646cSMatti Vaittinen .init = { 12152ece646cSMatti Vaittinen .reg = BD71837_REG_BUCK4_CTRL, 12162ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 12172ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 12182ece646cSMatti Vaittinen }, 12192ece646cSMatti Vaittinen }, 12202ece646cSMatti Vaittinen { 12212ece646cSMatti Vaittinen .desc = { 12222ece646cSMatti Vaittinen .name = "buck5", 12232ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK5"), 12242ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 12252ece646cSMatti Vaittinen .id = BD718XX_BUCK5, 12262ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 12272ece646cSMatti Vaittinen .n_voltages = BD71837_BUCK5_VOLTAGE_NUM, 12282ece646cSMatti Vaittinen .linear_ranges = bd71837_buck5_volts, 12292ece646cSMatti Vaittinen .n_linear_ranges = 12302ece646cSMatti Vaittinen ARRAY_SIZE(bd71837_buck5_volts), 12312ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 12322ece646cSMatti Vaittinen .vsel_mask = BD71837_BUCK5_MASK, 12332ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, 12342ece646cSMatti Vaittinen .vsel_range_mask = BD71837_BUCK5_RANGE_MASK, 12352ece646cSMatti Vaittinen .linear_range_selectors = bd71837_buck5_volt_range_sel, 12362ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 12372ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 12383b66e4a8SGuido Günther .enable_time = BD71837_BUCK5_STARTUP_TIME, 12392ece646cSMatti Vaittinen .owner = THIS_MODULE, 12402ece646cSMatti Vaittinen }, 12412ece646cSMatti Vaittinen .init = { 12422ece646cSMatti Vaittinen .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, 12432ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 12442ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 12452ece646cSMatti Vaittinen }, 12462ece646cSMatti Vaittinen }, 12472ece646cSMatti Vaittinen { 12482ece646cSMatti Vaittinen .desc = { 12492ece646cSMatti Vaittinen .name = "buck6", 12502ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK6"), 12512ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 12522ece646cSMatti Vaittinen .id = BD718XX_BUCK6, 12532ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 12542ece646cSMatti Vaittinen .n_voltages = BD71837_BUCK6_VOLTAGE_NUM, 12552ece646cSMatti Vaittinen .linear_ranges = bd71837_buck6_volts, 12562ece646cSMatti Vaittinen .n_linear_ranges = 12572ece646cSMatti Vaittinen ARRAY_SIZE(bd71837_buck6_volts), 12582ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, 12592ece646cSMatti Vaittinen .vsel_mask = BD71837_BUCK6_MASK, 12602ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 12612ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 12623b66e4a8SGuido Günther .enable_time = BD71837_BUCK6_STARTUP_TIME, 12632ece646cSMatti Vaittinen .owner = THIS_MODULE, 12642ece646cSMatti Vaittinen }, 12652ece646cSMatti Vaittinen .init = { 12662ece646cSMatti Vaittinen .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, 12672ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 12682ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 12692ece646cSMatti Vaittinen }, 12702ece646cSMatti Vaittinen }, 12712ece646cSMatti Vaittinen { 12722ece646cSMatti Vaittinen .desc = { 12732ece646cSMatti Vaittinen .name = "buck7", 12742ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK7"), 12752ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 12762ece646cSMatti Vaittinen .id = BD718XX_BUCK7, 12772ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 12782ece646cSMatti Vaittinen .volt_table = &bd718xx_3rd_nodvs_buck_volts[0], 12792ece646cSMatti Vaittinen .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts), 12802ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT, 12812ece646cSMatti Vaittinen .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, 12822ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 12832ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 12843b66e4a8SGuido Günther .enable_time = BD71837_BUCK7_STARTUP_TIME, 12852ece646cSMatti Vaittinen .owner = THIS_MODULE, 12862ece646cSMatti Vaittinen }, 12872ece646cSMatti Vaittinen .init = { 12882ece646cSMatti Vaittinen .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, 12892ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 12902ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 12912ece646cSMatti Vaittinen }, 12922ece646cSMatti Vaittinen }, 12932ece646cSMatti Vaittinen { 12942ece646cSMatti Vaittinen .desc = { 12952ece646cSMatti Vaittinen .name = "buck8", 12962ece646cSMatti Vaittinen .of_match = of_match_ptr("BUCK8"), 12972ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 12982ece646cSMatti Vaittinen .id = BD718XX_BUCK8, 12992ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 13002ece646cSMatti Vaittinen .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM, 13012ece646cSMatti Vaittinen .linear_ranges = bd718xx_4th_nodvs_buck_volts, 13022ece646cSMatti Vaittinen .n_linear_ranges = 13032ece646cSMatti Vaittinen ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts), 13042ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT, 13052ece646cSMatti Vaittinen .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, 13062ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 13072ece646cSMatti Vaittinen .enable_mask = BD718XX_BUCK_EN, 13083b66e4a8SGuido Günther .enable_time = BD71837_BUCK8_STARTUP_TIME, 13092ece646cSMatti Vaittinen .owner = THIS_MODULE, 13102ece646cSMatti Vaittinen }, 13112ece646cSMatti Vaittinen .init = { 13122ece646cSMatti Vaittinen .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, 13132ece646cSMatti Vaittinen .mask = BD718XX_BUCK_SEL, 13142ece646cSMatti Vaittinen .val = BD718XX_BUCK_SEL, 13152ece646cSMatti Vaittinen }, 13162ece646cSMatti Vaittinen }, 13172ece646cSMatti Vaittinen { 13182ece646cSMatti Vaittinen .desc = { 13192ece646cSMatti Vaittinen .name = "ldo1", 13202ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO1"), 13212ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 13222ece646cSMatti Vaittinen .id = BD718XX_LDO1, 13232ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 13242ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO1_VOLTAGE_NUM, 13252ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo1_volts, 13262ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts), 13272ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO1_VOLT, 13282ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO1_MASK, 13292ece646cSMatti Vaittinen .vsel_range_reg = BD718XX_REG_LDO1_VOLT, 13302ece646cSMatti Vaittinen .vsel_range_mask = BD718XX_LDO1_RANGE_MASK, 13312ece646cSMatti Vaittinen .linear_range_selectors = bd718xx_ldo1_volt_range_sel, 13322ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO1_VOLT, 13332ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 13343b66e4a8SGuido Günther .enable_time = BD71837_LDO1_STARTUP_TIME, 13352ece646cSMatti Vaittinen .owner = THIS_MODULE, 13362ece646cSMatti Vaittinen }, 13372ece646cSMatti Vaittinen .init = { 13382ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO1_VOLT, 13392ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 13402ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 13412ece646cSMatti Vaittinen }, 13422ece646cSMatti Vaittinen }, 13432ece646cSMatti Vaittinen { 13442ece646cSMatti Vaittinen .desc = { 13452ece646cSMatti Vaittinen .name = "ldo2", 13462ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO2"), 13472ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 13482ece646cSMatti Vaittinen .id = BD718XX_LDO2, 13492ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 13502ece646cSMatti Vaittinen .volt_table = &ldo_2_volts[0], 13512ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO2_VOLT, 13522ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO2_MASK, 13532ece646cSMatti Vaittinen .n_voltages = ARRAY_SIZE(ldo_2_volts), 13542ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO2_VOLT, 13552ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 13563b66e4a8SGuido Günther .enable_time = BD71837_LDO2_STARTUP_TIME, 13572ece646cSMatti Vaittinen .owner = THIS_MODULE, 13582ece646cSMatti Vaittinen }, 13592ece646cSMatti Vaittinen .init = { 13602ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO2_VOLT, 13612ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 13622ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 13632ece646cSMatti Vaittinen }, 13642ece646cSMatti Vaittinen }, 13652ece646cSMatti Vaittinen { 13662ece646cSMatti Vaittinen .desc = { 13672ece646cSMatti Vaittinen .name = "ldo3", 13682ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO3"), 13692ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 13702ece646cSMatti Vaittinen .id = BD718XX_LDO3, 13712ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 13722ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO3_VOLTAGE_NUM, 13732ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo3_volts, 13742ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts), 13752ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO3_VOLT, 13762ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO3_MASK, 13772ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO3_VOLT, 13782ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 13793b66e4a8SGuido Günther .enable_time = BD71837_LDO3_STARTUP_TIME, 13802ece646cSMatti Vaittinen .owner = THIS_MODULE, 13812ece646cSMatti Vaittinen }, 13822ece646cSMatti Vaittinen .init = { 13832ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO3_VOLT, 13842ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 13852ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 13862ece646cSMatti Vaittinen }, 13872ece646cSMatti Vaittinen }, 13882ece646cSMatti Vaittinen { 13892ece646cSMatti Vaittinen .desc = { 13902ece646cSMatti Vaittinen .name = "ldo4", 13912ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO4"), 13922ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 13932ece646cSMatti Vaittinen .id = BD718XX_LDO4, 13942ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 13952ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO4_VOLTAGE_NUM, 13962ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo4_volts, 13972ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts), 13982ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO4_VOLT, 13992ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO4_MASK, 14002ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO4_VOLT, 14012ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 14023b66e4a8SGuido Günther .enable_time = BD71837_LDO4_STARTUP_TIME, 14032ece646cSMatti Vaittinen .owner = THIS_MODULE, 14042ece646cSMatti Vaittinen }, 14052ece646cSMatti Vaittinen .init = { 14062ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO4_VOLT, 14072ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 14082ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 14092ece646cSMatti Vaittinen }, 14102ece646cSMatti Vaittinen }, 14112ece646cSMatti Vaittinen { 14122ece646cSMatti Vaittinen .desc = { 14132ece646cSMatti Vaittinen .name = "ldo5", 14142ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO5"), 14152ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 14162ece646cSMatti Vaittinen .id = BD718XX_LDO5, 14172ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 14182ece646cSMatti Vaittinen .n_voltages = BD71837_LDO5_VOLTAGE_NUM, 14192ece646cSMatti Vaittinen .linear_ranges = bd71837_ldo5_volts, 14202ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_volts), 14212ece646cSMatti Vaittinen /* LDO5 is supplied by buck6 */ 14222ece646cSMatti Vaittinen .supply_name = "buck6", 14232ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO5_VOLT, 14242ece646cSMatti Vaittinen .vsel_mask = BD71837_LDO5_MASK, 14252ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO5_VOLT, 14262ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 14273b66e4a8SGuido Günther .enable_time = BD71837_LDO5_STARTUP_TIME, 14282ece646cSMatti Vaittinen .owner = THIS_MODULE, 14292ece646cSMatti Vaittinen }, 14302ece646cSMatti Vaittinen .init = { 14312ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO5_VOLT, 14322ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 14332ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 14342ece646cSMatti Vaittinen }, 14352ece646cSMatti Vaittinen .additional_inits = bd71837_ldo5_inits, 14362ece646cSMatti Vaittinen .additional_init_amnt = ARRAY_SIZE(bd71837_ldo5_inits), 14372ece646cSMatti Vaittinen }, 14382ece646cSMatti Vaittinen { 14392ece646cSMatti Vaittinen .desc = { 14402ece646cSMatti Vaittinen .name = "ldo6", 14412ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO6"), 14422ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 14432ece646cSMatti Vaittinen .id = BD718XX_LDO6, 14442ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 14452ece646cSMatti Vaittinen .n_voltages = BD718XX_LDO6_VOLTAGE_NUM, 14462ece646cSMatti Vaittinen .linear_ranges = bd718xx_ldo6_volts, 14472ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts), 14482ece646cSMatti Vaittinen /* LDO6 is supplied by buck7 */ 14492ece646cSMatti Vaittinen .supply_name = "buck7", 14502ece646cSMatti Vaittinen .vsel_reg = BD718XX_REG_LDO6_VOLT, 14512ece646cSMatti Vaittinen .vsel_mask = BD718XX_LDO6_MASK, 14522ece646cSMatti Vaittinen .enable_reg = BD718XX_REG_LDO6_VOLT, 14532ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 14543b66e4a8SGuido Günther .enable_time = BD71837_LDO6_STARTUP_TIME, 14552ece646cSMatti Vaittinen .owner = THIS_MODULE, 14562ece646cSMatti Vaittinen }, 14572ece646cSMatti Vaittinen .init = { 14582ece646cSMatti Vaittinen .reg = BD718XX_REG_LDO6_VOLT, 14592ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 14602ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 14612ece646cSMatti Vaittinen }, 14622ece646cSMatti Vaittinen .additional_inits = bd71837_ldo6_inits, 14632ece646cSMatti Vaittinen .additional_init_amnt = ARRAY_SIZE(bd71837_ldo6_inits), 14642ece646cSMatti Vaittinen }, 14652ece646cSMatti Vaittinen { 14662ece646cSMatti Vaittinen .desc = { 14672ece646cSMatti Vaittinen .name = "ldo7", 14682ece646cSMatti Vaittinen .of_match = of_match_ptr("LDO7"), 14692ece646cSMatti Vaittinen .regulators_node = of_match_ptr("regulators"), 14702ece646cSMatti Vaittinen .id = BD718XX_LDO7, 14712ece646cSMatti Vaittinen .type = REGULATOR_VOLTAGE, 14722ece646cSMatti Vaittinen .n_voltages = BD71837_LDO7_VOLTAGE_NUM, 14732ece646cSMatti Vaittinen .linear_ranges = bd71837_ldo7_volts, 14742ece646cSMatti Vaittinen .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_volts), 14752ece646cSMatti Vaittinen .vsel_reg = BD71837_REG_LDO7_VOLT, 14762ece646cSMatti Vaittinen .vsel_mask = BD71837_LDO7_MASK, 14772ece646cSMatti Vaittinen .enable_reg = BD71837_REG_LDO7_VOLT, 14782ece646cSMatti Vaittinen .enable_mask = BD718XX_LDO_EN, 14793b66e4a8SGuido Günther .enable_time = BD71837_LDO7_STARTUP_TIME, 14802ece646cSMatti Vaittinen .owner = THIS_MODULE, 14812ece646cSMatti Vaittinen }, 14822ece646cSMatti Vaittinen .init = { 14832ece646cSMatti Vaittinen .reg = BD71837_REG_LDO7_VOLT, 14842ece646cSMatti Vaittinen .mask = BD718XX_LDO_SEL, 14852ece646cSMatti Vaittinen .val = BD718XX_LDO_SEL, 14862ece646cSMatti Vaittinen }, 14872ece646cSMatti Vaittinen }, 14882ece646cSMatti Vaittinen }; 14892ece646cSMatti Vaittinen 14901d848d68SMatti Vaittinen static void mark_hw_controlled(struct device *dev, struct device_node *np, 14911d848d68SMatti Vaittinen struct bd718xx_regulator_data *reg_data, 14921d848d68SMatti Vaittinen unsigned int num_reg_data, int *info) 14931d848d68SMatti Vaittinen { 14941d848d68SMatti Vaittinen int i; 14951d848d68SMatti Vaittinen 14961d848d68SMatti Vaittinen for (i = 1; i <= num_reg_data; i++) { 14971d848d68SMatti Vaittinen if (!of_node_name_eq(np, reg_data[i-1].desc.of_match)) 14981d848d68SMatti Vaittinen continue; 14991d848d68SMatti Vaittinen 15001d848d68SMatti Vaittinen *info |= 1 << (i - 1); 15011d848d68SMatti Vaittinen dev_dbg(dev, "regulator %d runlevel controlled\n", i); 15021d848d68SMatti Vaittinen return; 15031d848d68SMatti Vaittinen } 15041d848d68SMatti Vaittinen dev_warn(dev, "Bad regulator node\n"); 15051d848d68SMatti Vaittinen } 15061d848d68SMatti Vaittinen 1507d2ad9811SMatti Vaittinen /* 1508d2ad9811SMatti Vaittinen * Setups where regulator (especially the buck8) output voltage is scaled 1509d2ad9811SMatti Vaittinen * by adding external connection where some other regulator output is connected 1510d2ad9811SMatti Vaittinen * to feedback-pin (over suitable resistors) is getting popular amongst users 1511d2ad9811SMatti Vaittinen * of BD71837. (This allows for example scaling down the buck8 voltages to suit 1512d2ad9811SMatti Vaittinen * lover GPU voltages for projects where buck8 is (ab)used to supply power 1513d2ad9811SMatti Vaittinen * for GPU. Additionally some setups do allow DVS for buck8 but as this do 1514d2ad9811SMatti Vaittinen * produce voltage spikes the HW must be evaluated to be able to survive this 1515d2ad9811SMatti Vaittinen * - hence I keep the DVS disabled for non DVS bucks by default. I don't want 1516d2ad9811SMatti Vaittinen * to help you burn your proto board) 1517d2ad9811SMatti Vaittinen * 1518d2ad9811SMatti Vaittinen * So we allow describing this external connection from DT and scale the 1519d2ad9811SMatti Vaittinen * voltages accordingly. This is what the connection should look like: 1520d2ad9811SMatti Vaittinen * 1521d2ad9811SMatti Vaittinen * |------------| 1522d2ad9811SMatti Vaittinen * | buck 8 |-------+----->Vout 1523d2ad9811SMatti Vaittinen * | | | 1524d2ad9811SMatti Vaittinen * |------------| | 1525d2ad9811SMatti Vaittinen * | FB pin | 1526d2ad9811SMatti Vaittinen * | | 1527d2ad9811SMatti Vaittinen * +-------+--R2---+ 1528d2ad9811SMatti Vaittinen * | 1529d2ad9811SMatti Vaittinen * R1 1530d2ad9811SMatti Vaittinen * | 1531d2ad9811SMatti Vaittinen * V FB-pull-up 1532d2ad9811SMatti Vaittinen * 1533d2ad9811SMatti Vaittinen * Here the buck output is sifted according to formula: 1534d2ad9811SMatti Vaittinen * 1535d2ad9811SMatti Vaittinen * Vout_o = Vo - (Vpu - Vo)*R2/R1 1536d2ad9811SMatti Vaittinen * Linear_step = step_orig*(R1+R2)/R1 1537d2ad9811SMatti Vaittinen * 1538d2ad9811SMatti Vaittinen * where: 1539d2ad9811SMatti Vaittinen * Vout_o is adjusted voltage output at vsel reg value 0 1540d2ad9811SMatti Vaittinen * Vo is original voltage output at vsel reg value 0 1541d2ad9811SMatti Vaittinen * Vpu is the pull-up voltage V FB-pull-up in the picture 1542d2ad9811SMatti Vaittinen * R1 and R2 are resistor values. 1543d2ad9811SMatti Vaittinen * 1544d2ad9811SMatti Vaittinen * As a real world example for buck8 and a specific GPU: 1545d2ad9811SMatti Vaittinen * VLDO = 1.6V (used as FB-pull-up) 1546d2ad9811SMatti Vaittinen * R1 = 1000ohms 1547d2ad9811SMatti Vaittinen * R2 = 150ohms 1548d2ad9811SMatti Vaittinen * VSEL 0x0 => 0.8V – (VLDO – 0.8) * R2 / R1 = 0.68V 1549d2ad9811SMatti Vaittinen * Linear Step = 10mV * (R1 + R2) / R1 = 11.5mV 1550d2ad9811SMatti Vaittinen */ 1551d2ad9811SMatti Vaittinen static int setup_feedback_loop(struct device *dev, struct device_node *np, 1552d2ad9811SMatti Vaittinen struct bd718xx_regulator_data *reg_data, 1553d2ad9811SMatti Vaittinen unsigned int num_reg_data, int fb_uv) 1554d2ad9811SMatti Vaittinen { 1555d2ad9811SMatti Vaittinen int i, r1, r2, ret; 1556d2ad9811SMatti Vaittinen 1557d2ad9811SMatti Vaittinen /* 1558d2ad9811SMatti Vaittinen * We do adjust the values in the global desc based on DT settings. 1559d2ad9811SMatti Vaittinen * This may not be best approach as it can cause problems if more than 1560d2ad9811SMatti Vaittinen * one PMIC is controlled from same processor. I don't see such use-case 1561d2ad9811SMatti Vaittinen * for BD718x7 now - so we spare some bits. 1562d2ad9811SMatti Vaittinen * 1563d2ad9811SMatti Vaittinen * If this will point out to be a problem - then we can allocate new 1564d2ad9811SMatti Vaittinen * bd718xx_regulator_data array at probe and just use the global 1565d2ad9811SMatti Vaittinen * array as a template where we copy initial values. Then we can 1566d2ad9811SMatti Vaittinen * use allocated descs for regultor registration and do IC specific 1567d2ad9811SMatti Vaittinen * modifications to this copy while leaving other PMICs untouched. But 1568d2ad9811SMatti Vaittinen * that means allocating new array for each PMIC - and currently I see 1569d2ad9811SMatti Vaittinen * no need for that. 1570d2ad9811SMatti Vaittinen */ 1571d2ad9811SMatti Vaittinen 1572d2ad9811SMatti Vaittinen for (i = 0; i < num_reg_data; i++) { 1573d2ad9811SMatti Vaittinen struct regulator_desc *desc = ®_data[i].desc; 1574d2ad9811SMatti Vaittinen int j; 1575d2ad9811SMatti Vaittinen 1576d2ad9811SMatti Vaittinen if (!of_node_name_eq(np, desc->of_match)) 1577d2ad9811SMatti Vaittinen continue; 1578d2ad9811SMatti Vaittinen 1579d2ad9811SMatti Vaittinen /* The feedback loop connection does not make sense for LDOs */ 1580d2ad9811SMatti Vaittinen if (desc->id >= BD718XX_LDO1) 1581d2ad9811SMatti Vaittinen return -EINVAL; 1582d2ad9811SMatti Vaittinen 1583d2ad9811SMatti Vaittinen ret = of_property_read_u32(np, "rohm,feedback-pull-up-r1-ohms", 1584d2ad9811SMatti Vaittinen &r1); 1585d2ad9811SMatti Vaittinen if (ret) 1586d2ad9811SMatti Vaittinen return ret; 1587d2ad9811SMatti Vaittinen 1588d2ad9811SMatti Vaittinen if (!r1) 1589d2ad9811SMatti Vaittinen return -EINVAL; 1590d2ad9811SMatti Vaittinen 1591d2ad9811SMatti Vaittinen ret = of_property_read_u32(np, "rohm,feedback-pull-up-r2-ohms", 1592d2ad9811SMatti Vaittinen &r2); 1593d2ad9811SMatti Vaittinen if (ret) 1594d2ad9811SMatti Vaittinen return ret; 1595d2ad9811SMatti Vaittinen 1596d2ad9811SMatti Vaittinen if (desc->n_linear_ranges && desc->linear_ranges) { 1597d2ad9811SMatti Vaittinen struct linear_range *new; 1598d2ad9811SMatti Vaittinen 1599d2ad9811SMatti Vaittinen new = devm_kzalloc(dev, desc->n_linear_ranges * 1600d2ad9811SMatti Vaittinen sizeof(struct linear_range), 1601d2ad9811SMatti Vaittinen GFP_KERNEL); 1602d2ad9811SMatti Vaittinen if (!new) 1603d2ad9811SMatti Vaittinen return -ENOMEM; 1604d2ad9811SMatti Vaittinen 1605d2ad9811SMatti Vaittinen for (j = 0; j < desc->n_linear_ranges; j++) { 1606d2ad9811SMatti Vaittinen int min = desc->linear_ranges[j].min; 1607d2ad9811SMatti Vaittinen int step = desc->linear_ranges[j].step; 1608d2ad9811SMatti Vaittinen 1609d2ad9811SMatti Vaittinen min -= (fb_uv - min)*r2/r1; 1610d2ad9811SMatti Vaittinen step = step * (r1 + r2); 1611d2ad9811SMatti Vaittinen step /= r1; 1612d2ad9811SMatti Vaittinen 1613d2ad9811SMatti Vaittinen new[j].min = min; 1614d2ad9811SMatti Vaittinen new[j].step = step; 1615d2ad9811SMatti Vaittinen 1616d2ad9811SMatti Vaittinen dev_dbg(dev, "%s: old range min %d, step %d\n", 1617d2ad9811SMatti Vaittinen desc->name, desc->linear_ranges[j].min, 1618d2ad9811SMatti Vaittinen desc->linear_ranges[j].step); 1619d2ad9811SMatti Vaittinen dev_dbg(dev, "new range min %d, step %d\n", min, 1620d2ad9811SMatti Vaittinen step); 1621d2ad9811SMatti Vaittinen } 1622d2ad9811SMatti Vaittinen desc->linear_ranges = new; 1623d2ad9811SMatti Vaittinen } 1624d2ad9811SMatti Vaittinen dev_dbg(dev, "regulator '%s' has FB pull-up configured\n", 1625d2ad9811SMatti Vaittinen desc->name); 1626d2ad9811SMatti Vaittinen 1627d2ad9811SMatti Vaittinen return 0; 1628d2ad9811SMatti Vaittinen } 1629d2ad9811SMatti Vaittinen 1630d2ad9811SMatti Vaittinen return -ENODEV; 1631d2ad9811SMatti Vaittinen } 1632d2ad9811SMatti Vaittinen 1633d2ad9811SMatti Vaittinen static int get_special_regulators(struct device *dev, 16341d848d68SMatti Vaittinen struct bd718xx_regulator_data *reg_data, 16351d848d68SMatti Vaittinen unsigned int num_reg_data, int *info) 16361d848d68SMatti Vaittinen { 1637d2ad9811SMatti Vaittinen int ret; 16381d848d68SMatti Vaittinen struct device_node *np; 16391d848d68SMatti Vaittinen struct device_node *nproot = dev->of_node; 1640d2ad9811SMatti Vaittinen int uv; 16411d848d68SMatti Vaittinen 16421d848d68SMatti Vaittinen *info = 0; 16431d848d68SMatti Vaittinen 16441d848d68SMatti Vaittinen nproot = of_get_child_by_name(nproot, "regulators"); 16451d848d68SMatti Vaittinen if (!nproot) { 16461d848d68SMatti Vaittinen dev_err(dev, "failed to find regulators node\n"); 16471d848d68SMatti Vaittinen return -ENODEV; 16481d848d68SMatti Vaittinen } 1649d2ad9811SMatti Vaittinen for_each_child_of_node(nproot, np) { 1650d2ad9811SMatti Vaittinen if (of_property_read_bool(np, "rohm,no-regulator-enable-control")) 16511d848d68SMatti Vaittinen mark_hw_controlled(dev, np, reg_data, num_reg_data, 16521d848d68SMatti Vaittinen info); 1653d2ad9811SMatti Vaittinen ret = of_property_read_u32(np, "rohm,fb-pull-up-microvolt", 1654d2ad9811SMatti Vaittinen &uv); 1655d2ad9811SMatti Vaittinen if (ret) { 1656d2ad9811SMatti Vaittinen if (ret == -EINVAL) 1657d2ad9811SMatti Vaittinen continue; 1658d2ad9811SMatti Vaittinen else 1659d2ad9811SMatti Vaittinen goto err_out; 1660d2ad9811SMatti Vaittinen } 1661d2ad9811SMatti Vaittinen 1662d2ad9811SMatti Vaittinen ret = setup_feedback_loop(dev, np, reg_data, num_reg_data, uv); 1663d2ad9811SMatti Vaittinen if (ret) 1664d2ad9811SMatti Vaittinen goto err_out; 1665d2ad9811SMatti Vaittinen } 16661d848d68SMatti Vaittinen 16671d848d68SMatti Vaittinen of_node_put(nproot); 16681d848d68SMatti Vaittinen return 0; 1669d2ad9811SMatti Vaittinen 1670d2ad9811SMatti Vaittinen err_out: 1671d2ad9811SMatti Vaittinen of_node_put(np); 1672d2ad9811SMatti Vaittinen of_node_put(nproot); 1673d2ad9811SMatti Vaittinen 1674d2ad9811SMatti Vaittinen return ret; 16751d848d68SMatti Vaittinen } 16761d848d68SMatti Vaittinen 16772ece646cSMatti Vaittinen static int bd718xx_probe(struct platform_device *pdev) 16782ece646cSMatti Vaittinen { 1679907dfdc9SMatti Vaittinen struct regmap *regmap; 16802ece646cSMatti Vaittinen struct regulator_config config = { 0 }; 16811d848d68SMatti Vaittinen int i, j, err, omit_enable; 1682049369d4SMatti Vaittinen bool use_snvs; 16831d848d68SMatti Vaittinen struct bd718xx_regulator_data *reg_data; 1684b389ceaeSAxel Lin unsigned int num_reg_data; 16851b1c26b2SMatti Vaittinen enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; 16861d848d68SMatti Vaittinen const struct regulator_ops **swops, **hwops; 16872ece646cSMatti Vaittinen 1688907dfdc9SMatti Vaittinen regmap = dev_get_regmap(pdev->dev.parent, NULL); 1689907dfdc9SMatti Vaittinen if (!regmap) { 16902ece646cSMatti Vaittinen dev_err(&pdev->dev, "No MFD driver data\n"); 1691907dfdc9SMatti Vaittinen return -EINVAL; 16922ece646cSMatti Vaittinen } 1693bcb047ebSAxel Lin 1694af32f3a4SLinus Torvalds switch (chip) { 1695b389ceaeSAxel Lin case ROHM_CHIP_TYPE_BD71837: 1696b389ceaeSAxel Lin reg_data = bd71837_regulators; 1697b389ceaeSAxel Lin num_reg_data = ARRAY_SIZE(bd71837_regulators); 16981d848d68SMatti Vaittinen swops = &bd71837_swcontrol_ops[0]; 16991d848d68SMatti Vaittinen hwops = &bd71837_hwcontrol_ops[0]; 1700b389ceaeSAxel Lin break; 1701b389ceaeSAxel Lin case ROHM_CHIP_TYPE_BD71847: 1702b389ceaeSAxel Lin reg_data = bd71847_regulators; 1703b389ceaeSAxel Lin num_reg_data = ARRAY_SIZE(bd71847_regulators); 17041d848d68SMatti Vaittinen swops = &bd71847_swcontrol_ops[0]; 17051d848d68SMatti Vaittinen hwops = &bd71847_hwcontrol_ops[0]; 1706b389ceaeSAxel Lin break; 1707b389ceaeSAxel Lin default: 17082ece646cSMatti Vaittinen dev_err(&pdev->dev, "Unsupported chip type\n"); 1709*662a9bf8SMatti Vaittinen return -EINVAL; 17102ece646cSMatti Vaittinen } 17112ece646cSMatti Vaittinen 17122ece646cSMatti Vaittinen /* Register LOCK release */ 1713907dfdc9SMatti Vaittinen err = regmap_update_bits(regmap, BD718XX_REG_REGLOCK, 17142ece646cSMatti Vaittinen (REGLOCK_PWRSEQ | REGLOCK_VREG), 0); 1715*662a9bf8SMatti Vaittinen if (err) 1716*662a9bf8SMatti Vaittinen return dev_err_probe(&pdev->dev, err, "Failed to unlock PMIC\n"); 1717*662a9bf8SMatti Vaittinen 1718bcb047ebSAxel Lin dev_dbg(&pdev->dev, "Unlocked lock register 0x%x\n", 17192ece646cSMatti Vaittinen BD718XX_REG_REGLOCK); 17202ece646cSMatti Vaittinen 1721049369d4SMatti Vaittinen use_snvs = of_property_read_bool(pdev->dev.parent->of_node, 1722049369d4SMatti Vaittinen "rohm,reset-snvs-powered"); 1723049369d4SMatti Vaittinen 1724049369d4SMatti Vaittinen /* 1725e770b18bSMatti Vaittinen * Change the next stage from poweroff to be READY instead of SNVS 1726e770b18bSMatti Vaittinen * for all reset types because OTP loading at READY will clear SEL 1727e770b18bSMatti Vaittinen * bit allowing HW defaults for power rails to be used 1728e770b18bSMatti Vaittinen */ 1729049369d4SMatti Vaittinen if (!use_snvs) { 1730907dfdc9SMatti Vaittinen err = regmap_update_bits(regmap, BD718XX_REG_TRANS_COND1, 1731e770b18bSMatti Vaittinen BD718XX_ON_REQ_POWEROFF_MASK | 1732e770b18bSMatti Vaittinen BD718XX_SWRESET_POWEROFF_MASK | 1733e770b18bSMatti Vaittinen BD718XX_WDOG_POWEROFF_MASK | 1734e770b18bSMatti Vaittinen BD718XX_KEY_L_POWEROFF_MASK, 1735e770b18bSMatti Vaittinen BD718XX_POWOFF_TO_RDY); 1736*662a9bf8SMatti Vaittinen if (err) 1737*662a9bf8SMatti Vaittinen return dev_err_probe(&pdev->dev, err, 1738*662a9bf8SMatti Vaittinen "Failed to change reset target\n"); 1739*662a9bf8SMatti Vaittinen 1740*662a9bf8SMatti Vaittinen dev_dbg(&pdev->dev, "Changed all resets from SVNS to READY\n"); 1741e770b18bSMatti Vaittinen } 1742e770b18bSMatti Vaittinen 1743df9db254SMatti Vaittinen config.dev = pdev->dev.parent; 1744907dfdc9SMatti Vaittinen config.regmap = regmap; 17451d848d68SMatti Vaittinen /* 17461d848d68SMatti Vaittinen * There are cases when we want to leave the enable-control for 17471d848d68SMatti Vaittinen * the HW state machine and use this driver only for voltage control. 17481d848d68SMatti Vaittinen * One special case is when we use PMIC_STBY_REQ line from SoC to PMIC 17491d848d68SMatti Vaittinen * in order to set the system to SUSPEND state. 17501d848d68SMatti Vaittinen * 17511d848d68SMatti Vaittinen * If regulator is taken under SW control the regulator state will not 17521d848d68SMatti Vaittinen * be affected by PMIC state machine - Eg. regulator is likely to stay 17531d848d68SMatti Vaittinen * on even in SUSPEND 17541d848d68SMatti Vaittinen */ 1755d2ad9811SMatti Vaittinen err = get_special_regulators(pdev->dev.parent, reg_data, num_reg_data, 17561d848d68SMatti Vaittinen &omit_enable); 1757d2ad9811SMatti Vaittinen if (err) 1758d2ad9811SMatti Vaittinen return err; 1759df9db254SMatti Vaittinen 1760b389ceaeSAxel Lin for (i = 0; i < num_reg_data; i++) { 17612ece646cSMatti Vaittinen 17621d848d68SMatti Vaittinen struct regulator_desc *desc; 17632ece646cSMatti Vaittinen struct regulator_dev *rdev; 17641d848d68SMatti Vaittinen struct bd718xx_regulator_data *r; 17651d848d68SMatti Vaittinen int no_enable_control = omit_enable & (1 << i); 17662ece646cSMatti Vaittinen 1767b389ceaeSAxel Lin r = ®_data[i]; 17682ece646cSMatti Vaittinen desc = &r->desc; 17692ece646cSMatti Vaittinen 17701d848d68SMatti Vaittinen if (no_enable_control) 17711d848d68SMatti Vaittinen desc->ops = hwops[i]; 17721d848d68SMatti Vaittinen else 17731d848d68SMatti Vaittinen desc->ops = swops[i]; 17742ece646cSMatti Vaittinen 17752ece646cSMatti Vaittinen rdev = devm_regulator_register(&pdev->dev, desc, &config); 1776*662a9bf8SMatti Vaittinen if (IS_ERR(rdev)) 1777*662a9bf8SMatti Vaittinen return dev_err_probe(&pdev->dev, PTR_ERR(rdev), 17782ece646cSMatti Vaittinen "failed to register %s regulator\n", 17792ece646cSMatti Vaittinen desc->name); 1780049369d4SMatti Vaittinen 1781049369d4SMatti Vaittinen /* 1782049369d4SMatti Vaittinen * Regulator register gets the regulator constraints and 17832ece646cSMatti Vaittinen * applies them (set_machine_constraints). This should have 17842ece646cSMatti Vaittinen * turned the control register(s) to correct values and we 17852ece646cSMatti Vaittinen * can now switch the control from PMIC state machine to the 17862ece646cSMatti Vaittinen * register interface 1787049369d4SMatti Vaittinen * 1788049369d4SMatti Vaittinen * At poweroff transition PMIC HW disables EN bit for 1789049369d4SMatti Vaittinen * regulators but leaves SEL bit untouched. So if state 1790049369d4SMatti Vaittinen * transition from POWEROFF is done to SNVS - then all power 1791049369d4SMatti Vaittinen * rails controlled by SW (having SEL bit set) stay disabled 1792049369d4SMatti Vaittinen * as EN is cleared. This will result boot failure if any 1793049369d4SMatti Vaittinen * crucial systems are powered by these rails. We don't 1794049369d4SMatti Vaittinen * enable SW control for crucial regulators if snvs state is 1795049369d4SMatti Vaittinen * used 17962ece646cSMatti Vaittinen */ 17971d848d68SMatti Vaittinen if (!no_enable_control && (!use_snvs || 17981d848d68SMatti Vaittinen !rdev->constraints->always_on || 17991d848d68SMatti Vaittinen !rdev->constraints->boot_on)) { 1800907dfdc9SMatti Vaittinen err = regmap_update_bits(regmap, r->init.reg, 18012ece646cSMatti Vaittinen r->init.mask, r->init.val); 1802*662a9bf8SMatti Vaittinen if (err) 1803*662a9bf8SMatti Vaittinen return dev_err_probe(&pdev->dev, err, 1804049369d4SMatti Vaittinen "Failed to take control for (%s)\n", 18052ece646cSMatti Vaittinen desc->name); 1806049369d4SMatti Vaittinen } 18072ece646cSMatti Vaittinen for (j = 0; j < r->additional_init_amnt; j++) { 1808907dfdc9SMatti Vaittinen err = regmap_update_bits(regmap, 18092ece646cSMatti Vaittinen r->additional_inits[j].reg, 18102ece646cSMatti Vaittinen r->additional_inits[j].mask, 18112ece646cSMatti Vaittinen r->additional_inits[j].val); 1812*662a9bf8SMatti Vaittinen if (err) 1813*662a9bf8SMatti Vaittinen return dev_err_probe(&pdev->dev, err, 18142ece646cSMatti Vaittinen "Buck (%s) initialization failed\n", 18152ece646cSMatti Vaittinen desc->name); 18162ece646cSMatti Vaittinen } 18172ece646cSMatti Vaittinen } 18182ece646cSMatti Vaittinen 18192ece646cSMatti Vaittinen return err; 18202ece646cSMatti Vaittinen } 18212ece646cSMatti Vaittinen 18221b1c26b2SMatti Vaittinen static const struct platform_device_id bd718x7_pmic_id[] = { 18231b1c26b2SMatti Vaittinen { "bd71837-pmic", ROHM_CHIP_TYPE_BD71837 }, 18241b1c26b2SMatti Vaittinen { "bd71847-pmic", ROHM_CHIP_TYPE_BD71847 }, 18251b1c26b2SMatti Vaittinen { }, 18261b1c26b2SMatti Vaittinen }; 18271b1c26b2SMatti Vaittinen MODULE_DEVICE_TABLE(platform, bd718x7_pmic_id); 18281b1c26b2SMatti Vaittinen 18292ece646cSMatti Vaittinen static struct platform_driver bd718xx_regulator = { 18302ece646cSMatti Vaittinen .driver = { 18312ece646cSMatti Vaittinen .name = "bd718xx-pmic", 18322ece646cSMatti Vaittinen }, 18332ece646cSMatti Vaittinen .probe = bd718xx_probe, 18341b1c26b2SMatti Vaittinen .id_table = bd718x7_pmic_id, 18352ece646cSMatti Vaittinen }; 18362ece646cSMatti Vaittinen 18372ece646cSMatti Vaittinen module_platform_driver(bd718xx_regulator); 18382ece646cSMatti Vaittinen 18392ece646cSMatti Vaittinen MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 18402ece646cSMatti Vaittinen MODULE_DESCRIPTION("BD71837/BD71847 voltage regulator driver"); 18412ece646cSMatti Vaittinen MODULE_LICENSE("GPL"); 184295bddd8bSGuido Günther MODULE_ALIAS("platform:bd718xx-pmic"); 1843