blob: 34e61511d884c2318e25052c28283ecec73fe194 [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
Simon Glassadecfef2016-01-21 19:43:30 -070011#include <dm.h>
12#include <errno.h>
Simon Glass0f2af882020-05-10 11:40:05 -060013#include <log.h>
Jonas Karlman31c3c802023-07-02 12:41:15 +000014#include <linux/delay.h>
Jacob Chen614704b2017-05-02 14:54:52 +080015#include <power/rk8xx_pmic.h>
Simon Glassadecfef2016-01-21 19:43:30 -070016#include <power/pmic.h>
17#include <power/regulator.h>
18
19#ifndef CONFIG_SPL_BUILD
20#define ENABLE_DRIVER
21#endif
22
Elaine Zhangfa9cccc2019-09-26 15:43:53 +080023/* Not used or exisit register and configure */
24#define NA 0xff
25
Jacob Chen21a6a252017-05-02 14:54:50 +080026/* Field Definitions */
Quentin Schulzf7c6da12024-03-14 10:36:18 +010027#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
Jacob Chen21a6a252017-05-02 14:54:50 +080040#define RK808_BUCK_VSEL_MASK 0x3f
41#define RK808_BUCK4_VSEL_MASK 0xf
42#define RK808_LDO_VSEL_MASK 0x1f
43
Joseph Chend6b3e832019-09-26 15:45:07 +080044/* RK809 BUCK5 */
45#define RK809_BUCK5_CONFIG(n) (0xde + (n) * 1)
46#define RK809_BUCK5_VSEL_MASK 0x07
47
Joseph Chen4a1ae182019-09-26 15:44:55 +080048/* 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
Jacob Chen36163e32017-05-02 14:54:51 +080063#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
Wadim Egorovc2581052017-06-19 12:36:39 +020068#define RK818_USB_ILIM_SEL_MASK 0x0f
69#define RK818_USB_CHG_SD_VSEL_MASK 0x70
70
Elaine Zhangfa9cccc2019-09-26 15:43:53 +080071/*
72 * Ramp delay
73 */
Elaine Zhang1d9077e2019-09-26 15:43:55 +080074#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)
Joseph Chend6b3e832019-09-26 15:45:07 +080080
Elaine Zhangfa9cccc2019-09-26 15:43:53 +080081#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)
Jacob Chen36163e32017-05-02 14:54:51 +080087
Joseph Chen4a1ae182019-09-26 15:44:55 +080088#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
Jacob Chen614704b2017-05-02 14:54:52 +080095struct rk8xx_reg_info {
Simon Glassadecfef2016-01-21 19:43:30 -070096 uint min_uv;
97 uint step_uv;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +080098 u8 vsel_reg;
99 u8 vsel_sleep_reg;
100 u8 config_reg;
Jacob Chen21a6a252017-05-02 14:54:50 +0800101 u8 vsel_mask;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800102 u8 min_sel;
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000103 u8 max_sel;
Simon Glassadecfef2016-01-21 19:43:30 -0700104};
105
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100106static 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
Jacob Chen614704b2017-05-02 14:54:52 +0800149static const struct rk8xx_reg_info rk808_buck[] = {
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000150 { 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 },
Simon Glassadecfef2016-01-21 19:43:30 -0700154};
155
Elaine Zhang04e5a432019-09-26 15:43:54 +0800156static const struct rk8xx_reg_info rk816_buck[] = {
157 /* buck 1 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000158 { 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 },
Elaine Zhang04e5a432019-09-26 15:43:54 +0800161 /* buck 2 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000162 { 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 },
Elaine Zhang04e5a432019-09-26 15:43:54 +0800165 /* buck 3 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000166 { NA, NA, NA, NA, REG_BUCK3_CONFIG, NA, NA, NA },
Elaine Zhang04e5a432019-09-26 15:43:54 +0800167 /* buck 4 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000168 { 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 +0800169};
170
Joseph Chend6b3e832019-09-26 15:45:07 +0800171static const struct rk8xx_reg_info rk809_buck5[] = {
172 /* buck 5 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000173 { 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 },
Joseph Chend6b3e832019-09-26 15:45:07 +0800177};
178
Joseph Chen4a1ae182019-09-26 15:44:55 +0800179static const struct rk8xx_reg_info rk817_buck[] = {
180 /* buck 1 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000181 { 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 },
Joseph Chen4a1ae182019-09-26 15:44:55 +0800184 /* buck 2 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000185 { 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 },
Joseph Chen4a1ae182019-09-26 15:44:55 +0800188 /* buck 3 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000189 { 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 },
Joseph Chen4a1ae182019-09-26 15:44:55 +0800192 /* buck 4 */
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000193 { 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 },
Joseph Chen4a1ae182019-09-26 15:44:55 +0800196};
197
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200198static const struct rk8xx_reg_info rk818_buck[] = {
Joseph Chenfb18ddd2023-08-21 22:30:25 +0000199 { 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 },
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200203};
204
205#ifdef ENABLE_DRIVER
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100206static 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
Jacob Chen614704b2017-05-02 14:54:52 +0800245static const struct rk8xx_reg_info rk808_ldo[] = {
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800246 { 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, },
Simon Glassadecfef2016-01-21 19:43:30 -0700254};
255
Elaine Zhang04e5a432019-09-26 15:43:54 +0800256static 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
Joseph Chen4a1ae182019-09-26 15:44:55 +0800265static 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
Jacob Chen614704b2017-05-02 14:54:52 +0800295static const struct rk8xx_reg_info rk818_ldo[] = {
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800296 { 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, },
Jacob Chen36163e32017-05-02 14:54:51 +0800304};
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200305#endif
Jacob Chen36163e32017-05-02 14:54:51 +0800306
Jacob Chen614704b2017-05-02 14:54:52 +0800307static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800308 int num, int uvolt)
Jacob Chen36163e32017-05-02 14:54:51 +0800309{
Jacob Chen614704b2017-05-02 14:54:52 +0800310 struct rk8xx_priv *priv = dev_get_priv(pmic);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800311
Jacob Chen614704b2017-05-02 14:54:52 +0800312 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800313 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800314 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 }
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100327 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];
Joseph Chend6b3e832019-09-26 15:45:07 +0800333 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800334 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];
Joseph Chend6b3e832019-09-26 15:45:07 +0800350 /* 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];
Joseph Chen4a1ae182019-09-26 15:44:55 +0800360 }
Jacob Chen36163e32017-05-02 14:54:51 +0800361 case RK818_ID:
362 return &rk818_buck[num];
363 default:
364 return &rk808_buck[num];
365 }
366}
367
Simon Glassadecfef2016-01-21 19:43:30 -0700368static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
369{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800370 const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800371 struct rk8xx_priv *priv = dev_get_priv(pmic);
Jacob Chen21a6a252017-05-02 14:54:50 +0800372 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -0700373 int val;
374
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800375 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -0700376 return -ENOSYS;
Elaine Zhang04e5a432019-09-26 15:43:54 +0800377
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800378 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",
384 __func__, uvolt, buck + 1, info->vsel_reg, mask, val);
385
Elaine Zhang04e5a432019-09-26 15:43:54 +0800386 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 }
Simon Glassadecfef2016-01-21 19:43:30 -0700393}
394
395static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
396{
Elaine Zhang04e5a432019-09-26 15:43:54 +0800397 uint mask, value, en_reg;
Joseph Chen4a1ae182019-09-26 15:44:55 +0800398 int ret = 0;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800399 struct rk8xx_priv *priv = dev_get_priv(pmic);
Simon Glassadecfef2016-01-21 19:43:30 -0700400
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800401 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800402 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800403 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;
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100416 case RK806_ID:
417 value = RK806_POWER_EN_CLRSETBITS(buck % 4, enable);
418 en_reg = RK806_POWER_EN((buck + 1) / 4);
419 ret = pmic_reg_write(pmic, en_reg, value);
420 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800421 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;
Joseph Chend6b3e832019-09-26 15:45:07 +0800433 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800434 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);
Joseph Chend6b3e832019-09-26 15:45:07 +0800441 /* 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);
Joseph Chen4a1ae182019-09-26 15:44:55 +0800448 }
449 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800450 default:
451 ret = -EINVAL;
Simon Glassadecfef2016-01-21 19:43:30 -0700452 }
453
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800454 return ret;
Simon Glassadecfef2016-01-21 19:43:30 -0700455}
456
457#ifdef ENABLE_DRIVER
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800458static 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",
473 __func__, uvolt, buck + 1, info->vsel_sleep_reg, mask, val);
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) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800485 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800486 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;
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100495 case RK806_ID:
496 mask = BIT(buck % 4);
497 ret = pmic_reg_read(pmic, RK806_POWER_EN((buck + 1) / 4));
498 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800499 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;
Joseph Chend6b3e832019-09-26 15:45:07 +0800506 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800507 case RK817_ID:
508 if (buck < 4) {
509 mask = 1 << buck;
510 ret = pmic_reg_read(pmic, RK817_POWER_EN(0));
Joseph Chend6b3e832019-09-26 15:45:07 +0800511 /* BUCK5 for RK809 */
512 } else {
513 mask = 1 << 1;
514 ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
Joseph Chen4a1ae182019-09-26 15:44:55 +0800515 }
516 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800517 }
518
519 if (ret < 0)
520 return ret;
521
Quentin Schulz53dfd482024-06-05 11:33:23 +0200522 return (ret & mask) ? true : false;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800523}
524
525static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
526{
Joseph Chen4a1ae182019-09-26 15:44:55 +0800527 uint mask = 0;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800528 int ret;
529 struct rk8xx_priv *priv = dev_get_priv(pmic);
530
531 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800532 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800533 case RK816_ID:
534 mask = 1 << buck;
535 ret = pmic_clrsetbits(pmic, RK816_REG_DCDC_SLP_EN, mask,
536 enable ? mask : 0);
537 break;
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100538 case RK806_ID:
539 {
540 u8 reg;
541
542 if (buck + 1 >= 9) {
543 reg = RK806_POWER_SLP_EN1;
544 mask = BIT(buck + 1 - 3);
545 } else {
546 reg = RK806_POWER_SLP_EN0;
547 mask = BIT(buck + 1);
548 }
549 ret = pmic_clrsetbits(pmic, reg, mask, enable ? mask : 0);
550 }
551 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800552 case RK808_ID:
553 case RK818_ID:
554 mask = 1 << buck;
555 ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask,
556 enable ? 0 : mask);
557 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800558 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800559 case RK817_ID:
560 if (buck < 4)
561 mask = 1 << buck;
Joseph Chend6b3e832019-09-26 15:45:07 +0800562 else
563 mask = 1 << 5; /* BUCK5 for RK809 */
Joseph Chen4a1ae182019-09-26 15:44:55 +0800564 ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
565 enable ? mask : 0);
566 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800567 default:
568 ret = -EINVAL;
569 }
570
571 return ret;
572}
573
574static int _buck_get_suspend_enable(struct udevice *pmic, int buck)
575{
576 struct rk8xx_priv *priv = dev_get_priv(pmic);
577 int ret, val;
Joseph Chen4a1ae182019-09-26 15:44:55 +0800578 uint mask = 0;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800579
580 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800581 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800582 case RK816_ID:
583 mask = 1 << buck;
584 val = pmic_reg_read(pmic, RK816_REG_DCDC_SLP_EN);
585 if (val < 0)
586 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200587 ret = (val & mask) ? 1 : 0;
Elaine Zhang04e5a432019-09-26 15:43:54 +0800588 break;
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100589 case RK806_ID:
590 {
591 u8 reg;
592
593 if (buck + 1 >= 9) {
594 reg = RK806_POWER_SLP_EN1;
595 mask = BIT(buck + 1 - 3);
596 } else {
597 reg = RK806_POWER_SLP_EN0;
598 mask = BIT(buck + 1);
599 }
600 val = pmic_reg_read(pmic, reg);
601 }
602 ret = (val & mask) ? 1 : 0;
603 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800604 case RK808_ID:
605 case RK818_ID:
606 mask = 1 << buck;
607 val = pmic_reg_read(pmic, REG_SLEEP_SET_OFF1);
608 if (val < 0)
609 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200610 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800611 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800612 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800613 case RK817_ID:
614 if (buck < 4)
615 mask = 1 << buck;
Joseph Chend6b3e832019-09-26 15:45:07 +0800616 else
617 mask = 1 << 5; /* BUCK5 for RK809 */
Joseph Chen4a1ae182019-09-26 15:44:55 +0800618
619 val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
620 if (val < 0)
621 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200622 ret = (val & mask) ? 1 : 0;
Joseph Chen4a1ae182019-09-26 15:44:55 +0800623 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800624 default:
625 ret = -EINVAL;
626 }
627
628 return ret;
629}
630
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200631static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800632 int num, int uvolt)
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200633{
634 struct rk8xx_priv *priv = dev_get_priv(pmic);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800635
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200636 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800637 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800638 case RK816_ID:
639 return &rk816_ldo[num];
Joseph Chend6b3e832019-09-26 15:45:07 +0800640 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800641 case RK817_ID:
642 if (uvolt < 3400000)
643 return &rk817_ldo[num * 2 + 0];
644 else
645 return &rk817_ldo[num * 2 + 1];
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200646 case RK818_ID:
647 return &rk818_ldo[num];
648 default:
649 return &rk808_ldo[num];
650 }
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800651}
652
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100653static const struct rk8xx_reg_info *get_nldo_reg(struct udevice *pmic,
654 int num, int uvolt)
655{
656 const struct rk8xx_priv *priv = dev_get_priv(pmic);
657
658 switch (priv->variant) {
659 case RK806_ID:
660 default:
661 if (uvolt < 3400000)
662 return &rk806_nldo[num * 2 + 0];
663 return &rk806_nldo[num * 2 + 1];
664 }
665}
666
667static const struct rk8xx_reg_info *get_pldo_reg(struct udevice *pmic,
668 int num, int uvolt)
669{
670 const struct rk8xx_priv *priv = dev_get_priv(pmic);
671
672 switch (priv->variant) {
673 case RK806_ID:
674 default:
675 if (uvolt < 3400000)
676 return &rk806_pldo[num * 2 + 0];
677 return &rk806_pldo[num * 2 + 1];
678 }
679}
680
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800681static int _ldo_get_enable(struct udevice *pmic, int ldo)
682{
683 struct rk8xx_priv *priv = dev_get_priv(pmic);
684 uint mask = 0;
685 int ret = 0;
686
687 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800688 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800689 case RK816_ID:
690 if (ldo >= 4) {
691 mask = 1 << (ldo - 4);
692 ret = pmic_reg_read(pmic, RK816_REG_LDO_EN2);
693 } else {
694 mask = 1 << ldo;
695 ret = pmic_reg_read(pmic, RK816_REG_LDO_EN1);
696 }
697 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800698 case RK808_ID:
699 case RK818_ID:
700 mask = 1 << ldo;
701 ret = pmic_reg_read(pmic, REG_LDO_EN);
702 if (ret < 0)
703 return ret;
704 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800705 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800706 case RK817_ID:
707 if (ldo < 4) {
708 mask = 1 << ldo;
709 ret = pmic_reg_read(pmic, RK817_POWER_EN(1));
710 } else if (ldo < 8) {
711 mask = 1 << (ldo - 4);
712 ret = pmic_reg_read(pmic, RK817_POWER_EN(2));
713 } else if (ldo == 8) {
714 mask = 1 << 0;
715 ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
716 } else {
717 return false;
718 }
719 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800720 }
721
722 if (ret < 0)
723 return ret;
724
Quentin Schulz53dfd482024-06-05 11:33:23 +0200725 return (ret & mask) ? true : false;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800726}
727
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100728static int _nldo_get_enable(struct udevice *pmic, int nldo)
729{
730 struct rk8xx_priv *priv = dev_get_priv(pmic);
731 uint mask = 0;
732 int ret = 0;
733 u8 en_reg = 0;
734
735 switch (priv->variant) {
736 case RK806_ID:
737 default:
738 if (nldo + 1 >= 5) {
739 mask = BIT(2);
740 en_reg = RK806_POWER_EN(5);
741 } else {
742 mask = BIT(nldo);
743 en_reg = RK806_POWER_EN(3);
744 }
745 ret = pmic_reg_read(pmic, en_reg);
746 break;
747 }
748
749 if (ret < 0)
750 return ret;
751
752 return (ret & mask) ? 1 : 0;
753}
754
755static int _pldo_get_enable(struct udevice *pmic, int pldo)
756{
757 struct rk8xx_priv *priv = dev_get_priv(pmic);
758 uint mask = 0;
759 int ret = 0;
760 u8 en_reg = 0;
761
762 switch (priv->variant) {
763 case RK806_ID:
764 default:
765 if (pldo + 1 <= 3) {
766 mask = BIT(pldo + 1);
767 en_reg = RK806_POWER_EN(4);
768 } else if (pldo + 1 == 6) {
769 mask = BIT(0);
770 en_reg = RK806_POWER_EN(4);
771 } else {
772 mask = BIT((pldo + 1) % 4);
773 en_reg = RK806_POWER_EN(5);
774 }
775 ret = pmic_reg_read(pmic, en_reg);
776 break;
777 }
778
779 if (ret < 0)
780 return ret;
781
782 return (ret & mask) ? 1 : 0;
783}
784
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800785static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
786{
787 struct rk8xx_priv *priv = dev_get_priv(pmic);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800788 uint mask, value, en_reg;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800789 int ret = 0;
790
791 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800792 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800793 case RK816_ID:
794 if (ldo >= 4) {
795 ldo -= 4;
796 en_reg = RK816_REG_LDO_EN2;
797 } else {
798 en_reg = RK816_REG_LDO_EN1;
799 }
800 if (enable)
801 value = ((1 << ldo) | (1 << (ldo + 4)));
802 else
803 value = ((0 << ldo) | (1 << (ldo + 4)));
804
805 ret = pmic_reg_write(pmic, en_reg, value);
806 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800807 case RK808_ID:
808 case RK818_ID:
809 mask = 1 << ldo;
810 ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
Elaine Zhang04e5a432019-09-26 15:43:54 +0800811 enable ? mask : 0);
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800812 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800813 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800814 case RK817_ID:
815 if (ldo < 4) {
816 en_reg = RK817_POWER_EN(1);
817 } else if (ldo < 8) {
818 ldo -= 4;
819 en_reg = RK817_POWER_EN(2);
820 } else if (ldo == 8) {
821 ldo = 0; /* BIT 0 */
822 en_reg = RK817_POWER_EN(3);
823 } else {
824 return -EINVAL;
825 }
826 if (enable)
827 value = ((1 << ldo) | (1 << (ldo + 4)));
828 else
829 value = ((0 << ldo) | (1 << (ldo + 4)));
830 ret = pmic_reg_write(pmic, en_reg, value);
831 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800832 }
833
Jonas Karlman31c3c802023-07-02 12:41:15 +0000834 if (enable)
835 udelay(500);
836
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800837 return ret;
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200838}
839
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100840static int _nldo_set_enable(struct udevice *pmic, int nldo, bool enable)
841{
842 struct rk8xx_priv *priv = dev_get_priv(pmic);
843 uint value, en_reg;
844 int ret = 0;
845
846 switch (priv->variant) {
847 case RK806_ID:
848 default:
849 if (nldo + 1 >= 5) {
850 value = RK806_POWER_EN_CLRSETBITS(2, enable);
851 en_reg = RK806_POWER_EN(5);
852 } else {
853 value = RK806_POWER_EN_CLRSETBITS(nldo, enable);
854 en_reg = RK806_POWER_EN(3);
855 }
856 ret = pmic_reg_write(pmic, en_reg, value);
857 break;
858 }
859
860 if (enable)
861 udelay(500);
862
863 return ret;
864}
865
866static int _pldo_set_enable(struct udevice *pmic, int pldo, bool enable)
867{
868 struct rk8xx_priv *priv = dev_get_priv(pmic);
869 uint value, en_reg;
870 int ret = 0;
871
872 switch (priv->variant) {
873 case RK806_ID:
874 default:
875 /* PLDO */
876 if (pldo + 1 <= 3) {
877 value = RK806_POWER_EN_CLRSETBITS(pldo + 1, enable);
878 en_reg = RK806_POWER_EN(4);
879 } else if (pldo + 1 == 6) {
880 value = RK806_POWER_EN_CLRSETBITS(0, enable);
881 en_reg = RK806_POWER_EN(4);
882 } else {
883 value = RK806_POWER_EN_CLRSETBITS((pldo + 1) % 4, enable);
884 en_reg = RK806_POWER_EN(5);
885 }
886 ret = pmic_reg_write(pmic, en_reg, value);
887 break;
888 }
889
890 if (enable)
891 udelay(500);
892
893 return ret;
894}
895
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800896static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
897{
898 struct rk8xx_priv *priv = dev_get_priv(pmic);
899 uint mask;
900 int ret = 0;
901
902 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800903 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800904 case RK816_ID:
905 mask = 1 << ldo;
906 ret = pmic_clrsetbits(pmic, RK816_REG_LDO_SLP_EN, mask,
907 enable ? mask : 0);
908 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800909 case RK808_ID:
910 case RK818_ID:
911 mask = 1 << ldo;
912 ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask,
913 enable ? 0 : mask);
914 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800915 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800916 case RK817_ID:
917 if (ldo == 8) {
918 mask = 1 << 4; /* LDO9 */
919 ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
920 enable ? mask : 0);
921 } else {
922 mask = 1 << ldo;
923 ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(1), mask,
924 enable ? mask : 0);
925 }
926 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800927 }
928
929 return ret;
930}
931
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100932static int _nldo_set_suspend_enable(struct udevice *pmic, int nldo, bool enable)
933{
934 struct rk8xx_priv *priv = dev_get_priv(pmic);
935 uint mask;
936 int ret = 0;
937
938 switch (priv->variant) {
939 case RK806_ID:
940 default:
941 mask = BIT(nldo);
942 ret = pmic_clrsetbits(pmic, RK806_POWER_SLP_EN1, mask, enable ? mask : 0);
943 break;
944 }
945
946 return ret;
947}
948
949static int _pldo_set_suspend_enable(struct udevice *pmic, int pldo, bool enable)
950{
951 struct rk8xx_priv *priv = dev_get_priv(pmic);
952 uint mask;
953 int ret = 0;
954
955 switch (priv->variant) {
956 case RK806_ID:
957 default:
958 if (pldo + 1 >= 6)
959 mask = BIT(0);
960 else
961 mask = BIT(pldo + 1);
962 ret = pmic_clrsetbits(pmic, RK806_POWER_SLP_EN2, mask, enable ? mask : 0);
963 break;
964 }
965
966 return ret;
967}
968
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800969static int _ldo_get_suspend_enable(struct udevice *pmic, int ldo)
970{
971 struct rk8xx_priv *priv = dev_get_priv(pmic);
972 int val, ret = 0;
973 uint mask;
974
975 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800976 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800977 case RK816_ID:
978 mask = 1 << ldo;
979 val = pmic_reg_read(pmic, RK816_REG_LDO_SLP_EN);
980 if (val < 0)
981 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200982 ret = (val & mask) ? 1 : 0;
Elaine Zhang04e5a432019-09-26 15:43:54 +0800983 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800984 case RK808_ID:
985 case RK818_ID:
986 mask = 1 << ldo;
987 val = pmic_reg_read(pmic, REG_SLEEP_SET_OFF2);
988 if (val < 0)
989 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200990 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800991 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800992 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800993 case RK817_ID:
994 if (ldo == 8) {
995 mask = 1 << 4; /* LDO9 */
996 val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
997 if (val < 0)
998 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200999 ret = (val & mask) ? 1 : 0;
Joseph Chen4a1ae182019-09-26 15:44:55 +08001000 } else {
1001 mask = 1 << ldo;
1002 val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(1));
1003 if (val < 0)
1004 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001005 ret = (val & mask) ? 1 : 0;
Joseph Chen4a1ae182019-09-26 15:44:55 +08001006 }
1007 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001008 }
1009
1010 return ret;
1011}
1012
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001013static int _nldo_get_suspend_enable(struct udevice *pmic, int nldo)
1014{
1015 struct rk8xx_priv *priv = dev_get_priv(pmic);
1016 int val, ret = 0;
1017 uint mask;
1018
1019 switch (priv->variant) {
1020 case RK806_ID:
1021 default:
1022 mask = BIT(nldo);
1023 val = pmic_reg_read(pmic, RK806_POWER_SLP_EN1);
1024 ret = (val & mask) ? 1 : 0;
1025 break;
1026 }
1027
1028 return ret;
1029}
1030
1031static int _pldo_get_suspend_enable(struct udevice *pmic, int pldo)
1032{
1033 struct rk8xx_priv *priv = dev_get_priv(pmic);
1034 int val, ret = 0;
1035 uint mask;
1036
1037 switch (priv->variant) {
1038 case RK806_ID:
1039 default:
1040 if (pldo + 1 >= 6)
1041 mask = BIT(0);
1042 else
1043 mask = BIT(pldo + 1);
1044 val = pmic_reg_read(pmic, RK806_POWER_SLP_EN2);
1045 ret = (val & mask) ? 1 : 0;
1046 break;
1047 }
1048
1049 return ret;
1050}
1051
Simon Glassadecfef2016-01-21 19:43:30 -07001052static int buck_get_value(struct udevice *dev)
1053{
1054 int buck = dev->driver_data - 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001055 const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
Jacob Chen21a6a252017-05-02 14:54:50 +08001056 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -07001057 int ret, val;
1058
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001059 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -07001060 return -ENOSYS;
Elaine Zhang04e5a432019-09-26 15:43:54 +08001061
Simon Glassadecfef2016-01-21 19:43:30 -07001062 ret = pmic_reg_read(dev->parent, info->vsel_reg);
1063 if (ret < 0)
1064 return ret;
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001065
Simon Glassadecfef2016-01-21 19:43:30 -07001066 val = ret & mask;
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001067 while (val > info->max_sel)
1068 info++;
Simon Glassadecfef2016-01-21 19:43:30 -07001069
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001070 return info->min_uv + (val - info->min_sel) * info->step_uv;
Simon Glassadecfef2016-01-21 19:43:30 -07001071}
1072
1073static int buck_set_value(struct udevice *dev, int uvolt)
1074{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001075 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001076
1077 return _buck_set_value(dev->parent, buck, uvolt);
1078}
1079
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001080static int buck_get_suspend_value(struct udevice *dev)
1081{
1082 int buck = dev->driver_data - 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001083 const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
1084 int mask = info->vsel_mask;
1085 int ret, val;
1086
1087 if (info->vsel_sleep_reg == NA)
1088 return -ENOSYS;
1089
1090 ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
1091 if (ret < 0)
1092 return ret;
1093
1094 val = ret & mask;
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001095 while (val > info->max_sel)
1096 info++;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001097
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001098 return info->min_uv + (val - info->min_sel) * info->step_uv;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001099}
1100
1101static int buck_set_suspend_value(struct udevice *dev, int uvolt)
1102{
1103 int buck = dev->driver_data - 1;
1104
1105 return _buck_set_suspend_value(dev->parent, buck, uvolt);
1106}
1107
Simon Glassadecfef2016-01-21 19:43:30 -07001108static int buck_set_enable(struct udevice *dev, bool enable)
1109{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001110 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001111
1112 return _buck_set_enable(dev->parent, buck, enable);
1113}
1114
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001115static int buck_set_suspend_enable(struct udevice *dev, bool enable)
Simon Glassadecfef2016-01-21 19:43:30 -07001116{
1117 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001118
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001119 return _buck_set_suspend_enable(dev->parent, buck, enable);
1120}
Simon Glassadecfef2016-01-21 19:43:30 -07001121
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001122static int buck_get_suspend_enable(struct udevice *dev)
1123{
1124 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001125
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001126 return _buck_get_suspend_enable(dev->parent, buck);
Simon Glassadecfef2016-01-21 19:43:30 -07001127}
1128
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001129static int buck_get_enable(struct udevice *dev)
1130{
1131 int buck = dev->driver_data - 1;
1132
1133 return _buck_get_enable(dev->parent, buck);
1134}
1135
Quentin Schulz23b16d42024-06-05 11:33:22 +02001136static int _ldo_get_value(struct udevice *pmic, const struct rk8xx_reg_info *info)
Simon Glassadecfef2016-01-21 19:43:30 -07001137{
Jacob Chen21a6a252017-05-02 14:54:50 +08001138 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -07001139 int ret, val;
1140
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001141 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -07001142 return -ENOSYS;
Quentin Schulz23b16d42024-06-05 11:33:22 +02001143 ret = pmic_reg_read(pmic, info->vsel_reg);
Simon Glassadecfef2016-01-21 19:43:30 -07001144 if (ret < 0)
1145 return ret;
1146 val = ret & mask;
1147
1148 return info->min_uv + val * info->step_uv;
1149}
1150
Quentin Schulzec7dd642024-03-14 10:36:17 +01001151static int ldo_get_value(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001152{
1153 int ldo = dev->driver_data - 1;
Quentin Schulzec7dd642024-03-14 10:36:17 +01001154 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
1155
Quentin Schulz23b16d42024-06-05 11:33:22 +02001156 return _ldo_get_value(dev->parent, info);
Quentin Schulzec7dd642024-03-14 10:36:17 +01001157}
1158
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001159static int nldo_get_value(struct udevice *dev)
1160{
1161 int nldo = dev->driver_data - 1;
1162 const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, 0);
1163
Quentin Schulz23b16d42024-06-05 11:33:22 +02001164 return _ldo_get_value(dev->parent, info);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001165}
1166
1167static int pldo_get_value(struct udevice *dev)
1168{
1169 int pldo = dev->driver_data - 1;
1170 const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, 0);
1171
Quentin Schulz23b16d42024-06-05 11:33:22 +02001172 return _ldo_get_value(dev->parent, info);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001173}
1174
Quentin Schulz23b16d42024-06-05 11:33:22 +02001175static int _ldo_set_value(struct udevice *pmic, const struct rk8xx_reg_info *info, int uvolt)
Quentin Schulzec7dd642024-03-14 10:36:17 +01001176{
Jacob Chen21a6a252017-05-02 14:54:50 +08001177 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -07001178 int val;
1179
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001180 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -07001181 return -ENOSYS;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001182
1183 if (info->step_uv == 0)
1184 val = info->min_sel;
1185 else
1186 val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
1187
Quentin Schulzec7dd642024-03-14 10:36:17 +01001188 debug("%s: volt=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
1189 __func__, uvolt, info->vsel_reg, mask, val);
Simon Glassadecfef2016-01-21 19:43:30 -07001190
Quentin Schulz23b16d42024-06-05 11:33:22 +02001191 return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
Simon Glassadecfef2016-01-21 19:43:30 -07001192}
1193
Quentin Schulzec7dd642024-03-14 10:36:17 +01001194static int ldo_set_value(struct udevice *dev, int uvolt)
Simon Glassadecfef2016-01-21 19:43:30 -07001195{
1196 int ldo = dev->driver_data - 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001197 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
Quentin Schulzec7dd642024-03-14 10:36:17 +01001198
Quentin Schulz23b16d42024-06-05 11:33:22 +02001199 return _ldo_set_value(dev->parent, info, uvolt);
Quentin Schulzec7dd642024-03-14 10:36:17 +01001200}
1201
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001202static int nldo_set_value(struct udevice *dev, int uvolt)
1203{
1204 int nldo = dev->driver_data - 1;
1205 const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, uvolt);
1206
Quentin Schulz23b16d42024-06-05 11:33:22 +02001207 return _ldo_set_value(dev->parent, info, uvolt);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001208}
1209
1210static int pldo_set_value(struct udevice *dev, int uvolt)
1211{
1212 int pldo = dev->driver_data - 1;
1213 const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, uvolt);
1214
Quentin Schulz23b16d42024-06-05 11:33:22 +02001215 return _ldo_set_value(dev->parent, info, uvolt);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001216}
1217
Quentin Schulze4b47f52024-06-05 11:33:21 +02001218static int _ldo_set_suspend_value(struct udevice *pmic, const struct rk8xx_reg_info *info, int uvolt)
Quentin Schulzec7dd642024-03-14 10:36:17 +01001219{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001220 int mask = info->vsel_mask;
1221 int val;
1222
1223 if (info->vsel_sleep_reg == NA)
1224 return -ENOSYS;
Simon Glassadecfef2016-01-21 19:43:30 -07001225
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001226 if (info->step_uv == 0)
1227 val = info->min_sel;
1228 else
1229 val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
Simon Glassadecfef2016-01-21 19:43:30 -07001230
Quentin Schulzec7dd642024-03-14 10:36:17 +01001231 debug("%s: volt=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
1232 __func__, uvolt, info->vsel_sleep_reg, mask, val);
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001233
Quentin Schulze4b47f52024-06-05 11:33:21 +02001234 return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
Simon Glassadecfef2016-01-21 19:43:30 -07001235}
1236
Quentin Schulzec7dd642024-03-14 10:36:17 +01001237static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
Simon Glassadecfef2016-01-21 19:43:30 -07001238{
1239 int ldo = dev->driver_data - 1;
Quentin Schulzec7dd642024-03-14 10:36:17 +01001240 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
1241
1242 return _ldo_set_suspend_value(dev->parent, info, uvolt);
1243}
1244
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001245static int nldo_set_suspend_value(struct udevice *dev, int uvolt)
1246{
1247 int nldo = dev->driver_data - 1;
1248 const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, uvolt);
1249
1250 return _ldo_set_suspend_value(dev->parent, info, uvolt);
1251}
1252
1253static int pldo_set_suspend_value(struct udevice *dev, int uvolt)
1254{
1255 int pldo = dev->driver_data - 1;
1256 const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, uvolt);
1257
1258 return _ldo_set_suspend_value(dev->parent, info, uvolt);
1259}
1260
Quentin Schulze4b47f52024-06-05 11:33:21 +02001261static int _ldo_get_suspend_value(struct udevice *pmic, const struct rk8xx_reg_info *info)
Quentin Schulzec7dd642024-03-14 10:36:17 +01001262{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001263 int mask = info->vsel_mask;
1264 int val, ret;
Simon Glassadecfef2016-01-21 19:43:30 -07001265
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001266 if (info->vsel_sleep_reg == NA)
1267 return -ENOSYS;
Simon Glassadecfef2016-01-21 19:43:30 -07001268
Quentin Schulze4b47f52024-06-05 11:33:21 +02001269 ret = pmic_reg_read(pmic, info->vsel_sleep_reg);
Simon Glassadecfef2016-01-21 19:43:30 -07001270 if (ret < 0)
1271 return ret;
1272
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001273 val = ret & mask;
1274
1275 return info->min_uv + val * info->step_uv;
1276}
1277
Quentin Schulzec7dd642024-03-14 10:36:17 +01001278static int ldo_get_suspend_value(struct udevice *dev)
1279{
1280 int ldo = dev->driver_data - 1;
1281 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
1282
1283 return _ldo_get_suspend_value(dev->parent, info);
1284}
1285
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001286static int nldo_get_suspend_value(struct udevice *dev)
1287{
1288 int nldo = dev->driver_data - 1;
1289 const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, 0);
1290
1291 return _ldo_get_suspend_value(dev->parent, info);
1292}
1293
1294static int pldo_get_suspend_value(struct udevice *dev)
1295{
1296 int pldo = dev->driver_data - 1;
1297 const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, 0);
1298
1299 return _ldo_get_suspend_value(dev->parent, info);
1300}
1301
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001302static int ldo_set_enable(struct udevice *dev, bool enable)
1303{
1304 int ldo = dev->driver_data - 1;
1305
1306 return _ldo_set_enable(dev->parent, ldo, enable);
1307}
1308
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001309static int nldo_set_enable(struct udevice *dev, bool enable)
1310{
1311 int nldo = dev->driver_data - 1;
1312
1313 return _nldo_set_enable(dev->parent, nldo, enable);
1314}
1315
1316static int pldo_set_enable(struct udevice *dev, bool enable)
1317{
1318 int pldo = dev->driver_data - 1;
1319
1320 return _pldo_set_enable(dev->parent, pldo, enable);
1321}
1322
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001323static int ldo_set_suspend_enable(struct udevice *dev, bool enable)
1324{
1325 int ldo = dev->driver_data - 1;
1326
1327 return _ldo_set_suspend_enable(dev->parent, ldo, enable);
1328}
1329
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001330static int nldo_set_suspend_enable(struct udevice *dev, bool enable)
1331{
1332 int nldo = dev->driver_data - 1;
1333
1334 return _nldo_set_suspend_enable(dev->parent, nldo, enable);
1335}
1336
1337static int pldo_set_suspend_enable(struct udevice *dev, bool enable)
1338{
1339 int pldo = dev->driver_data - 1;
1340
1341 return _pldo_set_suspend_enable(dev->parent, pldo, enable);
1342}
1343
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001344static int ldo_get_suspend_enable(struct udevice *dev)
1345{
1346 int ldo = dev->driver_data - 1;
1347
1348 return _ldo_get_suspend_enable(dev->parent, ldo);
1349}
1350
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001351static int nldo_get_suspend_enable(struct udevice *dev)
1352{
1353 int nldo = dev->driver_data - 1;
1354
1355 return _nldo_get_suspend_enable(dev->parent, nldo);
1356}
1357
1358static int pldo_get_suspend_enable(struct udevice *dev)
1359{
1360 int pldo = dev->driver_data - 1;
1361
1362 return _pldo_get_suspend_enable(dev->parent, pldo);
1363}
1364
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001365static int ldo_get_enable(struct udevice *dev)
1366{
1367 int ldo = dev->driver_data - 1;
1368
1369 return _ldo_get_enable(dev->parent, ldo);
Simon Glassadecfef2016-01-21 19:43:30 -07001370}
1371
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001372static int nldo_get_enable(struct udevice *dev)
1373{
1374 int nldo = dev->driver_data - 1;
1375
1376 return _nldo_get_enable(dev->parent, nldo);
1377}
1378
1379static int pldo_get_enable(struct udevice *dev)
1380{
1381 int pldo = dev->driver_data - 1;
1382
1383 return _pldo_get_enable(dev->parent, pldo);
1384}
1385
Simon Glassadecfef2016-01-21 19:43:30 -07001386static int switch_set_enable(struct udevice *dev, bool enable)
1387{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001388 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1389 int ret = 0, sw = dev->driver_data - 1;
1390 uint mask = 0;
1391
1392 switch (priv->variant) {
1393 case RK808_ID:
1394 mask = 1 << (sw + 5);
1395 ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
1396 enable ? mask : 0);
1397 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001398 case RK809_ID:
1399 mask = (1 << (sw + 2)) | (1 << (sw + 6));
1400 ret = pmic_clrsetbits(dev->parent, RK817_POWER_EN(3), mask,
William Wub863e492024-03-14 10:36:16 +01001401 enable ? mask : (1 << (sw + 6)));
Joseph Chend6b3e832019-09-26 15:45:07 +08001402 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001403 case RK818_ID:
1404 mask = 1 << 6;
1405 ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
1406 enable ? mask : 0);
1407 break;
1408 }
Simon Glassadecfef2016-01-21 19:43:30 -07001409
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001410 debug("%s: switch%d, enable=%d, mask=0x%x\n",
1411 __func__, sw + 1, enable, mask);
Simon Glassadecfef2016-01-21 19:43:30 -07001412
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001413 return ret;
Simon Glassadecfef2016-01-21 19:43:30 -07001414}
1415
Keerthyc8f82fb2017-06-13 09:53:52 +05301416static int switch_get_enable(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001417{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001418 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1419 int ret = 0, sw = dev->driver_data - 1;
1420 uint mask = 0;
Simon Glassadecfef2016-01-21 19:43:30 -07001421
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001422 switch (priv->variant) {
1423 case RK808_ID:
1424 mask = 1 << (sw + 5);
1425 ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
1426 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001427 case RK809_ID:
1428 mask = 1 << (sw + 2);
1429 ret = pmic_reg_read(dev->parent, RK817_POWER_EN(3));
1430 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001431 case RK818_ID:
1432 mask = 1 << 6;
1433 ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
1434 break;
1435 }
Simon Glassadecfef2016-01-21 19:43:30 -07001436
Simon Glassadecfef2016-01-21 19:43:30 -07001437 if (ret < 0)
1438 return ret;
1439
Quentin Schulz53dfd482024-06-05 11:33:23 +02001440 return (ret & mask) ? true : false;
Simon Glassadecfef2016-01-21 19:43:30 -07001441}
1442
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001443static int switch_set_suspend_value(struct udevice *dev, int uvolt)
1444{
1445 return 0;
1446}
1447
1448static int switch_get_suspend_value(struct udevice *dev)
1449{
1450 return 0;
1451}
1452
1453static int switch_set_suspend_enable(struct udevice *dev, bool enable)
1454{
1455 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1456 int ret = 0, sw = dev->driver_data - 1;
1457 uint mask = 0;
1458
1459 switch (priv->variant) {
1460 case RK808_ID:
1461 mask = 1 << (sw + 5);
1462 ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
1463 enable ? 0 : mask);
1464 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001465 case RK809_ID:
1466 mask = 1 << (sw + 6);
1467 ret = pmic_clrsetbits(dev->parent, RK817_POWER_SLP_EN(0), mask,
1468 enable ? mask : 0);
1469 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001470 case RK818_ID:
1471 mask = 1 << 6;
1472 ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
1473 enable ? 0 : mask);
1474 break;
1475 }
1476
1477 debug("%s: switch%d, enable=%d, mask=0x%x\n",
1478 __func__, sw + 1, enable, mask);
1479
1480 return ret;
1481}
1482
1483static int switch_get_suspend_enable(struct udevice *dev)
1484{
1485 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1486 int val, ret = 0, sw = dev->driver_data - 1;
1487 uint mask = 0;
1488
1489 switch (priv->variant) {
1490 case RK808_ID:
1491 mask = 1 << (sw + 5);
1492 val = pmic_reg_read(dev->parent, REG_SLEEP_SET_OFF1);
1493 if (val < 0)
1494 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001495 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001496 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001497 case RK809_ID:
1498 mask = 1 << (sw + 6);
1499 val = pmic_reg_read(dev->parent, RK817_POWER_SLP_EN(0));
1500 if (val < 0)
1501 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001502 ret = (val & mask) ? 1 : 0;
Joseph Chend6b3e832019-09-26 15:45:07 +08001503 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001504 case RK818_ID:
1505 mask = 1 << 6;
1506 val = pmic_reg_read(dev->parent, REG_SLEEP_SET_OFF1);
1507 if (val < 0)
1508 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001509 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001510 break;
1511 }
1512
1513 return ret;
1514}
1515
1516/*
1517 * RK8xx switch does not need to set the voltage,
1518 * but if dts set regulator-min-microvolt/regulator-max-microvolt,
1519 * will cause regulator set value fail and not to enable this switch.
1520 * So add an empty function to return success.
1521 */
1522static int switch_get_value(struct udevice *dev)
1523{
shengfei Xu7851d4e2023-08-21 22:30:26 +00001524 static const char * const supply_name_rk809[] = {
1525 "vcc9-supply",
1526 "vcc8-supply",
1527 };
1528 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1529 struct udevice *supply;
1530 int id = dev->driver_data - 1;
1531
1532 if (!switch_get_enable(dev))
1533 return 0;
1534
1535 if (priv->variant == RK809_ID) {
1536 if (!uclass_get_device_by_phandle(UCLASS_REGULATOR,
1537 dev->parent,
1538 supply_name_rk809[id],
1539 &supply))
1540 return regulator_get_value(supply);
1541 }
1542
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001543 return 0;
1544}
1545
1546static int switch_set_value(struct udevice *dev, int uvolt)
1547{
1548 return 0;
1549}
1550
Jacob Chen614704b2017-05-02 14:54:52 +08001551static int rk8xx_buck_probe(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001552{
Simon Glass71fa5b42020-12-03 16:55:18 -07001553 struct dm_regulator_uclass_plat *uc_pdata;
Simon Glassadecfef2016-01-21 19:43:30 -07001554
Simon Glass71fa5b42020-12-03 16:55:18 -07001555 uc_pdata = dev_get_uclass_plat(dev);
Simon Glassadecfef2016-01-21 19:43:30 -07001556
1557 uc_pdata->type = REGULATOR_TYPE_BUCK;
1558 uc_pdata->mode_count = 0;
1559
1560 return 0;
1561}
1562
Jacob Chen614704b2017-05-02 14:54:52 +08001563static int rk8xx_ldo_probe(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001564{
Simon Glass71fa5b42020-12-03 16:55:18 -07001565 struct dm_regulator_uclass_plat *uc_pdata;
Simon Glassadecfef2016-01-21 19:43:30 -07001566
Simon Glass71fa5b42020-12-03 16:55:18 -07001567 uc_pdata = dev_get_uclass_plat(dev);
Simon Glassadecfef2016-01-21 19:43:30 -07001568
1569 uc_pdata->type = REGULATOR_TYPE_LDO;
1570 uc_pdata->mode_count = 0;
1571
1572 return 0;
1573}
1574
Jacob Chen614704b2017-05-02 14:54:52 +08001575static int rk8xx_switch_probe(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001576{
Simon Glass71fa5b42020-12-03 16:55:18 -07001577 struct dm_regulator_uclass_plat *uc_pdata;
Simon Glassadecfef2016-01-21 19:43:30 -07001578
Simon Glass71fa5b42020-12-03 16:55:18 -07001579 uc_pdata = dev_get_uclass_plat(dev);
Simon Glassadecfef2016-01-21 19:43:30 -07001580
1581 uc_pdata->type = REGULATOR_TYPE_FIXED;
1582 uc_pdata->mode_count = 0;
1583
1584 return 0;
1585}
1586
Jacob Chen614704b2017-05-02 14:54:52 +08001587static const struct dm_regulator_ops rk8xx_buck_ops = {
Simon Glassadecfef2016-01-21 19:43:30 -07001588 .get_value = buck_get_value,
1589 .set_value = buck_set_value,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001590 .set_suspend_value = buck_set_suspend_value,
1591 .get_suspend_value = buck_get_suspend_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001592 .get_enable = buck_get_enable,
1593 .set_enable = buck_set_enable,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001594 .set_suspend_enable = buck_set_suspend_enable,
1595 .get_suspend_enable = buck_get_suspend_enable,
Simon Glassadecfef2016-01-21 19:43:30 -07001596};
1597
Jacob Chen614704b2017-05-02 14:54:52 +08001598static const struct dm_regulator_ops rk8xx_ldo_ops = {
Simon Glassadecfef2016-01-21 19:43:30 -07001599 .get_value = ldo_get_value,
1600 .set_value = ldo_set_value,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001601 .set_suspend_value = ldo_set_suspend_value,
1602 .get_suspend_value = ldo_get_suspend_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001603 .get_enable = ldo_get_enable,
1604 .set_enable = ldo_set_enable,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001605 .set_suspend_enable = ldo_set_suspend_enable,
1606 .get_suspend_enable = ldo_get_suspend_enable,
Simon Glassadecfef2016-01-21 19:43:30 -07001607};
1608
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001609static const struct dm_regulator_ops rk8xx_nldo_ops = {
1610 .get_value = nldo_get_value,
1611 .set_value = nldo_set_value,
1612 .set_suspend_value = nldo_set_suspend_value,
1613 .get_suspend_value = nldo_get_suspend_value,
1614 .get_enable = nldo_get_enable,
1615 .set_enable = nldo_set_enable,
1616 .set_suspend_enable = nldo_set_suspend_enable,
1617 .get_suspend_enable = nldo_get_suspend_enable,
1618};
1619
1620static const struct dm_regulator_ops rk8xx_pldo_ops = {
1621 .get_value = pldo_get_value,
1622 .set_value = pldo_set_value,
1623 .set_suspend_value = pldo_set_suspend_value,
1624 .get_suspend_value = pldo_get_suspend_value,
1625 .get_enable = pldo_get_enable,
1626 .set_enable = pldo_set_enable,
1627 .set_suspend_enable = pldo_set_suspend_enable,
1628 .get_suspend_enable = pldo_get_suspend_enable,
1629};
1630
Jacob Chen614704b2017-05-02 14:54:52 +08001631static const struct dm_regulator_ops rk8xx_switch_ops = {
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001632 .get_value = switch_get_value,
1633 .set_value = switch_set_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001634 .get_enable = switch_get_enable,
1635 .set_enable = switch_set_enable,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001636 .set_suspend_enable = switch_set_suspend_enable,
1637 .get_suspend_enable = switch_get_suspend_enable,
1638 .set_suspend_value = switch_set_suspend_value,
1639 .get_suspend_value = switch_get_suspend_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001640};
1641
Jacob Chen614704b2017-05-02 14:54:52 +08001642U_BOOT_DRIVER(rk8xx_buck) = {
1643 .name = "rk8xx_buck",
Simon Glassadecfef2016-01-21 19:43:30 -07001644 .id = UCLASS_REGULATOR,
Jacob Chen614704b2017-05-02 14:54:52 +08001645 .ops = &rk8xx_buck_ops,
1646 .probe = rk8xx_buck_probe,
Simon Glassadecfef2016-01-21 19:43:30 -07001647};
1648
Jacob Chen614704b2017-05-02 14:54:52 +08001649U_BOOT_DRIVER(rk8xx_ldo) = {
1650 .name = "rk8xx_ldo",
Simon Glassadecfef2016-01-21 19:43:30 -07001651 .id = UCLASS_REGULATOR,
Jacob Chen614704b2017-05-02 14:54:52 +08001652 .ops = &rk8xx_ldo_ops,
1653 .probe = rk8xx_ldo_probe,
Simon Glassadecfef2016-01-21 19:43:30 -07001654};
1655
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001656U_BOOT_DRIVER(rk8xx_nldo) = {
1657 .name = "rk8xx_nldo",
1658 .id = UCLASS_REGULATOR,
1659 .ops = &rk8xx_nldo_ops,
1660 .probe = rk8xx_ldo_probe,
1661};
1662
1663U_BOOT_DRIVER(rk8xx_pldo) = {
1664 .name = "rk8xx_pldo",
1665 .id = UCLASS_REGULATOR,
1666 .ops = &rk8xx_pldo_ops,
1667 .probe = rk8xx_ldo_probe,
1668};
1669
Jacob Chen614704b2017-05-02 14:54:52 +08001670U_BOOT_DRIVER(rk8xx_switch) = {
1671 .name = "rk8xx_switch",
Simon Glassadecfef2016-01-21 19:43:30 -07001672 .id = UCLASS_REGULATOR,
Jacob Chen614704b2017-05-02 14:54:52 +08001673 .ops = &rk8xx_switch_ops,
1674 .probe = rk8xx_switch_probe,
Simon Glassadecfef2016-01-21 19:43:30 -07001675};
1676#endif
1677
Jacob Chen614704b2017-05-02 14:54:52 +08001678int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
Simon Glassadecfef2016-01-21 19:43:30 -07001679{
1680 int ret;
1681
1682 ret = _buck_set_value(pmic, buck, uvolt);
1683 if (ret)
1684 return ret;
1685
1686 return _buck_set_enable(pmic, buck, true);
1687}