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