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