blob: 375d06e3207f7381e18c121995f1978d7d7fdb2c [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",
Jonas Karlman431810c2024-09-17 20:59:18 +0000384 __func__, uvolt, buck, info->vsel_reg, mask, val);
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800385
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);
Jonas Karlman29425162024-09-17 20:59:17 +0000418 en_reg = RK806_POWER_EN(buck / 4);
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100419 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",
Jonas Karlman431810c2024-09-17 20:59:18 +0000473 __func__, uvolt, buck, info->vsel_sleep_reg, mask, val);
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800474
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);
Jonas Karlman29425162024-09-17 20:59:17 +0000497 ret = pmic_reg_read(pmic, RK806_POWER_EN(buck / 4));
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100498 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
Jonas Karlman431810c2024-09-17 20:59:18 +0000542 if (buck >= 8) {
543 /* BUCK9 and BUCK10 */
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100544 reg = RK806_POWER_SLP_EN1;
Jonas Karlman431810c2024-09-17 20:59:18 +0000545 mask = BIT(buck - 2);
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100546 } else {
547 reg = RK806_POWER_SLP_EN0;
Jonas Karlman29425162024-09-17 20:59:17 +0000548 mask = BIT(buck);
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100549 }
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
Jonas Karlman431810c2024-09-17 20:59:18 +0000594 if (buck >= 8) {
595 /* BUCK9 and BUCK10 */
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100596 reg = RK806_POWER_SLP_EN1;
Jonas Karlman431810c2024-09-17 20:59:18 +0000597 mask = BIT(buck - 2);
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100598 } else {
599 reg = RK806_POWER_SLP_EN0;
Jonas Karlman29425162024-09-17 20:59:17 +0000600 mask = BIT(buck);
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100601 }
602 val = pmic_reg_read(pmic, reg);
603 }
604 ret = (val & mask) ? 1 : 0;
605 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800606 case RK808_ID:
607 case RK818_ID:
608 mask = 1 << buck;
609 val = pmic_reg_read(pmic, REG_SLEEP_SET_OFF1);
610 if (val < 0)
611 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200612 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800613 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800614 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800615 case RK817_ID:
616 if (buck < 4)
617 mask = 1 << buck;
Joseph Chend6b3e832019-09-26 15:45:07 +0800618 else
619 mask = 1 << 5; /* BUCK5 for RK809 */
Joseph Chen4a1ae182019-09-26 15:44:55 +0800620
621 val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
622 if (val < 0)
623 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200624 ret = (val & mask) ? 1 : 0;
Joseph Chen4a1ae182019-09-26 15:44:55 +0800625 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800626 default:
627 ret = -EINVAL;
628 }
629
630 return ret;
631}
632
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200633static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800634 int num, int uvolt)
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200635{
636 struct rk8xx_priv *priv = dev_get_priv(pmic);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800637
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200638 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800639 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800640 case RK816_ID:
641 return &rk816_ldo[num];
Joseph Chend6b3e832019-09-26 15:45:07 +0800642 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800643 case RK817_ID:
644 if (uvolt < 3400000)
645 return &rk817_ldo[num * 2 + 0];
646 else
647 return &rk817_ldo[num * 2 + 1];
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200648 case RK818_ID:
649 return &rk818_ldo[num];
650 default:
651 return &rk808_ldo[num];
652 }
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800653}
654
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100655static const struct rk8xx_reg_info *get_nldo_reg(struct udevice *pmic,
656 int num, int uvolt)
657{
658 const struct rk8xx_priv *priv = dev_get_priv(pmic);
659
660 switch (priv->variant) {
661 case RK806_ID:
662 default:
663 if (uvolt < 3400000)
664 return &rk806_nldo[num * 2 + 0];
665 return &rk806_nldo[num * 2 + 1];
666 }
667}
668
669static const struct rk8xx_reg_info *get_pldo_reg(struct udevice *pmic,
670 int num, int uvolt)
671{
672 const struct rk8xx_priv *priv = dev_get_priv(pmic);
673
674 switch (priv->variant) {
675 case RK806_ID:
676 default:
677 if (uvolt < 3400000)
678 return &rk806_pldo[num * 2 + 0];
679 return &rk806_pldo[num * 2 + 1];
680 }
681}
682
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800683static int _ldo_get_enable(struct udevice *pmic, int ldo)
684{
685 struct rk8xx_priv *priv = dev_get_priv(pmic);
686 uint mask = 0;
687 int ret = 0;
688
689 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800690 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800691 case RK816_ID:
692 if (ldo >= 4) {
693 mask = 1 << (ldo - 4);
694 ret = pmic_reg_read(pmic, RK816_REG_LDO_EN2);
695 } else {
696 mask = 1 << ldo;
697 ret = pmic_reg_read(pmic, RK816_REG_LDO_EN1);
698 }
699 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800700 case RK808_ID:
701 case RK818_ID:
702 mask = 1 << ldo;
703 ret = pmic_reg_read(pmic, REG_LDO_EN);
704 if (ret < 0)
705 return ret;
706 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800707 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800708 case RK817_ID:
709 if (ldo < 4) {
710 mask = 1 << ldo;
711 ret = pmic_reg_read(pmic, RK817_POWER_EN(1));
712 } else if (ldo < 8) {
713 mask = 1 << (ldo - 4);
714 ret = pmic_reg_read(pmic, RK817_POWER_EN(2));
715 } else if (ldo == 8) {
716 mask = 1 << 0;
717 ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
718 } else {
719 return false;
720 }
721 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800722 }
723
724 if (ret < 0)
725 return ret;
726
Quentin Schulz53dfd482024-06-05 11:33:23 +0200727 return (ret & mask) ? true : false;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800728}
729
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100730static int _nldo_get_enable(struct udevice *pmic, int nldo)
731{
732 struct rk8xx_priv *priv = dev_get_priv(pmic);
733 uint mask = 0;
734 int ret = 0;
735 u8 en_reg = 0;
736
737 switch (priv->variant) {
738 case RK806_ID:
739 default:
740 if (nldo + 1 >= 5) {
741 mask = BIT(2);
742 en_reg = RK806_POWER_EN(5);
743 } else {
744 mask = BIT(nldo);
745 en_reg = RK806_POWER_EN(3);
746 }
747 ret = pmic_reg_read(pmic, en_reg);
748 break;
749 }
750
751 if (ret < 0)
752 return ret;
753
754 return (ret & mask) ? 1 : 0;
755}
756
757static int _pldo_get_enable(struct udevice *pmic, int pldo)
758{
759 struct rk8xx_priv *priv = dev_get_priv(pmic);
760 uint mask = 0;
761 int ret = 0;
762 u8 en_reg = 0;
763
764 switch (priv->variant) {
765 case RK806_ID:
766 default:
767 if (pldo + 1 <= 3) {
768 mask = BIT(pldo + 1);
769 en_reg = RK806_POWER_EN(4);
770 } else if (pldo + 1 == 6) {
771 mask = BIT(0);
772 en_reg = RK806_POWER_EN(4);
773 } else {
774 mask = BIT((pldo + 1) % 4);
775 en_reg = RK806_POWER_EN(5);
776 }
777 ret = pmic_reg_read(pmic, en_reg);
778 break;
779 }
780
781 if (ret < 0)
782 return ret;
783
784 return (ret & mask) ? 1 : 0;
785}
786
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800787static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
788{
789 struct rk8xx_priv *priv = dev_get_priv(pmic);
Elaine Zhang04e5a432019-09-26 15:43:54 +0800790 uint mask, value, en_reg;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800791 int ret = 0;
792
793 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800794 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800795 case RK816_ID:
796 if (ldo >= 4) {
797 ldo -= 4;
798 en_reg = RK816_REG_LDO_EN2;
799 } else {
800 en_reg = RK816_REG_LDO_EN1;
801 }
802 if (enable)
803 value = ((1 << ldo) | (1 << (ldo + 4)));
804 else
805 value = ((0 << ldo) | (1 << (ldo + 4)));
806
807 ret = pmic_reg_write(pmic, en_reg, value);
808 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800809 case RK808_ID:
810 case RK818_ID:
811 mask = 1 << ldo;
812 ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
Elaine Zhang04e5a432019-09-26 15:43:54 +0800813 enable ? mask : 0);
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800814 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800815 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800816 case RK817_ID:
817 if (ldo < 4) {
818 en_reg = RK817_POWER_EN(1);
819 } else if (ldo < 8) {
820 ldo -= 4;
821 en_reg = RK817_POWER_EN(2);
822 } else if (ldo == 8) {
823 ldo = 0; /* BIT 0 */
824 en_reg = RK817_POWER_EN(3);
825 } else {
826 return -EINVAL;
827 }
828 if (enable)
829 value = ((1 << ldo) | (1 << (ldo + 4)));
830 else
831 value = ((0 << ldo) | (1 << (ldo + 4)));
832 ret = pmic_reg_write(pmic, en_reg, value);
833 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800834 }
835
Jonas Karlman31c3c802023-07-02 12:41:15 +0000836 if (enable)
837 udelay(500);
838
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800839 return ret;
Wadim Egorov4c4905f2017-06-19 12:36:38 +0200840}
841
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100842static int _nldo_set_enable(struct udevice *pmic, int nldo, bool enable)
843{
844 struct rk8xx_priv *priv = dev_get_priv(pmic);
845 uint value, en_reg;
846 int ret = 0;
847
848 switch (priv->variant) {
849 case RK806_ID:
850 default:
851 if (nldo + 1 >= 5) {
852 value = RK806_POWER_EN_CLRSETBITS(2, enable);
853 en_reg = RK806_POWER_EN(5);
854 } else {
855 value = RK806_POWER_EN_CLRSETBITS(nldo, enable);
856 en_reg = RK806_POWER_EN(3);
857 }
858 ret = pmic_reg_write(pmic, en_reg, value);
859 break;
860 }
861
862 if (enable)
863 udelay(500);
864
865 return ret;
866}
867
868static int _pldo_set_enable(struct udevice *pmic, int pldo, bool enable)
869{
870 struct rk8xx_priv *priv = dev_get_priv(pmic);
871 uint value, en_reg;
872 int ret = 0;
873
874 switch (priv->variant) {
875 case RK806_ID:
876 default:
877 /* PLDO */
878 if (pldo + 1 <= 3) {
879 value = RK806_POWER_EN_CLRSETBITS(pldo + 1, enable);
880 en_reg = RK806_POWER_EN(4);
881 } else if (pldo + 1 == 6) {
882 value = RK806_POWER_EN_CLRSETBITS(0, enable);
883 en_reg = RK806_POWER_EN(4);
884 } else {
885 value = RK806_POWER_EN_CLRSETBITS((pldo + 1) % 4, enable);
886 en_reg = RK806_POWER_EN(5);
887 }
888 ret = pmic_reg_write(pmic, en_reg, value);
889 break;
890 }
891
892 if (enable)
893 udelay(500);
894
895 return ret;
896}
897
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800898static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
899{
900 struct rk8xx_priv *priv = dev_get_priv(pmic);
901 uint mask;
902 int ret = 0;
903
904 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800905 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800906 case RK816_ID:
907 mask = 1 << ldo;
908 ret = pmic_clrsetbits(pmic, RK816_REG_LDO_SLP_EN, mask,
909 enable ? mask : 0);
910 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800911 case RK808_ID:
912 case RK818_ID:
913 mask = 1 << ldo;
914 ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask,
915 enable ? 0 : mask);
916 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800917 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800918 case RK817_ID:
919 if (ldo == 8) {
920 mask = 1 << 4; /* LDO9 */
921 ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
922 enable ? mask : 0);
923 } else {
924 mask = 1 << ldo;
925 ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(1), mask,
926 enable ? mask : 0);
927 }
928 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800929 }
930
931 return ret;
932}
933
Quentin Schulzf7c6da12024-03-14 10:36:18 +0100934static int _nldo_set_suspend_enable(struct udevice *pmic, int nldo, bool enable)
935{
936 struct rk8xx_priv *priv = dev_get_priv(pmic);
937 uint mask;
938 int ret = 0;
939
940 switch (priv->variant) {
941 case RK806_ID:
942 default:
943 mask = BIT(nldo);
944 ret = pmic_clrsetbits(pmic, RK806_POWER_SLP_EN1, mask, enable ? mask : 0);
945 break;
946 }
947
948 return ret;
949}
950
951static int _pldo_set_suspend_enable(struct udevice *pmic, int pldo, bool enable)
952{
953 struct rk8xx_priv *priv = dev_get_priv(pmic);
954 uint mask;
955 int ret = 0;
956
957 switch (priv->variant) {
958 case RK806_ID:
959 default:
960 if (pldo + 1 >= 6)
961 mask = BIT(0);
962 else
963 mask = BIT(pldo + 1);
964 ret = pmic_clrsetbits(pmic, RK806_POWER_SLP_EN2, mask, enable ? mask : 0);
965 break;
966 }
967
968 return ret;
969}
970
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800971static int _ldo_get_suspend_enable(struct udevice *pmic, int ldo)
972{
973 struct rk8xx_priv *priv = dev_get_priv(pmic);
974 int val, ret = 0;
975 uint mask;
976
977 switch (priv->variant) {
Elaine Zhang1d9077e2019-09-26 15:43:55 +0800978 case RK805_ID:
Elaine Zhang04e5a432019-09-26 15:43:54 +0800979 case RK816_ID:
980 mask = 1 << ldo;
981 val = pmic_reg_read(pmic, RK816_REG_LDO_SLP_EN);
982 if (val < 0)
983 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200984 ret = (val & mask) ? 1 : 0;
Elaine Zhang04e5a432019-09-26 15:43:54 +0800985 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800986 case RK808_ID:
987 case RK818_ID:
988 mask = 1 << ldo;
989 val = pmic_reg_read(pmic, REG_SLEEP_SET_OFF2);
990 if (val < 0)
991 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +0200992 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +0800993 break;
Joseph Chend6b3e832019-09-26 15:45:07 +0800994 case RK809_ID:
Joseph Chen4a1ae182019-09-26 15:44:55 +0800995 case RK817_ID:
996 if (ldo == 8) {
997 mask = 1 << 4; /* LDO9 */
998 val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0));
999 if (val < 0)
1000 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001001 ret = (val & mask) ? 1 : 0;
Joseph Chen4a1ae182019-09-26 15:44:55 +08001002 } else {
1003 mask = 1 << ldo;
1004 val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(1));
1005 if (val < 0)
1006 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001007 ret = (val & mask) ? 1 : 0;
Joseph Chen4a1ae182019-09-26 15:44:55 +08001008 }
1009 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001010 }
1011
1012 return ret;
1013}
1014
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001015static int _nldo_get_suspend_enable(struct udevice *pmic, int nldo)
1016{
1017 struct rk8xx_priv *priv = dev_get_priv(pmic);
1018 int val, ret = 0;
1019 uint mask;
1020
1021 switch (priv->variant) {
1022 case RK806_ID:
1023 default:
1024 mask = BIT(nldo);
1025 val = pmic_reg_read(pmic, RK806_POWER_SLP_EN1);
1026 ret = (val & mask) ? 1 : 0;
1027 break;
1028 }
1029
1030 return ret;
1031}
1032
1033static int _pldo_get_suspend_enable(struct udevice *pmic, int pldo)
1034{
1035 struct rk8xx_priv *priv = dev_get_priv(pmic);
1036 int val, ret = 0;
1037 uint mask;
1038
1039 switch (priv->variant) {
1040 case RK806_ID:
1041 default:
1042 if (pldo + 1 >= 6)
1043 mask = BIT(0);
1044 else
1045 mask = BIT(pldo + 1);
1046 val = pmic_reg_read(pmic, RK806_POWER_SLP_EN2);
1047 ret = (val & mask) ? 1 : 0;
1048 break;
1049 }
1050
1051 return ret;
1052}
1053
Simon Glassadecfef2016-01-21 19:43:30 -07001054static int buck_get_value(struct udevice *dev)
1055{
1056 int buck = dev->driver_data - 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001057 const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
Jacob Chen21a6a252017-05-02 14:54:50 +08001058 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -07001059 int ret, val;
1060
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001061 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -07001062 return -ENOSYS;
Elaine Zhang04e5a432019-09-26 15:43:54 +08001063
Simon Glassadecfef2016-01-21 19:43:30 -07001064 ret = pmic_reg_read(dev->parent, info->vsel_reg);
1065 if (ret < 0)
1066 return ret;
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001067
Simon Glassadecfef2016-01-21 19:43:30 -07001068 val = ret & mask;
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001069 while (val > info->max_sel)
1070 info++;
Simon Glassadecfef2016-01-21 19:43:30 -07001071
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001072 return info->min_uv + (val - info->min_sel) * info->step_uv;
Simon Glassadecfef2016-01-21 19:43:30 -07001073}
1074
1075static int buck_set_value(struct udevice *dev, int uvolt)
1076{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001077 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001078
1079 return _buck_set_value(dev->parent, buck, uvolt);
1080}
1081
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001082static int buck_get_suspend_value(struct udevice *dev)
1083{
1084 int buck = dev->driver_data - 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001085 const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
1086 int mask = info->vsel_mask;
1087 int ret, val;
1088
1089 if (info->vsel_sleep_reg == NA)
1090 return -ENOSYS;
1091
1092 ret = pmic_reg_read(dev->parent, info->vsel_sleep_reg);
1093 if (ret < 0)
1094 return ret;
1095
1096 val = ret & mask;
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001097 while (val > info->max_sel)
1098 info++;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001099
Joseph Chenfb18ddd2023-08-21 22:30:25 +00001100 return info->min_uv + (val - info->min_sel) * info->step_uv;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001101}
1102
1103static int buck_set_suspend_value(struct udevice *dev, int uvolt)
1104{
1105 int buck = dev->driver_data - 1;
1106
1107 return _buck_set_suspend_value(dev->parent, buck, uvolt);
1108}
1109
Simon Glassadecfef2016-01-21 19:43:30 -07001110static int buck_set_enable(struct udevice *dev, bool enable)
1111{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001112 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001113
1114 return _buck_set_enable(dev->parent, buck, enable);
1115}
1116
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001117static int buck_set_suspend_enable(struct udevice *dev, bool enable)
Simon Glassadecfef2016-01-21 19:43:30 -07001118{
1119 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001120
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001121 return _buck_set_suspend_enable(dev->parent, buck, enable);
1122}
Simon Glassadecfef2016-01-21 19:43:30 -07001123
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001124static int buck_get_suspend_enable(struct udevice *dev)
1125{
1126 int buck = dev->driver_data - 1;
Simon Glassadecfef2016-01-21 19:43:30 -07001127
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001128 return _buck_get_suspend_enable(dev->parent, buck);
Simon Glassadecfef2016-01-21 19:43:30 -07001129}
1130
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001131static int buck_get_enable(struct udevice *dev)
1132{
1133 int buck = dev->driver_data - 1;
1134
1135 return _buck_get_enable(dev->parent, buck);
1136}
1137
Quentin Schulz23b16d42024-06-05 11:33:22 +02001138static int _ldo_get_value(struct udevice *pmic, const struct rk8xx_reg_info *info)
Simon Glassadecfef2016-01-21 19:43:30 -07001139{
Jacob Chen21a6a252017-05-02 14:54:50 +08001140 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -07001141 int ret, val;
1142
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001143 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -07001144 return -ENOSYS;
Quentin Schulz23b16d42024-06-05 11:33:22 +02001145 ret = pmic_reg_read(pmic, info->vsel_reg);
Simon Glassadecfef2016-01-21 19:43:30 -07001146 if (ret < 0)
1147 return ret;
1148 val = ret & mask;
1149
1150 return info->min_uv + val * info->step_uv;
1151}
1152
Quentin Schulzec7dd642024-03-14 10:36:17 +01001153static int ldo_get_value(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001154{
1155 int ldo = dev->driver_data - 1;
Quentin Schulzec7dd642024-03-14 10:36:17 +01001156 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
1157
Quentin Schulz23b16d42024-06-05 11:33:22 +02001158 return _ldo_get_value(dev->parent, info);
Quentin Schulzec7dd642024-03-14 10:36:17 +01001159}
1160
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001161static int nldo_get_value(struct udevice *dev)
1162{
1163 int nldo = dev->driver_data - 1;
1164 const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, 0);
1165
Quentin Schulz23b16d42024-06-05 11:33:22 +02001166 return _ldo_get_value(dev->parent, info);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001167}
1168
1169static int pldo_get_value(struct udevice *dev)
1170{
1171 int pldo = dev->driver_data - 1;
1172 const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, 0);
1173
Quentin Schulz23b16d42024-06-05 11:33:22 +02001174 return _ldo_get_value(dev->parent, info);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001175}
1176
Quentin Schulz23b16d42024-06-05 11:33:22 +02001177static int _ldo_set_value(struct udevice *pmic, const struct rk8xx_reg_info *info, int uvolt)
Quentin Schulzec7dd642024-03-14 10:36:17 +01001178{
Jacob Chen21a6a252017-05-02 14:54:50 +08001179 int mask = info->vsel_mask;
Simon Glassadecfef2016-01-21 19:43:30 -07001180 int val;
1181
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001182 if (info->vsel_reg == NA)
Simon Glassadecfef2016-01-21 19:43:30 -07001183 return -ENOSYS;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001184
1185 if (info->step_uv == 0)
1186 val = info->min_sel;
1187 else
1188 val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
1189
Quentin Schulzec7dd642024-03-14 10:36:17 +01001190 debug("%s: volt=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
1191 __func__, uvolt, info->vsel_reg, mask, val);
Simon Glassadecfef2016-01-21 19:43:30 -07001192
Quentin Schulz23b16d42024-06-05 11:33:22 +02001193 return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
Simon Glassadecfef2016-01-21 19:43:30 -07001194}
1195
Quentin Schulzec7dd642024-03-14 10:36:17 +01001196static int ldo_set_value(struct udevice *dev, int uvolt)
Simon Glassadecfef2016-01-21 19:43:30 -07001197{
1198 int ldo = dev->driver_data - 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001199 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
Quentin Schulzec7dd642024-03-14 10:36:17 +01001200
Quentin Schulz23b16d42024-06-05 11:33:22 +02001201 return _ldo_set_value(dev->parent, info, uvolt);
Quentin Schulzec7dd642024-03-14 10:36:17 +01001202}
1203
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001204static int nldo_set_value(struct udevice *dev, int uvolt)
1205{
1206 int nldo = dev->driver_data - 1;
1207 const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, uvolt);
1208
Quentin Schulz23b16d42024-06-05 11:33:22 +02001209 return _ldo_set_value(dev->parent, info, uvolt);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001210}
1211
1212static int pldo_set_value(struct udevice *dev, int uvolt)
1213{
1214 int pldo = dev->driver_data - 1;
1215 const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, uvolt);
1216
Quentin Schulz23b16d42024-06-05 11:33:22 +02001217 return _ldo_set_value(dev->parent, info, uvolt);
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001218}
1219
Quentin Schulze4b47f52024-06-05 11:33:21 +02001220static int _ldo_set_suspend_value(struct udevice *pmic, const struct rk8xx_reg_info *info, int uvolt)
Quentin Schulzec7dd642024-03-14 10:36:17 +01001221{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001222 int mask = info->vsel_mask;
1223 int val;
1224
1225 if (info->vsel_sleep_reg == NA)
1226 return -ENOSYS;
Simon Glassadecfef2016-01-21 19:43:30 -07001227
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001228 if (info->step_uv == 0)
1229 val = info->min_sel;
1230 else
1231 val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
Simon Glassadecfef2016-01-21 19:43:30 -07001232
Quentin Schulzec7dd642024-03-14 10:36:17 +01001233 debug("%s: volt=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
1234 __func__, uvolt, info->vsel_sleep_reg, mask, val);
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001235
Quentin Schulze4b47f52024-06-05 11:33:21 +02001236 return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
Simon Glassadecfef2016-01-21 19:43:30 -07001237}
1238
Quentin Schulzec7dd642024-03-14 10:36:17 +01001239static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
Simon Glassadecfef2016-01-21 19:43:30 -07001240{
1241 int ldo = dev->driver_data - 1;
Quentin Schulzec7dd642024-03-14 10:36:17 +01001242 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
1243
1244 return _ldo_set_suspend_value(dev->parent, info, uvolt);
1245}
1246
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001247static int nldo_set_suspend_value(struct udevice *dev, int uvolt)
1248{
1249 int nldo = dev->driver_data - 1;
1250 const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, uvolt);
1251
1252 return _ldo_set_suspend_value(dev->parent, info, uvolt);
1253}
1254
1255static int pldo_set_suspend_value(struct udevice *dev, int uvolt)
1256{
1257 int pldo = dev->driver_data - 1;
1258 const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, uvolt);
1259
1260 return _ldo_set_suspend_value(dev->parent, info, uvolt);
1261}
1262
Quentin Schulze4b47f52024-06-05 11:33:21 +02001263static int _ldo_get_suspend_value(struct udevice *pmic, const struct rk8xx_reg_info *info)
Quentin Schulzec7dd642024-03-14 10:36:17 +01001264{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001265 int mask = info->vsel_mask;
1266 int val, ret;
Simon Glassadecfef2016-01-21 19:43:30 -07001267
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001268 if (info->vsel_sleep_reg == NA)
1269 return -ENOSYS;
Simon Glassadecfef2016-01-21 19:43:30 -07001270
Quentin Schulze4b47f52024-06-05 11:33:21 +02001271 ret = pmic_reg_read(pmic, info->vsel_sleep_reg);
Simon Glassadecfef2016-01-21 19:43:30 -07001272 if (ret < 0)
1273 return ret;
1274
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001275 val = ret & mask;
1276
1277 return info->min_uv + val * info->step_uv;
1278}
1279
Quentin Schulzec7dd642024-03-14 10:36:17 +01001280static int ldo_get_suspend_value(struct udevice *dev)
1281{
1282 int ldo = dev->driver_data - 1;
1283 const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
1284
1285 return _ldo_get_suspend_value(dev->parent, info);
1286}
1287
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001288static int nldo_get_suspend_value(struct udevice *dev)
1289{
1290 int nldo = dev->driver_data - 1;
1291 const struct rk8xx_reg_info *info = get_nldo_reg(dev->parent, nldo, 0);
1292
1293 return _ldo_get_suspend_value(dev->parent, info);
1294}
1295
1296static int pldo_get_suspend_value(struct udevice *dev)
1297{
1298 int pldo = dev->driver_data - 1;
1299 const struct rk8xx_reg_info *info = get_pldo_reg(dev->parent, pldo, 0);
1300
1301 return _ldo_get_suspend_value(dev->parent, info);
1302}
1303
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001304static int ldo_set_enable(struct udevice *dev, bool enable)
1305{
1306 int ldo = dev->driver_data - 1;
1307
1308 return _ldo_set_enable(dev->parent, ldo, enable);
1309}
1310
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001311static int nldo_set_enable(struct udevice *dev, bool enable)
1312{
1313 int nldo = dev->driver_data - 1;
1314
1315 return _nldo_set_enable(dev->parent, nldo, enable);
1316}
1317
1318static int pldo_set_enable(struct udevice *dev, bool enable)
1319{
1320 int pldo = dev->driver_data - 1;
1321
1322 return _pldo_set_enable(dev->parent, pldo, enable);
1323}
1324
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001325static int ldo_set_suspend_enable(struct udevice *dev, bool enable)
1326{
1327 int ldo = dev->driver_data - 1;
1328
1329 return _ldo_set_suspend_enable(dev->parent, ldo, enable);
1330}
1331
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001332static int nldo_set_suspend_enable(struct udevice *dev, bool enable)
1333{
1334 int nldo = dev->driver_data - 1;
1335
1336 return _nldo_set_suspend_enable(dev->parent, nldo, enable);
1337}
1338
1339static int pldo_set_suspend_enable(struct udevice *dev, bool enable)
1340{
1341 int pldo = dev->driver_data - 1;
1342
1343 return _pldo_set_suspend_enable(dev->parent, pldo, enable);
1344}
1345
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001346static int ldo_get_suspend_enable(struct udevice *dev)
1347{
1348 int ldo = dev->driver_data - 1;
1349
1350 return _ldo_get_suspend_enable(dev->parent, ldo);
1351}
1352
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001353static int nldo_get_suspend_enable(struct udevice *dev)
1354{
1355 int nldo = dev->driver_data - 1;
1356
1357 return _nldo_get_suspend_enable(dev->parent, nldo);
1358}
1359
1360static int pldo_get_suspend_enable(struct udevice *dev)
1361{
1362 int pldo = dev->driver_data - 1;
1363
1364 return _pldo_get_suspend_enable(dev->parent, pldo);
1365}
1366
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001367static int ldo_get_enable(struct udevice *dev)
1368{
1369 int ldo = dev->driver_data - 1;
1370
1371 return _ldo_get_enable(dev->parent, ldo);
Simon Glassadecfef2016-01-21 19:43:30 -07001372}
1373
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001374static int nldo_get_enable(struct udevice *dev)
1375{
1376 int nldo = dev->driver_data - 1;
1377
1378 return _nldo_get_enable(dev->parent, nldo);
1379}
1380
1381static int pldo_get_enable(struct udevice *dev)
1382{
1383 int pldo = dev->driver_data - 1;
1384
1385 return _pldo_get_enable(dev->parent, pldo);
1386}
1387
Simon Glassadecfef2016-01-21 19:43:30 -07001388static int switch_set_enable(struct udevice *dev, bool enable)
1389{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001390 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1391 int ret = 0, sw = dev->driver_data - 1;
1392 uint mask = 0;
1393
1394 switch (priv->variant) {
1395 case RK808_ID:
1396 mask = 1 << (sw + 5);
1397 ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
1398 enable ? mask : 0);
1399 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001400 case RK809_ID:
1401 mask = (1 << (sw + 2)) | (1 << (sw + 6));
1402 ret = pmic_clrsetbits(dev->parent, RK817_POWER_EN(3), mask,
William Wub863e492024-03-14 10:36:16 +01001403 enable ? mask : (1 << (sw + 6)));
Joseph Chend6b3e832019-09-26 15:45:07 +08001404 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001405 case RK818_ID:
1406 mask = 1 << 6;
1407 ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
1408 enable ? mask : 0);
1409 break;
1410 }
Simon Glassadecfef2016-01-21 19:43:30 -07001411
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001412 debug("%s: switch%d, enable=%d, mask=0x%x\n",
1413 __func__, sw + 1, enable, mask);
Simon Glassadecfef2016-01-21 19:43:30 -07001414
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001415 return ret;
Simon Glassadecfef2016-01-21 19:43:30 -07001416}
1417
Keerthyc8f82fb2017-06-13 09:53:52 +05301418static int switch_get_enable(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001419{
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001420 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1421 int ret = 0, sw = dev->driver_data - 1;
1422 uint mask = 0;
Simon Glassadecfef2016-01-21 19:43:30 -07001423
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001424 switch (priv->variant) {
1425 case RK808_ID:
1426 mask = 1 << (sw + 5);
1427 ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
1428 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001429 case RK809_ID:
1430 mask = 1 << (sw + 2);
1431 ret = pmic_reg_read(dev->parent, RK817_POWER_EN(3));
1432 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001433 case RK818_ID:
1434 mask = 1 << 6;
1435 ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
1436 break;
1437 }
Simon Glassadecfef2016-01-21 19:43:30 -07001438
Simon Glassadecfef2016-01-21 19:43:30 -07001439 if (ret < 0)
1440 return ret;
1441
Quentin Schulz53dfd482024-06-05 11:33:23 +02001442 return (ret & mask) ? true : false;
Simon Glassadecfef2016-01-21 19:43:30 -07001443}
1444
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001445static int switch_set_suspend_value(struct udevice *dev, int uvolt)
1446{
1447 return 0;
1448}
1449
1450static int switch_get_suspend_value(struct udevice *dev)
1451{
1452 return 0;
1453}
1454
1455static int switch_set_suspend_enable(struct udevice *dev, bool enable)
1456{
1457 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1458 int ret = 0, sw = dev->driver_data - 1;
1459 uint mask = 0;
1460
1461 switch (priv->variant) {
1462 case RK808_ID:
1463 mask = 1 << (sw + 5);
1464 ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
1465 enable ? 0 : mask);
1466 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001467 case RK809_ID:
1468 mask = 1 << (sw + 6);
1469 ret = pmic_clrsetbits(dev->parent, RK817_POWER_SLP_EN(0), mask,
1470 enable ? mask : 0);
1471 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001472 case RK818_ID:
1473 mask = 1 << 6;
1474 ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
1475 enable ? 0 : mask);
1476 break;
1477 }
1478
1479 debug("%s: switch%d, enable=%d, mask=0x%x\n",
1480 __func__, sw + 1, enable, mask);
1481
1482 return ret;
1483}
1484
1485static int switch_get_suspend_enable(struct udevice *dev)
1486{
1487 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1488 int val, ret = 0, sw = dev->driver_data - 1;
1489 uint mask = 0;
1490
1491 switch (priv->variant) {
1492 case RK808_ID:
1493 mask = 1 << (sw + 5);
1494 val = pmic_reg_read(dev->parent, REG_SLEEP_SET_OFF1);
1495 if (val < 0)
1496 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001497 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001498 break;
Joseph Chend6b3e832019-09-26 15:45:07 +08001499 case RK809_ID:
1500 mask = 1 << (sw + 6);
1501 val = pmic_reg_read(dev->parent, RK817_POWER_SLP_EN(0));
1502 if (val < 0)
1503 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001504 ret = (val & mask) ? 1 : 0;
Joseph Chend6b3e832019-09-26 15:45:07 +08001505 break;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001506 case RK818_ID:
1507 mask = 1 << 6;
1508 val = pmic_reg_read(dev->parent, REG_SLEEP_SET_OFF1);
1509 if (val < 0)
1510 return val;
Quentin Schulz53dfd482024-06-05 11:33:23 +02001511 ret = (val & mask) ? 0 : 1;
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001512 break;
1513 }
1514
1515 return ret;
1516}
1517
1518/*
1519 * RK8xx switch does not need to set the voltage,
1520 * but if dts set regulator-min-microvolt/regulator-max-microvolt,
1521 * will cause regulator set value fail and not to enable this switch.
1522 * So add an empty function to return success.
1523 */
1524static int switch_get_value(struct udevice *dev)
1525{
shengfei Xu7851d4e2023-08-21 22:30:26 +00001526 static const char * const supply_name_rk809[] = {
1527 "vcc9-supply",
1528 "vcc8-supply",
1529 };
1530 struct rk8xx_priv *priv = dev_get_priv(dev->parent);
1531 struct udevice *supply;
1532 int id = dev->driver_data - 1;
1533
1534 if (!switch_get_enable(dev))
1535 return 0;
1536
1537 if (priv->variant == RK809_ID) {
1538 if (!uclass_get_device_by_phandle(UCLASS_REGULATOR,
1539 dev->parent,
1540 supply_name_rk809[id],
1541 &supply))
1542 return regulator_get_value(supply);
1543 }
1544
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001545 return 0;
1546}
1547
1548static int switch_set_value(struct udevice *dev, int uvolt)
1549{
1550 return 0;
1551}
1552
Jacob Chen614704b2017-05-02 14:54:52 +08001553static int rk8xx_buck_probe(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001554{
Simon Glass71fa5b42020-12-03 16:55:18 -07001555 struct dm_regulator_uclass_plat *uc_pdata;
Simon Glassadecfef2016-01-21 19:43:30 -07001556
Simon Glass71fa5b42020-12-03 16:55:18 -07001557 uc_pdata = dev_get_uclass_plat(dev);
Simon Glassadecfef2016-01-21 19:43:30 -07001558
1559 uc_pdata->type = REGULATOR_TYPE_BUCK;
1560 uc_pdata->mode_count = 0;
1561
1562 return 0;
1563}
1564
Jacob Chen614704b2017-05-02 14:54:52 +08001565static int rk8xx_ldo_probe(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001566{
Simon Glass71fa5b42020-12-03 16:55:18 -07001567 struct dm_regulator_uclass_plat *uc_pdata;
Simon Glassadecfef2016-01-21 19:43:30 -07001568
Simon Glass71fa5b42020-12-03 16:55:18 -07001569 uc_pdata = dev_get_uclass_plat(dev);
Simon Glassadecfef2016-01-21 19:43:30 -07001570
1571 uc_pdata->type = REGULATOR_TYPE_LDO;
1572 uc_pdata->mode_count = 0;
1573
1574 return 0;
1575}
1576
Jacob Chen614704b2017-05-02 14:54:52 +08001577static int rk8xx_switch_probe(struct udevice *dev)
Simon Glassadecfef2016-01-21 19:43:30 -07001578{
Simon Glass71fa5b42020-12-03 16:55:18 -07001579 struct dm_regulator_uclass_plat *uc_pdata;
Simon Glassadecfef2016-01-21 19:43:30 -07001580
Simon Glass71fa5b42020-12-03 16:55:18 -07001581 uc_pdata = dev_get_uclass_plat(dev);
Simon Glassadecfef2016-01-21 19:43:30 -07001582
1583 uc_pdata->type = REGULATOR_TYPE_FIXED;
1584 uc_pdata->mode_count = 0;
1585
1586 return 0;
1587}
1588
Jacob Chen614704b2017-05-02 14:54:52 +08001589static const struct dm_regulator_ops rk8xx_buck_ops = {
Simon Glassadecfef2016-01-21 19:43:30 -07001590 .get_value = buck_get_value,
1591 .set_value = buck_set_value,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001592 .set_suspend_value = buck_set_suspend_value,
1593 .get_suspend_value = buck_get_suspend_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001594 .get_enable = buck_get_enable,
1595 .set_enable = buck_set_enable,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001596 .set_suspend_enable = buck_set_suspend_enable,
1597 .get_suspend_enable = buck_get_suspend_enable,
Simon Glassadecfef2016-01-21 19:43:30 -07001598};
1599
Jacob Chen614704b2017-05-02 14:54:52 +08001600static const struct dm_regulator_ops rk8xx_ldo_ops = {
Simon Glassadecfef2016-01-21 19:43:30 -07001601 .get_value = ldo_get_value,
1602 .set_value = ldo_set_value,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001603 .set_suspend_value = ldo_set_suspend_value,
1604 .get_suspend_value = ldo_get_suspend_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001605 .get_enable = ldo_get_enable,
1606 .set_enable = ldo_set_enable,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001607 .set_suspend_enable = ldo_set_suspend_enable,
1608 .get_suspend_enable = ldo_get_suspend_enable,
Simon Glassadecfef2016-01-21 19:43:30 -07001609};
1610
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001611static const struct dm_regulator_ops rk8xx_nldo_ops = {
1612 .get_value = nldo_get_value,
1613 .set_value = nldo_set_value,
1614 .set_suspend_value = nldo_set_suspend_value,
1615 .get_suspend_value = nldo_get_suspend_value,
1616 .get_enable = nldo_get_enable,
1617 .set_enable = nldo_set_enable,
1618 .set_suspend_enable = nldo_set_suspend_enable,
1619 .get_suspend_enable = nldo_get_suspend_enable,
1620};
1621
1622static const struct dm_regulator_ops rk8xx_pldo_ops = {
1623 .get_value = pldo_get_value,
1624 .set_value = pldo_set_value,
1625 .set_suspend_value = pldo_set_suspend_value,
1626 .get_suspend_value = pldo_get_suspend_value,
1627 .get_enable = pldo_get_enable,
1628 .set_enable = pldo_set_enable,
1629 .set_suspend_enable = pldo_set_suspend_enable,
1630 .get_suspend_enable = pldo_get_suspend_enable,
1631};
1632
Jacob Chen614704b2017-05-02 14:54:52 +08001633static const struct dm_regulator_ops rk8xx_switch_ops = {
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001634 .get_value = switch_get_value,
1635 .set_value = switch_set_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001636 .get_enable = switch_get_enable,
1637 .set_enable = switch_set_enable,
Elaine Zhangfa9cccc2019-09-26 15:43:53 +08001638 .set_suspend_enable = switch_set_suspend_enable,
1639 .get_suspend_enable = switch_get_suspend_enable,
1640 .set_suspend_value = switch_set_suspend_value,
1641 .get_suspend_value = switch_get_suspend_value,
Simon Glassadecfef2016-01-21 19:43:30 -07001642};
1643
Jacob Chen614704b2017-05-02 14:54:52 +08001644U_BOOT_DRIVER(rk8xx_buck) = {
1645 .name = "rk8xx_buck",
Simon Glassadecfef2016-01-21 19:43:30 -07001646 .id = UCLASS_REGULATOR,
Jacob Chen614704b2017-05-02 14:54:52 +08001647 .ops = &rk8xx_buck_ops,
1648 .probe = rk8xx_buck_probe,
Simon Glassadecfef2016-01-21 19:43:30 -07001649};
1650
Jacob Chen614704b2017-05-02 14:54:52 +08001651U_BOOT_DRIVER(rk8xx_ldo) = {
1652 .name = "rk8xx_ldo",
Simon Glassadecfef2016-01-21 19:43:30 -07001653 .id = UCLASS_REGULATOR,
Jacob Chen614704b2017-05-02 14:54:52 +08001654 .ops = &rk8xx_ldo_ops,
1655 .probe = rk8xx_ldo_probe,
Simon Glassadecfef2016-01-21 19:43:30 -07001656};
1657
Quentin Schulzf7c6da12024-03-14 10:36:18 +01001658U_BOOT_DRIVER(rk8xx_nldo) = {
1659 .name = "rk8xx_nldo",
1660 .id = UCLASS_REGULATOR,
1661 .ops = &rk8xx_nldo_ops,
1662 .probe = rk8xx_ldo_probe,
1663};
1664
1665U_BOOT_DRIVER(rk8xx_pldo) = {
1666 .name = "rk8xx_pldo",
1667 .id = UCLASS_REGULATOR,
1668 .ops = &rk8xx_pldo_ops,
1669 .probe = rk8xx_ldo_probe,
1670};
1671
Jacob Chen614704b2017-05-02 14:54:52 +08001672U_BOOT_DRIVER(rk8xx_switch) = {
1673 .name = "rk8xx_switch",
Simon Glassadecfef2016-01-21 19:43:30 -07001674 .id = UCLASS_REGULATOR,
Jacob Chen614704b2017-05-02 14:54:52 +08001675 .ops = &rk8xx_switch_ops,
1676 .probe = rk8xx_switch_probe,
Simon Glassadecfef2016-01-21 19:43:30 -07001677};
1678#endif
1679
Jacob Chen614704b2017-05-02 14:54:52 +08001680int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
Simon Glassadecfef2016-01-21 19:43:30 -07001681{
1682 int ret;
1683
1684 ret = _buck_set_value(pmic, buck, uvolt);
1685 if (ret)
1686 return ret;
1687
1688 return _buck_set_enable(pmic, buck, true);
1689}