xref: /OK3568_Linux_fs/u-boot/drivers/power/regulator/rk806.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2021 Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <dm.h>
9*4882a593Smuzhiyun #include <errno.h>
10*4882a593Smuzhiyun #include <power/rk8xx_pmic.h>
11*4882a593Smuzhiyun #include <power/pmic.h>
12*4882a593Smuzhiyun #include <power/regulator.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #ifndef CONFIG_SPL_BUILD
15*4882a593Smuzhiyun #define ENABLE_DRIVER
16*4882a593Smuzhiyun #endif
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun /* Not used or exisit register and configure */
19*4882a593Smuzhiyun #define NA			-1
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /* rk806 buck*/
22*4882a593Smuzhiyun #define RK806_BUCK_ON_VSEL(n)		(0x1a + n - 1)
23*4882a593Smuzhiyun #define RK806_BUCK_SLP_VSEL(n)		(0x24 + n - 1)
24*4882a593Smuzhiyun #define RK806_BUCK_CONFIG(n)		(0x10 + n - 1)
25*4882a593Smuzhiyun #define RK806_BUCK_VSEL_MASK		0xff
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun /* RK806 LDO */
28*4882a593Smuzhiyun #define RK806_NLDO_ON_VSEL(n)		(0x43 + n - 1)
29*4882a593Smuzhiyun #define RK806_NLDO_SLP_VSEL(n)		(0x48 + n - 1)
30*4882a593Smuzhiyun #define RK806_NLDO_VSEL_MASK		0xff
31*4882a593Smuzhiyun #define RK806_PLDO_ON_VSEL(n)		(0x4e + n - 1)
32*4882a593Smuzhiyun #define RK806_PLDO_SLP_VSEL(n)		(0x54 + n - 1)
33*4882a593Smuzhiyun #define RK806_PLDO_VSEL_MASK		0xff
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /* RK806 ENABLE */
36*4882a593Smuzhiyun #define RK806_POWER_EN(n)		(0x00 + n)
37*4882a593Smuzhiyun #define RK806_NLDO_EN(n)		(0x03 + n)
38*4882a593Smuzhiyun #define RK806_PLDO_EN(n)		(0x04 + n)
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define RK806_BUCK_SUSPEND_EN		0x06
41*4882a593Smuzhiyun #define RK806_NLDO_SUSPEND_EN		0x07
42*4882a593Smuzhiyun #define RK806_PLDO_SUSPEND_EN		0x08
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define RK806_RAMP_RATE_MASK1		0xc0
45*4882a593Smuzhiyun #define RK806_RAMP_RATE_REG1(n)		(0x10 + n)
46*4882a593Smuzhiyun #define RK806_RAMP_RATE_REG1_8		0xeb
47*4882a593Smuzhiyun #define RK806_RAMP_RATE_REG9_10		0xea
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define RK806_RAMP_RATE_4LSB_PER_1CLK	0x00/* LDO 100mV/uS buck 50mV/us */
50*4882a593Smuzhiyun #define RK806_RAMP_RATE_2LSB_PER_1CLK	0x01/* LDO 50mV/uS buck 25mV/us */
51*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_1CLK	0x02/* LDO 25mV/uS buck 12.5mV/us */
52*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_2CLK	0x03/* LDO 12.5mV/uS buck 6.25mV/us */
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_4CLK	0x04/* LDO 6.28/2mV/uS buck 3.125mV/us */
55*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_8CLK	0x05/* LDO 3.12mV/uS buck 1.56mV/us */
56*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_13CLK	0x06/* LDO 1.9mV/uS buck 961mV/us */
57*4882a593Smuzhiyun #define RK806_RAMP_RATE_1LSB_PER_32CLK	0x07/* LDO 0.78mV/uS buck 0.39mV/us */
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun #define RK806_PLDO0_2_MSK(pldo)		(BIT(pldo + 5))
60*4882a593Smuzhiyun #define RK806_PLDO0_2_SET(pldo)		(BIT(pldo + 1) | RK806_PLDO0_2_MSK(pldo))
61*4882a593Smuzhiyun #define RK806_PLDO0_2_CLR(pldo)		RK806_PLDO0_2_MSK(pldo)
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun struct rk8xx_reg_info {
64*4882a593Smuzhiyun 	uint min_uv;
65*4882a593Smuzhiyun 	uint step_uv;
66*4882a593Smuzhiyun 	u8 vsel_reg;
67*4882a593Smuzhiyun 	u8 vsel_sleep_reg;
68*4882a593Smuzhiyun 	u8 config_reg;
69*4882a593Smuzhiyun 	u8 vsel_mask;
70*4882a593Smuzhiyun 	u8 min_sel;
71*4882a593Smuzhiyun 	/* only for buck now */
72*4882a593Smuzhiyun 	u8 max_sel;
73*4882a593Smuzhiyun 	u8 range_num;
74*4882a593Smuzhiyun };
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun static const struct rk8xx_reg_info rk806_buck[] = {
77*4882a593Smuzhiyun 	/* buck 1 */
78*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(1), RK806_BUCK_SLP_VSEL(1), RK806_BUCK_CONFIG(1), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
79*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(1), RK806_BUCK_SLP_VSEL(1), RK806_BUCK_CONFIG(1), RK806_BUCK_VSEL_MASK, 0xa0, 0xec, 3},
80*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(1), RK806_BUCK_SLP_VSEL(1), RK806_BUCK_CONFIG(1), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
81*4882a593Smuzhiyun 	/* buck 2 */
82*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(2), RK806_BUCK_SLP_VSEL(2), RK806_BUCK_CONFIG(2), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
83*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(2), RK806_BUCK_SLP_VSEL(2), RK806_BUCK_CONFIG(2), RK806_BUCK_VSEL_MASK, 0xa0, 0xed, 3},
84*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(2), RK806_BUCK_SLP_VSEL(2), RK806_BUCK_CONFIG(2), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
85*4882a593Smuzhiyun 	/* buck 3 */
86*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(3), RK806_BUCK_SLP_VSEL(3), RK806_BUCK_CONFIG(3), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
87*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(3), RK806_BUCK_SLP_VSEL(3), RK806_BUCK_CONFIG(3), RK806_BUCK_VSEL_MASK, 0xa0, 0xed, 3},
88*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(3), RK806_BUCK_SLP_VSEL(3), RK806_BUCK_CONFIG(3), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
89*4882a593Smuzhiyun 	/* buck 4 */
90*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(4), RK806_BUCK_SLP_VSEL(4), RK806_BUCK_CONFIG(4), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
91*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(4), RK806_BUCK_SLP_VSEL(4), RK806_BUCK_CONFIG(4), RK806_BUCK_VSEL_MASK, 0xa0, 0xed, 3},
92*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(4), RK806_BUCK_SLP_VSEL(4), RK806_BUCK_CONFIG(4), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
93*4882a593Smuzhiyun 	/* buck 5 */
94*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(5), RK806_BUCK_SLP_VSEL(5), RK806_BUCK_CONFIG(5), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
95*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(5), RK806_BUCK_SLP_VSEL(5), RK806_BUCK_CONFIG(5), RK806_BUCK_VSEL_MASK, 0xa0, 0xed, 3},
96*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(5), RK806_BUCK_SLP_VSEL(5), RK806_BUCK_CONFIG(5), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
97*4882a593Smuzhiyun 	/* buck 6 */
98*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(6), RK806_BUCK_SLP_VSEL(6), RK806_BUCK_CONFIG(6), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
99*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(6), RK806_BUCK_SLP_VSEL(6), RK806_BUCK_CONFIG(6), RK806_BUCK_VSEL_MASK, 0xa0, 0xed, 3},
100*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(6), RK806_BUCK_SLP_VSEL(6), RK806_BUCK_CONFIG(6), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
101*4882a593Smuzhiyun 	/* buck 7 */
102*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(7), RK806_BUCK_SLP_VSEL(7), RK806_BUCK_CONFIG(7), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
103*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(7), RK806_BUCK_SLP_VSEL(7), RK806_BUCK_CONFIG(7), RK806_BUCK_VSEL_MASK, 0xa0, 0xed, 3},
104*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(7), RK806_BUCK_SLP_VSEL(7), RK806_BUCK_CONFIG(7), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
105*4882a593Smuzhiyun 	/* buck 8 */
106*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(8), RK806_BUCK_SLP_VSEL(8), RK806_BUCK_CONFIG(8), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
107*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(8), RK806_BUCK_SLP_VSEL(8), RK806_BUCK_CONFIG(8), RK806_BUCK_VSEL_MASK, 0xa0, 0xed, 3},
108*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(8), RK806_BUCK_SLP_VSEL(8), RK806_BUCK_CONFIG(8), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
109*4882a593Smuzhiyun 	/* buck 9 */
110*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(9), RK806_BUCK_SLP_VSEL(9), RK806_BUCK_CONFIG(9), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
111*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(9), RK806_BUCK_SLP_VSEL(9), RK806_BUCK_CONFIG(9), RK806_BUCK_VSEL_MASK, 0xa0, 0xed, 3},
112*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(9), RK806_BUCK_SLP_VSEL(9), RK806_BUCK_CONFIG(9), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
113*4882a593Smuzhiyun 	/* buck 10 */
114*4882a593Smuzhiyun 	{  500000,   6250, RK806_BUCK_ON_VSEL(10), RK806_BUCK_SLP_VSEL(10), RK806_BUCK_CONFIG(10), RK806_BUCK_VSEL_MASK, 0x00, 0x9f, 3},
115*4882a593Smuzhiyun 	{  1500000, 25000, RK806_BUCK_ON_VSEL(10), RK806_BUCK_SLP_VSEL(10), RK806_BUCK_CONFIG(10), RK806_BUCK_VSEL_MASK, 0xa0, 0xed, 3},
116*4882a593Smuzhiyun 	{  3400000,     0, RK806_BUCK_ON_VSEL(10), RK806_BUCK_SLP_VSEL(10), RK806_BUCK_CONFIG(10), RK806_BUCK_VSEL_MASK, 0xed, 0xff, 3},
117*4882a593Smuzhiyun };
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun static const struct rk8xx_reg_info rk806_nldo[] = {
120*4882a593Smuzhiyun 	/* nldo1 */
121*4882a593Smuzhiyun 	{  500000, 12500, RK806_NLDO_ON_VSEL(1), RK806_NLDO_SLP_VSEL(1), NA, RK806_NLDO_VSEL_MASK, 0x00, },
122*4882a593Smuzhiyun 	{  3400000,    0, RK806_NLDO_ON_VSEL(1), RK806_NLDO_SLP_VSEL(1), NA, RK806_NLDO_VSEL_MASK, 0xE8, },
123*4882a593Smuzhiyun 	/* nldo2 */
124*4882a593Smuzhiyun 	{  500000, 12500, RK806_NLDO_ON_VSEL(2), RK806_NLDO_SLP_VSEL(2), NA, RK806_NLDO_VSEL_MASK, 0x00, },
125*4882a593Smuzhiyun 	{  3400000,    0, RK806_NLDO_ON_VSEL(2), RK806_NLDO_SLP_VSEL(2), NA, RK806_NLDO_VSEL_MASK, 0xE8, },
126*4882a593Smuzhiyun 	/* nldo3 */
127*4882a593Smuzhiyun 	{  500000, 12500, RK806_NLDO_ON_VSEL(3), RK806_NLDO_SLP_VSEL(3), NA, RK806_NLDO_VSEL_MASK, 0x00, },
128*4882a593Smuzhiyun 	{  3400000,    0, RK806_NLDO_ON_VSEL(3), RK806_NLDO_SLP_VSEL(3), NA, RK806_NLDO_VSEL_MASK, 0xE8, },
129*4882a593Smuzhiyun 	/* nldo4 */
130*4882a593Smuzhiyun 	{  500000, 12500, RK806_NLDO_ON_VSEL(4), RK806_NLDO_SLP_VSEL(4), NA, RK806_NLDO_VSEL_MASK, 0x00, },
131*4882a593Smuzhiyun 	{  3400000,    0, RK806_NLDO_ON_VSEL(4), RK806_NLDO_SLP_VSEL(4), NA, RK806_NLDO_VSEL_MASK, 0xE8, },
132*4882a593Smuzhiyun 	/* nldo5 */
133*4882a593Smuzhiyun 	{  500000, 12500, RK806_NLDO_ON_VSEL(5), RK806_NLDO_SLP_VSEL(5), NA, RK806_NLDO_VSEL_MASK, 0x00, },
134*4882a593Smuzhiyun 	{  3400000,    0, RK806_NLDO_ON_VSEL(5), RK806_NLDO_SLP_VSEL(5), NA, RK806_NLDO_VSEL_MASK, 0xE8, },
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun static const struct rk8xx_reg_info rk806_pldo[] = {
138*4882a593Smuzhiyun 	/* pldo1 */
139*4882a593Smuzhiyun 	{  500000, 12500, RK806_PLDO_ON_VSEL(1), RK806_PLDO_SLP_VSEL(1), NA, RK806_PLDO_VSEL_MASK, 0x00, },
140*4882a593Smuzhiyun 	{  3400000,    0, RK806_PLDO_ON_VSEL(1), RK806_PLDO_SLP_VSEL(1), NA, RK806_PLDO_VSEL_MASK, 0xE8, },
141*4882a593Smuzhiyun 	/* pldo2 */
142*4882a593Smuzhiyun 	{  500000, 12500, RK806_PLDO_ON_VSEL(2), RK806_PLDO_SLP_VSEL(2), NA, RK806_PLDO_VSEL_MASK, 0x00, },
143*4882a593Smuzhiyun 	{  3400000,    0, RK806_PLDO_ON_VSEL(2), RK806_PLDO_SLP_VSEL(2), NA, RK806_PLDO_VSEL_MASK, 0xE8, },
144*4882a593Smuzhiyun 	/* pldo3 */
145*4882a593Smuzhiyun 	{  500000, 12500, RK806_PLDO_ON_VSEL(3), RK806_PLDO_SLP_VSEL(3), NA, RK806_PLDO_VSEL_MASK, 0x00, },
146*4882a593Smuzhiyun 	{  3400000,    0, RK806_PLDO_ON_VSEL(3), RK806_PLDO_SLP_VSEL(3), NA, RK806_PLDO_VSEL_MASK, 0xE8, },
147*4882a593Smuzhiyun 	/* pldo4 */
148*4882a593Smuzhiyun 	{  500000, 12500, RK806_PLDO_ON_VSEL(4), RK806_PLDO_SLP_VSEL(4), NA, RK806_PLDO_VSEL_MASK, 0x00, },
149*4882a593Smuzhiyun 	{  3400000,    0, RK806_PLDO_ON_VSEL(4), RK806_PLDO_SLP_VSEL(4), NA, RK806_PLDO_VSEL_MASK, 0xE8, },
150*4882a593Smuzhiyun 	/* pldo5 */
151*4882a593Smuzhiyun 	{  500000, 12500, RK806_PLDO_ON_VSEL(5), RK806_PLDO_SLP_VSEL(5), NA, RK806_PLDO_VSEL_MASK, 0x00, },
152*4882a593Smuzhiyun 	{  3400000,    0, RK806_PLDO_ON_VSEL(5), RK806_PLDO_SLP_VSEL(5), NA, RK806_PLDO_VSEL_MASK, 0xE8, },
153*4882a593Smuzhiyun 	/* pldo6 */
154*4882a593Smuzhiyun 	{  500000, 12500, RK806_PLDO_ON_VSEL(6), RK806_PLDO_SLP_VSEL(6), NA, RK806_PLDO_VSEL_MASK, 0x00, },
155*4882a593Smuzhiyun 	{  3400000,    0, RK806_PLDO_ON_VSEL(6), RK806_PLDO_SLP_VSEL(6), NA, RK806_PLDO_VSEL_MASK, 0xE8, },
156*4882a593Smuzhiyun };
157*4882a593Smuzhiyun 
get_buck_reg(struct udevice * pmic,int num,int uvolt)158*4882a593Smuzhiyun static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
159*4882a593Smuzhiyun 						 int num, int uvolt)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	switch (priv->variant) {
164*4882a593Smuzhiyun 	case RK806_ID:
165*4882a593Smuzhiyun 		switch (num) {
166*4882a593Smuzhiyun 		case 0 ... 9:
167*4882a593Smuzhiyun 			if (uvolt < 1500000)
168*4882a593Smuzhiyun 				return &rk806_buck[num * 3 + 0];
169*4882a593Smuzhiyun 			else if (uvolt < 3400000)
170*4882a593Smuzhiyun 				return &rk806_buck[num * 3 + 1];
171*4882a593Smuzhiyun 			else
172*4882a593Smuzhiyun 				return &rk806_buck[num * 3 + 2];
173*4882a593Smuzhiyun 			break;
174*4882a593Smuzhiyun 		}
175*4882a593Smuzhiyun 	default:
176*4882a593Smuzhiyun 		return &rk806_buck[num * 3 + 0];
177*4882a593Smuzhiyun 	}
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun 
_buck_set_value(struct udevice * pmic,int buck,int uvolt)180*4882a593Smuzhiyun static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
183*4882a593Smuzhiyun 	int mask = info->vsel_mask;
184*4882a593Smuzhiyun 	int val;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	if (info->vsel_reg == NA)
187*4882a593Smuzhiyun 		return -EINVAL;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	if (info->step_uv == 0)	/* Fixed voltage */
190*4882a593Smuzhiyun 		val = info->min_sel;
191*4882a593Smuzhiyun 	else
192*4882a593Smuzhiyun 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
195*4882a593Smuzhiyun 	      __func__, uvolt, buck + 1, info->vsel_reg, mask, val);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
_buck_set_enable(struct udevice * pmic,int buck,bool enable)200*4882a593Smuzhiyun static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
203*4882a593Smuzhiyun 	uint value, en_reg;
204*4882a593Smuzhiyun 	int ret;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	switch (priv->variant) {
207*4882a593Smuzhiyun 	case RK806_ID:
208*4882a593Smuzhiyun 		en_reg = RK806_POWER_EN(buck / 4);
209*4882a593Smuzhiyun 		if (enable)
210*4882a593Smuzhiyun 			value = ((1 << buck % 4) | (1 << (buck % 4 + 4)));
211*4882a593Smuzhiyun 		else
212*4882a593Smuzhiyun 			value = ((0 << buck % 4) | (1 << (buck % 4 + 4)));
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 		ret = pmic_reg_write(pmic, en_reg, value);
215*4882a593Smuzhiyun 		break;
216*4882a593Smuzhiyun 	default:
217*4882a593Smuzhiyun 		ret = -EINVAL;
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	return ret;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun #ifdef ENABLE_DRIVER
_buck_set_suspend_value(struct udevice * pmic,int buck,int uvolt)224*4882a593Smuzhiyun static int _buck_set_suspend_value(struct udevice *pmic, int buck, int uvolt)
225*4882a593Smuzhiyun {
226*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
227*4882a593Smuzhiyun 	int mask = info->vsel_mask;
228*4882a593Smuzhiyun 	int val;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	if (info->vsel_sleep_reg == NA)
231*4882a593Smuzhiyun 		return -EINVAL;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	if (info->step_uv == 0)
234*4882a593Smuzhiyun 		val = info->min_sel;
235*4882a593Smuzhiyun 	else
236*4882a593Smuzhiyun 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
239*4882a593Smuzhiyun 	      __func__, uvolt, buck + 1, info->vsel_sleep_reg, mask, val);
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
_buck_get_enable(struct udevice * pmic,int buck)244*4882a593Smuzhiyun static int _buck_get_enable(struct udevice *pmic, int buck)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
247*4882a593Smuzhiyun 	uint mask = 0;
248*4882a593Smuzhiyun 	int ret = 0;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	switch (priv->variant) {
251*4882a593Smuzhiyun 	case RK806_ID:
252*4882a593Smuzhiyun 		mask = 1 << buck % 4;
253*4882a593Smuzhiyun 		ret = pmic_reg_read(pmic, RK806_POWER_EN(buck / 4));
254*4882a593Smuzhiyun 		break;
255*4882a593Smuzhiyun 	default:
256*4882a593Smuzhiyun 		ret = 0;
257*4882a593Smuzhiyun 	}
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	if (ret < 0)
260*4882a593Smuzhiyun 		return ret;
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	return ret & mask ? true : false;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun 
_buck_set_ramp_delay(struct udevice * pmic,int buck,u32 ramp_delay)265*4882a593Smuzhiyun static int _buck_set_ramp_delay(struct udevice *pmic, int buck, u32 ramp_delay)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, 0);
268*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
269*4882a593Smuzhiyun 	int ramp_value = 0, reg_value;
270*4882a593Smuzhiyun 	int ramp_reg1, ramp_reg2;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	if (info->config_reg == NA)
273*4882a593Smuzhiyun 		return -EINVAL;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	switch (priv->variant) {
276*4882a593Smuzhiyun 	case RK806_ID:
277*4882a593Smuzhiyun 		switch (ramp_delay) {
278*4882a593Smuzhiyun 		case 1 ... 390:
279*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_32CLK;
280*4882a593Smuzhiyun 			break;
281*4882a593Smuzhiyun 		case 391 ... 961:
282*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_13CLK;
283*4882a593Smuzhiyun 			break;
284*4882a593Smuzhiyun 		case 962 ... 1560:
285*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_8CLK;
286*4882a593Smuzhiyun 			break;
287*4882a593Smuzhiyun 		case 1561 ... 3125:
288*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_4CLK;
289*4882a593Smuzhiyun 			break;
290*4882a593Smuzhiyun 		case 3126 ... 6250:
291*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_2CLK;
292*4882a593Smuzhiyun 			break;
293*4882a593Smuzhiyun 		case 6251 ... 12500:
294*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_1CLK;
295*4882a593Smuzhiyun 			break;
296*4882a593Smuzhiyun 		case 12501 ... 25000:
297*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_2LSB_PER_1CLK;
298*4882a593Smuzhiyun 			break;
299*4882a593Smuzhiyun 		case 25001 ... 50000: /* 50mV/us */
300*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_4LSB_PER_1CLK;
301*4882a593Smuzhiyun 			break;
302*4882a593Smuzhiyun 		default:
303*4882a593Smuzhiyun 			ramp_value = RK806_RAMP_RATE_1LSB_PER_32CLK;
304*4882a593Smuzhiyun 			printf("buck%d ramp_delay: %d not supported\n",
305*4882a593Smuzhiyun 			       buck, ramp_delay);
306*4882a593Smuzhiyun 			break;
307*4882a593Smuzhiyun 		}
308*4882a593Smuzhiyun 		break;
309*4882a593Smuzhiyun 	default:
310*4882a593Smuzhiyun 		ramp_value = RK806_RAMP_RATE_1LSB_PER_32CLK;
311*4882a593Smuzhiyun 		return -EINVAL;
312*4882a593Smuzhiyun 	}
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	ramp_reg1 = RK806_RAMP_RATE_REG1(buck);
315*4882a593Smuzhiyun 	if (buck < 8)
316*4882a593Smuzhiyun 		ramp_reg2 = RK806_RAMP_RATE_REG1_8;
317*4882a593Smuzhiyun 	else
318*4882a593Smuzhiyun 		ramp_reg2 = RK806_RAMP_RATE_REG9_10;
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	reg_value = pmic_reg_read(pmic, ramp_reg1);
321*4882a593Smuzhiyun 	if (reg_value < 0) {
322*4882a593Smuzhiyun 		printf("buck%d read ramp reg(0x%x) error: %d", buck, ramp_reg1, reg_value);
323*4882a593Smuzhiyun 		return reg_value;
324*4882a593Smuzhiyun 	}
325*4882a593Smuzhiyun 	reg_value &= 0x3f;
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	pmic_reg_write(pmic,
328*4882a593Smuzhiyun 		       ramp_reg1,
329*4882a593Smuzhiyun 		       reg_value | (ramp_value & 0x03) << 0x06);
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	reg_value = pmic_reg_read(pmic, ramp_reg2);
332*4882a593Smuzhiyun 	if (reg_value < 0) {
333*4882a593Smuzhiyun 		printf("buck%d read ramp reg(0x%x) error: %d", buck, ramp_reg2, reg_value);
334*4882a593Smuzhiyun 		return reg_value;
335*4882a593Smuzhiyun 	}
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	return pmic_reg_write(pmic,
338*4882a593Smuzhiyun 			      ramp_reg2,
339*4882a593Smuzhiyun 			      reg_value | (ramp_value & 0x04) << (buck % 8));
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun 
_buck_set_suspend_enable(struct udevice * pmic,int buck,bool enable)342*4882a593Smuzhiyun static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun 	uint mask;
345*4882a593Smuzhiyun 	int ret;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	if (buck <= 7) {
348*4882a593Smuzhiyun 		mask = 1 << buck;
349*4882a593Smuzhiyun 		ret = pmic_clrsetbits(pmic, RK806_BUCK_SUSPEND_EN, mask,
350*4882a593Smuzhiyun 				      enable ? mask : 0);
351*4882a593Smuzhiyun 	} else {
352*4882a593Smuzhiyun 		if (buck == 8)
353*4882a593Smuzhiyun 			mask = 0x40;
354*4882a593Smuzhiyun 		else
355*4882a593Smuzhiyun 			mask = 0x80;
356*4882a593Smuzhiyun 		ret = pmic_clrsetbits(pmic, RK806_NLDO_SUSPEND_EN, mask,
357*4882a593Smuzhiyun 				      enable ? mask : 0);
358*4882a593Smuzhiyun 	}
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	return ret;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun 
_buck_get_suspend_enable(struct udevice * pmic,int buck)363*4882a593Smuzhiyun static int _buck_get_suspend_enable(struct udevice *pmic, int buck)
364*4882a593Smuzhiyun {
365*4882a593Smuzhiyun 	uint mask, val;
366*4882a593Smuzhiyun 	int ret;
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	if (buck <= 7) {
369*4882a593Smuzhiyun 		mask = 1 << buck % 7;
370*4882a593Smuzhiyun 		val = pmic_reg_read(pmic, RK806_BUCK_SUSPEND_EN);
371*4882a593Smuzhiyun 	} else {
372*4882a593Smuzhiyun 		mask = 1 << ((buck - 7) + 6);
373*4882a593Smuzhiyun 		val = pmic_reg_read(pmic, RK806_NLDO_SUSPEND_EN);
374*4882a593Smuzhiyun 	}
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	if (val < 0)
377*4882a593Smuzhiyun 		return val;
378*4882a593Smuzhiyun 	ret = val & mask ? 1 : 0;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	return ret;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun 
get_ldo_reg(struct udevice * pmic,int num,int uvolt)383*4882a593Smuzhiyun static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
384*4882a593Smuzhiyun 						int num, int uvolt)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	switch (priv->variant) {
389*4882a593Smuzhiyun 	case RK806_ID:
390*4882a593Smuzhiyun 		if (uvolt < 3400000)
391*4882a593Smuzhiyun 			return &rk806_nldo[num * 2];
392*4882a593Smuzhiyun 		else
393*4882a593Smuzhiyun 			return &rk806_nldo[num * 2 + 1];
394*4882a593Smuzhiyun 	default:
395*4882a593Smuzhiyun 		return &rk806_nldo[num * 2];
396*4882a593Smuzhiyun 	}
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun 
get_pldo_reg(struct udevice * pmic,int num,int uvolt)399*4882a593Smuzhiyun static const struct rk8xx_reg_info *get_pldo_reg(struct udevice *pmic,
400*4882a593Smuzhiyun 						 int num, int uvolt)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	switch (priv->variant) {
405*4882a593Smuzhiyun 	case RK806_ID:
406*4882a593Smuzhiyun 		if (uvolt < 3400000)
407*4882a593Smuzhiyun 			return &rk806_pldo[num * 2];
408*4882a593Smuzhiyun 		else
409*4882a593Smuzhiyun 			return &rk806_pldo[num * 2 + 1];
410*4882a593Smuzhiyun 	default:
411*4882a593Smuzhiyun 		return &rk806_pldo[num * 2];
412*4882a593Smuzhiyun 	}
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun 
_ldo_get_enable(struct udevice * pmic,int ldo)415*4882a593Smuzhiyun static int _ldo_get_enable(struct udevice *pmic, int ldo)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
418*4882a593Smuzhiyun 	uint mask = 0;
419*4882a593Smuzhiyun 	int ret = 0;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	switch (priv->variant) {
422*4882a593Smuzhiyun 	case RK806_ID:
423*4882a593Smuzhiyun 		if (ldo < 4) {
424*4882a593Smuzhiyun 			mask = 1 << ldo % 4;
425*4882a593Smuzhiyun 			ret = pmic_reg_read(pmic, RK806_NLDO_EN(ldo / 4));
426*4882a593Smuzhiyun 		} else {
427*4882a593Smuzhiyun 			mask = 1 << 2;
428*4882a593Smuzhiyun 			ret = pmic_reg_read(pmic, RK806_NLDO_EN(2));
429*4882a593Smuzhiyun 		}
430*4882a593Smuzhiyun 		break;
431*4882a593Smuzhiyun 	default:
432*4882a593Smuzhiyun 		return false;
433*4882a593Smuzhiyun 	}
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	if (ret < 0)
436*4882a593Smuzhiyun 		return ret;
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	return ret & mask ? true : false;
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun 
_ldo_set_enable(struct udevice * pmic,int ldo,bool enable)441*4882a593Smuzhiyun static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
444*4882a593Smuzhiyun 	uint value, en_reg;
445*4882a593Smuzhiyun 	int ret = 0;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	switch (priv->variant) {
448*4882a593Smuzhiyun 	case RK806_ID:
449*4882a593Smuzhiyun 		if (ldo < 4) {
450*4882a593Smuzhiyun 			en_reg = RK806_NLDO_EN(0);
451*4882a593Smuzhiyun 			if (enable)
452*4882a593Smuzhiyun 				value = ((1 << ldo % 4) | (1 << (ldo % 4 + 4)));
453*4882a593Smuzhiyun 			else
454*4882a593Smuzhiyun 				value = ((0 << ldo % 4) | (1 << (ldo % 4 + 4)));
455*4882a593Smuzhiyun 			ret = pmic_reg_write(pmic, en_reg, value);
456*4882a593Smuzhiyun 		} else {
457*4882a593Smuzhiyun 			en_reg = RK806_NLDO_EN(2);
458*4882a593Smuzhiyun 			if (enable)
459*4882a593Smuzhiyun 				value = 0x44;
460*4882a593Smuzhiyun 			else
461*4882a593Smuzhiyun 				value = 0x40;
462*4882a593Smuzhiyun 			ret = pmic_reg_write(pmic, en_reg, value);
463*4882a593Smuzhiyun 		}
464*4882a593Smuzhiyun 		break;
465*4882a593Smuzhiyun 	default:
466*4882a593Smuzhiyun 		return -EINVAL;
467*4882a593Smuzhiyun 	}
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	return ret;
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun 
_pldo_get_enable(struct udevice * pmic,int pldo)472*4882a593Smuzhiyun static int _pldo_get_enable(struct udevice *pmic, int pldo)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
475*4882a593Smuzhiyun 	uint mask = 0, en_reg;
476*4882a593Smuzhiyun 	int ret = 0;
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	switch (priv->variant) {
479*4882a593Smuzhiyun 	case RK806_ID:
480*4882a593Smuzhiyun 		if ((pldo < 3) || (pldo == 5)) {
481*4882a593Smuzhiyun 			en_reg = RK806_PLDO_EN(0);
482*4882a593Smuzhiyun 			mask = RK806_PLDO0_2_SET(pldo);
483*4882a593Smuzhiyun 			if (pldo == 5)
484*4882a593Smuzhiyun 				mask = (1 << 0);
485*4882a593Smuzhiyun 			ret = pmic_reg_read(pmic, en_reg);
486*4882a593Smuzhiyun 		} else if ((pldo == 3) || (pldo == 4)) {
487*4882a593Smuzhiyun 			en_reg = RK806_PLDO_EN(1);
488*4882a593Smuzhiyun 			if (pldo == 3)
489*4882a593Smuzhiyun 				mask = (1 << 0);
490*4882a593Smuzhiyun 			else
491*4882a593Smuzhiyun 				mask = (1 << 1);
492*4882a593Smuzhiyun 			ret = pmic_reg_read(pmic, en_reg);
493*4882a593Smuzhiyun 		}
494*4882a593Smuzhiyun 		break;
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	default:
497*4882a593Smuzhiyun 		return -EINVAL;
498*4882a593Smuzhiyun 	}
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	if (ret < 0)
501*4882a593Smuzhiyun 		return ret;
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	return ret & mask ? true : false;
504*4882a593Smuzhiyun }
505*4882a593Smuzhiyun 
_pldo_set_enable(struct udevice * pmic,int pldo,bool enable)506*4882a593Smuzhiyun static int _pldo_set_enable(struct udevice *pmic, int pldo, bool enable)
507*4882a593Smuzhiyun {
508*4882a593Smuzhiyun 	struct rk8xx_priv *priv = dev_get_priv(pmic);
509*4882a593Smuzhiyun 	uint value, en_reg;
510*4882a593Smuzhiyun 	int ret = 0;
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 	switch (priv->variant) {
513*4882a593Smuzhiyun 	case RK806_ID:
514*4882a593Smuzhiyun 		if (pldo < 3) {
515*4882a593Smuzhiyun 			en_reg = RK806_PLDO_EN(0);
516*4882a593Smuzhiyun 			if (enable)
517*4882a593Smuzhiyun 				value = RK806_PLDO0_2_SET(pldo);
518*4882a593Smuzhiyun 			else
519*4882a593Smuzhiyun 				value = RK806_PLDO0_2_CLR(pldo);
520*4882a593Smuzhiyun 			ret = pmic_reg_write(pmic, en_reg, value);
521*4882a593Smuzhiyun 		} else if (pldo == 3) {
522*4882a593Smuzhiyun 			en_reg = RK806_PLDO_EN(1);
523*4882a593Smuzhiyun 			if (enable)
524*4882a593Smuzhiyun 				value = ((1 << 0) | (1 << 4));
525*4882a593Smuzhiyun 			else
526*4882a593Smuzhiyun 				value = (1 << 4);
527*4882a593Smuzhiyun 			ret = pmic_reg_write(pmic, en_reg, value);
528*4882a593Smuzhiyun 		} else if (pldo == 4) {
529*4882a593Smuzhiyun 			en_reg = RK806_PLDO_EN(1);
530*4882a593Smuzhiyun 			if (enable)
531*4882a593Smuzhiyun 				value = ((1 << 1) | (1 << 5));
532*4882a593Smuzhiyun 			else
533*4882a593Smuzhiyun 				value = ((0 << 1) | (1 << 5));
534*4882a593Smuzhiyun 			ret = pmic_reg_write(pmic, en_reg, value);
535*4882a593Smuzhiyun 		} else if (pldo == 5) {
536*4882a593Smuzhiyun 			en_reg = RK806_PLDO_EN(0);
537*4882a593Smuzhiyun 			if (enable)
538*4882a593Smuzhiyun 				value = ((1 << 0) | (1 << 4));
539*4882a593Smuzhiyun 			else
540*4882a593Smuzhiyun 				value = ((0 << 0) | (1 << 4));
541*4882a593Smuzhiyun 			ret = pmic_reg_write(pmic, en_reg, value);
542*4882a593Smuzhiyun 		}
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 		break;
545*4882a593Smuzhiyun 	default:
546*4882a593Smuzhiyun 		return -EINVAL;
547*4882a593Smuzhiyun 	}
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	return ret;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
_ldo_set_suspend_enable(struct udevice * pmic,int ldo,bool enable)552*4882a593Smuzhiyun static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
553*4882a593Smuzhiyun {
554*4882a593Smuzhiyun 	uint mask;
555*4882a593Smuzhiyun 	int ret;
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 	mask = 1 << ldo;
558*4882a593Smuzhiyun 	ret = pmic_clrsetbits(pmic, RK806_NLDO_SUSPEND_EN, mask,
559*4882a593Smuzhiyun 			      enable ? mask : 0);
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	return ret;
562*4882a593Smuzhiyun }
563*4882a593Smuzhiyun 
_ldo_get_suspend_enable(struct udevice * pmic,int ldo)564*4882a593Smuzhiyun static int _ldo_get_suspend_enable(struct udevice *pmic, int ldo)
565*4882a593Smuzhiyun {
566*4882a593Smuzhiyun 	uint mask, val;
567*4882a593Smuzhiyun 	int ret;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	mask = 1 << ldo;
570*4882a593Smuzhiyun 	val = pmic_reg_read(pmic, RK806_NLDO_SUSPEND_EN);
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	if (val < 0)
573*4882a593Smuzhiyun 		return val;
574*4882a593Smuzhiyun 	ret = val & mask ? 1 : 0;
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	return ret;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun 
buck_get_value(struct udevice * dev)579*4882a593Smuzhiyun static int buck_get_value(struct udevice *dev)
580*4882a593Smuzhiyun {
581*4882a593Smuzhiyun 	int buck = dev->driver_data - 1;
582*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
583*4882a593Smuzhiyun 	int mask = info->vsel_mask;
584*4882a593Smuzhiyun 	int i, ret, val;
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	if (info->vsel_reg == NA)
587*4882a593Smuzhiyun 		return -EINVAL;
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	ret = pmic_reg_read(dev->parent, info->vsel_reg);
590*4882a593Smuzhiyun 	if (ret < 0)
591*4882a593Smuzhiyun 		return ret;
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	val = ret & mask;
594*4882a593Smuzhiyun 	if (val >= info->min_sel && val <= info->max_sel)
595*4882a593Smuzhiyun 		goto finish;
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	/* unlucky to try */
598*4882a593Smuzhiyun 	for (i = 1; i < info->range_num; i++) {
599*4882a593Smuzhiyun 		info++;
600*4882a593Smuzhiyun 		if (val <= info->max_sel && val >= info->min_sel)
601*4882a593Smuzhiyun 			break;
602*4882a593Smuzhiyun 	}
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun finish:
605*4882a593Smuzhiyun 	return info->min_uv + (val - info->min_sel) * info->step_uv;
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun 
buck_set_value(struct udevice * dev,int uvolt)608*4882a593Smuzhiyun static int buck_set_value(struct udevice *dev, int uvolt)
609*4882a593Smuzhiyun {
610*4882a593Smuzhiyun 	int buck = dev->driver_data - 1;
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	return _buck_set_value(dev->parent, buck, uvolt);
613*4882a593Smuzhiyun }
614*4882a593Smuzhiyun 
buck_get_suspend_value(struct udevice * dev)615*4882a593Smuzhiyun static int buck_get_suspend_value(struct udevice *dev)
616*4882a593Smuzhiyun {
617*4882a593Smuzhiyun 	int buck = dev->driver_data - 1;
618*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
619*4882a593Smuzhiyun 	int mask = info->vsel_mask;
620*4882a593Smuzhiyun 	int i, ret, val;
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	if (info->vsel_sleep_reg == NA)
623*4882a593Smuzhiyun 		return -EINVAL;
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
626*4882a593Smuzhiyun 	if (ret < 0)
627*4882a593Smuzhiyun 		return ret;
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	val = ret & mask;
630*4882a593Smuzhiyun 	if (val <= info->max_sel && val >= info->min_sel)
631*4882a593Smuzhiyun 		goto finish;
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun 	/* unlucky to try */
634*4882a593Smuzhiyun 	for (i = 1; i < info->range_num; i++) {
635*4882a593Smuzhiyun 		info++;
636*4882a593Smuzhiyun 		if (val <= info->max_sel && val >= info->min_sel)
637*4882a593Smuzhiyun 			break;
638*4882a593Smuzhiyun 	}
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun finish:
641*4882a593Smuzhiyun 	return info->min_uv + (val - info->min_sel) * info->step_uv;
642*4882a593Smuzhiyun }
643*4882a593Smuzhiyun 
buck_set_suspend_value(struct udevice * dev,int uvolt)644*4882a593Smuzhiyun static int buck_set_suspend_value(struct udevice *dev, int uvolt)
645*4882a593Smuzhiyun {
646*4882a593Smuzhiyun 	int buck = dev->driver_data - 1;
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	return _buck_set_suspend_value(dev->parent, buck, uvolt);
649*4882a593Smuzhiyun }
650*4882a593Smuzhiyun 
buck_set_enable(struct udevice * dev,bool enable)651*4882a593Smuzhiyun static int buck_set_enable(struct udevice *dev, bool enable)
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun 	int buck = dev->driver_data - 1;
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	return _buck_set_enable(dev->parent, buck, enable);
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun 
buck_set_suspend_enable(struct udevice * dev,bool enable)658*4882a593Smuzhiyun static int buck_set_suspend_enable(struct udevice *dev, bool enable)
659*4882a593Smuzhiyun {
660*4882a593Smuzhiyun 	int buck = dev->driver_data - 1;
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	return _buck_set_suspend_enable(dev->parent, buck, enable);
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun 
buck_get_suspend_enable(struct udevice * dev)665*4882a593Smuzhiyun static int buck_get_suspend_enable(struct udevice *dev)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun 	int buck = dev->driver_data - 1;
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun 	return _buck_get_suspend_enable(dev->parent, buck);
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun 
buck_set_ramp_delay(struct udevice * dev,u32 ramp_delay)672*4882a593Smuzhiyun static int buck_set_ramp_delay(struct udevice *dev, u32 ramp_delay)
673*4882a593Smuzhiyun {
674*4882a593Smuzhiyun 	int buck = dev->driver_data - 1;
675*4882a593Smuzhiyun 
676*4882a593Smuzhiyun 	return _buck_set_ramp_delay(dev->parent, buck, ramp_delay);
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun 
buck_get_enable(struct udevice * dev)679*4882a593Smuzhiyun static int buck_get_enable(struct udevice *dev)
680*4882a593Smuzhiyun {
681*4882a593Smuzhiyun 	int buck = dev->driver_data - 1;
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	return _buck_get_enable(dev->parent, buck);
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun 
ldo_get_value(struct udevice * dev)686*4882a593Smuzhiyun static int ldo_get_value(struct udevice *dev)
687*4882a593Smuzhiyun {
688*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
689*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
690*4882a593Smuzhiyun 	int mask = info->vsel_mask;
691*4882a593Smuzhiyun 	int ret, val;
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	if (info->vsel_reg == NA)
694*4882a593Smuzhiyun 		return -EINVAL;
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 	ret = pmic_reg_read(dev->parent, info->vsel_reg);
697*4882a593Smuzhiyun 	if (ret < 0)
698*4882a593Smuzhiyun 		return ret;
699*4882a593Smuzhiyun 	val = ret & mask;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	return info->min_uv + val * info->step_uv;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun 
ldo_set_value(struct udevice * dev,int uvolt)704*4882a593Smuzhiyun static int ldo_set_value(struct udevice *dev, int uvolt)
705*4882a593Smuzhiyun {
706*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
707*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
708*4882a593Smuzhiyun 	int mask = info->vsel_mask;
709*4882a593Smuzhiyun 	int val;
710*4882a593Smuzhiyun 
711*4882a593Smuzhiyun 	if (info->vsel_reg == NA)
712*4882a593Smuzhiyun 		return -EINVAL;
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	if (info->step_uv == 0)
715*4882a593Smuzhiyun 		val = info->min_sel;
716*4882a593Smuzhiyun 	else
717*4882a593Smuzhiyun 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun 	debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
720*4882a593Smuzhiyun 	      __func__, uvolt, ldo + 1, info->vsel_reg, mask, val);
721*4882a593Smuzhiyun 
722*4882a593Smuzhiyun 	return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
723*4882a593Smuzhiyun }
724*4882a593Smuzhiyun 
pldo_get_value(struct udevice * dev)725*4882a593Smuzhiyun static int pldo_get_value(struct udevice *dev)
726*4882a593Smuzhiyun {
727*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
728*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, ldo, 0);
729*4882a593Smuzhiyun 	int mask = info->vsel_mask;
730*4882a593Smuzhiyun 	int ret, val;
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun 	if (info->vsel_reg == NA)
733*4882a593Smuzhiyun 		return -EINVAL;
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun 	ret = pmic_reg_read(dev->parent, info->vsel_reg);
736*4882a593Smuzhiyun 	if (ret < 0)
737*4882a593Smuzhiyun 		return ret;
738*4882a593Smuzhiyun 	val = ret & mask;
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun 	return info->min_uv + val * info->step_uv;
741*4882a593Smuzhiyun }
742*4882a593Smuzhiyun 
pldo_set_value(struct udevice * dev,int uvolt)743*4882a593Smuzhiyun static int pldo_set_value(struct udevice *dev, int uvolt)
744*4882a593Smuzhiyun {
745*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
746*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, ldo, uvolt);
747*4882a593Smuzhiyun 	int mask = info->vsel_mask;
748*4882a593Smuzhiyun 	int val;
749*4882a593Smuzhiyun 
750*4882a593Smuzhiyun 	if (info->vsel_reg == NA)
751*4882a593Smuzhiyun 		return -EINVAL;
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 	if (info->step_uv == 0)
754*4882a593Smuzhiyun 		val = info->min_sel;
755*4882a593Smuzhiyun 	else
756*4882a593Smuzhiyun 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun 	debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
759*4882a593Smuzhiyun 	      __func__, uvolt, ldo + 1, info->vsel_reg, mask, val);
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 	return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
762*4882a593Smuzhiyun }
763*4882a593Smuzhiyun 
ldo_set_suspend_value(struct udevice * dev,int uvolt)764*4882a593Smuzhiyun static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
765*4882a593Smuzhiyun {
766*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
767*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
768*4882a593Smuzhiyun 	int mask = info->vsel_mask;
769*4882a593Smuzhiyun 	int val;
770*4882a593Smuzhiyun 
771*4882a593Smuzhiyun 	if (info->vsel_sleep_reg == NA)
772*4882a593Smuzhiyun 		return -EINVAL;
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun 	if (info->step_uv == 0)
775*4882a593Smuzhiyun 		val = info->min_sel;
776*4882a593Smuzhiyun 	else
777*4882a593Smuzhiyun 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 	debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
780*4882a593Smuzhiyun 	      __func__, uvolt, ldo + 1, info->vsel_sleep_reg, mask, val);
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	return pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, mask, val);
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun 
ldo_get_suspend_value(struct udevice * dev)785*4882a593Smuzhiyun static int ldo_get_suspend_value(struct udevice *dev)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
788*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
789*4882a593Smuzhiyun 	int mask = info->vsel_mask;
790*4882a593Smuzhiyun 	int val, ret;
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 	if (info->vsel_sleep_reg == NA)
793*4882a593Smuzhiyun 		return -EINVAL;
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 	ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
796*4882a593Smuzhiyun 	if (ret < 0)
797*4882a593Smuzhiyun 		return ret;
798*4882a593Smuzhiyun 
799*4882a593Smuzhiyun 	val = ret & mask;
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	return info->min_uv + val * info->step_uv;
802*4882a593Smuzhiyun }
803*4882a593Smuzhiyun 
ldo_set_enable(struct udevice * dev,bool enable)804*4882a593Smuzhiyun static int ldo_set_enable(struct udevice *dev, bool enable)
805*4882a593Smuzhiyun {
806*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun 	return _ldo_set_enable(dev->parent, ldo, enable);
809*4882a593Smuzhiyun }
810*4882a593Smuzhiyun 
ldo_set_suspend_enable(struct udevice * dev,bool enable)811*4882a593Smuzhiyun static int ldo_set_suspend_enable(struct udevice *dev, bool enable)
812*4882a593Smuzhiyun {
813*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
814*4882a593Smuzhiyun 
815*4882a593Smuzhiyun 	return _ldo_set_suspend_enable(dev->parent, ldo, enable);
816*4882a593Smuzhiyun }
817*4882a593Smuzhiyun 
ldo_get_suspend_enable(struct udevice * dev)818*4882a593Smuzhiyun static int ldo_get_suspend_enable(struct udevice *dev)
819*4882a593Smuzhiyun {
820*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun 	return _ldo_get_suspend_enable(dev->parent, ldo);
823*4882a593Smuzhiyun }
824*4882a593Smuzhiyun 
ldo_get_enable(struct udevice * dev)825*4882a593Smuzhiyun static int ldo_get_enable(struct udevice *dev)
826*4882a593Smuzhiyun {
827*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	return _ldo_get_enable(dev->parent, ldo);
830*4882a593Smuzhiyun }
831*4882a593Smuzhiyun 
pldo_set_enable(struct udevice * dev,bool enable)832*4882a593Smuzhiyun static int pldo_set_enable(struct udevice *dev, bool enable)
833*4882a593Smuzhiyun {
834*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	return _pldo_set_enable(dev->parent, ldo, enable);
837*4882a593Smuzhiyun }
838*4882a593Smuzhiyun 
pldo_get_enable(struct udevice * dev)839*4882a593Smuzhiyun static int pldo_get_enable(struct udevice *dev)
840*4882a593Smuzhiyun {
841*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
842*4882a593Smuzhiyun 
843*4882a593Smuzhiyun 	return _pldo_get_enable(dev->parent, ldo);
844*4882a593Smuzhiyun }
845*4882a593Smuzhiyun 
pldo_set_suspend_value(struct udevice * dev,int uvolt)846*4882a593Smuzhiyun static int pldo_set_suspend_value(struct udevice *dev, int uvolt)
847*4882a593Smuzhiyun {
848*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
849*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, ldo, uvolt);;
850*4882a593Smuzhiyun 	int mask = info->vsel_mask;
851*4882a593Smuzhiyun 	int val;
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 	if (info->vsel_sleep_reg == NA)
854*4882a593Smuzhiyun 		return -EINVAL;
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 	if (info->step_uv == 0)
857*4882a593Smuzhiyun 		val = info->min_sel;
858*4882a593Smuzhiyun 	else
859*4882a593Smuzhiyun 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun 	return pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, mask, val);
862*4882a593Smuzhiyun }
863*4882a593Smuzhiyun 
pldo_get_suspend_value(struct udevice * dev)864*4882a593Smuzhiyun static int pldo_get_suspend_value(struct udevice *dev)
865*4882a593Smuzhiyun {
866*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
867*4882a593Smuzhiyun 	const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, ldo, 0);
868*4882a593Smuzhiyun 	int mask = info->vsel_mask;
869*4882a593Smuzhiyun 	int val, ret;
870*4882a593Smuzhiyun 
871*4882a593Smuzhiyun 	if (info->vsel_sleep_reg == NA)
872*4882a593Smuzhiyun 		return -EINVAL;
873*4882a593Smuzhiyun 
874*4882a593Smuzhiyun 	ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
875*4882a593Smuzhiyun 	if (ret < 0)
876*4882a593Smuzhiyun 		return ret;
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun 	val = ret & mask;
879*4882a593Smuzhiyun 
880*4882a593Smuzhiyun 	return info->min_uv + val * info->step_uv;
881*4882a593Smuzhiyun }
882*4882a593Smuzhiyun 
_pldo_set_suspend_enable(struct udevice * pmic,int ldo,bool enable)883*4882a593Smuzhiyun static int _pldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
884*4882a593Smuzhiyun {
885*4882a593Smuzhiyun 	uint mask;
886*4882a593Smuzhiyun 	int ret;
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 	if (ldo < 5)
889*4882a593Smuzhiyun 		mask = 1 << (ldo + 1);
890*4882a593Smuzhiyun 	else
891*4882a593Smuzhiyun 		mask = 1;
892*4882a593Smuzhiyun 	ret = pmic_clrsetbits(pmic, RK806_PLDO_SUSPEND_EN, mask,
893*4882a593Smuzhiyun 			      enable ? mask : 0);
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun 	return ret;
896*4882a593Smuzhiyun }
897*4882a593Smuzhiyun 
_pldo_get_suspend_enable(struct udevice * pmic,int ldo)898*4882a593Smuzhiyun static int _pldo_get_suspend_enable(struct udevice *pmic, int ldo)
899*4882a593Smuzhiyun {
900*4882a593Smuzhiyun 	uint mask, val;
901*4882a593Smuzhiyun 	int ret;
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun 	if (ldo < 5)
904*4882a593Smuzhiyun 		mask = 1 << (ldo + 1);
905*4882a593Smuzhiyun 	else
906*4882a593Smuzhiyun 		mask = 1;
907*4882a593Smuzhiyun 	val = pmic_reg_read(pmic, RK806_PLDO_SUSPEND_EN);
908*4882a593Smuzhiyun 
909*4882a593Smuzhiyun 	if (val < 0)
910*4882a593Smuzhiyun 		return val;
911*4882a593Smuzhiyun 	ret = val & mask ? 1 : 0;
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun 	return ret;
914*4882a593Smuzhiyun }
915*4882a593Smuzhiyun 
pldo_set_suspend_enable(struct udevice * dev,bool enable)916*4882a593Smuzhiyun static int pldo_set_suspend_enable(struct udevice *dev, bool enable)
917*4882a593Smuzhiyun {
918*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
919*4882a593Smuzhiyun 
920*4882a593Smuzhiyun 	return _pldo_set_suspend_enable(dev->parent, ldo, enable);
921*4882a593Smuzhiyun }
922*4882a593Smuzhiyun 
pldo_get_suspend_enable(struct udevice * dev)923*4882a593Smuzhiyun static int pldo_get_suspend_enable(struct udevice *dev)
924*4882a593Smuzhiyun {
925*4882a593Smuzhiyun 	int ldo = dev->driver_data - 1;
926*4882a593Smuzhiyun 
927*4882a593Smuzhiyun 	return _pldo_get_suspend_enable(dev->parent, ldo);
928*4882a593Smuzhiyun }
929*4882a593Smuzhiyun 
rk8xx_buck_probe(struct udevice * dev)930*4882a593Smuzhiyun static int rk8xx_buck_probe(struct udevice *dev)
931*4882a593Smuzhiyun {
932*4882a593Smuzhiyun 	struct dm_regulator_uclass_platdata *uc_pdata;
933*4882a593Smuzhiyun 
934*4882a593Smuzhiyun 	uc_pdata = dev_get_uclass_platdata(dev);
935*4882a593Smuzhiyun 	uc_pdata->type = REGULATOR_TYPE_BUCK;
936*4882a593Smuzhiyun 	uc_pdata->mode_count = 0;
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun 	return 0;
939*4882a593Smuzhiyun }
940*4882a593Smuzhiyun 
rk8xx_ldo_probe(struct udevice * dev)941*4882a593Smuzhiyun static int rk8xx_ldo_probe(struct udevice *dev)
942*4882a593Smuzhiyun {
943*4882a593Smuzhiyun 	struct dm_regulator_uclass_platdata *uc_pdata;
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun 	uc_pdata = dev_get_uclass_platdata(dev);
946*4882a593Smuzhiyun 	uc_pdata->type = REGULATOR_TYPE_LDO;
947*4882a593Smuzhiyun 	uc_pdata->mode_count = 0;
948*4882a593Smuzhiyun 
949*4882a593Smuzhiyun 	return 0;
950*4882a593Smuzhiyun }
951*4882a593Smuzhiyun 
rk8xx_pldo_probe(struct udevice * dev)952*4882a593Smuzhiyun static int rk8xx_pldo_probe(struct udevice *dev)
953*4882a593Smuzhiyun {
954*4882a593Smuzhiyun 	struct dm_regulator_uclass_platdata *uc_pdata;
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun 	uc_pdata = dev_get_uclass_platdata(dev);
957*4882a593Smuzhiyun 	uc_pdata->type = REGULATOR_TYPE_LDO;
958*4882a593Smuzhiyun 	uc_pdata->mode_count = 0;
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	return 0;
961*4882a593Smuzhiyun }
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun static const struct dm_regulator_ops rk8xx_buck_ops = {
964*4882a593Smuzhiyun 	.get_value  = buck_get_value,
965*4882a593Smuzhiyun 	.set_value  = buck_set_value,
966*4882a593Smuzhiyun 	.set_suspend_value = buck_set_suspend_value,
967*4882a593Smuzhiyun 	.get_suspend_value = buck_get_suspend_value,
968*4882a593Smuzhiyun 	.get_enable = buck_get_enable,
969*4882a593Smuzhiyun 	.set_enable = buck_set_enable,
970*4882a593Smuzhiyun 	.set_suspend_enable = buck_set_suspend_enable,
971*4882a593Smuzhiyun 	.get_suspend_enable = buck_get_suspend_enable,
972*4882a593Smuzhiyun 	.set_ramp_delay = buck_set_ramp_delay,
973*4882a593Smuzhiyun };
974*4882a593Smuzhiyun 
975*4882a593Smuzhiyun static const struct dm_regulator_ops rk8xx_ldo_ops = {
976*4882a593Smuzhiyun 	.get_value  = ldo_get_value,
977*4882a593Smuzhiyun 	.set_value  = ldo_set_value,
978*4882a593Smuzhiyun 	.set_suspend_value = ldo_set_suspend_value,
979*4882a593Smuzhiyun 	.get_suspend_value = ldo_get_suspend_value,
980*4882a593Smuzhiyun 	.get_enable = ldo_get_enable,
981*4882a593Smuzhiyun 	.set_enable = ldo_set_enable,
982*4882a593Smuzhiyun 	.set_suspend_enable = ldo_set_suspend_enable,
983*4882a593Smuzhiyun 	.get_suspend_enable = ldo_get_suspend_enable,
984*4882a593Smuzhiyun };
985*4882a593Smuzhiyun 
986*4882a593Smuzhiyun static const struct dm_regulator_ops rk8xx_pldo_ops = {
987*4882a593Smuzhiyun 	.get_value  = pldo_get_value,
988*4882a593Smuzhiyun 	.set_value  = pldo_set_value,
989*4882a593Smuzhiyun 	.set_suspend_value = pldo_set_suspend_value,
990*4882a593Smuzhiyun 	.get_suspend_value = pldo_get_suspend_value,
991*4882a593Smuzhiyun 	.get_enable = pldo_get_enable,
992*4882a593Smuzhiyun 	.set_enable = pldo_set_enable,
993*4882a593Smuzhiyun 	.set_suspend_enable = pldo_set_suspend_enable,
994*4882a593Smuzhiyun 	.get_suspend_enable = pldo_get_suspend_enable,
995*4882a593Smuzhiyun };
996*4882a593Smuzhiyun 
997*4882a593Smuzhiyun U_BOOT_DRIVER(rk8xx_spi_buck) = {
998*4882a593Smuzhiyun 	.name = "rk8xx_spi_buck",
999*4882a593Smuzhiyun 	.id = UCLASS_REGULATOR,
1000*4882a593Smuzhiyun 	.ops = &rk8xx_buck_ops,
1001*4882a593Smuzhiyun 	.probe = rk8xx_buck_probe,
1002*4882a593Smuzhiyun };
1003*4882a593Smuzhiyun 
1004*4882a593Smuzhiyun U_BOOT_DRIVER(rk8xx_spi_ldo) = {
1005*4882a593Smuzhiyun 	.name = "rk8xx_spi_ldo",
1006*4882a593Smuzhiyun 	.id = UCLASS_REGULATOR,
1007*4882a593Smuzhiyun 	.ops = &rk8xx_ldo_ops,
1008*4882a593Smuzhiyun 	.probe = rk8xx_ldo_probe,
1009*4882a593Smuzhiyun };
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun U_BOOT_DRIVER(rk8xx_spi_pldo) = {
1012*4882a593Smuzhiyun 	.name = "rk8xx_spi_pldo",
1013*4882a593Smuzhiyun 	.id = UCLASS_REGULATOR,
1014*4882a593Smuzhiyun 	.ops = &rk8xx_pldo_ops,
1015*4882a593Smuzhiyun 	.probe = rk8xx_pldo_probe,
1016*4882a593Smuzhiyun };
1017*4882a593Smuzhiyun #endif
1018