1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2015 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
5 *
6 * Based on Rockchip's drivers/power/pmic/pmic_rk808.c:
7 * Copyright (C) 2012 rockchips
8 * zyw <zyw@rock-chips.com>
9 */
10
11#include <common.h>
12#include <dm.h>
13#include <errno.h>
14#include <log.h>
15#include <linux/delay.h>
16#include <power/rk8xx_pmic.h>
17#include <power/pmic.h>
18#include <power/regulator.h>
19
20#ifndef CONFIG_SPL_BUILD
21#define ENABLE_DRIVER
22#endif
23
24/* Not used or exisit register and configure */
25#define NA			0xff
26
27/* Field Definitions */
28#define RK806_BUCK_CONFIG(n)	(0x10 + (n) - 1)
29#define RK806_BUCK_ON_VSEL(n)	(0x1a + (n) - 1)
30#define RK806_BUCK_SLP_VSEL(n)	(0x24 + (n) - 1)
31#define RK806_BUCK_VSEL_MASK	0xff
32
33#define RK806_NLDO_ON_VSEL(n)	(0x43 + (n) - 1)
34#define RK806_NLDO_SLP_VSEL(n)	(0x48 + (n) - 1)
35#define RK806_NLDO_VSEL_MASK	0xff
36
37#define RK806_PLDO_ON_VSEL(n)	(0x4e + (n) - 1)
38#define RK806_PLDO_SLP_VSEL(n)	(0x54 + (n) - 1)
39#define RK806_PLDO_VSEL_MASK	0xff
40
41#define RK808_BUCK_VSEL_MASK	0x3f
42#define RK808_BUCK4_VSEL_MASK	0xf
43#define RK808_LDO_VSEL_MASK	0x1f
44
45/* RK809 BUCK5 */
46#define RK809_BUCK5_CONFIG(n)		(0xde + (n) * 1)
47#define RK809_BUCK5_VSEL_MASK		0x07
48
49/* RK817 BUCK */
50#define RK817_BUCK_ON_VSEL(n)		(0xbb + 3 * ((n) - 1))
51#define RK817_BUCK_SLP_VSEL(n)		(0xbc + 3 * ((n) - 1))
52#define RK817_BUCK_VSEL_MASK		0x7f
53#define RK817_BUCK_CONFIG(i)		(0xba + (i) * 3)
54
55/* RK817 LDO */
56#define RK817_LDO_ON_VSEL(n)		(0xcc + 2 * ((n) - 1))
57#define RK817_LDO_SLP_VSEL(n)		(0xcd + 2 * ((n) - 1))
58#define RK817_LDO_VSEL_MASK		0x7f
59
60/* RK817 ENABLE */
61#define RK817_POWER_EN(n)		(0xb1 + (n))
62#define RK817_POWER_SLP_EN(n)		(0xb5 + (n))
63
64#define RK818_BUCK_VSEL_MASK		0x3f
65#define RK818_BUCK4_VSEL_MASK		0x1f
66#define RK818_LDO_VSEL_MASK		0x1f
67#define RK818_LDO3_ON_VSEL_MASK	0xf
68#define RK818_BOOST_ON_VSEL_MASK	0xe0
69#define RK818_USB_ILIM_SEL_MASK		0x0f
70#define RK818_USB_CHG_SD_VSEL_MASK	0x70
71
72/*
73 * Ramp delay
74 */
75#define RK805_RAMP_RATE_OFFSET		3
76#define RK805_RAMP_RATE_MASK		(3 << RK805_RAMP_RATE_OFFSET)
77#define RK805_RAMP_RATE_3MV_PER_US	(0 << RK805_RAMP_RATE_OFFSET)
78#define RK805_RAMP_RATE_6MV_PER_US	(1 << RK805_RAMP_RATE_OFFSET)
79#define RK805_RAMP_RATE_12_5MV_PER_US	(2 << RK805_RAMP_RATE_OFFSET)
80#define RK805_RAMP_RATE_25MV_PER_US	(3 << RK805_RAMP_RATE_OFFSET)
81
82#define RK808_RAMP_RATE_OFFSET		3
83#define RK808_RAMP_RATE_MASK		(3 << RK808_RAMP_RATE_OFFSET)
84#define RK808_RAMP_RATE_2MV_PER_US	(0 << RK808_RAMP_RATE_OFFSET)
85#define RK808_RAMP_RATE_4MV_PER_US	(1 << RK808_RAMP_RATE_OFFSET)
86#define RK808_RAMP_RATE_6MV_PER_US	(2 << RK808_RAMP_RATE_OFFSET)
87#define RK808_RAMP_RATE_10MV_PER_US	(3 << RK808_RAMP_RATE_OFFSET)
88
89#define RK817_RAMP_RATE_OFFSET		6
90#define RK817_RAMP_RATE_MASK		(0x3 << RK817_RAMP_RATE_OFFSET)
91#define RK817_RAMP_RATE_3MV_PER_US	(0x0 << RK817_RAMP_RATE_OFFSET)
92#define RK817_RAMP_RATE_6_3MV_PER_US	(0x1 << RK817_RAMP_RATE_OFFSET)
93#define RK817_RAMP_RATE_12_5MV_PER_US	(0x2 << RK817_RAMP_RATE_OFFSET)
94#define RK817_RAMP_RATE_25MV_PER_US	(0x3 << RK817_RAMP_RATE_OFFSET)
95
96struct rk8xx_reg_info {
97	uint min_uv;
98	uint step_uv;
99	u8 vsel_reg;
100	u8 vsel_sleep_reg;
101	u8 config_reg;
102	u8 vsel_mask;
103	u8 min_sel;
104	u8 max_sel;
105};
106
107static const struct rk8xx_reg_info rk806_buck[] = {
108	/* buck 1 */
109	{  500000,   6250, RK806_BUCK_ON_VSEL(1), RK806_BUCK_SLP_VSEL(1), RK806_BUCK_CONFIG(1), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
110	{ 1500000,  25000, RK806_BUCK_ON_VSEL(1), RK806_BUCK_SLP_VSEL(1), RK806_BUCK_CONFIG(1), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
111	{ 3400000,	0, RK806_BUCK_ON_VSEL(1), RK806_BUCK_SLP_VSEL(1), RK806_BUCK_CONFIG(1), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
112	/* buck 2 */
113	{  500000,   6250, RK806_BUCK_ON_VSEL(2), RK806_BUCK_SLP_VSEL(2), RK806_BUCK_CONFIG(2), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
114	{ 1500000,  25000, RK806_BUCK_ON_VSEL(2), RK806_BUCK_SLP_VSEL(2), RK806_BUCK_CONFIG(2), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
115	{ 3400000,	0, RK806_BUCK_ON_VSEL(2), RK806_BUCK_SLP_VSEL(2), RK806_BUCK_CONFIG(2), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
116	/* buck 3 */
117	{  500000,   6250, RK806_BUCK_ON_VSEL(3), RK806_BUCK_SLP_VSEL(3), RK806_BUCK_CONFIG(3), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
118	{ 1500000,  25000, RK806_BUCK_ON_VSEL(3), RK806_BUCK_SLP_VSEL(3), RK806_BUCK_CONFIG(3), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
119	{ 3400000,	0, RK806_BUCK_ON_VSEL(3), RK806_BUCK_SLP_VSEL(3), RK806_BUCK_CONFIG(3), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
120	/* buck 4 */
121	{  500000,   6250, RK806_BUCK_ON_VSEL(4), RK806_BUCK_SLP_VSEL(4), RK806_BUCK_CONFIG(4), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
122	{ 1500000,  25000, RK806_BUCK_ON_VSEL(4), RK806_BUCK_SLP_VSEL(4), RK806_BUCK_CONFIG(4), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
123	{ 3400000,	0, RK806_BUCK_ON_VSEL(4), RK806_BUCK_SLP_VSEL(4), RK806_BUCK_CONFIG(4), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
124	/* buck 5 */
125	{  500000,   6250, RK806_BUCK_ON_VSEL(5), RK806_BUCK_SLP_VSEL(5), RK806_BUCK_CONFIG(5), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
126	{ 1500000,  25000, RK806_BUCK_ON_VSEL(5), RK806_BUCK_SLP_VSEL(5), RK806_BUCK_CONFIG(5), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
127	{ 3400000,	0, RK806_BUCK_ON_VSEL(5), RK806_BUCK_SLP_VSEL(5), RK806_BUCK_CONFIG(5), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
128	/* buck 6 */
129	{  500000,   6250, RK806_BUCK_ON_VSEL(6), RK806_BUCK_SLP_VSEL(6), RK806_BUCK_CONFIG(6), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
130	{ 1500000,  25000, RK806_BUCK_ON_VSEL(6), RK806_BUCK_SLP_VSEL(6), RK806_BUCK_CONFIG(6), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
131	{ 3400000,	0, RK806_BUCK_ON_VSEL(6), RK806_BUCK_SLP_VSEL(6), RK806_BUCK_CONFIG(6), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
132	/* buck 7 */
133	{  500000,   6250, RK806_BUCK_ON_VSEL(7), RK806_BUCK_SLP_VSEL(7), RK806_BUCK_CONFIG(7), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
134	{ 1500000,  25000, RK806_BUCK_ON_VSEL(7), RK806_BUCK_SLP_VSEL(7), RK806_BUCK_CONFIG(7), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
135	{ 3400000,	0, RK806_BUCK_ON_VSEL(7), RK806_BUCK_SLP_VSEL(7), RK806_BUCK_CONFIG(7), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
136	/* buck 8 */
137	{  500000,   6250, RK806_BUCK_ON_VSEL(8), RK806_BUCK_SLP_VSEL(8), RK806_BUCK_CONFIG(8), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
138	{ 1500000,  25000, RK806_BUCK_ON_VSEL(8), RK806_BUCK_SLP_VSEL(8), RK806_BUCK_CONFIG(8), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
139	{ 3400000,	0, RK806_BUCK_ON_VSEL(8), RK806_BUCK_SLP_VSEL(8), RK806_BUCK_CONFIG(8), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
140	/* buck 9 */
141	{  500000,   6250, RK806_BUCK_ON_VSEL(9), RK806_BUCK_SLP_VSEL(9), RK806_BUCK_CONFIG(9), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
142	{ 1500000,  25000, RK806_BUCK_ON_VSEL(9), RK806_BUCK_SLP_VSEL(9), RK806_BUCK_CONFIG(9), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
143	{ 3400000,	0, RK806_BUCK_ON_VSEL(9), RK806_BUCK_SLP_VSEL(9), RK806_BUCK_CONFIG(9), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
144	/* buck 10 */
145	{  500000,   6250, RK806_BUCK_ON_VSEL(10), RK806_BUCK_SLP_VSEL(10), RK806_BUCK_CONFIG(10), RK806_BUCK_VSEL_MASK, 0x00, 0x9f },
146	{ 1500000,  25000, RK806_BUCK_ON_VSEL(10), RK806_BUCK_SLP_VSEL(10), RK806_BUCK_CONFIG(10), RK806_BUCK_VSEL_MASK, 0xa0, 0xeb },
147	{ 3400000,	0, RK806_BUCK_ON_VSEL(10), RK806_BUCK_SLP_VSEL(10), RK806_BUCK_CONFIG(10), RK806_BUCK_VSEL_MASK, 0xec, 0xff },
148};
149
150static const struct rk8xx_reg_info rk808_buck[] = {
151	{  712500,  12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG,  RK808_BUCK_VSEL_MASK, 0x00, 0x3f },
152	{  712500,  12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG,  RK808_BUCK_VSEL_MASK, 0x00, 0x3f },
153	{      NA,     NA,		  NA,		      NA, REG_BUCK3_CONFIG,		       NA,   NA,   NA },
154	{ 1800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK808_BUCK4_VSEL_MASK, 0x00, 0x0f },
155};
156
157static const struct rk8xx_reg_info rk816_buck[] = {
158	/* buck 1 */
159	{  712500,  12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG,  RK818_BUCK_VSEL_MASK, 0x00, 0x3b },
160	{ 1800000, 200000, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG,  RK818_BUCK_VSEL_MASK, 0x3c, 0x3e },
161	{ 2300000,	0, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG,  RK818_BUCK_VSEL_MASK, 0x3f, 0x3f },
162	/* buck 2 */
163	{  712500,  12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG,  RK818_BUCK_VSEL_MASK, 0x00, 0x3b },
164	{ 1800000, 200000, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG,  RK818_BUCK_VSEL_MASK, 0x3c, 0x3e },
165	{ 2300000,	0, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG,  RK818_BUCK_VSEL_MASK, 0x3f, 0x3f },
166	/* buck 3 */
167	{      NA,     NA,		  NA,		      NA, REG_BUCK3_CONFIG,                    NA,   NA,   NA },
168	/* buck 4 */
169	{  800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK818_BUCK4_VSEL_MASK, 0x00, 0x1f },
170};
171
172static const struct rk8xx_reg_info rk809_buck5[] = {
173	/* buck 5 */
174	{ 1500000,	0, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x00, 0x00 },
175	{ 1800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x01, 0x03 },
176	{ 2800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x04, 0x05 },
177	{ 3300000, 300000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x06, 0x07 },
178};
179
180static const struct rk8xx_reg_info rk817_buck[] = {
181	/* buck 1 */
182	{  500000,  12500, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x00, 0x4f },
183	{ 1500000, 100000, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x50, 0x58 },
184	{ 2400000,	0, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x59, 0x7f },
185	/* buck 2 */
186	{  500000,  12500, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x00, 0x4f },
187	{ 1500000, 100000, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x50, 0x58 },
188	{ 2400000,	0, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x59, 0x7f },
189	/* buck 3 */
190	{  500000,  12500, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x00, 0x4f },
191	{ 1500000, 100000, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x50, 0x58 },
192	{ 2400000,	0, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x59, 0x7f },
193	/* buck 4 */
194	{  500000,  12500, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x00, 0x4f },
195	{ 1500000, 100000, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x50, 0x62 },
196	{ 3400000,	0, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x63, 0x7f },
197};
198
199static const struct rk8xx_reg_info rk818_buck[] = {
200	{ 712500,   12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG,  RK818_BUCK_VSEL_MASK, 0x00, 0x3f },
201	{ 712500,   12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG,  RK818_BUCK_VSEL_MASK, 0x00, 0x3f },
202	{     NA,      NA,		  NA,		      NA, REG_BUCK3_CONFIG,		       NA,   NA,   NA },
203	{ 1800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK818_BUCK4_VSEL_MASK, 0x00, 0x1f },
204};
205
206#ifdef ENABLE_DRIVER
207static const struct rk8xx_reg_info rk806_nldo[] = {
208	/* nldo 1 */
209	{  500000, 12500, RK806_NLDO_ON_VSEL(1), RK806_NLDO_SLP_VSEL(1), NA, RK806_NLDO_VSEL_MASK, 0x00, 0xe7},
210	{ 3400000,     0, RK806_NLDO_ON_VSEL(1), RK806_NLDO_SLP_VSEL(1), NA, RK806_NLDO_VSEL_MASK, 0xe8, 0xff},
211	/* nldo 2 */
212	{  500000, 12500, RK806_NLDO_ON_VSEL(2), RK806_NLDO_SLP_VSEL(2), NA, RK806_NLDO_VSEL_MASK, 0x00, 0xe7},
213	{ 3400000,     0, RK806_NLDO_ON_VSEL(2), RK806_NLDO_SLP_VSEL(2), NA, RK806_NLDO_VSEL_MASK, 0xe8, 0xff},
214	/* nldo 3 */
215	{  500000, 12500, RK806_NLDO_ON_VSEL(3), RK806_NLDO_SLP_VSEL(3), NA, RK806_NLDO_VSEL_MASK, 0x00, 0xe7},
216	{ 3400000,     0, RK806_NLDO_ON_VSEL(3), RK806_NLDO_SLP_VSEL(3), NA, RK806_NLDO_VSEL_MASK, 0xe8, 0xff},
217	/* nldo 4 */
218	{  500000, 12500, RK806_NLDO_ON_VSEL(4), RK806_NLDO_SLP_VSEL(4), NA, RK806_NLDO_VSEL_MASK, 0x00, 0xe7},
219	{ 3400000,     0, RK806_NLDO_ON_VSEL(4), RK806_NLDO_SLP_VSEL(4), NA, RK806_NLDO_VSEL_MASK, 0xe8, 0xff},
220	/* nldo 5 */
221	{  500000, 12500, RK806_NLDO_ON_VSEL(5), RK806_NLDO_SLP_VSEL(5), NA, RK806_NLDO_VSEL_MASK, 0x00, 0xe7},
222	{ 3400000,     0, RK806_NLDO_ON_VSEL(5), RK806_NLDO_SLP_VSEL(5), NA, RK806_NLDO_VSEL_MASK, 0xe8, 0xff},
223};
224
225static const struct rk8xx_reg_info rk806_pldo[] = {
226	/* pldo 1 */
227	{  500000, 12500, RK806_PLDO_ON_VSEL(1), RK806_PLDO_SLP_VSEL(1), NA, RK806_PLDO_VSEL_MASK, 0x00, 0xe7},
228	{ 3400000,     0, RK806_PLDO_ON_VSEL(1), RK806_PLDO_SLP_VSEL(1), NA, RK806_PLDO_VSEL_MASK, 0xe8, 0xff},
229	/* pldo 2 */
230	{  500000, 12500, RK806_PLDO_ON_VSEL(2), RK806_PLDO_SLP_VSEL(2), NA, RK806_PLDO_VSEL_MASK, 0x00, 0xe7},
231	{ 3400000,     0, RK806_PLDO_ON_VSEL(2), RK806_PLDO_SLP_VSEL(2), NA, RK806_PLDO_VSEL_MASK, 0xe8, 0xff},
232	/* pldo 3 */
233	{  500000, 12500, RK806_PLDO_ON_VSEL(3), RK806_PLDO_SLP_VSEL(3), NA, RK806_PLDO_VSEL_MASK, 0x00, 0xe7},
234	{ 3400000,     0, RK806_PLDO_ON_VSEL(3), RK806_PLDO_SLP_VSEL(3), NA, RK806_PLDO_VSEL_MASK, 0xe8, 0xff},
235	/* pldo 4 */
236	{  500000, 12500, RK806_PLDO_ON_VSEL(4), RK806_PLDO_SLP_VSEL(4), NA, RK806_PLDO_VSEL_MASK, 0x00, 0xe7},
237	{ 3400000,     0, RK806_PLDO_ON_VSEL(4), RK806_PLDO_SLP_VSEL(4), NA, RK806_PLDO_VSEL_MASK, 0xe8, 0xff},
238	/* pldo 5 */
239	{  500000, 12500, RK806_PLDO_ON_VSEL(5), RK806_PLDO_SLP_VSEL(5), NA, RK806_PLDO_VSEL_MASK, 0x00, 0xe7},
240	{ 3400000,     0, RK806_PLDO_ON_VSEL(5), RK806_PLDO_SLP_VSEL(5), NA, RK806_PLDO_VSEL_MASK, 0xe8, 0xff},
241	/* pldo 6 */
242	{  500000, 12500, RK806_PLDO_ON_VSEL(6), RK806_PLDO_SLP_VSEL(6), NA, RK806_PLDO_VSEL_MASK, 0x00, 0xe7},
243	{ 3400000,     0, RK806_PLDO_ON_VSEL(6), RK806_PLDO_SLP_VSEL(6), NA, RK806_PLDO_VSEL_MASK, 0xe8, 0xff},
244};
245
246static const struct rk8xx_reg_info rk808_ldo[] = {
247	{ 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
248	{ 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
249	{  800000, 100000, REG_LDO3_ON_VSEL, REG_LDO3_SLP_VSEL, NA, RK808_BUCK4_VSEL_MASK, },
250	{ 1800000, 100000, REG_LDO4_ON_VSEL, REG_LDO4_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
251	{ 1800000, 100000, REG_LDO5_ON_VSEL, REG_LDO5_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
252	{  800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
253	{  800000, 100000, REG_LDO7_ON_VSEL, REG_LDO7_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
254	{ 1800000, 100000, REG_LDO8_ON_VSEL, REG_LDO8_SLP_VSEL, NA, RK808_LDO_VSEL_MASK, },
255};
256
257static const struct rk8xx_reg_info rk816_ldo[] = {
258	{ 800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
259	{ 800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
260	{ 800000, 100000, REG_LDO3_ON_VSEL, REG_LDO3_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
261	{ 800000, 100000, REG_LDO4_ON_VSEL, REG_LDO4_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
262	{ 800000, 100000, REG_LDO5_ON_VSEL, REG_LDO5_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
263	{ 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
264};
265
266static const struct rk8xx_reg_info rk817_ldo[] = {
267	/* ldo1 */
268	{  600000, 25000, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), NA, RK817_LDO_VSEL_MASK, 0x00, },
269	{ 3400000,     0, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), NA, RK817_LDO_VSEL_MASK, 0x70, },
270	/* ldo2 */
271	{  600000, 25000, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x00, },
272	{ 3400000,     0, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x70, },
273	/* ldo3 */
274	{  600000, 25000, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x00, },
275	{ 3400000,     0, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x70, },
276	/* ldo4 */
277	{  600000, 25000, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x00, },
278	{ 3400000,     0, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x70, },
279	/* ldo5 */
280	{  600000, 25000, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x00, },
281	{ 3400000,     0, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x70, },
282	/* ldo6 */
283	{  600000, 25000, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x00, },
284	{ 3400000,     0, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x70, },
285	/* ldo7 */
286	{  600000, 25000, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x00, },
287	{ 3400000,     0, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x70, },
288	/* ldo8 */
289	{  600000, 25000, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x00, },
290	{ 3400000,     0, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x70, },
291	/* ldo9 */
292	{  600000, 25000, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x00, },
293	{ 3400000,     0, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x70, },
294};
295
296static const struct rk8xx_reg_info rk818_ldo[] = {
297	{ 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
298	{ 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
299	{  800000, 100000, REG_LDO3_ON_VSEL, REG_LDO3_SLP_VSEL, NA, RK818_LDO3_ON_VSEL_MASK, },
300	{ 1800000, 100000, REG_LDO4_ON_VSEL, REG_LDO4_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
301	{ 1800000, 100000, REG_LDO5_ON_VSEL, REG_LDO5_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
302	{  800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
303	{  800000, 100000, REG_LDO7_ON_VSEL, REG_LDO7_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
304	{ 1800000, 100000, REG_LDO8_ON_VSEL, REG_LDO8_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, },
305};
306#endif
307
308static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
309						 int num, int uvolt)
310{
311	struct rk8xx_priv *priv = dev_get_priv(pmic);
312
313	switch (priv->variant) {
314	case RK805_ID:
315	case RK816_ID:
316		switch (num) {
317		case 0:
318		case 1:
319			if (uvolt <= 1450000)
320				return &rk816_buck[num * 3 + 0];
321			else if (uvolt <= 2200000)
322				return &rk816_buck[num * 3 + 1];
323			else
324				return &rk816_buck[num * 3 + 2];
325		default:
326			return &rk816_buck[num + 4];
327		}
328	case RK806_ID:
329		if (uvolt < 1500000)
330			return &rk806_buck[num * 3 + 0];
331		else if (uvolt < 3400000)
332			return &rk806_buck[num * 3 + 1];
333		return &rk806_buck[num * 3 + 2];
334	case RK809_ID:
335	case RK817_ID:
336		switch (num) {
337		case 0 ... 2:
338			if (uvolt < 1500000)
339				return &rk817_buck[num * 3 + 0];
340			else if (uvolt < 2400000)
341				return &rk817_buck[num * 3 + 1];
342			else
343				return &rk817_buck[num * 3 + 2];
344		case 3:
345			if (uvolt < 1500000)
346				return &rk817_buck[num * 3 + 0];
347			else if (uvolt < 3400000)
348				return &rk817_buck[num * 3 + 1];
349			else
350				return &rk817_buck[num * 3 + 2];
351		/* BUCK5 for RK809 */
352		default:
353			if (uvolt < 1800000)
354				return &rk809_buck5[0];
355			else if (uvolt < 2800000)
356				return &rk809_buck5[1];
357			else if (uvolt < 3300000)
358				return &rk809_buck5[2];
359			else
360				return &rk809_buck5[3];
361		}
362	case RK818_ID:
363		return &rk818_buck[num];
364	default:
365		return &rk808_buck[num];
366	}
367}
368
369static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
370{
371	const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
372	struct rk8xx_priv *priv = dev_get_priv(pmic);
373	int mask = info->vsel_mask;
374	int val;
375
376	if (info->vsel_reg == NA)
377		return -ENOSYS;
378
379	if (info->step_uv == 0)	/* Fixed voltage */
380		val = info->min_sel;
381	else
382		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
383
384	debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
385	      __func__, uvolt, buck + 1, info->vsel_reg, mask, val);
386
387	if (priv->variant == RK816_ID) {
388		pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
389		return pmic_clrsetbits(pmic, RK816_REG_DCDC_EN2,
390				       1 << 7, 1 << 7);
391	} else {
392		return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
393	}
394}
395
396static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
397{
398	uint mask, value, en_reg;
399	int ret = 0;
400	struct rk8xx_priv *priv = dev_get_priv(pmic);
401
402	switch (priv->variant) {
403	case RK805_ID:
404	case RK816_ID:
405		if (buck >= 4) {
406			buck -= 4;
407			en_reg = RK816_REG_DCDC_EN2;
408		} else {
409			en_reg = RK816_REG_DCDC_EN1;
410		}
411		if (enable)
412			value = ((1 << buck) | (1 << (buck + 4)));
413		else
414			value = ((0 << buck) | (1 << (buck + 4)));
415		ret = pmic_reg_write(pmic, en_reg, value);
416		break;
417	case RK806_ID:
418		value = RK806_POWER_EN_CLRSETBITS(buck % 4, enable);
419		en_reg = RK806_POWER_EN((buck + 1) / 4);
420		ret = pmic_reg_write(pmic, en_reg, value);
421		break;
422	case RK808_ID:
423	case RK818_ID:
424		mask = 1 << buck;
425		if (enable) {
426			ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX,
427					      0, 3 << (buck * 2));
428			if (ret)
429				return ret;
430		}
431		ret = pmic_clrsetbits(pmic, REG_DCDC_EN, mask,
432				      enable ? mask : 0);
433		break;
434	case RK809_ID:
435	case RK817_ID:
436		if (buck < 4) {
437			if (enable)
438				value = ((1 << buck) | (1 << (buck + 4)));
439			else
440				value = ((0 << buck) | (1 << (buck + 4)));
441			ret = pmic_reg_write(pmic, RK817_POWER_EN(0), value);
442		/* BUCK5 for RK809 */
443		} else {
444			if (enable)
445				value = ((1 << 1) | (1 << 5));
446			else
447				value = ((0 << 1) | (1 << 5));
448			ret = pmic_reg_write(pmic, RK817_POWER_EN(3), value);
449		}
450		break;
451	default:
452		ret = -EINVAL;
453	}
454
455	return ret;
456}
457
458#ifdef ENABLE_DRIVER
459static int _buck_set_suspend_value(struct udevice *pmic, int buck, int uvolt)
460{
461	const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
462	int mask = info->vsel_mask;
463	int val;
464
465	if (info->vsel_sleep_reg == NA)
466		return -ENOSYS;
467
468	if (info->step_uv == 0)
469		val = info->min_sel;
470	else
471		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
472
473	debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
474	      __func__, uvolt, buck + 1, info->vsel_sleep_reg, mask, val);
475
476	return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
477}
478
479static int _buck_get_enable(struct udevice *pmic, int buck)
480{
481	struct rk8xx_priv *priv = dev_get_priv(pmic);
482	uint mask = 0;
483	int ret = 0;
484
485	switch (priv->variant) {
486	case RK805_ID:
487	case RK816_ID:
488		if (buck >= 4) {
489			mask = 1 << (buck - 4);
490			ret = pmic_reg_read(pmic, RK816_REG_DCDC_EN2);
491		} else {
492			mask = 1 << buck;
493			ret = pmic_reg_read(pmic, RK816_REG_DCDC_EN1);
494		}
495		break;
496	case RK806_ID:
497		mask = BIT(buck % 4);
498		ret = pmic_reg_read(pmic, RK806_POWER_EN((buck + 1) / 4));
499		break;
500	case RK808_ID:
501	case RK818_ID:
502		mask = 1 << buck;
503		ret = pmic_reg_read(pmic, REG_DCDC_EN);
504		if (ret < 0)
505			return ret;
506		break;
507	case RK809_ID:
508	case RK817_ID:
509		if (buck < 4) {
510			mask = 1 << buck;
511			ret = pmic_reg_read(pmic, RK817_POWER_EN(0));
512		/* BUCK5 for RK809 */
513		} else {
514			mask = 1 << 1;
515			ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
516		}
517		break;
518	}
519
520	if (ret < 0)
521		return ret;
522
523	return (ret & mask) ? true : false;
524}
525
526static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
527{
528	uint mask = 0;
529	int ret;
530	struct rk8xx_priv *priv = dev_get_priv(pmic);
531
532	switch (priv->variant) {
533	case RK805_ID:
534	case RK816_ID:
535		mask = 1 << buck;
536		ret = pmic_clrsetbits(pmic, RK816_REG_DCDC_SLP_EN, mask,
537				      enable ? mask : 0);
538		break;
539	case RK806_ID:
540		{
541			u8 reg;
542
543			if (buck + 1 >= 9) {
544				reg = RK806_POWER_SLP_EN1;
545				mask = BIT(buck + 1 - 3);
546			} else {
547				reg = RK806_POWER_SLP_EN0;
548				mask = BIT(buck + 1);
549			}
550			ret = pmic_clrsetbits(pmic, reg, mask, enable ? mask : 0);
551		}
552		break;
553	case RK808_ID:
554	case RK818_ID:
555		mask = 1 << buck;
556		ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask,
557				      enable ? 0 : mask);
558		break;
559	case RK809_ID:
560	case RK817_ID:
561		if (buck < 4)
562			mask = 1 << buck;
563		else
564			mask = 1 << 5;	/* BUCK5 for RK809 */
565		ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
566				      enable ? mask : 0);
567		break;
568	default:
569		ret = -EINVAL;
570	}
571
572	return ret;
573}
574
575static int _buck_get_suspend_enable(struct udevice *pmic, int buck)
576{
577	struct rk8xx_priv *priv = dev_get_priv(pmic);
578	int ret, val;
579	uint mask = 0;
580
581	switch (priv->variant) {
582	case RK805_ID:
583	case RK816_ID:
584		mask = 1 << buck;
585		val = pmic_reg_read(pmic, RK816_REG_DCDC_SLP_EN);
586		if (val < 0)
587			return val;
588		ret = (val & mask) ? 1 : 0;
589		break;
590	case RK806_ID:
591		{
592			u8 reg;
593
594			if (buck + 1 >= 9) {
595				reg = RK806_POWER_SLP_EN1;
596				mask = BIT(buck + 1 - 3);
597			} else {
598				reg = RK806_POWER_SLP_EN0;
599				mask = BIT(buck + 1);
600			}
601			val = pmic_reg_read(pmic, reg);
602		}
603		ret = (val & mask) ? 1 : 0;
604		break;
605	case RK808_ID:
606	case RK818_ID:
607		mask = 1 << buck;
608		val = pmic_reg_read(pmic, REG_SLEEP_SET_OFF1);
609		if (val < 0)
610			return val;
611		ret = (val & mask) ? 0 : 1;
612		break;
613	case RK809_ID:
614	case RK817_ID:
615		if (buck < 4)
616			mask = 1 << buck;
617		else
618			mask = 1 << 5;	/* BUCK5 for RK809 */
619
620		val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
621		if (val < 0)
622			return val;
623		ret = (val & mask) ? 1 : 0;
624		break;
625	default:
626		ret = -EINVAL;
627	}
628
629	return ret;
630}
631
632static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
633						int num, int uvolt)
634{
635	struct rk8xx_priv *priv = dev_get_priv(pmic);
636
637	switch (priv->variant) {
638	case RK805_ID:
639	case RK816_ID:
640		return &rk816_ldo[num];
641	case RK809_ID:
642	case RK817_ID:
643		if (uvolt < 3400000)
644			return &rk817_ldo[num * 2 + 0];
645		else
646			return &rk817_ldo[num * 2 + 1];
647	case RK818_ID:
648		return &rk818_ldo[num];
649	default:
650		return &rk808_ldo[num];
651	}
652}
653
654static const struct rk8xx_reg_info *get_nldo_reg(struct udevice *pmic,
655						 int num, int uvolt)
656{
657	const struct rk8xx_priv *priv = dev_get_priv(pmic);
658
659	switch (priv->variant) {
660	case RK806_ID:
661	default:
662		if (uvolt < 3400000)
663			return &rk806_nldo[num * 2 + 0];
664		return &rk806_nldo[num * 2 + 1];
665	}
666}
667
668static const struct rk8xx_reg_info *get_pldo_reg(struct udevice *pmic,
669						 int num, int uvolt)
670{
671	const struct rk8xx_priv *priv = dev_get_priv(pmic);
672
673	switch (priv->variant) {
674	case RK806_ID:
675	default:
676		if (uvolt < 3400000)
677			return &rk806_pldo[num * 2 + 0];
678		return &rk806_pldo[num * 2 + 1];
679	}
680}
681
682static int _ldo_get_enable(struct udevice *pmic, int ldo)
683{
684	struct rk8xx_priv *priv = dev_get_priv(pmic);
685	uint mask = 0;
686	int ret = 0;
687
688	switch (priv->variant) {
689	case RK805_ID:
690	case RK816_ID:
691		if (ldo >= 4) {
692			mask = 1 << (ldo - 4);
693			ret = pmic_reg_read(pmic, RK816_REG_LDO_EN2);
694		} else {
695			mask = 1 << ldo;
696			ret = pmic_reg_read(pmic, RK816_REG_LDO_EN1);
697		}
698		break;
699	case RK808_ID:
700	case RK818_ID:
701		mask = 1 << ldo;
702		ret = pmic_reg_read(pmic, REG_LDO_EN);
703		if (ret < 0)
704			return ret;
705		break;
706	case RK809_ID:
707	case RK817_ID:
708		if (ldo < 4) {
709			mask = 1 << ldo;
710			ret = pmic_reg_read(pmic, RK817_POWER_EN(1));
711		} else if (ldo < 8) {
712			mask = 1 << (ldo - 4);
713			ret = pmic_reg_read(pmic, RK817_POWER_EN(2));
714		} else if (ldo == 8) {
715			mask = 1 << 0;
716			ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
717		} else {
718			return false;
719		}
720		break;
721	}
722
723	if (ret < 0)
724		return ret;
725
726	return (ret & mask) ? true : false;
727}
728
729static int _nldo_get_enable(struct udevice *pmic, int nldo)
730{
731	struct rk8xx_priv *priv = dev_get_priv(pmic);
732	uint mask = 0;
733	int ret = 0;
734	u8 en_reg = 0;
735
736	switch (priv->variant) {
737	case RK806_ID:
738	default:
739		if (nldo + 1 >= 5) {
740			mask = BIT(2);
741			en_reg = RK806_POWER_EN(5);
742		} else {
743			mask = BIT(nldo);
744			en_reg = RK806_POWER_EN(3);
745		}
746		ret = pmic_reg_read(pmic, en_reg);
747		break;
748	}
749
750	if (ret < 0)
751		return ret;
752
753	return (ret & mask) ? 1 : 0;
754}
755
756static int _pldo_get_enable(struct udevice *pmic, int pldo)
757{
758	struct rk8xx_priv *priv = dev_get_priv(pmic);
759	uint mask = 0;
760	int ret = 0;
761	u8 en_reg = 0;
762
763	switch (priv->variant) {
764	case RK806_ID:
765	default:
766		if (pldo + 1 <= 3) {
767			mask = BIT(pldo + 1);
768			en_reg = RK806_POWER_EN(4);
769		} else if (pldo + 1 == 6) {
770			mask = BIT(0);
771			en_reg = RK806_POWER_EN(4);
772		} else {
773			mask = BIT((pldo + 1) % 4);
774			en_reg = RK806_POWER_EN(5);
775		}
776		ret = pmic_reg_read(pmic, en_reg);
777		break;
778	}
779
780	if (ret < 0)
781		return ret;
782
783	return (ret & mask) ? 1 : 0;
784}
785
786static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
787{
788	struct rk8xx_priv *priv = dev_get_priv(pmic);
789	uint mask, value, en_reg;
790	int ret = 0;
791
792	switch (priv->variant) {
793	case RK805_ID:
794	case RK816_ID:
795		if (ldo >= 4) {
796			ldo -= 4;
797			en_reg = RK816_REG_LDO_EN2;
798		} else {
799			en_reg = RK816_REG_LDO_EN1;
800		}
801		if (enable)
802			value = ((1 << ldo) | (1 << (ldo + 4)));
803		else
804			value = ((0 << ldo) | (1 << (ldo + 4)));
805
806		ret = pmic_reg_write(pmic, en_reg, value);
807		break;
808	case RK808_ID:
809	case RK818_ID:
810		mask = 1 << ldo;
811		ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
812				       enable ? mask : 0);
813		break;
814	case RK809_ID:
815	case RK817_ID:
816		if (ldo < 4) {
817			en_reg = RK817_POWER_EN(1);
818		} else if (ldo < 8) {
819			ldo -= 4;
820			en_reg = RK817_POWER_EN(2);
821		} else if (ldo == 8) {
822			ldo = 0;	/* BIT 0 */
823			en_reg = RK817_POWER_EN(3);
824		} else {
825			return -EINVAL;
826		}
827		if (enable)
828			value = ((1 << ldo) | (1 << (ldo + 4)));
829		else
830			value = ((0 << ldo) | (1 << (ldo + 4)));
831		ret = pmic_reg_write(pmic, en_reg, value);
832		break;
833	}
834
835	if (enable)
836		udelay(500);
837
838	return ret;
839}
840
841static int _nldo_set_enable(struct udevice *pmic, int nldo, bool enable)
842{
843	struct rk8xx_priv *priv = dev_get_priv(pmic);
844	uint value, en_reg;
845	int ret = 0;
846
847	switch (priv->variant) {
848	case RK806_ID:
849	default:
850		if (nldo + 1 >= 5) {
851			value = RK806_POWER_EN_CLRSETBITS(2, enable);
852			en_reg = RK806_POWER_EN(5);
853		} else {
854			value = RK806_POWER_EN_CLRSETBITS(nldo, enable);
855			en_reg = RK806_POWER_EN(3);
856		}
857		ret = pmic_reg_write(pmic, en_reg, value);
858		break;
859	}
860
861	if (enable)
862		udelay(500);
863
864	return ret;
865}
866
867static int _pldo_set_enable(struct udevice *pmic, int pldo, bool enable)
868{
869	struct rk8xx_priv *priv = dev_get_priv(pmic);
870	uint value, en_reg;
871	int ret = 0;
872
873	switch (priv->variant) {
874	case RK806_ID:
875	default:
876		/* PLDO */
877		if (pldo + 1 <= 3) {
878			value = RK806_POWER_EN_CLRSETBITS(pldo + 1, enable);
879			en_reg = RK806_POWER_EN(4);
880		} else if (pldo + 1 == 6) {
881			value = RK806_POWER_EN_CLRSETBITS(0, enable);
882			en_reg = RK806_POWER_EN(4);
883		} else {
884			value = RK806_POWER_EN_CLRSETBITS((pldo + 1) % 4, enable);
885			en_reg = RK806_POWER_EN(5);
886		}
887		ret = pmic_reg_write(pmic, en_reg, value);
888		break;
889	}
890
891	if (enable)
892		udelay(500);
893
894	return ret;
895}
896
897static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
898{
899	struct rk8xx_priv *priv = dev_get_priv(pmic);
900	uint mask;
901	int ret = 0;
902
903	switch (priv->variant) {
904	case RK805_ID:
905	case RK816_ID:
906		mask = 1 << ldo;
907		ret = pmic_clrsetbits(pmic, RK816_REG_LDO_SLP_EN, mask,
908				      enable ? mask : 0);
909		break;
910	case RK808_ID:
911	case RK818_ID:
912		mask = 1 << ldo;
913		ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask,
914				      enable ? 0 : mask);
915		break;
916	case RK809_ID:
917	case RK817_ID:
918		if (ldo == 8) {
919			mask = 1 << 4;	/* LDO9 */
920			ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
921					      enable ? mask : 0);
922		} else {
923			mask = 1 << ldo;
924			ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(1), mask,
925					      enable ? mask : 0);
926		}
927		break;
928	}
929
930	return ret;
931}
932
933static int _nldo_set_suspend_enable(struct udevice *pmic, int nldo, bool enable)
934{
935	struct rk8xx_priv *priv = dev_get_priv(pmic);
936	uint mask;
937	int ret = 0;
938
939	switch (priv->variant) {
940	case RK806_ID:
941	default:
942		mask = BIT(nldo);
943		ret = pmic_clrsetbits(pmic, RK806_POWER_SLP_EN1, mask, enable ? mask : 0);
944		break;
945	}
946
947	return ret;
948}
949
950static int _pldo_set_suspend_enable(struct udevice *pmic, int pldo, bool enable)
951{
952	struct rk8xx_priv *priv = dev_get_priv(pmic);
953	uint mask;
954	int ret = 0;
955
956	switch (priv->variant) {
957	case RK806_ID:
958	default:
959		if (pldo + 1 >= 6)
960			mask = BIT(0);
961		else
962			mask = BIT(pldo + 1);
963		ret = pmic_clrsetbits(pmic, RK806_POWER_SLP_EN2, mask, enable ? mask : 0);
964		break;
965	}
966
967	return ret;
968}
969
970static int _ldo_get_suspend_enable(struct udevice *pmic, int ldo)
971{
972	struct rk8xx_priv *priv = dev_get_priv(pmic);
973	int val, ret = 0;
974	uint mask;
975
976	switch (priv->variant) {
977	case RK805_ID:
978	case RK816_ID:
979		mask = 1 << ldo;
980		val = pmic_reg_read(pmic, RK816_REG_LDO_SLP_EN);
981		if (val < 0)
982			return val;
983		ret = (val & mask) ? 1 : 0;
984		break;
985	case RK808_ID:
986	case RK818_ID:
987		mask = 1 << ldo;
988		val = pmic_reg_read(pmic, REG_SLEEP_SET_OFF2);
989		if (val < 0)
990			return val;
991		ret = (val & mask) ? 0 : 1;
992		break;
993	case RK809_ID:
994	case RK817_ID:
995		if (ldo == 8) {
996			mask = 1 << 4;	/* LDO9 */
997			val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
998			if (val < 0)
999				return val;
1000			ret = (val & mask) ? 1 : 0;
1001		} else {
1002			mask = 1 << ldo;
1003			val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(1));
1004			if (val < 0)
1005				return val;
1006			ret = (val & mask) ? 1 : 0;
1007		}
1008		break;
1009	}
1010
1011	return ret;
1012}
1013
1014static int _nldo_get_suspend_enable(struct udevice *pmic, int nldo)
1015{
1016	struct rk8xx_priv *priv = dev_get_priv(pmic);
1017	int val, ret = 0;
1018	uint mask;
1019
1020	switch (priv->variant) {
1021	case RK806_ID:
1022	default:
1023		mask = BIT(nldo);
1024		val = pmic_reg_read(pmic, RK806_POWER_SLP_EN1);
1025		ret = (val & mask) ? 1 : 0;
1026		break;
1027	}
1028
1029	return ret;
1030}
1031
1032static int _pldo_get_suspend_enable(struct udevice *pmic, int pldo)
1033{
1034	struct rk8xx_priv *priv = dev_get_priv(pmic);
1035	int val, ret = 0;
1036	uint mask;
1037
1038	switch (priv->variant) {
1039	case RK806_ID:
1040	default:
1041		if (pldo + 1 >= 6)
1042			mask = BIT(0);
1043		else
1044			mask = BIT(pldo + 1);
1045		val = pmic_reg_read(pmic, RK806_POWER_SLP_EN2);
1046		ret = (val & mask) ? 1 : 0;
1047		break;
1048	}
1049
1050	return ret;
1051}
1052
1053static int buck_get_value(struct udevice *dev)
1054{
1055	int buck = dev->driver_data - 1;
1056	const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
1057	int mask = info->vsel_mask;
1058	int ret, val;
1059
1060	if (info->vsel_reg == NA)
1061		return -ENOSYS;
1062
1063	ret = pmic_reg_read(dev->parent, info->vsel_reg);
1064	if (ret < 0)
1065		return ret;
1066
1067	val = ret & mask;
1068	while (val > info->max_sel)
1069		info++;
1070
1071	return info->min_uv + (val - info->min_sel) * info->step_uv;
1072}
1073
1074static int buck_set_value(struct udevice *dev, int uvolt)
1075{
1076	int buck = dev->driver_data - 1;
1077
1078	return _buck_set_value(dev->parent, buck, uvolt);
1079}
1080
1081static int buck_get_suspend_value(struct udevice *dev)
1082{
1083	int buck = dev->driver_data - 1;
1084	const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
1085	int mask = info->vsel_mask;
1086	int ret, val;
1087
1088	if (info->vsel_sleep_reg == NA)
1089		return -ENOSYS;
1090
1091	ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
1092	if (ret < 0)
1093		return ret;
1094
1095	val = ret & mask;
1096	while (val > info->max_sel)
1097		info++;
1098
1099	return info->min_uv + (val - info->min_sel) * info->step_uv;
1100}
1101
1102static int buck_set_suspend_value(struct udevice *dev, int uvolt)
1103{
1104	int buck = dev->driver_data - 1;
1105
1106	return _buck_set_suspend_value(dev->parent, buck, uvolt);
1107}
1108
1109static int buck_set_enable(struct udevice *dev, bool enable)
1110{
1111	int buck = dev->driver_data - 1;
1112
1113	return _buck_set_enable(dev->parent, buck, enable);
1114}
1115
1116static int buck_set_suspend_enable(struct udevice *dev, bool enable)
1117{
1118	int buck = dev->driver_data - 1;
1119
1120	return _buck_set_suspend_enable(dev->parent, buck, enable);
1121}
1122
1123static int buck_get_suspend_enable(struct udevice *dev)
1124{
1125	int buck = dev->driver_data - 1;
1126
1127	return _buck_get_suspend_enable(dev->parent, buck);
1128}
1129
1130static int buck_get_enable(struct udevice *dev)
1131{
1132	int buck = dev->driver_data - 1;
1133
1134	return _buck_get_enable(dev->parent, buck);
1135}
1136
1137static int _ldo_get_value(struct udevice *pmic, const struct rk8xx_reg_info *info)
1138{
1139	int mask = info->vsel_mask;
1140	int ret, val;
1141
1142	if (info->vsel_reg == NA)
1143		return -ENOSYS;
1144	ret = pmic_reg_read(pmic, info->vsel_reg);
1145	if (ret < 0)
1146		return ret;
1147	val = ret & mask;
1148
1149	return info->min_uv + val * info->step_uv;
1150}
1151
1152static int ldo_get_value(struct udevice *dev)
1153{
1154	int ldo = dev->driver_data - 1;
1155	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
1156
1157	return _ldo_get_value(dev->parent, info);
1158}
1159
1160static int nldo_get_value(struct udevice *dev)
1161{
1162	int nldo = dev->driver_data - 1;
1163	const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, 0);
1164
1165	return _ldo_get_value(dev->parent, info);
1166}
1167
1168static int pldo_get_value(struct udevice *dev)
1169{
1170	int pldo = dev->driver_data - 1;
1171	const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, 0);
1172
1173	return _ldo_get_value(dev->parent, info);
1174}
1175
1176static int _ldo_set_value(struct udevice *pmic, const struct rk8xx_reg_info *info, int uvolt)
1177{
1178	int mask = info->vsel_mask;
1179	int val;
1180
1181	if (info->vsel_reg == NA)
1182		return -ENOSYS;
1183
1184	if (info->step_uv == 0)
1185		val = info->min_sel;
1186	else
1187		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
1188
1189	debug("%s: volt=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
1190	      __func__, uvolt, info->vsel_reg, mask, val);
1191
1192	return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
1193}
1194
1195static int ldo_set_value(struct udevice *dev, int uvolt)
1196{
1197	int ldo = dev->driver_data - 1;
1198	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
1199
1200	return _ldo_set_value(dev->parent, info, uvolt);
1201}
1202
1203static int nldo_set_value(struct udevice *dev, int uvolt)
1204{
1205	int nldo = dev->driver_data - 1;
1206	const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, uvolt);
1207
1208	return _ldo_set_value(dev->parent, info, uvolt);
1209}
1210
1211static int pldo_set_value(struct udevice *dev, int uvolt)
1212{
1213	int pldo = dev->driver_data - 1;
1214	const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, uvolt);
1215
1216	return _ldo_set_value(dev->parent, info, uvolt);
1217}
1218
1219static int _ldo_set_suspend_value(struct udevice *pmic, const struct rk8xx_reg_info *info, int uvolt)
1220{
1221	int mask = info->vsel_mask;
1222	int val;
1223
1224	if (info->vsel_sleep_reg == NA)
1225		return -ENOSYS;
1226
1227	if (info->step_uv == 0)
1228		val = info->min_sel;
1229	else
1230		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
1231
1232	debug("%s: volt=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
1233	      __func__, uvolt, info->vsel_sleep_reg, mask, val);
1234
1235	return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
1236}
1237
1238static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
1239{
1240	int ldo = dev->driver_data - 1;
1241	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
1242
1243	return _ldo_set_suspend_value(dev->parent, info, uvolt);
1244}
1245
1246static int nldo_set_suspend_value(struct udevice *dev, int uvolt)
1247{
1248	int nldo = dev->driver_data - 1;
1249	const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, uvolt);
1250
1251	return _ldo_set_suspend_value(dev->parent, info, uvolt);
1252}
1253
1254static int pldo_set_suspend_value(struct udevice *dev, int uvolt)
1255{
1256	int pldo = dev->driver_data - 1;
1257	const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, uvolt);
1258
1259	return _ldo_set_suspend_value(dev->parent, info, uvolt);
1260}
1261
1262static int _ldo_get_suspend_value(struct udevice *pmic, const struct rk8xx_reg_info *info)
1263{
1264	int mask = info->vsel_mask;
1265	int val, ret;
1266
1267	if (info->vsel_sleep_reg == NA)
1268		return -ENOSYS;
1269
1270	ret = pmic_reg_read(pmic, info->vsel_sleep_reg);
1271	if (ret < 0)
1272		return ret;
1273
1274	val = ret & mask;
1275
1276	return info->min_uv + val * info->step_uv;
1277}
1278
1279static int ldo_get_suspend_value(struct udevice *dev)
1280{
1281	int ldo = dev->driver_data - 1;
1282	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
1283
1284	return _ldo_get_suspend_value(dev->parent, info);
1285}
1286
1287static int nldo_get_suspend_value(struct udevice *dev)
1288{
1289	int nldo = dev->driver_data - 1;
1290	const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, 0);
1291
1292	return _ldo_get_suspend_value(dev->parent, info);
1293}
1294
1295static int pldo_get_suspend_value(struct udevice *dev)
1296{
1297	int pldo = dev->driver_data - 1;
1298	const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, 0);
1299
1300	return _ldo_get_suspend_value(dev->parent, info);
1301}
1302
1303static int ldo_set_enable(struct udevice *dev, bool enable)
1304{
1305	int ldo = dev->driver_data - 1;
1306
1307	return _ldo_set_enable(dev->parent, ldo, enable);
1308}
1309
1310static int nldo_set_enable(struct udevice *dev, bool enable)
1311{
1312	int nldo = dev->driver_data - 1;
1313
1314	return _nldo_set_enable(dev->parent, nldo, enable);
1315}
1316
1317static int pldo_set_enable(struct udevice *dev, bool enable)
1318{
1319	int pldo = dev->driver_data - 1;
1320
1321	return _pldo_set_enable(dev->parent, pldo, enable);
1322}
1323
1324static int ldo_set_suspend_enable(struct udevice *dev, bool enable)
1325{
1326	int ldo = dev->driver_data - 1;
1327
1328	return _ldo_set_suspend_enable(dev->parent, ldo, enable);
1329}
1330
1331static int nldo_set_suspend_enable(struct udevice *dev, bool enable)
1332{
1333	int nldo = dev->driver_data - 1;
1334
1335	return _nldo_set_suspend_enable(dev->parent, nldo, enable);
1336}
1337
1338static int pldo_set_suspend_enable(struct udevice *dev, bool enable)
1339{
1340	int pldo = dev->driver_data - 1;
1341
1342	return _pldo_set_suspend_enable(dev->parent, pldo, enable);
1343}
1344
1345static int ldo_get_suspend_enable(struct udevice *dev)
1346{
1347	int ldo = dev->driver_data - 1;
1348
1349	return _ldo_get_suspend_enable(dev->parent, ldo);
1350}
1351
1352static int nldo_get_suspend_enable(struct udevice *dev)
1353{
1354	int nldo = dev->driver_data - 1;
1355
1356	return _nldo_get_suspend_enable(dev->parent, nldo);
1357}
1358
1359static int pldo_get_suspend_enable(struct udevice *dev)
1360{
1361	int pldo = dev->driver_data - 1;
1362
1363	return _pldo_get_suspend_enable(dev->parent, pldo);
1364}
1365
1366static int ldo_get_enable(struct udevice *dev)
1367{
1368	int ldo = dev->driver_data - 1;
1369
1370	return _ldo_get_enable(dev->parent, ldo);
1371}
1372
1373static int nldo_get_enable(struct udevice *dev)
1374{
1375	int nldo = dev->driver_data - 1;
1376
1377	return _nldo_get_enable(dev->parent, nldo);
1378}
1379
1380static int pldo_get_enable(struct udevice *dev)
1381{
1382	int pldo = dev->driver_data - 1;
1383
1384	return _pldo_get_enable(dev->parent, pldo);
1385}
1386
1387static int switch_set_enable(struct udevice *dev, bool enable)
1388{
1389	struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1390	int ret = 0, sw = dev->driver_data - 1;
1391	uint mask = 0;
1392
1393	switch (priv->variant) {
1394	case RK808_ID:
1395		mask = 1 << (sw + 5);
1396		ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
1397				      enable ? mask : 0);
1398		break;
1399	case RK809_ID:
1400		mask = (1 << (sw + 2)) | (1 << (sw + 6));
1401		ret = pmic_clrsetbits(dev->parent, RK817_POWER_EN(3), mask,
1402				      enable ? mask : (1 << (sw + 6)));
1403		break;
1404	case RK818_ID:
1405		mask = 1 << 6;
1406		ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
1407				      enable ? mask : 0);
1408		break;
1409	}
1410
1411	debug("%s: switch%d, enable=%d, mask=0x%x\n",
1412	      __func__, sw + 1, enable, mask);
1413
1414	return ret;
1415}
1416
1417static int switch_get_enable(struct udevice *dev)
1418{
1419	struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1420	int ret = 0, sw = dev->driver_data - 1;
1421	uint mask = 0;
1422
1423	switch (priv->variant) {
1424	case RK808_ID:
1425		mask = 1 << (sw + 5);
1426		ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
1427		break;
1428	case RK809_ID:
1429		mask = 1 << (sw + 2);
1430		ret = pmic_reg_read(dev->parent, RK817_POWER_EN(3));
1431		break;
1432	case RK818_ID:
1433		mask = 1 << 6;
1434		ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
1435		break;
1436	}
1437
1438	if (ret < 0)
1439		return ret;
1440
1441	return (ret & mask) ? true : false;
1442}
1443
1444static int switch_set_suspend_value(struct udevice *dev, int uvolt)
1445{
1446	return 0;
1447}
1448
1449static int switch_get_suspend_value(struct udevice *dev)
1450{
1451	return 0;
1452}
1453
1454static int switch_set_suspend_enable(struct udevice *dev, bool enable)
1455{
1456	struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1457	int ret = 0, sw = dev->driver_data - 1;
1458	uint mask = 0;
1459
1460	switch (priv->variant) {
1461	case RK808_ID:
1462		mask = 1 << (sw + 5);
1463		ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
1464				      enable ? 0 : mask);
1465		break;
1466	case RK809_ID:
1467		mask = 1 << (sw + 6);
1468		ret = pmic_clrsetbits(dev->parent, RK817_POWER_SLP_EN(0), mask,
1469				      enable ? mask : 0);
1470		break;
1471	case RK818_ID:
1472		mask = 1 << 6;
1473		ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
1474				      enable ? 0 : mask);
1475		break;
1476	}
1477
1478	debug("%s: switch%d, enable=%d, mask=0x%x\n",
1479	      __func__, sw + 1, enable, mask);
1480
1481	return ret;
1482}
1483
1484static int switch_get_suspend_enable(struct udevice *dev)
1485{
1486	struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1487	int val, ret = 0, sw = dev->driver_data - 1;
1488	uint mask = 0;
1489
1490	switch (priv->variant) {
1491	case RK808_ID:
1492		mask = 1 << (sw + 5);
1493		val = pmic_reg_read(dev->parent, REG_SLEEP_SET_OFF1);
1494		if (val < 0)
1495			return val;
1496		ret = (val & mask) ? 0 : 1;
1497		break;
1498	case RK809_ID:
1499		mask = 1 << (sw + 6);
1500		val = pmic_reg_read(dev->parent, RK817_POWER_SLP_EN(0));
1501		if (val < 0)
1502			return val;
1503		ret = (val & mask) ? 1 : 0;
1504		break;
1505	case RK818_ID:
1506		mask = 1 << 6;
1507		val = pmic_reg_read(dev->parent, REG_SLEEP_SET_OFF1);
1508		if (val < 0)
1509			return val;
1510		ret = (val & mask) ? 0 : 1;
1511		break;
1512	}
1513
1514	return ret;
1515}
1516
1517/*
1518 * RK8xx switch does not need to set the voltage,
1519 * but if dts set regulator-min-microvolt/regulator-max-microvolt,
1520 * will cause regulator set value fail and not to enable this switch.
1521 * So add an empty function to return success.
1522 */
1523static int switch_get_value(struct udevice *dev)
1524{
1525	static const char * const supply_name_rk809[] = {
1526		"vcc9-supply",
1527		"vcc8-supply",
1528	};
1529	struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1530	struct udevice *supply;
1531	int id = dev->driver_data - 1;
1532
1533	if (!switch_get_enable(dev))
1534		return 0;
1535
1536	if (priv->variant == RK809_ID) {
1537		if (!uclass_get_device_by_phandle(UCLASS_REGULATOR,
1538						  dev->parent,
1539						  supply_name_rk809[id],
1540						  &supply))
1541			return regulator_get_value(supply);
1542	}
1543
1544	return 0;
1545}
1546
1547static int switch_set_value(struct udevice *dev, int uvolt)
1548{
1549	return 0;
1550}
1551
1552static int rk8xx_buck_probe(struct udevice *dev)
1553{
1554	struct dm_regulator_uclass_plat *uc_pdata;
1555
1556	uc_pdata = dev_get_uclass_plat(dev);
1557
1558	uc_pdata->type = REGULATOR_TYPE_BUCK;
1559	uc_pdata->mode_count = 0;
1560
1561	return 0;
1562}
1563
1564static int rk8xx_ldo_probe(struct udevice *dev)
1565{
1566	struct dm_regulator_uclass_plat *uc_pdata;
1567
1568	uc_pdata = dev_get_uclass_plat(dev);
1569
1570	uc_pdata->type = REGULATOR_TYPE_LDO;
1571	uc_pdata->mode_count = 0;
1572
1573	return 0;
1574}
1575
1576static int rk8xx_switch_probe(struct udevice *dev)
1577{
1578	struct dm_regulator_uclass_plat *uc_pdata;
1579
1580	uc_pdata = dev_get_uclass_plat(dev);
1581
1582	uc_pdata->type = REGULATOR_TYPE_FIXED;
1583	uc_pdata->mode_count = 0;
1584
1585	return 0;
1586}
1587
1588static const struct dm_regulator_ops rk8xx_buck_ops = {
1589	.get_value  = buck_get_value,
1590	.set_value  = buck_set_value,
1591	.set_suspend_value = buck_set_suspend_value,
1592	.get_suspend_value = buck_get_suspend_value,
1593	.get_enable = buck_get_enable,
1594	.set_enable = buck_set_enable,
1595	.set_suspend_enable = buck_set_suspend_enable,
1596	.get_suspend_enable = buck_get_suspend_enable,
1597};
1598
1599static const struct dm_regulator_ops rk8xx_ldo_ops = {
1600	.get_value  = ldo_get_value,
1601	.set_value  = ldo_set_value,
1602	.set_suspend_value = ldo_set_suspend_value,
1603	.get_suspend_value = ldo_get_suspend_value,
1604	.get_enable = ldo_get_enable,
1605	.set_enable = ldo_set_enable,
1606	.set_suspend_enable = ldo_set_suspend_enable,
1607	.get_suspend_enable = ldo_get_suspend_enable,
1608};
1609
1610static const struct dm_regulator_ops rk8xx_nldo_ops = {
1611	.get_value  = nldo_get_value,
1612	.set_value  = nldo_set_value,
1613	.set_suspend_value = nldo_set_suspend_value,
1614	.get_suspend_value = nldo_get_suspend_value,
1615	.get_enable = nldo_get_enable,
1616	.set_enable = nldo_set_enable,
1617	.set_suspend_enable = nldo_set_suspend_enable,
1618	.get_suspend_enable = nldo_get_suspend_enable,
1619};
1620
1621static const struct dm_regulator_ops rk8xx_pldo_ops = {
1622	.get_value  = pldo_get_value,
1623	.set_value  = pldo_set_value,
1624	.set_suspend_value = pldo_set_suspend_value,
1625	.get_suspend_value = pldo_get_suspend_value,
1626	.get_enable = pldo_get_enable,
1627	.set_enable = pldo_set_enable,
1628	.set_suspend_enable = pldo_set_suspend_enable,
1629	.get_suspend_enable = pldo_get_suspend_enable,
1630};
1631
1632static const struct dm_regulator_ops rk8xx_switch_ops = {
1633	.get_value  = switch_get_value,
1634	.set_value  = switch_set_value,
1635	.get_enable = switch_get_enable,
1636	.set_enable = switch_set_enable,
1637	.set_suspend_enable = switch_set_suspend_enable,
1638	.get_suspend_enable = switch_get_suspend_enable,
1639	.set_suspend_value = switch_set_suspend_value,
1640	.get_suspend_value = switch_get_suspend_value,
1641};
1642
1643U_BOOT_DRIVER(rk8xx_buck) = {
1644	.name = "rk8xx_buck",
1645	.id = UCLASS_REGULATOR,
1646	.ops = &rk8xx_buck_ops,
1647	.probe = rk8xx_buck_probe,
1648};
1649
1650U_BOOT_DRIVER(rk8xx_ldo) = {
1651	.name = "rk8xx_ldo",
1652	.id = UCLASS_REGULATOR,
1653	.ops = &rk8xx_ldo_ops,
1654	.probe = rk8xx_ldo_probe,
1655};
1656
1657U_BOOT_DRIVER(rk8xx_nldo) = {
1658	.name = "rk8xx_nldo",
1659	.id = UCLASS_REGULATOR,
1660	.ops = &rk8xx_nldo_ops,
1661	.probe = rk8xx_ldo_probe,
1662};
1663
1664U_BOOT_DRIVER(rk8xx_pldo) = {
1665	.name = "rk8xx_pldo",
1666	.id = UCLASS_REGULATOR,
1667	.ops = &rk8xx_pldo_ops,
1668	.probe = rk8xx_ldo_probe,
1669};
1670
1671U_BOOT_DRIVER(rk8xx_switch) = {
1672	.name = "rk8xx_switch",
1673	.id = UCLASS_REGULATOR,
1674	.ops = &rk8xx_switch_ops,
1675	.probe = rk8xx_switch_probe,
1676};
1677#endif
1678
1679int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
1680{
1681	int ret;
1682
1683	ret = _buck_set_value(pmic, buck, uvolt);
1684	if (ret)
1685		return ret;
1686
1687	return _buck_set_enable(pmic, buck, true);
1688}
1689