xref: /OK3568_Linux_fs/kernel/drivers/regulator/da9062-regulator.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // Regulator device driver for DA9061 and DA9062.
4*4882a593Smuzhiyun // Copyright (C) 2015-2017  Dialog Semiconductor
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/kernel.h>
7*4882a593Smuzhiyun #include <linux/module.h>
8*4882a593Smuzhiyun #include <linux/init.h>
9*4882a593Smuzhiyun #include <linux/err.h>
10*4882a593Smuzhiyun #include <linux/slab.h>
11*4882a593Smuzhiyun #include <linux/of.h>
12*4882a593Smuzhiyun #include <linux/platform_device.h>
13*4882a593Smuzhiyun #include <linux/regmap.h>
14*4882a593Smuzhiyun #include <linux/regulator/driver.h>
15*4882a593Smuzhiyun #include <linux/regulator/machine.h>
16*4882a593Smuzhiyun #include <linux/regulator/of_regulator.h>
17*4882a593Smuzhiyun #include <linux/mfd/da9062/core.h>
18*4882a593Smuzhiyun #include <linux/mfd/da9062/registers.h>
19*4882a593Smuzhiyun #include <dt-bindings/regulator/dlg,da9063-regulator.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /* Regulator IDs */
22*4882a593Smuzhiyun enum {
23*4882a593Smuzhiyun 	DA9061_ID_BUCK1,
24*4882a593Smuzhiyun 	DA9061_ID_BUCK2,
25*4882a593Smuzhiyun 	DA9061_ID_BUCK3,
26*4882a593Smuzhiyun 	DA9061_ID_LDO1,
27*4882a593Smuzhiyun 	DA9061_ID_LDO2,
28*4882a593Smuzhiyun 	DA9061_ID_LDO3,
29*4882a593Smuzhiyun 	DA9061_ID_LDO4,
30*4882a593Smuzhiyun 	DA9061_MAX_REGULATORS,
31*4882a593Smuzhiyun };
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun enum {
34*4882a593Smuzhiyun 	DA9062_ID_BUCK1,
35*4882a593Smuzhiyun 	DA9062_ID_BUCK2,
36*4882a593Smuzhiyun 	DA9062_ID_BUCK3,
37*4882a593Smuzhiyun 	DA9062_ID_BUCK4,
38*4882a593Smuzhiyun 	DA9062_ID_LDO1,
39*4882a593Smuzhiyun 	DA9062_ID_LDO2,
40*4882a593Smuzhiyun 	DA9062_ID_LDO3,
41*4882a593Smuzhiyun 	DA9062_ID_LDO4,
42*4882a593Smuzhiyun 	DA9062_MAX_REGULATORS,
43*4882a593Smuzhiyun };
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /* Regulator capabilities and registers description */
46*4882a593Smuzhiyun struct da9062_regulator_info {
47*4882a593Smuzhiyun 	struct regulator_desc desc;
48*4882a593Smuzhiyun 	/* Main register fields */
49*4882a593Smuzhiyun 	struct reg_field mode;
50*4882a593Smuzhiyun 	struct reg_field suspend;
51*4882a593Smuzhiyun 	struct reg_field sleep;
52*4882a593Smuzhiyun 	struct reg_field suspend_sleep;
53*4882a593Smuzhiyun 	unsigned int suspend_vsel_reg;
54*4882a593Smuzhiyun 	/* Event detection bit */
55*4882a593Smuzhiyun 	struct reg_field oc_event;
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /* Single regulator settings */
59*4882a593Smuzhiyun struct da9062_regulator {
60*4882a593Smuzhiyun 	struct regulator_desc			desc;
61*4882a593Smuzhiyun 	struct regulator_dev			*rdev;
62*4882a593Smuzhiyun 	struct da9062				*hw;
63*4882a593Smuzhiyun 	const struct da9062_regulator_info	*info;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	struct regmap_field			*mode;
66*4882a593Smuzhiyun 	struct regmap_field			*suspend;
67*4882a593Smuzhiyun 	struct regmap_field			*sleep;
68*4882a593Smuzhiyun 	struct regmap_field			*suspend_sleep;
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /* Encapsulates all information for the regulators driver */
72*4882a593Smuzhiyun struct da9062_regulators {
73*4882a593Smuzhiyun 	int					irq_ldo_lim;
74*4882a593Smuzhiyun 	unsigned				n_regulators;
75*4882a593Smuzhiyun 	/* Array size to be defined during init. Keep at end. */
76*4882a593Smuzhiyun 	struct da9062_regulator			regulator[];
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /* Regulator operations */
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun /* Current limits array (in uA)
82*4882a593Smuzhiyun  * - DA9061_ID_[BUCK1|BUCK3]
83*4882a593Smuzhiyun  * - DA9062_ID_[BUCK1|BUCK2|BUCK4]
84*4882a593Smuzhiyun  * Entry indexes corresponds to register values.
85*4882a593Smuzhiyun  */
86*4882a593Smuzhiyun static const unsigned int da9062_buck_a_limits[] = {
87*4882a593Smuzhiyun 	 500000,  600000,  700000,  800000,  900000, 1000000, 1100000, 1200000,
88*4882a593Smuzhiyun 	1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /* Current limits array (in uA)
92*4882a593Smuzhiyun  * - DA9061_ID_BUCK2
93*4882a593Smuzhiyun  * - DA9062_ID_BUCK3
94*4882a593Smuzhiyun  * Entry indexes corresponds to register values.
95*4882a593Smuzhiyun  */
96*4882a593Smuzhiyun static const unsigned int da9062_buck_b_limits[] = {
97*4882a593Smuzhiyun 	1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000,
98*4882a593Smuzhiyun 	2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000
99*4882a593Smuzhiyun };
100*4882a593Smuzhiyun 
da9062_map_buck_mode(unsigned int mode)101*4882a593Smuzhiyun static unsigned int da9062_map_buck_mode(unsigned int mode)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun 	switch (mode) {
104*4882a593Smuzhiyun 	case DA9063_BUCK_MODE_SLEEP:
105*4882a593Smuzhiyun 		return REGULATOR_MODE_STANDBY;
106*4882a593Smuzhiyun 	case DA9063_BUCK_MODE_SYNC:
107*4882a593Smuzhiyun 		return REGULATOR_MODE_FAST;
108*4882a593Smuzhiyun 	case DA9063_BUCK_MODE_AUTO:
109*4882a593Smuzhiyun 		return REGULATOR_MODE_NORMAL;
110*4882a593Smuzhiyun 	default:
111*4882a593Smuzhiyun 		return REGULATOR_MODE_INVALID;
112*4882a593Smuzhiyun 	}
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
da9062_buck_set_mode(struct regulator_dev * rdev,unsigned mode)115*4882a593Smuzhiyun static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
118*4882a593Smuzhiyun 	unsigned val;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	switch (mode) {
121*4882a593Smuzhiyun 	case REGULATOR_MODE_FAST:
122*4882a593Smuzhiyun 		val = DA9063_BUCK_MODE_SYNC;
123*4882a593Smuzhiyun 		break;
124*4882a593Smuzhiyun 	case REGULATOR_MODE_NORMAL:
125*4882a593Smuzhiyun 		val = DA9063_BUCK_MODE_AUTO;
126*4882a593Smuzhiyun 		break;
127*4882a593Smuzhiyun 	case REGULATOR_MODE_STANDBY:
128*4882a593Smuzhiyun 		val = DA9063_BUCK_MODE_SLEEP;
129*4882a593Smuzhiyun 		break;
130*4882a593Smuzhiyun 	default:
131*4882a593Smuzhiyun 		return -EINVAL;
132*4882a593Smuzhiyun 	}
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	return regmap_field_write(regl->mode, val);
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun /*
138*4882a593Smuzhiyun  * Bucks use single mode register field for normal operation
139*4882a593Smuzhiyun  * and suspend state.
140*4882a593Smuzhiyun  * There are 3 modes to map to: FAST, NORMAL, and STANDBY.
141*4882a593Smuzhiyun  */
142*4882a593Smuzhiyun 
da9062_buck_get_mode(struct regulator_dev * rdev)143*4882a593Smuzhiyun static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
146*4882a593Smuzhiyun 	unsigned int val;
147*4882a593Smuzhiyun 	int ret;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	ret = regmap_field_read(regl->mode, &val);
150*4882a593Smuzhiyun 	if (ret < 0)
151*4882a593Smuzhiyun 		return ret;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	switch (val) {
154*4882a593Smuzhiyun 	default:
155*4882a593Smuzhiyun 		/* Sleep flag bit decides the mode */
156*4882a593Smuzhiyun 		break;
157*4882a593Smuzhiyun 	case DA9063_BUCK_MODE_SLEEP:
158*4882a593Smuzhiyun 		return REGULATOR_MODE_STANDBY;
159*4882a593Smuzhiyun 	case DA9063_BUCK_MODE_SYNC:
160*4882a593Smuzhiyun 		return REGULATOR_MODE_FAST;
161*4882a593Smuzhiyun 	case DA9063_BUCK_MODE_AUTO:
162*4882a593Smuzhiyun 		return REGULATOR_MODE_NORMAL;
163*4882a593Smuzhiyun 	}
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	ret = regmap_field_read(regl->sleep, &val);
166*4882a593Smuzhiyun 	if (ret < 0)
167*4882a593Smuzhiyun 		return 0;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	if (val)
170*4882a593Smuzhiyun 		return REGULATOR_MODE_STANDBY;
171*4882a593Smuzhiyun 	else
172*4882a593Smuzhiyun 		return REGULATOR_MODE_FAST;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun /*
176*4882a593Smuzhiyun  * LDOs use sleep flags - one for normal and one for suspend state.
177*4882a593Smuzhiyun  * There are 2 modes to map to: NORMAL and STANDBY (sleep) for each state.
178*4882a593Smuzhiyun  */
179*4882a593Smuzhiyun 
da9062_ldo_set_mode(struct regulator_dev * rdev,unsigned mode)180*4882a593Smuzhiyun static int da9062_ldo_set_mode(struct regulator_dev *rdev, unsigned mode)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
183*4882a593Smuzhiyun 	unsigned val;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	switch (mode) {
186*4882a593Smuzhiyun 	case REGULATOR_MODE_NORMAL:
187*4882a593Smuzhiyun 		val = 0;
188*4882a593Smuzhiyun 		break;
189*4882a593Smuzhiyun 	case REGULATOR_MODE_STANDBY:
190*4882a593Smuzhiyun 		val = 1;
191*4882a593Smuzhiyun 		break;
192*4882a593Smuzhiyun 	default:
193*4882a593Smuzhiyun 		return -EINVAL;
194*4882a593Smuzhiyun 	}
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	return regmap_field_write(regl->sleep, val);
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun 
da9062_ldo_get_mode(struct regulator_dev * rdev)199*4882a593Smuzhiyun static unsigned da9062_ldo_get_mode(struct regulator_dev *rdev)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
202*4882a593Smuzhiyun 	int ret, val;
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	ret = regmap_field_read(regl->sleep, &val);
205*4882a593Smuzhiyun 	if (ret < 0)
206*4882a593Smuzhiyun 		return 0;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	if (val)
209*4882a593Smuzhiyun 		return REGULATOR_MODE_STANDBY;
210*4882a593Smuzhiyun 	else
211*4882a593Smuzhiyun 		return REGULATOR_MODE_NORMAL;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun 
da9062_buck_get_status(struct regulator_dev * rdev)214*4882a593Smuzhiyun static int da9062_buck_get_status(struct regulator_dev *rdev)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun 	int ret = regulator_is_enabled_regmap(rdev);
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	if (ret == 0) {
219*4882a593Smuzhiyun 		ret = REGULATOR_STATUS_OFF;
220*4882a593Smuzhiyun 	} else if (ret > 0) {
221*4882a593Smuzhiyun 		ret = da9062_buck_get_mode(rdev);
222*4882a593Smuzhiyun 		if (ret > 0)
223*4882a593Smuzhiyun 			ret = regulator_mode_to_status(ret);
224*4882a593Smuzhiyun 		else if (ret == 0)
225*4882a593Smuzhiyun 			ret = -EIO;
226*4882a593Smuzhiyun 	}
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	return ret;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun 
da9062_ldo_get_status(struct regulator_dev * rdev)231*4882a593Smuzhiyun static int da9062_ldo_get_status(struct regulator_dev *rdev)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun 	int ret = regulator_is_enabled_regmap(rdev);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	if (ret == 0) {
236*4882a593Smuzhiyun 		ret = REGULATOR_STATUS_OFF;
237*4882a593Smuzhiyun 	} else if (ret > 0) {
238*4882a593Smuzhiyun 		ret = da9062_ldo_get_mode(rdev);
239*4882a593Smuzhiyun 		if (ret > 0)
240*4882a593Smuzhiyun 			ret = regulator_mode_to_status(ret);
241*4882a593Smuzhiyun 		else if (ret == 0)
242*4882a593Smuzhiyun 			ret = -EIO;
243*4882a593Smuzhiyun 	}
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	return ret;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun 
da9062_set_suspend_voltage(struct regulator_dev * rdev,int uv)248*4882a593Smuzhiyun static int da9062_set_suspend_voltage(struct regulator_dev *rdev, int uv)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
251*4882a593Smuzhiyun 	const struct da9062_regulator_info *rinfo = regl->info;
252*4882a593Smuzhiyun 	int ret, sel;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	sel = regulator_map_voltage_linear(rdev, uv, uv);
255*4882a593Smuzhiyun 	if (sel < 0)
256*4882a593Smuzhiyun 		return sel;
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	sel <<= ffs(rdev->desc->vsel_mask) - 1;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	ret = regmap_update_bits(regl->hw->regmap, rinfo->suspend_vsel_reg,
261*4882a593Smuzhiyun 				 rdev->desc->vsel_mask, sel);
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	return ret;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun 
da9062_suspend_enable(struct regulator_dev * rdev)266*4882a593Smuzhiyun static int da9062_suspend_enable(struct regulator_dev *rdev)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	return regmap_field_write(regl->suspend, 1);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun 
da9062_suspend_disable(struct regulator_dev * rdev)273*4882a593Smuzhiyun static int da9062_suspend_disable(struct regulator_dev *rdev)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	return regmap_field_write(regl->suspend, 0);
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun 
da9062_buck_set_suspend_mode(struct regulator_dev * rdev,unsigned mode)280*4882a593Smuzhiyun static int da9062_buck_set_suspend_mode(struct regulator_dev *rdev,
281*4882a593Smuzhiyun 					unsigned mode)
282*4882a593Smuzhiyun {
283*4882a593Smuzhiyun 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
284*4882a593Smuzhiyun 	int val;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	switch (mode) {
287*4882a593Smuzhiyun 	case REGULATOR_MODE_FAST:
288*4882a593Smuzhiyun 		val = DA9063_BUCK_MODE_SYNC;
289*4882a593Smuzhiyun 		break;
290*4882a593Smuzhiyun 	case REGULATOR_MODE_NORMAL:
291*4882a593Smuzhiyun 		val = DA9063_BUCK_MODE_AUTO;
292*4882a593Smuzhiyun 		break;
293*4882a593Smuzhiyun 	case REGULATOR_MODE_STANDBY:
294*4882a593Smuzhiyun 		val = DA9063_BUCK_MODE_SLEEP;
295*4882a593Smuzhiyun 		break;
296*4882a593Smuzhiyun 	default:
297*4882a593Smuzhiyun 		return -EINVAL;
298*4882a593Smuzhiyun 	}
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	return regmap_field_write(regl->mode, val);
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun 
da9062_ldo_set_suspend_mode(struct regulator_dev * rdev,unsigned mode)303*4882a593Smuzhiyun static int da9062_ldo_set_suspend_mode(struct regulator_dev *rdev,
304*4882a593Smuzhiyun 						unsigned mode)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
307*4882a593Smuzhiyun 	unsigned val;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	switch (mode) {
310*4882a593Smuzhiyun 	case REGULATOR_MODE_NORMAL:
311*4882a593Smuzhiyun 		val = 0;
312*4882a593Smuzhiyun 		break;
313*4882a593Smuzhiyun 	case REGULATOR_MODE_STANDBY:
314*4882a593Smuzhiyun 		val = 1;
315*4882a593Smuzhiyun 		break;
316*4882a593Smuzhiyun 	default:
317*4882a593Smuzhiyun 		return -EINVAL;
318*4882a593Smuzhiyun 	}
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	return regmap_field_write(regl->suspend_sleep, val);
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun static const struct regulator_ops da9062_buck_ops = {
324*4882a593Smuzhiyun 	.enable			= regulator_enable_regmap,
325*4882a593Smuzhiyun 	.disable		= regulator_disable_regmap,
326*4882a593Smuzhiyun 	.is_enabled		= regulator_is_enabled_regmap,
327*4882a593Smuzhiyun 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
328*4882a593Smuzhiyun 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
329*4882a593Smuzhiyun 	.list_voltage		= regulator_list_voltage_linear,
330*4882a593Smuzhiyun 	.set_current_limit	= regulator_set_current_limit_regmap,
331*4882a593Smuzhiyun 	.get_current_limit	= regulator_get_current_limit_regmap,
332*4882a593Smuzhiyun 	.set_mode		= da9062_buck_set_mode,
333*4882a593Smuzhiyun 	.get_mode		= da9062_buck_get_mode,
334*4882a593Smuzhiyun 	.get_status		= da9062_buck_get_status,
335*4882a593Smuzhiyun 	.set_suspend_voltage	= da9062_set_suspend_voltage,
336*4882a593Smuzhiyun 	.set_suspend_enable	= da9062_suspend_enable,
337*4882a593Smuzhiyun 	.set_suspend_disable	= da9062_suspend_disable,
338*4882a593Smuzhiyun 	.set_suspend_mode	= da9062_buck_set_suspend_mode,
339*4882a593Smuzhiyun };
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun static const struct regulator_ops da9062_ldo_ops = {
342*4882a593Smuzhiyun 	.enable			= regulator_enable_regmap,
343*4882a593Smuzhiyun 	.disable		= regulator_disable_regmap,
344*4882a593Smuzhiyun 	.is_enabled		= regulator_is_enabled_regmap,
345*4882a593Smuzhiyun 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
346*4882a593Smuzhiyun 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
347*4882a593Smuzhiyun 	.list_voltage		= regulator_list_voltage_linear,
348*4882a593Smuzhiyun 	.set_mode		= da9062_ldo_set_mode,
349*4882a593Smuzhiyun 	.get_mode		= da9062_ldo_get_mode,
350*4882a593Smuzhiyun 	.get_status		= da9062_ldo_get_status,
351*4882a593Smuzhiyun 	.set_suspend_voltage	= da9062_set_suspend_voltage,
352*4882a593Smuzhiyun 	.set_suspend_enable	= da9062_suspend_enable,
353*4882a593Smuzhiyun 	.set_suspend_disable	= da9062_suspend_disable,
354*4882a593Smuzhiyun 	.set_suspend_mode	= da9062_ldo_set_suspend_mode,
355*4882a593Smuzhiyun };
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun /* DA9061 Regulator information */
358*4882a593Smuzhiyun static const struct da9062_regulator_info local_da9061_regulator_info[] = {
359*4882a593Smuzhiyun 	{
360*4882a593Smuzhiyun 		.desc.id = DA9061_ID_BUCK1,
361*4882a593Smuzhiyun 		.desc.name = "DA9061 BUCK1",
362*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("buck1"),
363*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
364*4882a593Smuzhiyun 		.desc.ops = &da9062_buck_ops,
365*4882a593Smuzhiyun 		.desc.min_uV = (300) * 1000,
366*4882a593Smuzhiyun 		.desc.uV_step = (10) * 1000,
367*4882a593Smuzhiyun 		.desc.n_voltages = ((1570) - (300))/(10) + 1,
368*4882a593Smuzhiyun 		.desc.curr_table = da9062_buck_a_limits,
369*4882a593Smuzhiyun 		.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
370*4882a593Smuzhiyun 		.desc.csel_reg = DA9062AA_BUCK_ILIM_C,
371*4882a593Smuzhiyun 		.desc.csel_mask = DA9062AA_BUCK1_ILIM_MASK,
372*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_BUCK1_CONT,
373*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_BUCK1_EN_MASK,
374*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VBUCK1_A,
375*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VBUCK1_A_MASK,
376*4882a593Smuzhiyun 		.desc.linear_min_sel = 0,
377*4882a593Smuzhiyun 		.desc.of_map_mode = da9062_map_buck_mode,
378*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VBUCK1_A,
379*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK1_SL_A_MASK) - 1,
380*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
381*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK1_SL_A_MASK)) - 1),
382*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VBUCK1_B,
383*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK1_SL_B_MASK) - 1,
384*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
385*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK1_SL_B_MASK)) - 1),
386*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VBUCK1_B,
387*4882a593Smuzhiyun 		.mode = REG_FIELD(DA9062AA_BUCK1_CFG,
388*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
389*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
390*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
391*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
392*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
393*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
394*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
395*4882a593Smuzhiyun 	},
396*4882a593Smuzhiyun 	{
397*4882a593Smuzhiyun 		.desc.id = DA9061_ID_BUCK2,
398*4882a593Smuzhiyun 		.desc.name = "DA9061 BUCK2",
399*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("buck2"),
400*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
401*4882a593Smuzhiyun 		.desc.ops = &da9062_buck_ops,
402*4882a593Smuzhiyun 		.desc.min_uV = (800) * 1000,
403*4882a593Smuzhiyun 		.desc.uV_step = (20) * 1000,
404*4882a593Smuzhiyun 		.desc.n_voltages = ((3340) - (800))/(20) + 1,
405*4882a593Smuzhiyun 		.desc.curr_table = da9062_buck_b_limits,
406*4882a593Smuzhiyun 		.desc.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits),
407*4882a593Smuzhiyun 		.desc.csel_reg = DA9062AA_BUCK_ILIM_A,
408*4882a593Smuzhiyun 		.desc.csel_mask = DA9062AA_BUCK3_ILIM_MASK,
409*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_BUCK3_CONT,
410*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_BUCK3_EN_MASK,
411*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VBUCK3_A,
412*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VBUCK3_A_MASK,
413*4882a593Smuzhiyun 		.desc.linear_min_sel = 0,
414*4882a593Smuzhiyun 		.desc.of_map_mode = da9062_map_buck_mode,
415*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VBUCK3_A,
416*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK3_SL_A_MASK) - 1,
417*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
418*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK3_SL_A_MASK)) - 1),
419*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VBUCK3_B,
420*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK3_SL_B_MASK) - 1,
421*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
422*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK3_SL_B_MASK)) - 1),
423*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VBUCK3_B,
424*4882a593Smuzhiyun 		.mode = REG_FIELD(DA9062AA_BUCK3_CFG,
425*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
426*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
427*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
428*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
429*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
430*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
431*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
432*4882a593Smuzhiyun 	},
433*4882a593Smuzhiyun 	{
434*4882a593Smuzhiyun 		.desc.id = DA9061_ID_BUCK3,
435*4882a593Smuzhiyun 		.desc.name = "DA9061 BUCK3",
436*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("buck3"),
437*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
438*4882a593Smuzhiyun 		.desc.ops = &da9062_buck_ops,
439*4882a593Smuzhiyun 		.desc.min_uV = (530) * 1000,
440*4882a593Smuzhiyun 		.desc.uV_step = (10) * 1000,
441*4882a593Smuzhiyun 		.desc.n_voltages = ((1800) - (530))/(10) + 1,
442*4882a593Smuzhiyun 		.desc.curr_table = da9062_buck_a_limits,
443*4882a593Smuzhiyun 		.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
444*4882a593Smuzhiyun 		.desc.csel_reg = DA9062AA_BUCK_ILIM_B,
445*4882a593Smuzhiyun 		.desc.csel_mask = DA9062AA_BUCK4_ILIM_MASK,
446*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_BUCK4_CONT,
447*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_BUCK4_EN_MASK,
448*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VBUCK4_A,
449*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VBUCK4_A_MASK,
450*4882a593Smuzhiyun 		.desc.linear_min_sel = 0,
451*4882a593Smuzhiyun 		.desc.of_map_mode = da9062_map_buck_mode,
452*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VBUCK4_A,
453*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK4_SL_A_MASK) - 1,
454*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
455*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK4_SL_A_MASK)) - 1),
456*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VBUCK4_B,
457*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK4_SL_B_MASK) - 1,
458*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
459*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK4_SL_B_MASK)) - 1),
460*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VBUCK4_B,
461*4882a593Smuzhiyun 		.mode = REG_FIELD(DA9062AA_BUCK4_CFG,
462*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
463*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
464*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
465*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
466*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
467*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
468*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
469*4882a593Smuzhiyun 	},
470*4882a593Smuzhiyun 	{
471*4882a593Smuzhiyun 		.desc.id = DA9061_ID_LDO1,
472*4882a593Smuzhiyun 		.desc.name = "DA9061 LDO1",
473*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("ldo1"),
474*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
475*4882a593Smuzhiyun 		.desc.ops = &da9062_ldo_ops,
476*4882a593Smuzhiyun 		.desc.min_uV = (900) * 1000,
477*4882a593Smuzhiyun 		.desc.uV_step = (50) * 1000,
478*4882a593Smuzhiyun 		.desc.n_voltages = ((3600) - (900))/(50) + 1
479*4882a593Smuzhiyun 				+ DA9062AA_VLDO_A_MIN_SEL,
480*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_LDO1_CONT,
481*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_LDO1_EN_MASK,
482*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VLDO1_A,
483*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VLDO1_A_MASK,
484*4882a593Smuzhiyun 		.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
485*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VLDO1_A,
486*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO1_SL_A_MASK) - 1,
487*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
488*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO1_SL_A_MASK)) - 1),
489*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VLDO1_B,
490*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO1_SL_B_MASK) - 1,
491*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
492*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
493*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VLDO1_B,
494*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
495*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
496*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
497*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
498*4882a593Smuzhiyun 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
499*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
500*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
501*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO1_ILIM_MASK)) - 1),
502*4882a593Smuzhiyun 	},
503*4882a593Smuzhiyun 	{
504*4882a593Smuzhiyun 		.desc.id = DA9061_ID_LDO2,
505*4882a593Smuzhiyun 		.desc.name = "DA9061 LDO2",
506*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("ldo2"),
507*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
508*4882a593Smuzhiyun 		.desc.ops = &da9062_ldo_ops,
509*4882a593Smuzhiyun 		.desc.min_uV = (900) * 1000,
510*4882a593Smuzhiyun 		.desc.uV_step = (50) * 1000,
511*4882a593Smuzhiyun 		.desc.n_voltages = ((3600) - (900))/(50) + 1
512*4882a593Smuzhiyun 				+ DA9062AA_VLDO_A_MIN_SEL,
513*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_LDO2_CONT,
514*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_LDO2_EN_MASK,
515*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VLDO2_A,
516*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VLDO2_A_MASK,
517*4882a593Smuzhiyun 		.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
518*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VLDO2_A,
519*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO2_SL_A_MASK) - 1,
520*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
521*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO2_SL_A_MASK)) - 1),
522*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VLDO2_B,
523*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO2_SL_B_MASK) - 1,
524*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
525*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
526*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VLDO2_B,
527*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
528*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
529*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
530*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
531*4882a593Smuzhiyun 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
532*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
533*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
534*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO2_ILIM_MASK)) - 1),
535*4882a593Smuzhiyun 	},
536*4882a593Smuzhiyun 	{
537*4882a593Smuzhiyun 		.desc.id = DA9061_ID_LDO3,
538*4882a593Smuzhiyun 		.desc.name = "DA9061 LDO3",
539*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("ldo3"),
540*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
541*4882a593Smuzhiyun 		.desc.ops = &da9062_ldo_ops,
542*4882a593Smuzhiyun 		.desc.min_uV = (900) * 1000,
543*4882a593Smuzhiyun 		.desc.uV_step = (50) * 1000,
544*4882a593Smuzhiyun 		.desc.n_voltages = ((3600) - (900))/(50) + 1
545*4882a593Smuzhiyun 				+ DA9062AA_VLDO_A_MIN_SEL,
546*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_LDO3_CONT,
547*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_LDO3_EN_MASK,
548*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VLDO3_A,
549*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VLDO3_A_MASK,
550*4882a593Smuzhiyun 		.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
551*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VLDO3_A,
552*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO3_SL_A_MASK) - 1,
553*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
554*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO3_SL_A_MASK)) - 1),
555*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VLDO3_B,
556*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO3_SL_B_MASK) - 1,
557*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
558*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
559*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VLDO3_B,
560*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
561*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
562*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
563*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
564*4882a593Smuzhiyun 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
565*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
566*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
567*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO3_ILIM_MASK)) - 1),
568*4882a593Smuzhiyun 	},
569*4882a593Smuzhiyun 	{
570*4882a593Smuzhiyun 		.desc.id = DA9061_ID_LDO4,
571*4882a593Smuzhiyun 		.desc.name = "DA9061 LDO4",
572*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("ldo4"),
573*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
574*4882a593Smuzhiyun 		.desc.ops = &da9062_ldo_ops,
575*4882a593Smuzhiyun 		.desc.min_uV = (900) * 1000,
576*4882a593Smuzhiyun 		.desc.uV_step = (50) * 1000,
577*4882a593Smuzhiyun 		.desc.n_voltages = ((3600) - (900))/(50) + 1
578*4882a593Smuzhiyun 				+ DA9062AA_VLDO_A_MIN_SEL,
579*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_LDO4_CONT,
580*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_LDO4_EN_MASK,
581*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VLDO4_A,
582*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VLDO4_A_MASK,
583*4882a593Smuzhiyun 		.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
584*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VLDO4_A,
585*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO4_SL_A_MASK) - 1,
586*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
587*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO4_SL_A_MASK)) - 1),
588*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VLDO4_B,
589*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO4_SL_B_MASK) - 1,
590*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
591*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
592*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VLDO4_B,
593*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
594*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
595*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
596*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
597*4882a593Smuzhiyun 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
598*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
599*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
600*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO4_ILIM_MASK)) - 1),
601*4882a593Smuzhiyun 	},
602*4882a593Smuzhiyun };
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun /* DA9062 Regulator information */
605*4882a593Smuzhiyun static const struct da9062_regulator_info local_da9062_regulator_info[] = {
606*4882a593Smuzhiyun 	{
607*4882a593Smuzhiyun 		.desc.id = DA9062_ID_BUCK1,
608*4882a593Smuzhiyun 		.desc.name = "DA9062 BUCK1",
609*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("buck1"),
610*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
611*4882a593Smuzhiyun 		.desc.ops = &da9062_buck_ops,
612*4882a593Smuzhiyun 		.desc.min_uV = (300) * 1000,
613*4882a593Smuzhiyun 		.desc.uV_step = (10) * 1000,
614*4882a593Smuzhiyun 		.desc.n_voltages = ((1570) - (300))/(10) + 1,
615*4882a593Smuzhiyun 		.desc.curr_table = da9062_buck_a_limits,
616*4882a593Smuzhiyun 		.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
617*4882a593Smuzhiyun 		.desc.csel_reg = DA9062AA_BUCK_ILIM_C,
618*4882a593Smuzhiyun 		.desc.csel_mask = DA9062AA_BUCK1_ILIM_MASK,
619*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_BUCK1_CONT,
620*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_BUCK1_EN_MASK,
621*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VBUCK1_A,
622*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VBUCK1_A_MASK,
623*4882a593Smuzhiyun 		.desc.linear_min_sel = 0,
624*4882a593Smuzhiyun 		.desc.of_map_mode = da9062_map_buck_mode,
625*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VBUCK1_A,
626*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK1_SL_A_MASK) - 1,
627*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
628*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK1_SL_A_MASK)) - 1),
629*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VBUCK1_B,
630*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK1_SL_B_MASK) - 1,
631*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
632*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK1_SL_B_MASK)) - 1),
633*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VBUCK1_B,
634*4882a593Smuzhiyun 		.mode = REG_FIELD(DA9062AA_BUCK1_CFG,
635*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
636*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
637*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
638*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
639*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
640*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
641*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
642*4882a593Smuzhiyun 	},
643*4882a593Smuzhiyun 	{
644*4882a593Smuzhiyun 		.desc.id = DA9062_ID_BUCK2,
645*4882a593Smuzhiyun 		.desc.name = "DA9062 BUCK2",
646*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("buck2"),
647*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
648*4882a593Smuzhiyun 		.desc.ops = &da9062_buck_ops,
649*4882a593Smuzhiyun 		.desc.min_uV = (300) * 1000,
650*4882a593Smuzhiyun 		.desc.uV_step = (10) * 1000,
651*4882a593Smuzhiyun 		.desc.n_voltages = ((1570) - (300))/(10) + 1,
652*4882a593Smuzhiyun 		.desc.curr_table = da9062_buck_a_limits,
653*4882a593Smuzhiyun 		.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
654*4882a593Smuzhiyun 		.desc.csel_reg = DA9062AA_BUCK_ILIM_C,
655*4882a593Smuzhiyun 		.desc.csel_mask = DA9062AA_BUCK2_ILIM_MASK,
656*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_BUCK2_CONT,
657*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_BUCK2_EN_MASK,
658*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VBUCK2_A,
659*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VBUCK2_A_MASK,
660*4882a593Smuzhiyun 		.desc.linear_min_sel = 0,
661*4882a593Smuzhiyun 		.desc.of_map_mode = da9062_map_buck_mode,
662*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VBUCK2_A,
663*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK2_SL_A_MASK) - 1,
664*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
665*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK2_SL_A_MASK)) - 1),
666*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VBUCK2_B,
667*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK2_SL_B_MASK) - 1,
668*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
669*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK2_SL_B_MASK)) - 1),
670*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VBUCK2_B,
671*4882a593Smuzhiyun 		.mode = REG_FIELD(DA9062AA_BUCK2_CFG,
672*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK2_MODE_MASK) - 1,
673*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
674*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK2_MODE_MASK)) - 1),
675*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_BUCK2_CONT,
676*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
677*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
678*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
679*4882a593Smuzhiyun 	},
680*4882a593Smuzhiyun 	{
681*4882a593Smuzhiyun 		.desc.id = DA9062_ID_BUCK3,
682*4882a593Smuzhiyun 		.desc.name = "DA9062 BUCK3",
683*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("buck3"),
684*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
685*4882a593Smuzhiyun 		.desc.ops = &da9062_buck_ops,
686*4882a593Smuzhiyun 		.desc.min_uV = (800) * 1000,
687*4882a593Smuzhiyun 		.desc.uV_step = (20) * 1000,
688*4882a593Smuzhiyun 		.desc.n_voltages = ((3340) - (800))/(20) + 1,
689*4882a593Smuzhiyun 		.desc.curr_table = da9062_buck_b_limits,
690*4882a593Smuzhiyun 		.desc.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits),
691*4882a593Smuzhiyun 		.desc.csel_reg = DA9062AA_BUCK_ILIM_A,
692*4882a593Smuzhiyun 		.desc.csel_mask = DA9062AA_BUCK3_ILIM_MASK,
693*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_BUCK3_CONT,
694*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_BUCK3_EN_MASK,
695*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VBUCK3_A,
696*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VBUCK3_A_MASK,
697*4882a593Smuzhiyun 		.desc.linear_min_sel = 0,
698*4882a593Smuzhiyun 		.desc.of_map_mode = da9062_map_buck_mode,
699*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VBUCK3_A,
700*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK3_SL_A_MASK) - 1,
701*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
702*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK3_SL_A_MASK)) - 1),
703*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VBUCK3_B,
704*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK3_SL_B_MASK) - 1,
705*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
706*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK3_SL_B_MASK)) - 1),
707*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VBUCK3_B,
708*4882a593Smuzhiyun 		.mode = REG_FIELD(DA9062AA_BUCK3_CFG,
709*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
710*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
711*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
712*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
713*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
714*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
715*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
716*4882a593Smuzhiyun 	},
717*4882a593Smuzhiyun 	{
718*4882a593Smuzhiyun 		.desc.id = DA9062_ID_BUCK4,
719*4882a593Smuzhiyun 		.desc.name = "DA9062 BUCK4",
720*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("buck4"),
721*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
722*4882a593Smuzhiyun 		.desc.ops = &da9062_buck_ops,
723*4882a593Smuzhiyun 		.desc.min_uV = (530) * 1000,
724*4882a593Smuzhiyun 		.desc.uV_step = (10) * 1000,
725*4882a593Smuzhiyun 		.desc.n_voltages = ((1800) - (530))/(10) + 1,
726*4882a593Smuzhiyun 		.desc.curr_table = da9062_buck_a_limits,
727*4882a593Smuzhiyun 		.desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits),
728*4882a593Smuzhiyun 		.desc.csel_reg = DA9062AA_BUCK_ILIM_B,
729*4882a593Smuzhiyun 		.desc.csel_mask = DA9062AA_BUCK4_ILIM_MASK,
730*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_BUCK4_CONT,
731*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_BUCK4_EN_MASK,
732*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VBUCK4_A,
733*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VBUCK4_A_MASK,
734*4882a593Smuzhiyun 		.desc.linear_min_sel = 0,
735*4882a593Smuzhiyun 		.desc.of_map_mode = da9062_map_buck_mode,
736*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VBUCK4_A,
737*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK4_SL_A_MASK) - 1,
738*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
739*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK4_SL_A_MASK)) - 1),
740*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VBUCK4_B,
741*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK4_SL_B_MASK) - 1,
742*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
743*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK4_SL_B_MASK)) - 1),
744*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VBUCK4_B,
745*4882a593Smuzhiyun 		.mode = REG_FIELD(DA9062AA_BUCK4_CFG,
746*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
747*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
748*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
749*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
750*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
751*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
752*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
753*4882a593Smuzhiyun 	},
754*4882a593Smuzhiyun 	{
755*4882a593Smuzhiyun 		.desc.id = DA9062_ID_LDO1,
756*4882a593Smuzhiyun 		.desc.name = "DA9062 LDO1",
757*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("ldo1"),
758*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
759*4882a593Smuzhiyun 		.desc.ops = &da9062_ldo_ops,
760*4882a593Smuzhiyun 		.desc.min_uV = (900) * 1000,
761*4882a593Smuzhiyun 		.desc.uV_step = (50) * 1000,
762*4882a593Smuzhiyun 		.desc.n_voltages = ((3600) - (900))/(50) + 1
763*4882a593Smuzhiyun 				+ DA9062AA_VLDO_A_MIN_SEL,
764*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_LDO1_CONT,
765*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_LDO1_EN_MASK,
766*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VLDO1_A,
767*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VLDO1_A_MASK,
768*4882a593Smuzhiyun 		.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
769*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VLDO1_A,
770*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO1_SL_A_MASK) - 1,
771*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
772*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO1_SL_A_MASK)) - 1),
773*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VLDO1_B,
774*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO1_SL_B_MASK) - 1,
775*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
776*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
777*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VLDO1_B,
778*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
779*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
780*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
781*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
782*4882a593Smuzhiyun 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
783*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
784*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
785*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO1_ILIM_MASK)) - 1),
786*4882a593Smuzhiyun 	},
787*4882a593Smuzhiyun 	{
788*4882a593Smuzhiyun 		.desc.id = DA9062_ID_LDO2,
789*4882a593Smuzhiyun 		.desc.name = "DA9062 LDO2",
790*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("ldo2"),
791*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
792*4882a593Smuzhiyun 		.desc.ops = &da9062_ldo_ops,
793*4882a593Smuzhiyun 		.desc.min_uV = (900) * 1000,
794*4882a593Smuzhiyun 		.desc.uV_step = (50) * 1000,
795*4882a593Smuzhiyun 		.desc.n_voltages = ((3600) - (900))/(50) + 1
796*4882a593Smuzhiyun 				+ DA9062AA_VLDO_A_MIN_SEL,
797*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_LDO2_CONT,
798*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_LDO2_EN_MASK,
799*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VLDO2_A,
800*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VLDO2_A_MASK,
801*4882a593Smuzhiyun 		.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
802*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VLDO2_A,
803*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO2_SL_A_MASK) - 1,
804*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
805*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO2_SL_A_MASK)) - 1),
806*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VLDO2_B,
807*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO2_SL_B_MASK) - 1,
808*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
809*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
810*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VLDO2_B,
811*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
812*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
813*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
814*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
815*4882a593Smuzhiyun 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
816*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
817*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
818*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO2_ILIM_MASK)) - 1),
819*4882a593Smuzhiyun 	},
820*4882a593Smuzhiyun 	{
821*4882a593Smuzhiyun 		.desc.id = DA9062_ID_LDO3,
822*4882a593Smuzhiyun 		.desc.name = "DA9062 LDO3",
823*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("ldo3"),
824*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
825*4882a593Smuzhiyun 		.desc.ops = &da9062_ldo_ops,
826*4882a593Smuzhiyun 		.desc.min_uV = (900) * 1000,
827*4882a593Smuzhiyun 		.desc.uV_step = (50) * 1000,
828*4882a593Smuzhiyun 		.desc.n_voltages = ((3600) - (900))/(50) + 1
829*4882a593Smuzhiyun 				+ DA9062AA_VLDO_A_MIN_SEL,
830*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_LDO3_CONT,
831*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_LDO3_EN_MASK,
832*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VLDO3_A,
833*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VLDO3_A_MASK,
834*4882a593Smuzhiyun 		.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
835*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VLDO3_A,
836*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO3_SL_A_MASK) - 1,
837*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
838*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO3_SL_A_MASK)) - 1),
839*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VLDO3_B,
840*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO3_SL_B_MASK) - 1,
841*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
842*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
843*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VLDO3_B,
844*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
845*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
846*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
847*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
848*4882a593Smuzhiyun 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
849*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
850*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
851*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO3_ILIM_MASK)) - 1),
852*4882a593Smuzhiyun 	},
853*4882a593Smuzhiyun 	{
854*4882a593Smuzhiyun 		.desc.id = DA9062_ID_LDO4,
855*4882a593Smuzhiyun 		.desc.name = "DA9062 LDO4",
856*4882a593Smuzhiyun 		.desc.of_match = of_match_ptr("ldo4"),
857*4882a593Smuzhiyun 		.desc.regulators_node = of_match_ptr("regulators"),
858*4882a593Smuzhiyun 		.desc.ops = &da9062_ldo_ops,
859*4882a593Smuzhiyun 		.desc.min_uV = (900) * 1000,
860*4882a593Smuzhiyun 		.desc.uV_step = (50) * 1000,
861*4882a593Smuzhiyun 		.desc.n_voltages = ((3600) - (900))/(50) + 1
862*4882a593Smuzhiyun 				+ DA9062AA_VLDO_A_MIN_SEL,
863*4882a593Smuzhiyun 		.desc.enable_reg = DA9062AA_LDO4_CONT,
864*4882a593Smuzhiyun 		.desc.enable_mask = DA9062AA_LDO4_EN_MASK,
865*4882a593Smuzhiyun 		.desc.vsel_reg = DA9062AA_VLDO4_A,
866*4882a593Smuzhiyun 		.desc.vsel_mask = DA9062AA_VLDO4_A_MASK,
867*4882a593Smuzhiyun 		.desc.linear_min_sel = DA9062AA_VLDO_A_MIN_SEL,
868*4882a593Smuzhiyun 		.sleep = REG_FIELD(DA9062AA_VLDO4_A,
869*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO4_SL_A_MASK) - 1,
870*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
871*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO4_SL_A_MASK)) - 1),
872*4882a593Smuzhiyun 		.suspend_sleep = REG_FIELD(DA9062AA_VLDO4_B,
873*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO4_SL_B_MASK) - 1,
874*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
875*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
876*4882a593Smuzhiyun 		.suspend_vsel_reg = DA9062AA_VLDO4_B,
877*4882a593Smuzhiyun 		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
878*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
879*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
880*4882a593Smuzhiyun 			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
881*4882a593Smuzhiyun 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
882*4882a593Smuzhiyun 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
883*4882a593Smuzhiyun 			sizeof(unsigned int) * 8 -
884*4882a593Smuzhiyun 			__builtin_clz((DA9062AA_LDO4_ILIM_MASK)) - 1),
885*4882a593Smuzhiyun 	},
886*4882a593Smuzhiyun };
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun /* Regulator interrupt handlers */
da9062_ldo_lim_event(int irq,void * data)889*4882a593Smuzhiyun static irqreturn_t da9062_ldo_lim_event(int irq, void *data)
890*4882a593Smuzhiyun {
891*4882a593Smuzhiyun 	struct da9062_regulators *regulators = data;
892*4882a593Smuzhiyun 	struct da9062 *hw = regulators->regulator[0].hw;
893*4882a593Smuzhiyun 	struct da9062_regulator *regl;
894*4882a593Smuzhiyun 	int handled = IRQ_NONE;
895*4882a593Smuzhiyun 	int bits, i, ret;
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun 	ret = regmap_read(hw->regmap, DA9062AA_STATUS_D, &bits);
898*4882a593Smuzhiyun 	if (ret < 0) {
899*4882a593Smuzhiyun 		dev_err(hw->dev,
900*4882a593Smuzhiyun 			"Failed to read LDO overcurrent indicator\n");
901*4882a593Smuzhiyun 		goto ldo_lim_error;
902*4882a593Smuzhiyun 	}
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 	for (i = regulators->n_regulators - 1; i >= 0; i--) {
905*4882a593Smuzhiyun 		regl = &regulators->regulator[i];
906*4882a593Smuzhiyun 		if (regl->info->oc_event.reg != DA9062AA_STATUS_D)
907*4882a593Smuzhiyun 			continue;
908*4882a593Smuzhiyun 
909*4882a593Smuzhiyun 		if (BIT(regl->info->oc_event.lsb) & bits) {
910*4882a593Smuzhiyun 			regulator_notifier_call_chain(regl->rdev,
911*4882a593Smuzhiyun 					REGULATOR_EVENT_OVER_CURRENT, NULL);
912*4882a593Smuzhiyun 			handled = IRQ_HANDLED;
913*4882a593Smuzhiyun 		}
914*4882a593Smuzhiyun 	}
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun ldo_lim_error:
917*4882a593Smuzhiyun 	return handled;
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun 
da9062_regulator_probe(struct platform_device * pdev)920*4882a593Smuzhiyun static int da9062_regulator_probe(struct platform_device *pdev)
921*4882a593Smuzhiyun {
922*4882a593Smuzhiyun 	struct da9062 *chip = dev_get_drvdata(pdev->dev.parent);
923*4882a593Smuzhiyun 	struct da9062_regulators *regulators;
924*4882a593Smuzhiyun 	struct da9062_regulator *regl;
925*4882a593Smuzhiyun 	struct regulator_config config = { };
926*4882a593Smuzhiyun 	const struct da9062_regulator_info *rinfo;
927*4882a593Smuzhiyun 	int irq, n, ret;
928*4882a593Smuzhiyun 	int max_regulators;
929*4882a593Smuzhiyun 
930*4882a593Smuzhiyun 	switch (chip->chip_type) {
931*4882a593Smuzhiyun 	case COMPAT_TYPE_DA9061:
932*4882a593Smuzhiyun 		max_regulators = DA9061_MAX_REGULATORS;
933*4882a593Smuzhiyun 		rinfo = local_da9061_regulator_info;
934*4882a593Smuzhiyun 		break;
935*4882a593Smuzhiyun 	case COMPAT_TYPE_DA9062:
936*4882a593Smuzhiyun 		max_regulators = DA9062_MAX_REGULATORS;
937*4882a593Smuzhiyun 		rinfo = local_da9062_regulator_info;
938*4882a593Smuzhiyun 		break;
939*4882a593Smuzhiyun 	default:
940*4882a593Smuzhiyun 		dev_err(chip->dev, "Unrecognised chip type\n");
941*4882a593Smuzhiyun 		return -ENODEV;
942*4882a593Smuzhiyun 	}
943*4882a593Smuzhiyun 
944*4882a593Smuzhiyun 	/* Allocate memory required by usable regulators */
945*4882a593Smuzhiyun 	regulators = devm_kzalloc(&pdev->dev, struct_size(regulators, regulator,
946*4882a593Smuzhiyun 				  max_regulators), GFP_KERNEL);
947*4882a593Smuzhiyun 	if (!regulators)
948*4882a593Smuzhiyun 		return -ENOMEM;
949*4882a593Smuzhiyun 
950*4882a593Smuzhiyun 	regulators->n_regulators = max_regulators;
951*4882a593Smuzhiyun 	platform_set_drvdata(pdev, regulators);
952*4882a593Smuzhiyun 
953*4882a593Smuzhiyun 	for (n = 0; n < regulators->n_regulators; n++) {
954*4882a593Smuzhiyun 		/* Initialise regulator structure */
955*4882a593Smuzhiyun 		regl = &regulators->regulator[n];
956*4882a593Smuzhiyun 		regl->hw = chip;
957*4882a593Smuzhiyun 		regl->info = &rinfo[n];
958*4882a593Smuzhiyun 		regl->desc = regl->info->desc;
959*4882a593Smuzhiyun 		regl->desc.type = REGULATOR_VOLTAGE;
960*4882a593Smuzhiyun 		regl->desc.owner = THIS_MODULE;
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun 		if (regl->info->mode.reg) {
963*4882a593Smuzhiyun 			regl->mode = devm_regmap_field_alloc(
964*4882a593Smuzhiyun 					&pdev->dev,
965*4882a593Smuzhiyun 					chip->regmap,
966*4882a593Smuzhiyun 					regl->info->mode);
967*4882a593Smuzhiyun 			if (IS_ERR(regl->mode))
968*4882a593Smuzhiyun 				return PTR_ERR(regl->mode);
969*4882a593Smuzhiyun 		}
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun 		if (regl->info->suspend.reg) {
972*4882a593Smuzhiyun 			regl->suspend = devm_regmap_field_alloc(
973*4882a593Smuzhiyun 					&pdev->dev,
974*4882a593Smuzhiyun 					chip->regmap,
975*4882a593Smuzhiyun 					regl->info->suspend);
976*4882a593Smuzhiyun 			if (IS_ERR(regl->suspend))
977*4882a593Smuzhiyun 				return PTR_ERR(regl->suspend);
978*4882a593Smuzhiyun 		}
979*4882a593Smuzhiyun 
980*4882a593Smuzhiyun 		if (regl->info->sleep.reg) {
981*4882a593Smuzhiyun 			regl->sleep = devm_regmap_field_alloc(
982*4882a593Smuzhiyun 					&pdev->dev,
983*4882a593Smuzhiyun 					chip->regmap,
984*4882a593Smuzhiyun 					regl->info->sleep);
985*4882a593Smuzhiyun 			if (IS_ERR(regl->sleep))
986*4882a593Smuzhiyun 				return PTR_ERR(regl->sleep);
987*4882a593Smuzhiyun 		}
988*4882a593Smuzhiyun 
989*4882a593Smuzhiyun 		if (regl->info->suspend_sleep.reg) {
990*4882a593Smuzhiyun 			regl->suspend_sleep = devm_regmap_field_alloc(
991*4882a593Smuzhiyun 					&pdev->dev,
992*4882a593Smuzhiyun 					chip->regmap,
993*4882a593Smuzhiyun 					regl->info->suspend_sleep);
994*4882a593Smuzhiyun 			if (IS_ERR(regl->suspend_sleep))
995*4882a593Smuzhiyun 				return PTR_ERR(regl->suspend_sleep);
996*4882a593Smuzhiyun 		}
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun 		/* Register regulator */
999*4882a593Smuzhiyun 		memset(&config, 0, sizeof(config));
1000*4882a593Smuzhiyun 		config.dev = chip->dev;
1001*4882a593Smuzhiyun 		config.driver_data = regl;
1002*4882a593Smuzhiyun 		config.regmap = chip->regmap;
1003*4882a593Smuzhiyun 
1004*4882a593Smuzhiyun 		regl->rdev = devm_regulator_register(&pdev->dev, &regl->desc,
1005*4882a593Smuzhiyun 						     &config);
1006*4882a593Smuzhiyun 		if (IS_ERR(regl->rdev)) {
1007*4882a593Smuzhiyun 			dev_err(&pdev->dev,
1008*4882a593Smuzhiyun 				"Failed to register %s regulator\n",
1009*4882a593Smuzhiyun 				regl->desc.name);
1010*4882a593Smuzhiyun 			return PTR_ERR(regl->rdev);
1011*4882a593Smuzhiyun 		}
1012*4882a593Smuzhiyun 	}
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 	/* LDOs overcurrent event support */
1015*4882a593Smuzhiyun 	irq = platform_get_irq_byname(pdev, "LDO_LIM");
1016*4882a593Smuzhiyun 	if (irq < 0)
1017*4882a593Smuzhiyun 		return irq;
1018*4882a593Smuzhiyun 	regulators->irq_ldo_lim = irq;
1019*4882a593Smuzhiyun 
1020*4882a593Smuzhiyun 	ret = devm_request_threaded_irq(&pdev->dev, irq,
1021*4882a593Smuzhiyun 					NULL, da9062_ldo_lim_event,
1022*4882a593Smuzhiyun 					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1023*4882a593Smuzhiyun 					"LDO_LIM", regulators);
1024*4882a593Smuzhiyun 	if (ret) {
1025*4882a593Smuzhiyun 		dev_warn(&pdev->dev,
1026*4882a593Smuzhiyun 			 "Failed to request LDO_LIM IRQ.\n");
1027*4882a593Smuzhiyun 		regulators->irq_ldo_lim = -ENXIO;
1028*4882a593Smuzhiyun 	}
1029*4882a593Smuzhiyun 
1030*4882a593Smuzhiyun 	return 0;
1031*4882a593Smuzhiyun }
1032*4882a593Smuzhiyun 
1033*4882a593Smuzhiyun static struct platform_driver da9062_regulator_driver = {
1034*4882a593Smuzhiyun 	.driver = {
1035*4882a593Smuzhiyun 		.name = "da9062-regulators",
1036*4882a593Smuzhiyun 	},
1037*4882a593Smuzhiyun 	.probe = da9062_regulator_probe,
1038*4882a593Smuzhiyun };
1039*4882a593Smuzhiyun 
da9062_regulator_init(void)1040*4882a593Smuzhiyun static int __init da9062_regulator_init(void)
1041*4882a593Smuzhiyun {
1042*4882a593Smuzhiyun 	return platform_driver_register(&da9062_regulator_driver);
1043*4882a593Smuzhiyun }
1044*4882a593Smuzhiyun subsys_initcall(da9062_regulator_init);
1045*4882a593Smuzhiyun 
da9062_regulator_cleanup(void)1046*4882a593Smuzhiyun static void __exit da9062_regulator_cleanup(void)
1047*4882a593Smuzhiyun {
1048*4882a593Smuzhiyun 	platform_driver_unregister(&da9062_regulator_driver);
1049*4882a593Smuzhiyun }
1050*4882a593Smuzhiyun module_exit(da9062_regulator_cleanup);
1051*4882a593Smuzhiyun 
1052*4882a593Smuzhiyun /* Module information */
1053*4882a593Smuzhiyun MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>");
1054*4882a593Smuzhiyun MODULE_DESCRIPTION("REGULATOR device driver for Dialog DA9062 and DA9061");
1055*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1056*4882a593Smuzhiyun MODULE_ALIAS("platform:da9062-regulators");
1057