blob: 3125835bc07d6285675691316e809db333fd6173 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glassadecfef2016-01-21 19:43:30 -07002/*
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>
Simon Glassadecfef2016-01-21 19:43:30 -07009 */
10
Tom Riniabb9a042024-05-18 20:20:43 -060011#include <common.h>
Simon Glassadecfef2016-01-21 19:43:30 -070012#include <dm.h>
13#include <errno.h>
Simon Glass0f2af882020-05-10 11:40:05 -060014#include <log.h>
Jonas Karlman31c3c802023-07-02 12:41:15 +000015#include <linux/delay.h>
Jacob Chen614704b2017-05-02 14:54:52 +080016#include <power/rk8xx_pmic.h>
Simon Glassadecfef2016-01-21 19:43:30 -070017#include <power/pmic.h>
18#include <power/regulator.h>
19
20#ifndef CONFIG_SPL_BUILD
21#define ENABLE_DRIVER
22#endif
23
Elaine Zhangfa9cccc2019-09-26 15:43:53 +080024/* Not used or exisit register and configure */
25#define NA 0xff
26
Jacob Chen21a6a252017-05-02 14:54:50 +080027/* Field Definitions */
Quentin Schulzf7c6da12024-03-14 10:36:18 +010028#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
Jacob Chen21a6a252017-05-02 14:54:50 +080041#define RK808_BUCK_VSEL_MASK 0x3f
42#define RK808_BUCK4_VSEL_MASK 0xf
43#define RK808_LDO_VSEL_MASK 0x1f
44
Joseph Chend6b3e832019-09-26 15:45:07 +080045/* RK809 BUCK5 */
46#define RK809_BUCK5_CONFIG(n) (0xde + (n) * 1)
47#define RK809_BUCK5_VSEL_MASK 0x07
48
Joseph Chen4a1ae182019-09-26 15:44:55 +080049/* 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
Jacob Chen36163e32017-05-02 14:54:51 +080064#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
Wadim Egorovc2581052017-06-19 12:36:39 +020069#define RK818_USB_ILIM_SEL_MASK 0x0f
70#define RK818_USB_CHG_SD_VSEL_MASK 0x70
71
Elaine Zhangfa9cccc2019-09-26 15:43:53 +080072/*
73 * Ramp delay
74 */
Elaine Zhang1d9077e2019-09-26 15:43:55 +080075#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)
Joseph Chend6b3e832019-09-26 15:45:07 +080081
Elaine Zhangfa9cccc2019-09-26 15:43:53 +080082#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)
Jacob Chen36163e32017-05-02 14:54:51 +080088
Joseph Chen4a1ae182019-09-26 15:44:55 +080089#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
Jacob Chen614704b2017-05-02 14:54:52 +080096struct rk8xx_reg_info {
Simon Glassadecfef2016-01-21 19:43:30 -070097 uint min_uv;
98 uint step_uv;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +080099 u8 vsel_reg;
100 u8 vsel_sleep_reg;
101 u8 config_reg;
Jacob Chen21a6a252017-05-02 14:54:50 +0800102 u8 vsel_mask;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800103 u8 min_sel;
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000104 u8 max_sel;
Simon Glassadecfef2016-01-21 19:43:30 -0700105};
106
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100107static 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
Jacob Chen614704b2017-05-02 14:54:52 +0800150static const struct rk8xx_reg_info rk808_buck[] = {
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000151 { 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 },
Simon Glassadecfef2016-01-21 19:43:30 -0700155};
156
Elaine Zhang04e5a432019-09-26 15:43:54 +0800157static const struct rk8xx_reg_info rk816_buck[] = {
158 /* buck 1 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000159 { 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 },
Elaine Zhang04e5a432019-09-26 15:43:54 +0800162 /* buck 2 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000163 { 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 },
Elaine Zhang04e5a432019-09-26 15:43:54 +0800166 /* buck 3 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000167 { NA, NA, NA, NA, REG_BUCK3_CONFIG, NA, NA, NA },
Elaine Zhang04e5a432019-09-26 15:43:54 +0800168 /* buck 4 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000169 { 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK818_BUCK4_VSEL_MASK, 0x00, 0x1f },
Elaine Zhang04e5a432019-09-26 15:43:54 +0800170};
171
Joseph Chend6b3e832019-09-26 15:45:07 +0800172static const struct rk8xx_reg_info rk809_buck5[] = {
173 /* buck 5 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000174 { 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 },
Joseph Chend6b3e832019-09-26 15:45:07 +0800178};
179
Joseph Chen4a1ae182019-09-26 15:44:55 +0800180static const struct rk8xx_reg_info rk817_buck[] = {
181 /* buck 1 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000182 { 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 },
Joseph Chen4a1ae182019-09-26 15:44:55 +0800185 /* buck 2 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000186 { 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 },
Joseph Chen4a1ae182019-09-26 15:44:55 +0800189 /* buck 3 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000190 { 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 },
Joseph Chen4a1ae182019-09-26 15:44:55 +0800193 /* buck 4 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000194 { 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 },
Joseph Chen4a1ae182019-09-26 15:44:55 +0800197};
198
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200199static const struct rk8xx_reg_info rk818_buck[] = {
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000200 { 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 },
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200204};
205
206#ifdef ENABLE_DRIVER
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100207static 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
Jacob Chen614704b2017-05-02 14:54:52 +0800246static const struct rk8xx_reg_info rk808_ldo[] = {
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800247 { 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, },
Simon Glassadecfef2016-01-21 19:43:30 -0700255};
256
Elaine Zhang04e5a432019-09-26 15:43:54 +0800257static 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
Joseph Chen4a1ae182019-09-26 15:44:55 +0800266static 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
Jacob Chen614704b2017-05-02 14:54:52 +0800296static const struct rk8xx_reg_info rk818_ldo[] = {
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800297 { 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, },
Jacob Chen36163e32017-05-02 14:54:51 +0800305};
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200306#endif
Jacob Chen36163e32017-05-02 14:54:51 +0800307
Jacob Chen614704b2017-05-02 14:54:52 +0800308static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800309 int num, int uvolt)
Jacob Chen36163e32017-05-02 14:54:51 +0800310{
Jacob Chen614704b2017-05-02 14:54:52 +0800311 struct rk8xx_priv *priv = dev_get_priv(pmic);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800312
Jacob Chen614704b2017-05-02 14:54:52 +0800313 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800314 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800315 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 }
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100328 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];
Joseph Chend6b3e832019-09-26 15:45:07 +0800334 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800335 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];
Joseph Chend6b3e832019-09-26 15:45:07 +0800351 /* 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];
Joseph Chen4a1ae182019-09-26 15:44:55 +0800361 }
Jacob Chen36163e32017-05-02 14:54:51 +0800362 case RK818_ID:
363 return &rk818_buck[num];
364 default:
365 return &rk808_buck[num];
366 }
367}
368
Simon Glassadecfef2016-01-21 19:43:30 -0700369static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
370{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800371 const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800372 struct rk8xx_priv *priv = dev_get_priv(pmic);
Jacob Chen21a6a252017-05-02 14:54:50 +0800373 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -0700374 int val;
375
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800376 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -0700377 return -ENOSYS;
Elaine Zhang04e5a432019-09-26 15:43:54 +0800378
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800379 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
Elaine Zhang04e5a432019-09-26 15:43:54 +0800387 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 }
Simon Glassadecfef2016-01-21 19:43:30 -0700394}
395
396static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
397{
Elaine Zhang04e5a432019-09-26 15:43:54 +0800398 uint mask, value, en_reg;
Joseph Chen4a1ae182019-09-26 15:44:55 +0800399 int ret = 0;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800400 struct rk8xx_priv *priv = dev_get_priv(pmic);
Simon Glassadecfef2016-01-21 19:43:30 -0700401
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800402 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800403 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800404 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;
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100417 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;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800422 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;
Joseph Chend6b3e832019-09-26 15:45:07 +0800434 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800435 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);
Joseph Chend6b3e832019-09-26 15:45:07 +0800442 /* 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);
Joseph Chen4a1ae182019-09-26 15:44:55 +0800449 }
450 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800451 default:
452 ret = -EINVAL;
Simon Glassadecfef2016-01-21 19:43:30 -0700453 }
454
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800455 return ret;
Simon Glassadecfef2016-01-21 19:43:30 -0700456}
457
458#ifdef ENABLE_DRIVER
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800459static 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) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800486 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800487 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;
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100496 case RK806_ID:
497 mask = BIT(buck % 4);
498 ret = pmic_reg_read(pmic, RK806_POWER_EN((buck + 1) / 4));
499 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800500 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;
Joseph Chend6b3e832019-09-26 15:45:07 +0800507 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800508 case RK817_ID:
509 if (buck < 4) {
510 mask = 1 << buck;
511 ret = pmic_reg_read(pmic, RK817_POWER_EN(0));
Joseph Chend6b3e832019-09-26 15:45:07 +0800512 /* BUCK5 for RK809 */
513 } else {
514 mask = 1 << 1;
515 ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
Joseph Chen4a1ae182019-09-26 15:44:55 +0800516 }
517 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800518 }
519
520 if (ret < 0)
521 return ret;
522
Quentin Schulz53dfd482024-06-05 11:33:23 +0200523 return (ret & mask) ? true : false;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800524}
525
526static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
527{
Joseph Chen4a1ae182019-09-26 15:44:55 +0800528 uint mask = 0;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800529 int ret;
530 struct rk8xx_priv *priv = dev_get_priv(pmic);
531
532 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800533 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800534 case RK816_ID:
535 mask = 1 << buck;
536 ret = pmic_clrsetbits(pmic, RK816_REG_DCDC_SLP_EN, mask,
537 enable ? mask : 0);
538 break;
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100539 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;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800553 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;
Joseph Chend6b3e832019-09-26 15:45:07 +0800559 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800560 case RK817_ID:
561 if (buck < 4)
562 mask = 1 << buck;
Joseph Chend6b3e832019-09-26 15:45:07 +0800563 else
564 mask = 1 << 5; /* BUCK5 for RK809 */
Joseph Chen4a1ae182019-09-26 15:44:55 +0800565 ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
566 enable ? mask : 0);
567 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800568 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;
Joseph Chen4a1ae182019-09-26 15:44:55 +0800579 uint mask = 0;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800580
581 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800582 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800583 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;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200588 ret = (val & mask) ? 1 : 0;
Elaine Zhang04e5a432019-09-26 15:43:54 +0800589 break;
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100590 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;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800605 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;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200611 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800612 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800613 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800614 case RK817_ID:
615 if (buck < 4)
616 mask = 1 << buck;
Joseph Chend6b3e832019-09-26 15:45:07 +0800617 else
618 mask = 1 << 5; /* BUCK5 for RK809 */
Joseph Chen4a1ae182019-09-26 15:44:55 +0800619
620 val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
621 if (val < 0)
622 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200623 ret = (val & mask) ? 1 : 0;
Joseph Chen4a1ae182019-09-26 15:44:55 +0800624 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800625 default:
626 ret = -EINVAL;
627 }
628
629 return ret;
630}
631
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200632static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800633 int num, int uvolt)
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200634{
635 struct rk8xx_priv *priv = dev_get_priv(pmic);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800636
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200637 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800638 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800639 case RK816_ID:
640 return &rk816_ldo[num];
Joseph Chend6b3e832019-09-26 15:45:07 +0800641 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800642 case RK817_ID:
643 if (uvolt < 3400000)
644 return &rk817_ldo[num * 2 + 0];
645 else
646 return &rk817_ldo[num * 2 + 1];
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200647 case RK818_ID:
648 return &rk818_ldo[num];
649 default:
650 return &rk808_ldo[num];
651 }
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800652}
653
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100654static 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
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800682static 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) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800689 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800690 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;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800699 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;
Joseph Chend6b3e832019-09-26 15:45:07 +0800706 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800707 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;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800721 }
722
723 if (ret < 0)
724 return ret;
725
Quentin Schulz53dfd482024-06-05 11:33:23 +0200726 return (ret & mask) ? true : false;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800727}
728
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100729static 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
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800786static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
787{
788 struct rk8xx_priv *priv = dev_get_priv(pmic);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800789 uint mask, value, en_reg;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800790 int ret = 0;
791
792 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800793 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800794 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;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800808 case RK808_ID:
809 case RK818_ID:
810 mask = 1 << ldo;
811 ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
Elaine Zhang04e5a432019-09-26 15:43:54 +0800812 enable ? mask : 0);
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800813 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800814 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800815 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;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800833 }
834
Jonas Karlman31c3c802023-07-02 12:41:15 +0000835 if (enable)
836 udelay(500);
837
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800838 return ret;
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200839}
840
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100841static 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
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800897static 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) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800904 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800905 case RK816_ID:
906 mask = 1 << ldo;
907 ret = pmic_clrsetbits(pmic, RK816_REG_LDO_SLP_EN, mask,
908 enable ? mask : 0);
909 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800910 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;
Joseph Chend6b3e832019-09-26 15:45:07 +0800916 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800917 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;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800928 }
929
930 return ret;
931}
932
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100933static 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
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800970static 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) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800977 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800978 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;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200983 ret = (val & mask) ? 1 : 0;
Elaine Zhang04e5a432019-09-26 15:43:54 +0800984 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800985 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;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200991 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800992 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800993 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800994 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;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001000 ret = (val & mask) ? 1 : 0;
Joseph Chen4a1ae182019-09-26 15:44:55 +08001001 } else {
1002 mask = 1 << ldo;
1003 val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(1));
1004 if (val < 0)
1005 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001006 ret = (val & mask) ? 1 : 0;
Joseph Chen4a1ae182019-09-26 15:44:55 +08001007 }
1008 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001009 }
1010
1011 return ret;
1012}
1013
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001014static 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
Simon Glassadecfef2016-01-21 19:43:30 -07001053static int buck_get_value(struct udevice *dev)
1054{
1055 int buck = dev->driver_data - 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001056 const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
Jacob Chen21a6a252017-05-02 14:54:50 +08001057 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -07001058 int ret, val;
1059
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001060 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -07001061 return -ENOSYS;
Elaine Zhang04e5a432019-09-26 15:43:54 +08001062
Simon Glassadecfef2016-01-21 19:43:30 -07001063 ret = pmic_reg_read(dev->parent, info->vsel_reg);
1064 if (ret < 0)
1065 return ret;
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001066
Simon Glassadecfef2016-01-21 19:43:30 -07001067 val = ret & mask;
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001068 while (val > info->max_sel)
1069 info++;
Simon Glassadecfef2016-01-21 19:43:30 -07001070
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001071 return info->min_uv + (val - info->min_sel) * info->step_uv;
Simon Glassadecfef2016-01-21 19:43:30 -07001072}
1073
1074static int buck_set_value(struct udevice *dev, int uvolt)
1075{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001076 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001077
1078 return _buck_set_value(dev->parent, buck, uvolt);
1079}
1080
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001081static int buck_get_suspend_value(struct udevice *dev)
1082{
1083 int buck = dev->driver_data - 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001084 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;
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001096 while (val > info->max_sel)
1097 info++;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001098
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001099 return info->min_uv + (val - info->min_sel) * info->step_uv;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001100}
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
Simon Glassadecfef2016-01-21 19:43:30 -07001109static int buck_set_enable(struct udevice *dev, bool enable)
1110{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001111 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001112
1113 return _buck_set_enable(dev->parent, buck, enable);
1114}
1115
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001116static int buck_set_suspend_enable(struct udevice *dev, bool enable)
Simon Glassadecfef2016-01-21 19:43:30 -07001117{
1118 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001119
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001120 return _buck_set_suspend_enable(dev->parent, buck, enable);
1121}
Simon Glassadecfef2016-01-21 19:43:30 -07001122
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001123static int buck_get_suspend_enable(struct udevice *dev)
1124{
1125 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001126
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001127 return _buck_get_suspend_enable(dev->parent, buck);
Simon Glassadecfef2016-01-21 19:43:30 -07001128}
1129
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001130static 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
Quentin Schulz23b16d42024-06-05 11:33:22 +02001137static int _ldo_get_value(struct udevice *pmic, const struct rk8xx_reg_info *info)
Simon Glassadecfef2016-01-21 19:43:30 -07001138{
Jacob Chen21a6a252017-05-02 14:54:50 +08001139 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -07001140 int ret, val;
1141
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001142 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -07001143 return -ENOSYS;
Quentin Schulz23b16d42024-06-05 11:33:22 +02001144 ret = pmic_reg_read(pmic, info->vsel_reg);
Simon Glassadecfef2016-01-21 19:43:30 -07001145 if (ret < 0)
1146 return ret;
1147 val = ret & mask;
1148
1149 return info->min_uv + val * info->step_uv;
1150}
1151
Quentin Schulzec7dd642024-03-14 10:36:17 +01001152static int ldo_get_value(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001153{
1154 int ldo = dev->driver_data - 1;
Quentin Schulzec7dd642024-03-14 10:36:17 +01001155 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
1156
Quentin Schulz23b16d42024-06-05 11:33:22 +02001157 return _ldo_get_value(dev->parent, info);
Quentin Schulzec7dd642024-03-14 10:36:17 +01001158}
1159
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001160static 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
Quentin Schulz23b16d42024-06-05 11:33:22 +02001165 return _ldo_get_value(dev->parent, info);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001166}
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
Quentin Schulz23b16d42024-06-05 11:33:22 +02001173 return _ldo_get_value(dev->parent, info);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001174}
1175
Quentin Schulz23b16d42024-06-05 11:33:22 +02001176static int _ldo_set_value(struct udevice *pmic, const struct rk8xx_reg_info *info, int uvolt)
Quentin Schulzec7dd642024-03-14 10:36:17 +01001177{
Jacob Chen21a6a252017-05-02 14:54:50 +08001178 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -07001179 int val;
1180
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001181 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -07001182 return -ENOSYS;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001183
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
Quentin Schulzec7dd642024-03-14 10:36:17 +01001189 debug("%s: volt=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
1190 __func__, uvolt, info->vsel_reg, mask, val);
Simon Glassadecfef2016-01-21 19:43:30 -07001191
Quentin Schulz23b16d42024-06-05 11:33:22 +02001192 return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
Simon Glassadecfef2016-01-21 19:43:30 -07001193}
1194
Quentin Schulzec7dd642024-03-14 10:36:17 +01001195static int ldo_set_value(struct udevice *dev, int uvolt)
Simon Glassadecfef2016-01-21 19:43:30 -07001196{
1197 int ldo = dev->driver_data - 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001198 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
Quentin Schulzec7dd642024-03-14 10:36:17 +01001199
Quentin Schulz23b16d42024-06-05 11:33:22 +02001200 return _ldo_set_value(dev->parent, info, uvolt);
Quentin Schulzec7dd642024-03-14 10:36:17 +01001201}
1202
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001203static 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
Quentin Schulz23b16d42024-06-05 11:33:22 +02001208 return _ldo_set_value(dev->parent, info, uvolt);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001209}
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
Quentin Schulz23b16d42024-06-05 11:33:22 +02001216 return _ldo_set_value(dev->parent, info, uvolt);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001217}
1218
Quentin Schulze4b47f52024-06-05 11:33:21 +02001219static int _ldo_set_suspend_value(struct udevice *pmic, const struct rk8xx_reg_info *info, int uvolt)
Quentin Schulzec7dd642024-03-14 10:36:17 +01001220{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001221 int mask = info->vsel_mask;
1222 int val;
1223
1224 if (info->vsel_sleep_reg == NA)
1225 return -ENOSYS;
Simon Glassadecfef2016-01-21 19:43:30 -07001226
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001227 if (info->step_uv == 0)
1228 val = info->min_sel;
1229 else
1230 val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
Simon Glassadecfef2016-01-21 19:43:30 -07001231
Quentin Schulzec7dd642024-03-14 10:36:17 +01001232 debug("%s: volt=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
1233 __func__, uvolt, info->vsel_sleep_reg, mask, val);
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001234
Quentin Schulze4b47f52024-06-05 11:33:21 +02001235 return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
Simon Glassadecfef2016-01-21 19:43:30 -07001236}
1237
Quentin Schulzec7dd642024-03-14 10:36:17 +01001238static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
Simon Glassadecfef2016-01-21 19:43:30 -07001239{
1240 int ldo = dev->driver_data - 1;
Quentin Schulzec7dd642024-03-14 10:36:17 +01001241 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
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001246static 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
Quentin Schulze4b47f52024-06-05 11:33:21 +02001262static int _ldo_get_suspend_value(struct udevice *pmic, const struct rk8xx_reg_info *info)
Quentin Schulzec7dd642024-03-14 10:36:17 +01001263{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001264 int mask = info->vsel_mask;
1265 int val, ret;
Simon Glassadecfef2016-01-21 19:43:30 -07001266
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001267 if (info->vsel_sleep_reg == NA)
1268 return -ENOSYS;
Simon Glassadecfef2016-01-21 19:43:30 -07001269
Quentin Schulze4b47f52024-06-05 11:33:21 +02001270 ret = pmic_reg_read(pmic, info->vsel_sleep_reg);
Simon Glassadecfef2016-01-21 19:43:30 -07001271 if (ret < 0)
1272 return ret;
1273
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001274 val = ret & mask;
1275
1276 return info->min_uv + val * info->step_uv;
1277}
1278
Quentin Schulzec7dd642024-03-14 10:36:17 +01001279static 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
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001287static 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
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001303static 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
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001310static 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
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001324static 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
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001331static 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
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001345static 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
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001352static 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
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001366static int ldo_get_enable(struct udevice *dev)
1367{
1368 int ldo = dev->driver_data - 1;
1369
1370 return _ldo_get_enable(dev->parent, ldo);
Simon Glassadecfef2016-01-21 19:43:30 -07001371}
1372
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001373static 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
Simon Glassadecfef2016-01-21 19:43:30 -07001387static int switch_set_enable(struct udevice *dev, bool enable)
1388{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001389 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;
Joseph Chend6b3e832019-09-26 15:45:07 +08001399 case RK809_ID:
1400 mask = (1 << (sw + 2)) | (1 << (sw + 6));
1401 ret = pmic_clrsetbits(dev->parent, RK817_POWER_EN(3), mask,
William Wub863e492024-03-14 10:36:16 +01001402 enable ? mask : (1 << (sw + 6)));
Joseph Chend6b3e832019-09-26 15:45:07 +08001403 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001404 case RK818_ID:
1405 mask = 1 << 6;
1406 ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
1407 enable ? mask : 0);
1408 break;
1409 }
Simon Glassadecfef2016-01-21 19:43:30 -07001410
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001411 debug("%s: switch%d, enable=%d, mask=0x%x\n",
1412 __func__, sw + 1, enable, mask);
Simon Glassadecfef2016-01-21 19:43:30 -07001413
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001414 return ret;
Simon Glassadecfef2016-01-21 19:43:30 -07001415}
1416
Keerthyc8f82fb2017-06-13 09:53:52 +05301417static int switch_get_enable(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001418{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001419 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1420 int ret = 0, sw = dev->driver_data - 1;
1421 uint mask = 0;
Simon Glassadecfef2016-01-21 19:43:30 -07001422
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001423 switch (priv->variant) {
1424 case RK808_ID:
1425 mask = 1 << (sw + 5);
1426 ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
1427 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001428 case RK809_ID:
1429 mask = 1 << (sw + 2);
1430 ret = pmic_reg_read(dev->parent, RK817_POWER_EN(3));
1431 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001432 case RK818_ID:
1433 mask = 1 << 6;
1434 ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
1435 break;
1436 }
Simon Glassadecfef2016-01-21 19:43:30 -07001437
Simon Glassadecfef2016-01-21 19:43:30 -07001438 if (ret < 0)
1439 return ret;
1440
Quentin Schulz53dfd482024-06-05 11:33:23 +02001441 return (ret & mask) ? true : false;
Simon Glassadecfef2016-01-21 19:43:30 -07001442}
1443
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001444static 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;
Joseph Chend6b3e832019-09-26 15:45:07 +08001466 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;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001471 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;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001496 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001497 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001498 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;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001503 ret = (val & mask) ? 1 : 0;
Joseph Chend6b3e832019-09-26 15:45:07 +08001504 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001505 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;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001510 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001511 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{
shengfei Xu7851d4e2023-08-21 22:30:26 +00001525 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
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001544 return 0;
1545}
1546
1547static int switch_set_value(struct udevice *dev, int uvolt)
1548{
1549 return 0;
1550}
1551
Jacob Chen614704b2017-05-02 14:54:52 +08001552static int rk8xx_buck_probe(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001553{
Simon Glass71fa5b42020-12-03 16:55:18 -07001554 struct dm_regulator_uclass_plat *uc_pdata;
Simon Glassadecfef2016-01-21 19:43:30 -07001555
Simon Glass71fa5b42020-12-03 16:55:18 -07001556 uc_pdata = dev_get_uclass_plat(dev);
Simon Glassadecfef2016-01-21 19:43:30 -07001557
1558 uc_pdata->type = REGULATOR_TYPE_BUCK;
1559 uc_pdata->mode_count = 0;
1560
1561 return 0;
1562}
1563
Jacob Chen614704b2017-05-02 14:54:52 +08001564static int rk8xx_ldo_probe(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001565{
Simon Glass71fa5b42020-12-03 16:55:18 -07001566 struct dm_regulator_uclass_plat *uc_pdata;
Simon Glassadecfef2016-01-21 19:43:30 -07001567
Simon Glass71fa5b42020-12-03 16:55:18 -07001568 uc_pdata = dev_get_uclass_plat(dev);
Simon Glassadecfef2016-01-21 19:43:30 -07001569
1570 uc_pdata->type = REGULATOR_TYPE_LDO;
1571 uc_pdata->mode_count = 0;
1572
1573 return 0;
1574}
1575
Jacob Chen614704b2017-05-02 14:54:52 +08001576static int rk8xx_switch_probe(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001577{
Simon Glass71fa5b42020-12-03 16:55:18 -07001578 struct dm_regulator_uclass_plat *uc_pdata;
Simon Glassadecfef2016-01-21 19:43:30 -07001579
Simon Glass71fa5b42020-12-03 16:55:18 -07001580 uc_pdata = dev_get_uclass_plat(dev);
Simon Glassadecfef2016-01-21 19:43:30 -07001581
1582 uc_pdata->type = REGULATOR_TYPE_FIXED;
1583 uc_pdata->mode_count = 0;
1584
1585 return 0;
1586}
1587
Jacob Chen614704b2017-05-02 14:54:52 +08001588static const struct dm_regulator_ops rk8xx_buck_ops = {
Simon Glassadecfef2016-01-21 19:43:30 -07001589 .get_value = buck_get_value,
1590 .set_value = buck_set_value,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001591 .set_suspend_value = buck_set_suspend_value,
1592 .get_suspend_value = buck_get_suspend_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001593 .get_enable = buck_get_enable,
1594 .set_enable = buck_set_enable,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001595 .set_suspend_enable = buck_set_suspend_enable,
1596 .get_suspend_enable = buck_get_suspend_enable,
Simon Glassadecfef2016-01-21 19:43:30 -07001597};
1598
Jacob Chen614704b2017-05-02 14:54:52 +08001599static const struct dm_regulator_ops rk8xx_ldo_ops = {
Simon Glassadecfef2016-01-21 19:43:30 -07001600 .get_value = ldo_get_value,
1601 .set_value = ldo_set_value,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001602 .set_suspend_value = ldo_set_suspend_value,
1603 .get_suspend_value = ldo_get_suspend_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001604 .get_enable = ldo_get_enable,
1605 .set_enable = ldo_set_enable,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001606 .set_suspend_enable = ldo_set_suspend_enable,
1607 .get_suspend_enable = ldo_get_suspend_enable,
Simon Glassadecfef2016-01-21 19:43:30 -07001608};
1609
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001610static 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
Jacob Chen614704b2017-05-02 14:54:52 +08001632static const struct dm_regulator_ops rk8xx_switch_ops = {
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001633 .get_value = switch_get_value,
1634 .set_value = switch_set_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001635 .get_enable = switch_get_enable,
1636 .set_enable = switch_set_enable,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001637 .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,
Simon Glassadecfef2016-01-21 19:43:30 -07001641};
1642
Jacob Chen614704b2017-05-02 14:54:52 +08001643U_BOOT_DRIVER(rk8xx_buck) = {
1644 .name = "rk8xx_buck",
Simon Glassadecfef2016-01-21 19:43:30 -07001645 .id = UCLASS_REGULATOR,
Jacob Chen614704b2017-05-02 14:54:52 +08001646 .ops = &rk8xx_buck_ops,
1647 .probe = rk8xx_buck_probe,
Simon Glassadecfef2016-01-21 19:43:30 -07001648};
1649
Jacob Chen614704b2017-05-02 14:54:52 +08001650U_BOOT_DRIVER(rk8xx_ldo) = {
1651 .name = "rk8xx_ldo",
Simon Glassadecfef2016-01-21 19:43:30 -07001652 .id = UCLASS_REGULATOR,
Jacob Chen614704b2017-05-02 14:54:52 +08001653 .ops = &rk8xx_ldo_ops,
1654 .probe = rk8xx_ldo_probe,
Simon Glassadecfef2016-01-21 19:43:30 -07001655};
1656
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001657U_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
Jacob Chen614704b2017-05-02 14:54:52 +08001671U_BOOT_DRIVER(rk8xx_switch) = {
1672 .name = "rk8xx_switch",
Simon Glassadecfef2016-01-21 19:43:30 -07001673 .id = UCLASS_REGULATOR,
Jacob Chen614704b2017-05-02 14:54:52 +08001674 .ops = &rk8xx_switch_ops,
1675 .probe = rk8xx_switch_probe,
Simon Glassadecfef2016-01-21 19:43:30 -07001676};
1677#endif
1678
Jacob Chen614704b2017-05-02 14:54:52 +08001679int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
Simon Glassadecfef2016-01-21 19:43:30 -07001680{
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}