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