xref: /rk3399_rockchip-uboot/drivers/power/regulator/fan53555_regulator.c (revision e54cf6dba77ac6d2c1d495ebf95f5396402d3106)
1*e54cf6dbSElaine Zhang // SPDX-License-Identifier: GPL-2.0
2*e54cf6dbSElaine Zhang /*
3*e54cf6dbSElaine Zhang  * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
4*e54cf6dbSElaine Zhang  */
5*e54cf6dbSElaine Zhang #include <common.h>
6*e54cf6dbSElaine Zhang #include <dm.h>
7*e54cf6dbSElaine Zhang #include <errno.h>
8*e54cf6dbSElaine Zhang #include <asm/gpio.h>
9*e54cf6dbSElaine Zhang #include <power/regulator.h>
10*e54cf6dbSElaine Zhang #include <i2c.h>
11*e54cf6dbSElaine Zhang #include <asm/arch/clock.h>
12*e54cf6dbSElaine Zhang #include <asm/io.h>
13*e54cf6dbSElaine Zhang #include <syscon.h>
14*e54cf6dbSElaine Zhang 
15*e54cf6dbSElaine Zhang DECLARE_GLOBAL_DATA_PTR;
16*e54cf6dbSElaine Zhang 
17*e54cf6dbSElaine Zhang /* Voltage setting */
18*e54cf6dbSElaine Zhang #define FAN53555_VSEL0		0x00
19*e54cf6dbSElaine Zhang #define FAN53555_VSEL1		0x01
20*e54cf6dbSElaine Zhang 
21*e54cf6dbSElaine Zhang #define TCS452X_VSEL0		0x11
22*e54cf6dbSElaine Zhang #define TCS452X_VSEL1		0x10
23*e54cf6dbSElaine Zhang #define TCS452X_TIME		0x13
24*e54cf6dbSElaine Zhang #define TCS452X_COMMAND		0x14
25*e54cf6dbSElaine Zhang 
26*e54cf6dbSElaine Zhang /* Control register */
27*e54cf6dbSElaine Zhang #define FAN53555_CONTROL	0x02
28*e54cf6dbSElaine Zhang /* IC Type */
29*e54cf6dbSElaine Zhang #define FAN53555_ID1		0x03
30*e54cf6dbSElaine Zhang /* IC mask version */
31*e54cf6dbSElaine Zhang #define FAN53555_ID2		0x04
32*e54cf6dbSElaine Zhang /* Monitor register */
33*e54cf6dbSElaine Zhang #define FAN53555_MONITOR	0x05
34*e54cf6dbSElaine Zhang 
35*e54cf6dbSElaine Zhang /* VSEL bit definitions */
36*e54cf6dbSElaine Zhang #define VSEL_BUCK_EN		BIT(7)
37*e54cf6dbSElaine Zhang #define VSEL_MODE		BIT(6)
38*e54cf6dbSElaine Zhang #define VSEL_NSEL_MASK		0x3F
39*e54cf6dbSElaine Zhang 
40*e54cf6dbSElaine Zhang /* Chip ID and Version */
41*e54cf6dbSElaine Zhang #define DIE_ID			0x0F/* ID1 */
42*e54cf6dbSElaine Zhang #define DIE_REV			0x0F/* ID2 */
43*e54cf6dbSElaine Zhang /* Control bit definitions */
44*e54cf6dbSElaine Zhang #define CTL_OUTPUT_DISCHG	BIT(7)
45*e54cf6dbSElaine Zhang #define CTL_SLEW_MASK		(0x7 << 4)
46*e54cf6dbSElaine Zhang #define CTL_SLEW_SHIFT		4
47*e54cf6dbSElaine Zhang #define CTL_RESET		BIT(2)
48*e54cf6dbSElaine Zhang 
49*e54cf6dbSElaine Zhang #define TCS_VSEL_NSEL_MASK	0x7f
50*e54cf6dbSElaine Zhang #define TCS_VSEL0_MODE		BIT(7)
51*e54cf6dbSElaine Zhang #define TCS_VSEL1_MODE		BIT(6)
52*e54cf6dbSElaine Zhang 
53*e54cf6dbSElaine Zhang #define TCS_SLEW_SHIFT		3
54*e54cf6dbSElaine Zhang #define TCS_SLEW_MASK		(0x3 < 3)
55*e54cf6dbSElaine Zhang 
56*e54cf6dbSElaine Zhang #define FAN53555_NVOLTAGES_64	64/* Numbers of voltages */
57*e54cf6dbSElaine Zhang #define FAN53555_NVOLTAGES_127	127/* Numbers of voltages */
58*e54cf6dbSElaine Zhang 
59*e54cf6dbSElaine Zhang enum fan53555_vendor {
60*e54cf6dbSElaine Zhang 	FAN53555_VENDOR_FAIRCHILD = 0,
61*e54cf6dbSElaine Zhang 	FAN53555_VENDOR_SILERGY,
62*e54cf6dbSElaine Zhang 	FAN53555_VENDOR_TCS,
63*e54cf6dbSElaine Zhang };
64*e54cf6dbSElaine Zhang 
65*e54cf6dbSElaine Zhang /* IC Type */
66*e54cf6dbSElaine Zhang enum {
67*e54cf6dbSElaine Zhang 	FAN53555_CHIP_ID_00 = 0,
68*e54cf6dbSElaine Zhang 	FAN53555_CHIP_ID_01,
69*e54cf6dbSElaine Zhang 	FAN53555_CHIP_ID_02,
70*e54cf6dbSElaine Zhang 	FAN53555_CHIP_ID_03,
71*e54cf6dbSElaine Zhang 	FAN53555_CHIP_ID_04,
72*e54cf6dbSElaine Zhang 	FAN53555_CHIP_ID_05,
73*e54cf6dbSElaine Zhang 	FAN53555_CHIP_ID_08 = 8,
74*e54cf6dbSElaine Zhang };
75*e54cf6dbSElaine Zhang 
76*e54cf6dbSElaine Zhang /* IC mask revision */
77*e54cf6dbSElaine Zhang enum {
78*e54cf6dbSElaine Zhang 	FAN53555_CHIP_REV_00 = 0x3,
79*e54cf6dbSElaine Zhang 	FAN53555_CHIP_REV_13 = 0xf,
80*e54cf6dbSElaine Zhang };
81*e54cf6dbSElaine Zhang 
82*e54cf6dbSElaine Zhang enum {
83*e54cf6dbSElaine Zhang 	SILERGY_SYR82X = 8,
84*e54cf6dbSElaine Zhang };
85*e54cf6dbSElaine Zhang 
86*e54cf6dbSElaine Zhang enum {
87*e54cf6dbSElaine Zhang 	FAN53555_VSEL_ID_0 = 0,
88*e54cf6dbSElaine Zhang 	FAN53555_VSEL_ID_1,
89*e54cf6dbSElaine Zhang };
90*e54cf6dbSElaine Zhang 
91*e54cf6dbSElaine Zhang struct fan53555_regulator_info {
92*e54cf6dbSElaine Zhang 	enum fan53555_vendor vendor;
93*e54cf6dbSElaine Zhang 	struct udevice *dev;
94*e54cf6dbSElaine Zhang 	/* IC Type and Rev */
95*e54cf6dbSElaine Zhang 	int chip_id;
96*e54cf6dbSElaine Zhang 	int chip_rev;
97*e54cf6dbSElaine Zhang 	/* Voltage setting register */
98*e54cf6dbSElaine Zhang 	unsigned int vol_reg;
99*e54cf6dbSElaine Zhang 	unsigned int sleep_reg;
100*e54cf6dbSElaine Zhang 	unsigned int mode_reg;
101*e54cf6dbSElaine Zhang 	unsigned int vol_mask;
102*e54cf6dbSElaine Zhang 	unsigned int mode_mask;
103*e54cf6dbSElaine Zhang 	/* Voltage range and step(linear) */
104*e54cf6dbSElaine Zhang 	unsigned int vsel_min;
105*e54cf6dbSElaine Zhang 	unsigned int vsel_step;
106*e54cf6dbSElaine Zhang 	struct gpio_desc vsel_gpio;
107*e54cf6dbSElaine Zhang 	unsigned int sleep_vsel_id;
108*e54cf6dbSElaine Zhang };
109*e54cf6dbSElaine Zhang 
fan53555_write(struct udevice * dev,uint reg,const uint8_t * buff,int len)110*e54cf6dbSElaine Zhang static int fan53555_write(struct udevice *dev, uint reg, const uint8_t *buff,
111*e54cf6dbSElaine Zhang 			  int len)
112*e54cf6dbSElaine Zhang {
113*e54cf6dbSElaine Zhang 	int ret;
114*e54cf6dbSElaine Zhang 
115*e54cf6dbSElaine Zhang 	ret = dm_i2c_write(dev, reg, buff, len);
116*e54cf6dbSElaine Zhang 	if (ret) {
117*e54cf6dbSElaine Zhang 		debug("%s: write reg 0x%02x failed, ret=%d\n",
118*e54cf6dbSElaine Zhang 		      __func__, reg, ret);
119*e54cf6dbSElaine Zhang 		return ret;
120*e54cf6dbSElaine Zhang 	}
121*e54cf6dbSElaine Zhang 
122*e54cf6dbSElaine Zhang 	return 0;
123*e54cf6dbSElaine Zhang }
124*e54cf6dbSElaine Zhang 
fan53555_read(struct udevice * dev,uint reg,uint8_t * buff,int len)125*e54cf6dbSElaine Zhang static int fan53555_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
126*e54cf6dbSElaine Zhang {
127*e54cf6dbSElaine Zhang 	int ret;
128*e54cf6dbSElaine Zhang 
129*e54cf6dbSElaine Zhang 	ret = dm_i2c_read(dev, reg, buff, len);
130*e54cf6dbSElaine Zhang 	if (ret) {
131*e54cf6dbSElaine Zhang 		debug("%s: read reg 0x%02x failed, ret=%d\n",
132*e54cf6dbSElaine Zhang 		      __func__, reg, ret);
133*e54cf6dbSElaine Zhang 		return ret;
134*e54cf6dbSElaine Zhang 	}
135*e54cf6dbSElaine Zhang 
136*e54cf6dbSElaine Zhang 	return 0;
137*e54cf6dbSElaine Zhang }
138*e54cf6dbSElaine Zhang 
fan53555_reg_read(struct udevice * dev,uint reg)139*e54cf6dbSElaine Zhang int fan53555_reg_read(struct udevice *dev, uint reg)
140*e54cf6dbSElaine Zhang {
141*e54cf6dbSElaine Zhang 	u8 byte;
142*e54cf6dbSElaine Zhang 	int ret;
143*e54cf6dbSElaine Zhang 
144*e54cf6dbSElaine Zhang 	debug("%s: reg=%x", __func__, reg);
145*e54cf6dbSElaine Zhang 	ret = fan53555_read(dev, reg, &byte, 1);
146*e54cf6dbSElaine Zhang 	debug(", value=%x, ret=%d\n", byte, ret);
147*e54cf6dbSElaine Zhang 
148*e54cf6dbSElaine Zhang 	return ret ? ret : byte;
149*e54cf6dbSElaine Zhang }
150*e54cf6dbSElaine Zhang 
fan53555_reg_write(struct udevice * dev,uint reg,uint value)151*e54cf6dbSElaine Zhang int fan53555_reg_write(struct udevice *dev, uint reg, uint value)
152*e54cf6dbSElaine Zhang {
153*e54cf6dbSElaine Zhang 	u8 byte = value;
154*e54cf6dbSElaine Zhang 	int ret;
155*e54cf6dbSElaine Zhang 
156*e54cf6dbSElaine Zhang 	debug("%s: reg=%x, value=%x", __func__, reg, value);
157*e54cf6dbSElaine Zhang 	ret = fan53555_write(dev, reg, &byte, 1);
158*e54cf6dbSElaine Zhang 	debug(", ret=%d\n", ret);
159*e54cf6dbSElaine Zhang 
160*e54cf6dbSElaine Zhang 	return ret;
161*e54cf6dbSElaine Zhang }
162*e54cf6dbSElaine Zhang 
fan53555_clrsetbits(struct udevice * dev,uint reg,uint clr,uint set)163*e54cf6dbSElaine Zhang int  fan53555_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
164*e54cf6dbSElaine Zhang {
165*e54cf6dbSElaine Zhang 	u8 byte;
166*e54cf6dbSElaine Zhang 	int ret;
167*e54cf6dbSElaine Zhang 
168*e54cf6dbSElaine Zhang 	ret = fan53555_reg_read(dev, reg);
169*e54cf6dbSElaine Zhang 	if (ret < 0)
170*e54cf6dbSElaine Zhang 		return ret;
171*e54cf6dbSElaine Zhang 	byte = (ret & ~clr) | set;
172*e54cf6dbSElaine Zhang 
173*e54cf6dbSElaine Zhang 	return fan53555_reg_write(dev, reg, byte);
174*e54cf6dbSElaine Zhang }
175*e54cf6dbSElaine Zhang 
fan53555_regulator_set_enable(struct udevice * dev,bool enable)176*e54cf6dbSElaine Zhang static int fan53555_regulator_set_enable(struct udevice *dev, bool enable)
177*e54cf6dbSElaine Zhang {
178*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *priv = dev_get_priv(dev);
179*e54cf6dbSElaine Zhang 	int val, sleep_vsel_id;
180*e54cf6dbSElaine Zhang 
181*e54cf6dbSElaine Zhang 	if (enable) {
182*e54cf6dbSElaine Zhang 		val = VSEL_BUCK_EN;
183*e54cf6dbSElaine Zhang 		sleep_vsel_id = !priv->sleep_vsel_id;
184*e54cf6dbSElaine Zhang 	} else {
185*e54cf6dbSElaine Zhang 		val = 0;
186*e54cf6dbSElaine Zhang 		sleep_vsel_id = priv->sleep_vsel_id;
187*e54cf6dbSElaine Zhang 	}
188*e54cf6dbSElaine Zhang 
189*e54cf6dbSElaine Zhang 	if (dm_gpio_is_valid(&priv->vsel_gpio)) {
190*e54cf6dbSElaine Zhang 		dm_gpio_set_value(&priv->vsel_gpio, sleep_vsel_id);
191*e54cf6dbSElaine Zhang 		return 0;
192*e54cf6dbSElaine Zhang 	}
193*e54cf6dbSElaine Zhang 	fan53555_clrsetbits(dev, priv->vol_reg, VSEL_BUCK_EN, val);
194*e54cf6dbSElaine Zhang 
195*e54cf6dbSElaine Zhang 	return 0;
196*e54cf6dbSElaine Zhang }
197*e54cf6dbSElaine Zhang 
fan53555_regulator_get_enable(struct udevice * dev)198*e54cf6dbSElaine Zhang static int fan53555_regulator_get_enable(struct udevice *dev)
199*e54cf6dbSElaine Zhang {
200*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *priv = dev_get_priv(dev);
201*e54cf6dbSElaine Zhang 	int val;
202*e54cf6dbSElaine Zhang 
203*e54cf6dbSElaine Zhang 	if (dm_gpio_is_valid(&priv->vsel_gpio)) {
204*e54cf6dbSElaine Zhang 		if (priv->sleep_vsel_id)
205*e54cf6dbSElaine Zhang 			return !dm_gpio_get_value(&priv->vsel_gpio);
206*e54cf6dbSElaine Zhang 		else
207*e54cf6dbSElaine Zhang 			return dm_gpio_get_value(&priv->vsel_gpio);
208*e54cf6dbSElaine Zhang 	}
209*e54cf6dbSElaine Zhang 
210*e54cf6dbSElaine Zhang 	val = fan53555_reg_read(dev, priv->vol_reg);
211*e54cf6dbSElaine Zhang 	if (val & VSEL_BUCK_EN)
212*e54cf6dbSElaine Zhang 		return 1;
213*e54cf6dbSElaine Zhang 	else
214*e54cf6dbSElaine Zhang 		return 0;
215*e54cf6dbSElaine Zhang }
216*e54cf6dbSElaine Zhang 
fan53555_regulator_set_suspend_enable(struct udevice * dev,bool enable)217*e54cf6dbSElaine Zhang static int fan53555_regulator_set_suspend_enable(struct udevice *dev,
218*e54cf6dbSElaine Zhang 						 bool enable)
219*e54cf6dbSElaine Zhang {
220*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *priv = dev_get_priv(dev);
221*e54cf6dbSElaine Zhang 	int val;
222*e54cf6dbSElaine Zhang 
223*e54cf6dbSElaine Zhang 	if (enable)
224*e54cf6dbSElaine Zhang 		val = VSEL_BUCK_EN;
225*e54cf6dbSElaine Zhang 	else
226*e54cf6dbSElaine Zhang 		val = 0;
227*e54cf6dbSElaine Zhang 
228*e54cf6dbSElaine Zhang 	fan53555_clrsetbits(dev, priv->sleep_reg, VSEL_BUCK_EN, val);
229*e54cf6dbSElaine Zhang 
230*e54cf6dbSElaine Zhang 	return 0;
231*e54cf6dbSElaine Zhang }
232*e54cf6dbSElaine Zhang 
fan53555_regulator_get_suspend_enable(struct udevice * dev)233*e54cf6dbSElaine Zhang static int fan53555_regulator_get_suspend_enable(struct udevice *dev)
234*e54cf6dbSElaine Zhang {
235*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *priv = dev_get_priv(dev);
236*e54cf6dbSElaine Zhang 	int val;
237*e54cf6dbSElaine Zhang 
238*e54cf6dbSElaine Zhang 	val = fan53555_reg_read(dev, priv->sleep_reg);
239*e54cf6dbSElaine Zhang 	if (val & VSEL_BUCK_EN)
240*e54cf6dbSElaine Zhang 		return 1;
241*e54cf6dbSElaine Zhang 	else
242*e54cf6dbSElaine Zhang 		return 0;
243*e54cf6dbSElaine Zhang }
244*e54cf6dbSElaine Zhang 
fan53555_regulator_get_voltage(struct udevice * dev)245*e54cf6dbSElaine Zhang static int fan53555_regulator_get_voltage(struct udevice *dev)
246*e54cf6dbSElaine Zhang {
247*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *priv = dev_get_priv(dev);
248*e54cf6dbSElaine Zhang 	int uvolt = 0, val;
249*e54cf6dbSElaine Zhang 
250*e54cf6dbSElaine Zhang 	val = fan53555_reg_read(dev, priv->vol_reg);
251*e54cf6dbSElaine Zhang 	val &= priv->vol_mask;
252*e54cf6dbSElaine Zhang 	uvolt = (val * priv->vsel_step) + priv->vsel_min;
253*e54cf6dbSElaine Zhang 
254*e54cf6dbSElaine Zhang 	return uvolt;
255*e54cf6dbSElaine Zhang }
256*e54cf6dbSElaine Zhang 
fan53555_regulator_set_voltage(struct udevice * dev,int uvolt)257*e54cf6dbSElaine Zhang static int fan53555_regulator_set_voltage(struct udevice *dev, int uvolt)
258*e54cf6dbSElaine Zhang {
259*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *priv = dev_get_priv(dev);
260*e54cf6dbSElaine Zhang 	int val;
261*e54cf6dbSElaine Zhang 
262*e54cf6dbSElaine Zhang 	val = ((uvolt - priv->vsel_min) / priv->vsel_step);
263*e54cf6dbSElaine Zhang 	fan53555_clrsetbits(dev, priv->vol_reg, priv->vol_mask, val);
264*e54cf6dbSElaine Zhang 
265*e54cf6dbSElaine Zhang 	return 0;
266*e54cf6dbSElaine Zhang }
267*e54cf6dbSElaine Zhang 
fan53555_regulator_get_suspend_voltage(struct udevice * dev)268*e54cf6dbSElaine Zhang static int fan53555_regulator_get_suspend_voltage(struct udevice *dev)
269*e54cf6dbSElaine Zhang {
270*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *priv = dev_get_priv(dev);
271*e54cf6dbSElaine Zhang 	int uvolt = 0, val;
272*e54cf6dbSElaine Zhang 
273*e54cf6dbSElaine Zhang 	val = fan53555_reg_read(dev, priv->sleep_reg);
274*e54cf6dbSElaine Zhang 	val &= priv->vol_mask;
275*e54cf6dbSElaine Zhang 	uvolt = (val * priv->vsel_step) + priv->vsel_min;
276*e54cf6dbSElaine Zhang 
277*e54cf6dbSElaine Zhang 	return uvolt;
278*e54cf6dbSElaine Zhang }
279*e54cf6dbSElaine Zhang 
fan53555_regulator_set_suspend_voltage(struct udevice * dev,int uvolt)280*e54cf6dbSElaine Zhang static int fan53555_regulator_set_suspend_voltage(struct udevice *dev,
281*e54cf6dbSElaine Zhang 						  int uvolt)
282*e54cf6dbSElaine Zhang {
283*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *priv = dev_get_priv(dev);
284*e54cf6dbSElaine Zhang 	int val;
285*e54cf6dbSElaine Zhang 
286*e54cf6dbSElaine Zhang 	val = ((uvolt - priv->vsel_min) / priv->vsel_step);
287*e54cf6dbSElaine Zhang 	fan53555_clrsetbits(dev, priv->sleep_reg, priv->vol_mask, val);
288*e54cf6dbSElaine Zhang 
289*e54cf6dbSElaine Zhang 	return 0;
290*e54cf6dbSElaine Zhang }
291*e54cf6dbSElaine Zhang 
fan53555_voltages_setup_fairchild(struct fan53555_regulator_info * di)292*e54cf6dbSElaine Zhang static int fan53555_voltages_setup_fairchild(struct fan53555_regulator_info *di)
293*e54cf6dbSElaine Zhang {
294*e54cf6dbSElaine Zhang 	/* Init voltage range and step */
295*e54cf6dbSElaine Zhang 	switch (di->chip_id) {
296*e54cf6dbSElaine Zhang 	case FAN53555_CHIP_ID_00:
297*e54cf6dbSElaine Zhang 		switch (di->chip_rev) {
298*e54cf6dbSElaine Zhang 		case FAN53555_CHIP_REV_00:
299*e54cf6dbSElaine Zhang 			di->vsel_min = 600000;
300*e54cf6dbSElaine Zhang 			di->vsel_step = 10000;
301*e54cf6dbSElaine Zhang 			break;
302*e54cf6dbSElaine Zhang 		case FAN53555_CHIP_REV_13:
303*e54cf6dbSElaine Zhang 			di->vsel_min = 800000;
304*e54cf6dbSElaine Zhang 			di->vsel_step = 10000;
305*e54cf6dbSElaine Zhang 			break;
306*e54cf6dbSElaine Zhang 		default:
307*e54cf6dbSElaine Zhang 			dev_err(di->dev,
308*e54cf6dbSElaine Zhang 				"Chip ID %d with rev %d not supported!\n",
309*e54cf6dbSElaine Zhang 				di->chip_id, di->chip_rev);
310*e54cf6dbSElaine Zhang 			return -EINVAL;
311*e54cf6dbSElaine Zhang 		}
312*e54cf6dbSElaine Zhang 		break;
313*e54cf6dbSElaine Zhang 	case FAN53555_CHIP_ID_01:
314*e54cf6dbSElaine Zhang 	case FAN53555_CHIP_ID_03:
315*e54cf6dbSElaine Zhang 	case FAN53555_CHIP_ID_05:
316*e54cf6dbSElaine Zhang 	case FAN53555_CHIP_ID_08:
317*e54cf6dbSElaine Zhang 		di->vsel_min = 600000;
318*e54cf6dbSElaine Zhang 		di->vsel_step = 10000;
319*e54cf6dbSElaine Zhang 		break;
320*e54cf6dbSElaine Zhang 	case FAN53555_CHIP_ID_04:
321*e54cf6dbSElaine Zhang 		di->vsel_min = 603000;
322*e54cf6dbSElaine Zhang 		di->vsel_step = 12826;
323*e54cf6dbSElaine Zhang 		break;
324*e54cf6dbSElaine Zhang 	default:
325*e54cf6dbSElaine Zhang 		dev_err(di->dev,
326*e54cf6dbSElaine Zhang 			"Chip ID %d not supported!\n", di->chip_id);
327*e54cf6dbSElaine Zhang 		return -EINVAL;
328*e54cf6dbSElaine Zhang 	}
329*e54cf6dbSElaine Zhang 	di->vol_mask = VSEL_NSEL_MASK;
330*e54cf6dbSElaine Zhang 
331*e54cf6dbSElaine Zhang 	return 0;
332*e54cf6dbSElaine Zhang }
333*e54cf6dbSElaine Zhang 
fan53555_voltages_setup_silergy(struct fan53555_regulator_info * di)334*e54cf6dbSElaine Zhang static int fan53555_voltages_setup_silergy(struct fan53555_regulator_info *di)
335*e54cf6dbSElaine Zhang {
336*e54cf6dbSElaine Zhang 	/* Init voltage range and step */
337*e54cf6dbSElaine Zhang 	di->vsel_min = 712500;
338*e54cf6dbSElaine Zhang 	di->vsel_step = 12500;
339*e54cf6dbSElaine Zhang 	di->vol_mask = VSEL_NSEL_MASK;
340*e54cf6dbSElaine Zhang 
341*e54cf6dbSElaine Zhang 	return 0;
342*e54cf6dbSElaine Zhang }
343*e54cf6dbSElaine Zhang 
fan53555_voltages_setup_tcs(struct fan53555_regulator_info * di)344*e54cf6dbSElaine Zhang static int fan53555_voltages_setup_tcs(struct fan53555_regulator_info *di)
345*e54cf6dbSElaine Zhang {
346*e54cf6dbSElaine Zhang 	if (di->sleep_vsel_id) {
347*e54cf6dbSElaine Zhang 		di->sleep_reg = TCS452X_VSEL1;
348*e54cf6dbSElaine Zhang 		di->vol_reg = TCS452X_VSEL0;
349*e54cf6dbSElaine Zhang 	} else {
350*e54cf6dbSElaine Zhang 		di->sleep_reg = TCS452X_VSEL0;
351*e54cf6dbSElaine Zhang 		di->vol_reg = TCS452X_VSEL1;
352*e54cf6dbSElaine Zhang 	}
353*e54cf6dbSElaine Zhang 
354*e54cf6dbSElaine Zhang 	di->vol_mask = TCS_VSEL_NSEL_MASK;
355*e54cf6dbSElaine Zhang 
356*e54cf6dbSElaine Zhang 	/* Init voltage range and step */
357*e54cf6dbSElaine Zhang 	di->vsel_min = 600000;
358*e54cf6dbSElaine Zhang 	di->vsel_step = 6250;
359*e54cf6dbSElaine Zhang 
360*e54cf6dbSElaine Zhang 	return 0;
361*e54cf6dbSElaine Zhang }
362*e54cf6dbSElaine Zhang 
363*e54cf6dbSElaine Zhang /* For 00,01,03,05 options:
364*e54cf6dbSElaine Zhang  * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V.
365*e54cf6dbSElaine Zhang  * For 04 option:
366*e54cf6dbSElaine Zhang  * VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V.
367*e54cf6dbSElaine Zhang  *
368*e54cf6dbSElaine Zhang  */
369*e54cf6dbSElaine Zhang 
fan53555_device_setup(struct fan53555_regulator_info * di)370*e54cf6dbSElaine Zhang static int fan53555_device_setup(struct fan53555_regulator_info *di)
371*e54cf6dbSElaine Zhang {
372*e54cf6dbSElaine Zhang 	int ret = 0;
373*e54cf6dbSElaine Zhang 
374*e54cf6dbSElaine Zhang 	/* Setup voltage control register */
375*e54cf6dbSElaine Zhang 	switch (di->sleep_vsel_id) {
376*e54cf6dbSElaine Zhang 	case FAN53555_VSEL_ID_0:
377*e54cf6dbSElaine Zhang 		di->sleep_reg = FAN53555_VSEL0;
378*e54cf6dbSElaine Zhang 		di->vol_reg = FAN53555_VSEL1;
379*e54cf6dbSElaine Zhang 		break;
380*e54cf6dbSElaine Zhang 	case FAN53555_VSEL_ID_1:
381*e54cf6dbSElaine Zhang 		di->sleep_reg = FAN53555_VSEL1;
382*e54cf6dbSElaine Zhang 		di->vol_reg = FAN53555_VSEL0;
383*e54cf6dbSElaine Zhang 		break;
384*e54cf6dbSElaine Zhang 	default:
385*e54cf6dbSElaine Zhang 		dev_err(di->dev, "Invalid VSEL ID!\n");
386*e54cf6dbSElaine Zhang 		return -EINVAL;
387*e54cf6dbSElaine Zhang 	}
388*e54cf6dbSElaine Zhang 
389*e54cf6dbSElaine Zhang 	switch (di->vendor) {
390*e54cf6dbSElaine Zhang 	case FAN53555_VENDOR_FAIRCHILD:
391*e54cf6dbSElaine Zhang 		ret = fan53555_voltages_setup_fairchild(di);
392*e54cf6dbSElaine Zhang 		break;
393*e54cf6dbSElaine Zhang 	case FAN53555_VENDOR_SILERGY:
394*e54cf6dbSElaine Zhang 		ret = fan53555_voltages_setup_silergy(di);
395*e54cf6dbSElaine Zhang 		break;
396*e54cf6dbSElaine Zhang 	case FAN53555_VENDOR_TCS:
397*e54cf6dbSElaine Zhang 		ret = fan53555_voltages_setup_tcs(di);
398*e54cf6dbSElaine Zhang 		break;
399*e54cf6dbSElaine Zhang 	default:
400*e54cf6dbSElaine Zhang 		dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
401*e54cf6dbSElaine Zhang 		return -EINVAL;
402*e54cf6dbSElaine Zhang 	}
403*e54cf6dbSElaine Zhang 
404*e54cf6dbSElaine Zhang 	return ret;
405*e54cf6dbSElaine Zhang }
406*e54cf6dbSElaine Zhang 
fan53555_regulator_ofdata_to_platdata(struct udevice * dev)407*e54cf6dbSElaine Zhang static int fan53555_regulator_ofdata_to_platdata(struct udevice *dev)
408*e54cf6dbSElaine Zhang {
409*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *priv = dev_get_priv(dev);
410*e54cf6dbSElaine Zhang 	int ret;
411*e54cf6dbSElaine Zhang 
412*e54cf6dbSElaine Zhang 	priv->sleep_vsel_id = dev_read_u32_default(dev,
413*e54cf6dbSElaine Zhang 						   "fcs,suspend-voltage-selector",
414*e54cf6dbSElaine Zhang 						   1);
415*e54cf6dbSElaine Zhang 
416*e54cf6dbSElaine Zhang 	ret = gpio_request_by_name(dev, "vsel-gpios", 0,
417*e54cf6dbSElaine Zhang 				   &priv->vsel_gpio, GPIOD_IS_OUT);
418*e54cf6dbSElaine Zhang 	if (ret)
419*e54cf6dbSElaine Zhang 		dev_err(dev, "vsel-gpios- not found! Error: %d\n", ret);
420*e54cf6dbSElaine Zhang 
421*e54cf6dbSElaine Zhang 	if (dm_gpio_is_valid(&priv->vsel_gpio))
422*e54cf6dbSElaine Zhang 		dm_gpio_set_value(&priv->vsel_gpio, !priv->sleep_vsel_id);
423*e54cf6dbSElaine Zhang 
424*e54cf6dbSElaine Zhang 	priv->vendor = dev_get_driver_data(dev);
425*e54cf6dbSElaine Zhang 
426*e54cf6dbSElaine Zhang 	return 0;
427*e54cf6dbSElaine Zhang }
428*e54cf6dbSElaine Zhang 
fan53555_regulator_probe(struct udevice * dev)429*e54cf6dbSElaine Zhang static int fan53555_regulator_probe(struct udevice *dev)
430*e54cf6dbSElaine Zhang {
431*e54cf6dbSElaine Zhang 	struct fan53555_regulator_info *di = dev_get_priv(dev);
432*e54cf6dbSElaine Zhang 	struct dm_regulator_uclass_platdata *uc_pdata;
433*e54cf6dbSElaine Zhang 	u8 val;
434*e54cf6dbSElaine Zhang 	int ret;
435*e54cf6dbSElaine Zhang 
436*e54cf6dbSElaine Zhang 	uc_pdata = dev_get_uclass_platdata(dev);
437*e54cf6dbSElaine Zhang 	uc_pdata->type = REGULATOR_TYPE_BUCK;
438*e54cf6dbSElaine Zhang 	uc_pdata->mode_count = 0;
439*e54cf6dbSElaine Zhang 
440*e54cf6dbSElaine Zhang 	/* Get chip ID */
441*e54cf6dbSElaine Zhang 	val = fan53555_reg_read(dev, FAN53555_ID1);
442*e54cf6dbSElaine Zhang 	if (val < 0) {
443*e54cf6dbSElaine Zhang 		dev_err(dev, "Failed to get chip ID!\n");
444*e54cf6dbSElaine Zhang 		return val;
445*e54cf6dbSElaine Zhang 	}
446*e54cf6dbSElaine Zhang 	di->chip_id = val & DIE_ID;
447*e54cf6dbSElaine Zhang 
448*e54cf6dbSElaine Zhang 	/* Get chip revision */
449*e54cf6dbSElaine Zhang 	val = fan53555_reg_read(dev, FAN53555_ID2);
450*e54cf6dbSElaine Zhang 	if (val < 0) {
451*e54cf6dbSElaine Zhang 		dev_err(dev, "Failed to get chip Rev!\n");
452*e54cf6dbSElaine Zhang 		return val;
453*e54cf6dbSElaine Zhang 	}
454*e54cf6dbSElaine Zhang 	di->chip_rev = val & DIE_REV;
455*e54cf6dbSElaine Zhang 
456*e54cf6dbSElaine Zhang 	debug("FAN53555 Option[%d] Rev[%d] Detected!\n",
457*e54cf6dbSElaine Zhang 	      di->chip_id, di->chip_rev);
458*e54cf6dbSElaine Zhang 
459*e54cf6dbSElaine Zhang 	/* Device init */
460*e54cf6dbSElaine Zhang 	ret = fan53555_device_setup(di);
461*e54cf6dbSElaine Zhang 	if (ret < 0) {
462*e54cf6dbSElaine Zhang 		dev_err(dev, "Failed to setup device!\n");
463*e54cf6dbSElaine Zhang 		return ret;
464*e54cf6dbSElaine Zhang 	}
465*e54cf6dbSElaine Zhang 
466*e54cf6dbSElaine Zhang 	return 0;
467*e54cf6dbSElaine Zhang }
468*e54cf6dbSElaine Zhang 
469*e54cf6dbSElaine Zhang static const struct udevice_id fan53555_id[] = {
470*e54cf6dbSElaine Zhang 	{
471*e54cf6dbSElaine Zhang 		.compatible = "fan53555",
472*e54cf6dbSElaine Zhang 		.data = FAN53555_VENDOR_FAIRCHILD,
473*e54cf6dbSElaine Zhang 	}, {
474*e54cf6dbSElaine Zhang 		.compatible = "silergy,syr827",
475*e54cf6dbSElaine Zhang 		.data = FAN53555_VENDOR_SILERGY,
476*e54cf6dbSElaine Zhang 	}, {
477*e54cf6dbSElaine Zhang 		.compatible = "silergy,syr828",
478*e54cf6dbSElaine Zhang 		.data = FAN53555_VENDOR_SILERGY,
479*e54cf6dbSElaine Zhang 	}, {
480*e54cf6dbSElaine Zhang 		.compatible = "tcs,tcs452x", /* tcs4525/4526 */
481*e54cf6dbSElaine Zhang 		.data = FAN53555_VENDOR_TCS,
482*e54cf6dbSElaine Zhang 	},
483*e54cf6dbSElaine Zhang 	{ },
484*e54cf6dbSElaine Zhang };
485*e54cf6dbSElaine Zhang 
486*e54cf6dbSElaine Zhang static const struct dm_regulator_ops fan53555_regulator_ops = {
487*e54cf6dbSElaine Zhang 	.get_value  = fan53555_regulator_get_voltage,
488*e54cf6dbSElaine Zhang 	.set_value  = fan53555_regulator_set_voltage,
489*e54cf6dbSElaine Zhang 	.set_suspend_value = fan53555_regulator_set_suspend_voltage,
490*e54cf6dbSElaine Zhang 	.get_suspend_value = fan53555_regulator_get_suspend_voltage,
491*e54cf6dbSElaine Zhang 	.set_enable = fan53555_regulator_set_enable,
492*e54cf6dbSElaine Zhang 	.get_enable = fan53555_regulator_get_enable,
493*e54cf6dbSElaine Zhang 	.set_suspend_enable = fan53555_regulator_set_suspend_enable,
494*e54cf6dbSElaine Zhang 	.get_suspend_enable = fan53555_regulator_get_suspend_enable,
495*e54cf6dbSElaine Zhang };
496*e54cf6dbSElaine Zhang 
497*e54cf6dbSElaine Zhang U_BOOT_DRIVER(fan53555_regulator) = {
498*e54cf6dbSElaine Zhang 	.name = "fan53555_regulator",
499*e54cf6dbSElaine Zhang 	.id = UCLASS_REGULATOR,
500*e54cf6dbSElaine Zhang 	.ops = &fan53555_regulator_ops,
501*e54cf6dbSElaine Zhang 	.probe = fan53555_regulator_probe,
502*e54cf6dbSElaine Zhang 	.of_match = fan53555_id,
503*e54cf6dbSElaine Zhang 	.ofdata_to_platdata = fan53555_regulator_ofdata_to_platdata,
504*e54cf6dbSElaine Zhang 	.priv_auto_alloc_size = sizeof(struct fan53555_regulator_info),
505*e54cf6dbSElaine Zhang };
506*e54cf6dbSElaine Zhang 
507