xref: /rk3399_rockchip-uboot/drivers/power/regulator/rk860x_regulator.c (revision 4474bc1daa676d583b87fbb3c2ee98b7cea01c93)
1a09f237bSElaine Zhang // SPDX-License-Identifier: GPL-2.0
2a09f237bSElaine Zhang /*
3a09f237bSElaine Zhang  * Copyright (c) 2021 Rockchip Electronics Co., Ltd
4a09f237bSElaine Zhang  */
5a09f237bSElaine Zhang #include <common.h>
6a09f237bSElaine Zhang #include <dm.h>
7a09f237bSElaine Zhang #include <errno.h>
8a09f237bSElaine Zhang #include <i2c.h>
9a09f237bSElaine Zhang #include <syscon.h>
10a09f237bSElaine Zhang #include <asm/gpio.h>
11a09f237bSElaine Zhang #include <power/regulator.h>
12a09f237bSElaine Zhang #include <asm/arch/clock.h>
13a09f237bSElaine Zhang #include <asm/io.h>
14a09f237bSElaine Zhang 
15a09f237bSElaine Zhang DECLARE_GLOBAL_DATA_PTR;
16a09f237bSElaine Zhang 
17a09f237bSElaine Zhang /* Voltage setting */
18a09f237bSElaine Zhang 
19a09f237bSElaine Zhang #define RK860X_VSEL0_A		0x00
20a09f237bSElaine Zhang #define RK860X_VSEL1_A		0x01
21a09f237bSElaine Zhang #define RK860X_VSEL0_B		0x06
22a09f237bSElaine Zhang #define RK860X_VSEL1_B		0x07
23a09f237bSElaine Zhang #define RK860X_MAX_SET		0x08
24a09f237bSElaine Zhang 
25a09f237bSElaine Zhang /* Control register */
26a09f237bSElaine Zhang #define RK860X_CONTROL		0x02
27a09f237bSElaine Zhang /* IC Type */
28a09f237bSElaine Zhang #define RK860X_ID1		0x03
29a09f237bSElaine Zhang /* IC mask version */
30a09f237bSElaine Zhang #define RK860X_ID2		0x04
31a09f237bSElaine Zhang /* Monitor register */
32a09f237bSElaine Zhang #define RK860X_MONITOR		0x05
33a09f237bSElaine Zhang 
34a09f237bSElaine Zhang /* VSEL bit definitions */
35a09f237bSElaine Zhang #define VSEL_BUCK_EN		BIT(7)
36a09f237bSElaine Zhang #define VSEL_MODE		BIT(6)
37a09f237bSElaine Zhang #define VSEL_A_NSEL_MASK	0x3F
38a09f237bSElaine Zhang #define VSEL_B_NSEL_MASK	0xff
39a09f237bSElaine Zhang 
40a09f237bSElaine Zhang /* Chip ID */
41a09f237bSElaine Zhang #define DIE_ID			0x0F
42a09f237bSElaine Zhang #define DIE_REV			0x0F
43a09f237bSElaine Zhang /* Control bit definitions */
44a09f237bSElaine Zhang #define CTL_OUTPUT_DISCHG	BIT(7)
45a09f237bSElaine Zhang #define CTL_SLEW_MASK		(0x7 << 4)
46a09f237bSElaine Zhang #define CTL_SLEW_SHIFT		4
47a09f237bSElaine Zhang #define CTL_RESET		BIT(2)
48a09f237bSElaine Zhang 
49a09f237bSElaine Zhang #define RK860X_NVOLTAGES_64	64
50a09f237bSElaine Zhang #define RK860X_NVOLTAGES_160	160
51a09f237bSElaine Zhang 
52a09f237bSElaine Zhang /* IC Type */
53a09f237bSElaine Zhang enum {
54a09f237bSElaine Zhang 	RK860X_CHIP_ID_00 = 0,
55a09f237bSElaine Zhang 	RK860X_CHIP_ID_01,
56a09f237bSElaine Zhang 	RK860X_CHIP_ID_02,
57a09f237bSElaine Zhang 	RK860X_CHIP_ID_03,
58a09f237bSElaine Zhang };
59a09f237bSElaine Zhang 
60a09f237bSElaine Zhang struct rk860x_regulator_info {
61a09f237bSElaine Zhang 	struct udevice *dev;
62a09f237bSElaine Zhang 	/* IC Type and Rev */
63a09f237bSElaine Zhang 	int chip_id;
64a09f237bSElaine Zhang 	/* Voltage setting register */
65a09f237bSElaine Zhang 	unsigned int vol_reg;
66a09f237bSElaine Zhang 	unsigned int sleep_reg;
67a09f237bSElaine Zhang 	unsigned int en_reg;
68a09f237bSElaine Zhang 	unsigned int sleep_en_reg;
69a09f237bSElaine Zhang 	unsigned int mode_reg;
70a09f237bSElaine Zhang 	unsigned int vol_mask;
71a09f237bSElaine Zhang 	unsigned int mode_mask;
72a09f237bSElaine Zhang 	unsigned int n_voltages;
73a09f237bSElaine Zhang 	/* Voltage range and step(linear) */
74a09f237bSElaine Zhang 	unsigned int vsel_min;
75a09f237bSElaine Zhang 	unsigned int vsel_step;
76a09f237bSElaine Zhang 	struct gpio_desc vsel_gpio;
77a09f237bSElaine Zhang 	struct gpio_desc en_gpio;
78a09f237bSElaine Zhang 	unsigned int sleep_vsel_id;
79a09f237bSElaine Zhang };
80a09f237bSElaine Zhang 
rk860x_write(struct udevice * dev,uint reg,const uint8_t * buff,int len)81a09f237bSElaine Zhang static int rk860x_write(struct udevice *dev, uint reg, const uint8_t *buff,
82a09f237bSElaine Zhang 			int len)
83a09f237bSElaine Zhang {
84a09f237bSElaine Zhang 	int ret;
85a09f237bSElaine Zhang 
86a09f237bSElaine Zhang 	ret = dm_i2c_write(dev, reg, buff, len);
87a09f237bSElaine Zhang 	if (ret) {
88*4474bc1dSshengfei Xu 		dev_err(dev, "write reg[0x%02x] failed, ret=%d\n", reg, ret);
89a09f237bSElaine Zhang 		return ret;
90a09f237bSElaine Zhang 	}
91a09f237bSElaine Zhang 
92a09f237bSElaine Zhang 	return 0;
93a09f237bSElaine Zhang }
94a09f237bSElaine Zhang 
rk860x_read(struct udevice * dev,uint reg,uint8_t * buff,int len)95a09f237bSElaine Zhang static int rk860x_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
96a09f237bSElaine Zhang {
97a09f237bSElaine Zhang 	int ret;
98a09f237bSElaine Zhang 
99a09f237bSElaine Zhang 	ret = dm_i2c_read(dev, reg, buff, len);
100a09f237bSElaine Zhang 	if (ret) {
101*4474bc1dSshengfei Xu 		dev_err(dev, "read reg[0x%02x] failed, ret=%d\n", reg, ret);
102a09f237bSElaine Zhang 		return ret;
103a09f237bSElaine Zhang 	}
104a09f237bSElaine Zhang 
105a09f237bSElaine Zhang 	return 0;
106a09f237bSElaine Zhang }
107a09f237bSElaine Zhang 
rk860x_reg_read(struct udevice * dev,uint reg,u8 * val)108*4474bc1dSshengfei Xu static int rk860x_reg_read(struct udevice *dev, uint reg, u8 *val)
109a09f237bSElaine Zhang {
110a09f237bSElaine Zhang 	int ret;
111a09f237bSElaine Zhang 
112a09f237bSElaine Zhang 	debug("%s: reg=%x", __func__, reg);
113*4474bc1dSshengfei Xu 	ret = rk860x_read(dev, reg, val, 1);
114*4474bc1dSshengfei Xu 	debug(", value=%x, ret=%d\n", *val, ret);
115a09f237bSElaine Zhang 
116*4474bc1dSshengfei Xu 	return ret;
117a09f237bSElaine Zhang }
118a09f237bSElaine Zhang 
rk860x_reg_write(struct udevice * dev,uint reg,uint value)119*4474bc1dSshengfei Xu static int rk860x_reg_write(struct udevice *dev, uint reg, uint value)
120a09f237bSElaine Zhang {
121a09f237bSElaine Zhang 	u8 byte = value;
122a09f237bSElaine Zhang 	int ret;
123a09f237bSElaine Zhang 
124a09f237bSElaine Zhang 	debug("%s: reg=%x, value=%x", __func__, reg, value);
125a09f237bSElaine Zhang 	ret = rk860x_write(dev, reg, &byte, 1);
126a09f237bSElaine Zhang 	debug(", ret=%d\n", ret);
127a09f237bSElaine Zhang 
128a09f237bSElaine Zhang 	return ret;
129a09f237bSElaine Zhang }
130a09f237bSElaine Zhang 
rk860x_clrsetbits(struct udevice * dev,uint reg,uint clr,uint set)131*4474bc1dSshengfei Xu static int  rk860x_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
132a09f237bSElaine Zhang {
133*4474bc1dSshengfei Xu 	u8 byte, val;
134a09f237bSElaine Zhang 	int ret;
135a09f237bSElaine Zhang 
136*4474bc1dSshengfei Xu 	ret = rk860x_reg_read(dev, reg, &val);
137a09f237bSElaine Zhang 	if (ret < 0)
138a09f237bSElaine Zhang 		return ret;
139*4474bc1dSshengfei Xu 
140*4474bc1dSshengfei Xu 	byte = (val & ~clr) | set;
141a09f237bSElaine Zhang 
142a09f237bSElaine Zhang 	return rk860x_reg_write(dev, reg, byte);
143a09f237bSElaine Zhang }
144a09f237bSElaine Zhang 
rk860x_regulator_set_enable(struct udevice * dev,bool enable)145a09f237bSElaine Zhang static int rk860x_regulator_set_enable(struct udevice *dev, bool enable)
146a09f237bSElaine Zhang {
147a09f237bSElaine Zhang 	struct rk860x_regulator_info *priv = dev_get_priv(dev);
148a09f237bSElaine Zhang 	int val, sleep_vsel_id;
149a09f237bSElaine Zhang 
150a09f237bSElaine Zhang 	if (enable) {
151a09f237bSElaine Zhang 		val = VSEL_BUCK_EN;
152a09f237bSElaine Zhang 		sleep_vsel_id = !priv->sleep_vsel_id;
153a09f237bSElaine Zhang 	} else {
154a09f237bSElaine Zhang 		val = 0;
155a09f237bSElaine Zhang 		sleep_vsel_id = priv->sleep_vsel_id;
156a09f237bSElaine Zhang 	}
157a09f237bSElaine Zhang 
158a09f237bSElaine Zhang 	if (dm_gpio_is_valid(&priv->vsel_gpio)) {
159a09f237bSElaine Zhang 		dm_gpio_set_value(&priv->vsel_gpio, sleep_vsel_id);
160a09f237bSElaine Zhang 		return 0;
161a09f237bSElaine Zhang 	}
162a09f237bSElaine Zhang 	rk860x_clrsetbits(dev, priv->en_reg, VSEL_BUCK_EN, val);
163a09f237bSElaine Zhang 
164a09f237bSElaine Zhang 	return 0;
165a09f237bSElaine Zhang }
166a09f237bSElaine Zhang 
rk860x_regulator_get_enable(struct udevice * dev)167a09f237bSElaine Zhang static int rk860x_regulator_get_enable(struct udevice *dev)
168a09f237bSElaine Zhang {
169a09f237bSElaine Zhang 	struct rk860x_regulator_info *priv = dev_get_priv(dev);
170*4474bc1dSshengfei Xu 	u8 val;
171*4474bc1dSshengfei Xu 	int ret;
172a09f237bSElaine Zhang 
173a09f237bSElaine Zhang 	if (dm_gpio_is_valid(&priv->vsel_gpio)) {
174a09f237bSElaine Zhang 		if (priv->sleep_vsel_id)
175a09f237bSElaine Zhang 			return !dm_gpio_get_value(&priv->vsel_gpio);
176a09f237bSElaine Zhang 		else
177a09f237bSElaine Zhang 			return dm_gpio_get_value(&priv->vsel_gpio);
178a09f237bSElaine Zhang 	}
179a09f237bSElaine Zhang 
180*4474bc1dSshengfei Xu 	ret = rk860x_reg_read(dev, priv->en_reg, &val);
181*4474bc1dSshengfei Xu 	if (ret)
182*4474bc1dSshengfei Xu 		return ret;
183*4474bc1dSshengfei Xu 
184a09f237bSElaine Zhang 	if (val & VSEL_BUCK_EN)
185a09f237bSElaine Zhang 		return 1;
186a09f237bSElaine Zhang 	else
187a09f237bSElaine Zhang 		return 0;
188a09f237bSElaine Zhang }
189a09f237bSElaine Zhang 
rk860x_regulator_set_suspend_enable(struct udevice * dev,bool enable)190a09f237bSElaine Zhang static int rk860x_regulator_set_suspend_enable(struct udevice *dev,
191a09f237bSElaine Zhang 					       bool enable)
192a09f237bSElaine Zhang {
193a09f237bSElaine Zhang 	struct rk860x_regulator_info *priv = dev_get_priv(dev);
194a09f237bSElaine Zhang 	int val;
195a09f237bSElaine Zhang 
196a09f237bSElaine Zhang 	if (enable)
197a09f237bSElaine Zhang 		val = VSEL_BUCK_EN;
198a09f237bSElaine Zhang 	else
199a09f237bSElaine Zhang 		val = 0;
200a09f237bSElaine Zhang 
201a09f237bSElaine Zhang 	rk860x_clrsetbits(dev, priv->sleep_en_reg, VSEL_BUCK_EN, val);
202a09f237bSElaine Zhang 
203a09f237bSElaine Zhang 	return 0;
204a09f237bSElaine Zhang }
205a09f237bSElaine Zhang 
rk860x_regulator_get_suspend_enable(struct udevice * dev)206a09f237bSElaine Zhang static int rk860x_regulator_get_suspend_enable(struct udevice *dev)
207a09f237bSElaine Zhang {
208a09f237bSElaine Zhang 	struct rk860x_regulator_info *priv = dev_get_priv(dev);
209*4474bc1dSshengfei Xu 	int ret;
210*4474bc1dSshengfei Xu 	u8 val;
211a09f237bSElaine Zhang 
212*4474bc1dSshengfei Xu 	ret = rk860x_reg_read(dev, priv->sleep_en_reg, &val);
213*4474bc1dSshengfei Xu 	if (ret)
214*4474bc1dSshengfei Xu 		return ret;
215*4474bc1dSshengfei Xu 
216a09f237bSElaine Zhang 	if (val & VSEL_BUCK_EN)
217a09f237bSElaine Zhang 		return 1;
218a09f237bSElaine Zhang 	else
219a09f237bSElaine Zhang 		return 0;
220a09f237bSElaine Zhang }
221a09f237bSElaine Zhang 
rk860x_regulator_get_voltage(struct udevice * dev)222a09f237bSElaine Zhang static int rk860x_regulator_get_voltage(struct udevice *dev)
223a09f237bSElaine Zhang {
224a09f237bSElaine Zhang 	struct rk860x_regulator_info *priv = dev_get_priv(dev);
225*4474bc1dSshengfei Xu 	int uvolt = 0, ret;
226*4474bc1dSshengfei Xu 	u8 val;
227a09f237bSElaine Zhang 
228*4474bc1dSshengfei Xu 	ret = rk860x_reg_read(dev, priv->vol_reg, &val);
229*4474bc1dSshengfei Xu 	if (ret)
230*4474bc1dSshengfei Xu 		return ret;
231*4474bc1dSshengfei Xu 
232a09f237bSElaine Zhang 	val &= priv->vol_mask;
233a09f237bSElaine Zhang 	uvolt = (val * priv->vsel_step) + priv->vsel_min;
234a09f237bSElaine Zhang 
235a09f237bSElaine Zhang 	return uvolt;
236a09f237bSElaine Zhang }
237a09f237bSElaine Zhang 
rk860x_regulator_set_voltage(struct udevice * dev,int uvolt)238a09f237bSElaine Zhang static int rk860x_regulator_set_voltage(struct udevice *dev, int uvolt)
239a09f237bSElaine Zhang {
240a09f237bSElaine Zhang 	struct rk860x_regulator_info *priv = dev_get_priv(dev);
241a09f237bSElaine Zhang 	int val;
242a09f237bSElaine Zhang 
243a09f237bSElaine Zhang 	val = ((uvolt - priv->vsel_min) / priv->vsel_step);
244a09f237bSElaine Zhang 	rk860x_clrsetbits(dev, priv->vol_reg, priv->vol_mask, val);
245a09f237bSElaine Zhang 
246a09f237bSElaine Zhang 	return 0;
247a09f237bSElaine Zhang }
248a09f237bSElaine Zhang 
rk860x_regulator_get_suspend_voltage(struct udevice * dev)249a09f237bSElaine Zhang static int rk860x_regulator_get_suspend_voltage(struct udevice *dev)
250a09f237bSElaine Zhang {
251a09f237bSElaine Zhang 	struct rk860x_regulator_info *priv = dev_get_priv(dev);
252*4474bc1dSshengfei Xu 	int uvolt = 0, ret;
253*4474bc1dSshengfei Xu 	u8 val;
254a09f237bSElaine Zhang 
255*4474bc1dSshengfei Xu 	ret = rk860x_reg_read(dev, priv->sleep_reg, &val);
256*4474bc1dSshengfei Xu 	if (ret)
257*4474bc1dSshengfei Xu 		return ret;
258*4474bc1dSshengfei Xu 
259a09f237bSElaine Zhang 	val &= priv->vol_mask;
260a09f237bSElaine Zhang 	uvolt = (val * priv->vsel_step) + priv->vsel_min;
261a09f237bSElaine Zhang 
262a09f237bSElaine Zhang 	return uvolt;
263a09f237bSElaine Zhang }
264a09f237bSElaine Zhang 
rk860x_regulator_set_suspend_voltage(struct udevice * dev,int uvolt)265a09f237bSElaine Zhang static int rk860x_regulator_set_suspend_voltage(struct udevice *dev,
266a09f237bSElaine Zhang 						int uvolt)
267a09f237bSElaine Zhang {
268a09f237bSElaine Zhang 	struct rk860x_regulator_info *priv = dev_get_priv(dev);
269a09f237bSElaine Zhang 	int val;
270a09f237bSElaine Zhang 
271a09f237bSElaine Zhang 	val = ((uvolt - priv->vsel_min) / priv->vsel_step);
272a09f237bSElaine Zhang 	rk860x_clrsetbits(dev, priv->sleep_reg, priv->vol_mask, val);
273a09f237bSElaine Zhang 
274a09f237bSElaine Zhang 	return 0;
275a09f237bSElaine Zhang }
276a09f237bSElaine Zhang 
277a09f237bSElaine Zhang /* For 00,01 options:
278a09f237bSElaine Zhang  * VOUT = 0.7125V + NSELx * 12.5mV, from 0.7125 to 1.5V.
279a09f237bSElaine Zhang  * For 02,03 options:
280a09f237bSElaine Zhang  * VOUT = 0.5V + NSELx * 6.25mV, from 0.5 to 1.5V.
281a09f237bSElaine Zhang  */
rk860x_device_setup(struct rk860x_regulator_info * di)282a09f237bSElaine Zhang static int rk860x_device_setup(struct rk860x_regulator_info *di)
283a09f237bSElaine Zhang {
284a09f237bSElaine Zhang 	int ret = 0;
285a09f237bSElaine Zhang 
286a09f237bSElaine Zhang 	switch (di->chip_id) {
287a09f237bSElaine Zhang 	case RK860X_CHIP_ID_00:
288a09f237bSElaine Zhang 	case RK860X_CHIP_ID_01:
289a09f237bSElaine Zhang 		di->vsel_min = 712500;
290a09f237bSElaine Zhang 		di->vsel_step = 12500;
291a09f237bSElaine Zhang 		di->n_voltages = RK860X_NVOLTAGES_64;
292a09f237bSElaine Zhang 		di->vol_mask = VSEL_A_NSEL_MASK;
293a09f237bSElaine Zhang 		if (di->sleep_vsel_id) {
294a09f237bSElaine Zhang 			di->sleep_reg = RK860X_VSEL1_A;
295a09f237bSElaine Zhang 			di->vol_reg = RK860X_VSEL0_A;
296a09f237bSElaine Zhang 			di->mode_reg = RK860X_VSEL0_A;
297a09f237bSElaine Zhang 			di->en_reg = RK860X_VSEL0_A;
298a09f237bSElaine Zhang 			di->sleep_en_reg = RK860X_VSEL1_A;
299a09f237bSElaine Zhang 		} else {
300a09f237bSElaine Zhang 			di->sleep_reg = RK860X_VSEL0_A;
301a09f237bSElaine Zhang 			di->vol_reg = RK860X_VSEL1_A;
302a09f237bSElaine Zhang 			di->mode_reg = RK860X_VSEL1_A;
303a09f237bSElaine Zhang 			di->en_reg = RK860X_VSEL1_A;
304a09f237bSElaine Zhang 			di->sleep_en_reg = RK860X_VSEL0_A;
305a09f237bSElaine Zhang 		}
306a09f237bSElaine Zhang 		break;
307a09f237bSElaine Zhang 	case RK860X_CHIP_ID_02:
308a09f237bSElaine Zhang 	case RK860X_CHIP_ID_03:
309a09f237bSElaine Zhang 		di->vsel_min = 500000;
310a09f237bSElaine Zhang 		di->vsel_step = 6250;
311a09f237bSElaine Zhang 		di->n_voltages = RK860X_NVOLTAGES_160;
312a09f237bSElaine Zhang 		di->vol_mask = VSEL_B_NSEL_MASK;
313a09f237bSElaine Zhang 		if (di->sleep_vsel_id) {
314a09f237bSElaine Zhang 			di->sleep_reg = RK860X_VSEL1_B;
315a09f237bSElaine Zhang 			di->vol_reg = RK860X_VSEL0_B;
316a09f237bSElaine Zhang 			di->mode_reg = RK860X_VSEL0_A;
317a09f237bSElaine Zhang 			di->en_reg = RK860X_VSEL0_A;
318a09f237bSElaine Zhang 			di->sleep_en_reg = RK860X_VSEL1_A;
319a09f237bSElaine Zhang 		} else {
320a09f237bSElaine Zhang 			di->sleep_reg = RK860X_VSEL0_B;
321a09f237bSElaine Zhang 			di->vol_reg = RK860X_VSEL1_B;
322a09f237bSElaine Zhang 			di->mode_reg = RK860X_VSEL1_A;
323a09f237bSElaine Zhang 			di->en_reg = RK860X_VSEL1_A;
324a09f237bSElaine Zhang 			di->sleep_en_reg = RK860X_VSEL0_A;
325a09f237bSElaine Zhang 		}
326a09f237bSElaine Zhang 		break;
327a09f237bSElaine Zhang 	default:
328a09f237bSElaine Zhang 		dev_err(di->dev,
329a09f237bSElaine Zhang 			"Chip ID %d not supported!\n",
330a09f237bSElaine Zhang 			di->chip_id);
331a09f237bSElaine Zhang 		return -EINVAL;
332a09f237bSElaine Zhang 	}
333a09f237bSElaine Zhang 
334a09f237bSElaine Zhang 	di->mode_mask = VSEL_MODE;
335a09f237bSElaine Zhang 
336a09f237bSElaine Zhang 	return ret;
337a09f237bSElaine Zhang }
338a09f237bSElaine Zhang 
rk860x_regulator_ofdata_to_platdata(struct udevice * dev)339a09f237bSElaine Zhang static int rk860x_regulator_ofdata_to_platdata(struct udevice *dev)
340a09f237bSElaine Zhang {
341a09f237bSElaine Zhang 	struct rk860x_regulator_info *priv = dev_get_priv(dev);
342a09f237bSElaine Zhang 	int ret;
343a09f237bSElaine Zhang 
344a09f237bSElaine Zhang 	priv->sleep_vsel_id = dev_read_u32_default(dev,
345a09f237bSElaine Zhang 						   "rockchip,suspend-voltage-selector",
346a09f237bSElaine Zhang 						   1);
347a09f237bSElaine Zhang 
348a09f237bSElaine Zhang 	ret = gpio_request_by_name(dev, "vsel-gpios", 0,
349a09f237bSElaine Zhang 				   &priv->vsel_gpio, GPIOD_IS_OUT);
350a09f237bSElaine Zhang 	if (ret)
351*4474bc1dSshengfei Xu 		dev_err(dev, "vsel-gpios- not found!\n");
352a09f237bSElaine Zhang 
353a09f237bSElaine Zhang 	if (dm_gpio_is_valid(&priv->vsel_gpio))
354a09f237bSElaine Zhang 		dm_gpio_set_value(&priv->vsel_gpio, !priv->sleep_vsel_id);
355a09f237bSElaine Zhang 
356a09f237bSElaine Zhang 	ret = gpio_request_by_name(dev, "en-gpios", 0,
357a09f237bSElaine Zhang 				   &priv->en_gpio, GPIOD_IS_OUT);
358a09f237bSElaine Zhang 	if (ret)
359*4474bc1dSshengfei Xu 		dev_err(dev, "en-gpios- not found!\n");
360a09f237bSElaine Zhang 
361a09f237bSElaine Zhang 	if (dm_gpio_is_valid(&priv->en_gpio))
362a09f237bSElaine Zhang 		dm_gpio_set_value(&priv->en_gpio, 1);
363a09f237bSElaine Zhang 
364a09f237bSElaine Zhang 	return 0;
365a09f237bSElaine Zhang }
366a09f237bSElaine Zhang 
rk860x_regulator_probe(struct udevice * dev)367a09f237bSElaine Zhang static int rk860x_regulator_probe(struct udevice *dev)
368a09f237bSElaine Zhang {
369a09f237bSElaine Zhang 	struct rk860x_regulator_info *di = dev_get_priv(dev);
370a09f237bSElaine Zhang 	struct dm_regulator_uclass_platdata *uc_pdata;
371a09f237bSElaine Zhang 	u8 val;
372a09f237bSElaine Zhang 	int ret;
373a09f237bSElaine Zhang 
374a09f237bSElaine Zhang 	uc_pdata = dev_get_uclass_platdata(dev);
375a09f237bSElaine Zhang 	uc_pdata->type = REGULATOR_TYPE_BUCK;
376a09f237bSElaine Zhang 	uc_pdata->mode_count = 0;
377a09f237bSElaine Zhang 
378a09f237bSElaine Zhang 	/* Get chip ID */
379*4474bc1dSshengfei Xu 	ret = rk860x_reg_read(dev, RK860X_ID1, &val);
380*4474bc1dSshengfei Xu 	if (ret) {
381a09f237bSElaine Zhang 		dev_err(dev, "Failed to get chip ID!\n");
382*4474bc1dSshengfei Xu 		return ret;
383a09f237bSElaine Zhang 	}
384*4474bc1dSshengfei Xu 
385a09f237bSElaine Zhang 	if ((val & DIE_ID) == 0x8)
386a09f237bSElaine Zhang 		di->chip_id = RK860X_CHIP_ID_00;
387a09f237bSElaine Zhang 	else
388a09f237bSElaine Zhang 		di->chip_id = RK860X_CHIP_ID_02;
389a09f237bSElaine Zhang 
390a09f237bSElaine Zhang 	debug("RK860X Option[%d] Detected!\n", val & DIE_ID);
391a09f237bSElaine Zhang 
392a09f237bSElaine Zhang 	/* Device init */
393a09f237bSElaine Zhang 	ret = rk860x_device_setup(di);
394a09f237bSElaine Zhang 	if (ret < 0) {
395a09f237bSElaine Zhang 		dev_err(dev, "Failed to setup device!\n");
396a09f237bSElaine Zhang 		return ret;
397a09f237bSElaine Zhang 	}
398a09f237bSElaine Zhang 
399a09f237bSElaine Zhang 	return 0;
400a09f237bSElaine Zhang }
401a09f237bSElaine Zhang 
402a09f237bSElaine Zhang static const struct udevice_id rk860x_id[] = {
403a09f237bSElaine Zhang 	{
40417d678b9Sshengfei Xu 		.compatible = "rockchip,rk8600",
40517d678b9Sshengfei Xu 	},
40617d678b9Sshengfei Xu 	{
40717d678b9Sshengfei Xu 		.compatible = "rockchip,rk8601",
40817d678b9Sshengfei Xu 	},
40917d678b9Sshengfei Xu 	{
41017d678b9Sshengfei Xu 		.compatible = "rockchip,rk8602",
41117d678b9Sshengfei Xu 	},
41217d678b9Sshengfei Xu 	{
41317d678b9Sshengfei Xu 		.compatible = "rockchip,rk8603",
414a09f237bSElaine Zhang 	},
415a09f237bSElaine Zhang 	{ },
416a09f237bSElaine Zhang };
417a09f237bSElaine Zhang 
418a09f237bSElaine Zhang static const struct dm_regulator_ops rk860x_regulator_ops = {
419a09f237bSElaine Zhang 	.get_value  = rk860x_regulator_get_voltage,
420a09f237bSElaine Zhang 	.set_value  = rk860x_regulator_set_voltage,
421a09f237bSElaine Zhang 	.set_suspend_value = rk860x_regulator_set_suspend_voltage,
422a09f237bSElaine Zhang 	.get_suspend_value = rk860x_regulator_get_suspend_voltage,
423a09f237bSElaine Zhang 	.set_enable = rk860x_regulator_set_enable,
424a09f237bSElaine Zhang 	.get_enable = rk860x_regulator_get_enable,
425a09f237bSElaine Zhang 	.set_suspend_enable = rk860x_regulator_set_suspend_enable,
426a09f237bSElaine Zhang 	.get_suspend_enable = rk860x_regulator_get_suspend_enable,
427a09f237bSElaine Zhang };
428a09f237bSElaine Zhang 
429a09f237bSElaine Zhang U_BOOT_DRIVER(rk860x_regulator) = {
430a09f237bSElaine Zhang 	.name = "rk860x_regulator",
431a09f237bSElaine Zhang 	.id = UCLASS_REGULATOR,
432a09f237bSElaine Zhang 	.ops = &rk860x_regulator_ops,
433a09f237bSElaine Zhang 	.probe = rk860x_regulator_probe,
434a09f237bSElaine Zhang 	.of_match = rk860x_id,
435a09f237bSElaine Zhang 	.ofdata_to_platdata = rk860x_regulator_ofdata_to_platdata,
436a09f237bSElaine Zhang 	.priv_auto_alloc_size = sizeof(struct rk860x_regulator_info),
437a09f237bSElaine Zhang };
438a09f237bSElaine Zhang 
439