Commit b4a35574b38d0fb42031be32a47fb1095cceafa7
Committed by
Kever Yang
1 parent
b62280745e
Exists in
smarc_8mq_lf_v2020.04
and in
9 other branches
power: pmic: rk817: support rk817 pmic
The RK817 is a Power Management IC (PMIC) for multimedia and handheld devices. They contains the following components: - Regulators(4*BUCKs, 1* BOOST, 9*LDOs, 1*SWITCH) - RTC - Clocking Signed-off-by: Joseph Chen <chenjh@rock-chips.com> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Showing 3 changed files with 297 additions and 7 deletions Side-by-side Diff
drivers/power/pmic/rk8xx.c
... | ... | @@ -10,6 +10,13 @@ |
10 | 10 | #include <power/rk8xx_pmic.h> |
11 | 11 | #include <power/pmic.h> |
12 | 12 | |
13 | +static struct reg_data rk817_init_reg[] = { | |
14 | +/* enable the under-voltage protection, | |
15 | + * the under-voltage protection will shutdown the LDO3 and reset the PMIC | |
16 | + */ | |
17 | + { RK817_BUCK4_CMIN, 0x60, 0x60}, | |
18 | +}; | |
19 | + | |
13 | 20 | static const struct pmic_child_info pmic_children_info[] = { |
14 | 21 | { .prefix = "DCDC_REG", .driver = "rk8xx_buck"}, |
15 | 22 | { .prefix = "LDO_REG", .driver = "rk8xx_ldo"}, |
16 | 23 | |
17 | 24 | |
18 | 25 | |
19 | 26 | |
... | ... | @@ -76,14 +83,84 @@ |
76 | 83 | static int rk8xx_probe(struct udevice *dev) |
77 | 84 | { |
78 | 85 | struct rk8xx_priv *priv = dev_get_priv(dev); |
79 | - uint8_t msb, lsb; | |
86 | + struct reg_data *init_data = NULL; | |
87 | + int init_data_num = 0; | |
88 | + int ret = 0, i, show_variant; | |
89 | + u8 msb, lsb, id_msb, id_lsb; | |
90 | + u8 on_source = 0, off_source = 0; | |
91 | + u8 power_en0, power_en1, power_en2, power_en3; | |
92 | + u8 value; | |
80 | 93 | |
81 | 94 | /* read Chip variant */ |
82 | - rk8xx_read(dev, ID_MSB, &msb, 1); | |
83 | - rk8xx_read(dev, ID_LSB, &lsb, 1); | |
95 | + if (device_is_compatible(dev, "rockchip,rk817")) { | |
96 | + id_msb = RK817_ID_MSB; | |
97 | + id_lsb = RK817_ID_LSB; | |
98 | + } else { | |
99 | + id_msb = ID_MSB; | |
100 | + id_lsb = ID_LSB; | |
101 | + } | |
84 | 102 | |
103 | + ret = rk8xx_read(dev, id_msb, &msb, 1); | |
104 | + if (ret) | |
105 | + return ret; | |
106 | + ret = rk8xx_read(dev, id_lsb, &lsb, 1); | |
107 | + if (ret) | |
108 | + return ret; | |
109 | + | |
85 | 110 | priv->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK; |
111 | + show_variant = priv->variant; | |
112 | + switch (priv->variant) { | |
113 | + case RK808_ID: | |
114 | + show_variant = 0x808; /* RK808 hardware ID is 0 */ | |
115 | + break; | |
116 | + case RK805_ID: | |
117 | + case RK816_ID: | |
118 | + case RK818_ID: | |
119 | + on_source = RK8XX_ON_SOURCE; | |
120 | + off_source = RK8XX_OFF_SOURCE; | |
121 | + break; | |
122 | + case RK817_ID: | |
123 | + on_source = RK817_ON_SOURCE; | |
124 | + off_source = RK817_OFF_SOURCE; | |
125 | + init_data = rk817_init_reg; | |
126 | + init_data_num = ARRAY_SIZE(rk817_init_reg); | |
127 | + power_en0 = pmic_reg_read(dev, RK817_POWER_EN0); | |
128 | + power_en1 = pmic_reg_read(dev, RK817_POWER_EN1); | |
129 | + power_en2 = pmic_reg_read(dev, RK817_POWER_EN2); | |
130 | + power_en3 = pmic_reg_read(dev, RK817_POWER_EN3); | |
86 | 131 | |
132 | + value = (power_en0 & 0x0f) | ((power_en1 & 0x0f) << 4); | |
133 | + pmic_reg_write(dev, RK817_POWER_EN_SAVE0, value); | |
134 | + value = (power_en2 & 0x0f) | ((power_en3 & 0x0f) << 4); | |
135 | + pmic_reg_write(dev, RK817_POWER_EN_SAVE1, value); | |
136 | + break; | |
137 | + default: | |
138 | + printf("Unknown PMIC: RK%x!!\n", priv->variant); | |
139 | + return -EINVAL; | |
140 | + } | |
141 | + | |
142 | + for (i = 0; i < init_data_num; i++) { | |
143 | + ret = pmic_clrsetbits(dev, | |
144 | + init_data[i].reg, | |
145 | + init_data[i].mask, | |
146 | + init_data[i].val); | |
147 | + if (ret < 0) { | |
148 | + printf("%s: i2c set reg 0x%x failed, ret=%d\n", | |
149 | + __func__, init_data[i].reg, ret); | |
150 | + } | |
151 | + | |
152 | + debug("%s: reg[0x%x] = 0x%x\n", __func__, init_data[i].reg, | |
153 | + pmic_reg_read(dev, init_data[i].reg)); | |
154 | + } | |
155 | + | |
156 | + printf("PMIC: RK%x ", show_variant); | |
157 | + | |
158 | + if (on_source && off_source) | |
159 | + printf("(on=0x%02x, off=0x%02x)", | |
160 | + pmic_reg_read(dev, on_source), | |
161 | + pmic_reg_read(dev, off_source)); | |
162 | + printf("\n"); | |
163 | + | |
87 | 164 | return 0; |
88 | 165 | } |
89 | 166 | |
... | ... | @@ -97,6 +174,7 @@ |
97 | 174 | { .compatible = "rockchip,rk805" }, |
98 | 175 | { .compatible = "rockchip,rk808" }, |
99 | 176 | { .compatible = "rockchip,rk816" }, |
177 | + { .compatible = "rockchip,rk817" }, | |
100 | 178 | { .compatible = "rockchip,rk818" }, |
101 | 179 | { } |
102 | 180 | }; |
drivers/power/regulator/rk8xx.c
... | ... | @@ -27,6 +27,21 @@ |
27 | 27 | #define RK808_BUCK4_VSEL_MASK 0xf |
28 | 28 | #define RK808_LDO_VSEL_MASK 0x1f |
29 | 29 | |
30 | +/* RK817 BUCK */ | |
31 | +#define RK817_BUCK_ON_VSEL(n) (0xbb + 3 * ((n) - 1)) | |
32 | +#define RK817_BUCK_SLP_VSEL(n) (0xbc + 3 * ((n) - 1)) | |
33 | +#define RK817_BUCK_VSEL_MASK 0x7f | |
34 | +#define RK817_BUCK_CONFIG(i) (0xba + (i) * 3) | |
35 | + | |
36 | +/* RK817 LDO */ | |
37 | +#define RK817_LDO_ON_VSEL(n) (0xcc + 2 * ((n) - 1)) | |
38 | +#define RK817_LDO_SLP_VSEL(n) (0xcd + 2 * ((n) - 1)) | |
39 | +#define RK817_LDO_VSEL_MASK 0x7f | |
40 | + | |
41 | +/* RK817 ENABLE */ | |
42 | +#define RK817_POWER_EN(n) (0xb1 + (n)) | |
43 | +#define RK817_POWER_SLP_EN(n) (0xb5 + (n)) | |
44 | + | |
30 | 45 | #define RK818_BUCK_VSEL_MASK 0x3f |
31 | 46 | #define RK818_BUCK4_VSEL_MASK 0x1f |
32 | 47 | #define RK818_LDO_VSEL_MASK 0x1f |
33 | 48 | |
... | ... | @@ -45,13 +60,19 @@ |
45 | 60 | #define RK805_RAMP_RATE_12_5MV_PER_US (2 << RK805_RAMP_RATE_OFFSET) |
46 | 61 | #define RK805_RAMP_RATE_25MV_PER_US (3 << RK805_RAMP_RATE_OFFSET) |
47 | 62 | #define RK808_RAMP_RATE_OFFSET 3 |
48 | - | |
49 | 63 | #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) |
50 | 64 | #define RK808_RAMP_RATE_2MV_PER_US (0 << RK808_RAMP_RATE_OFFSET) |
51 | 65 | #define RK808_RAMP_RATE_4MV_PER_US (1 << RK808_RAMP_RATE_OFFSET) |
52 | 66 | #define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET) |
53 | 67 | #define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET) |
54 | 68 | |
69 | +#define RK817_RAMP_RATE_OFFSET 6 | |
70 | +#define RK817_RAMP_RATE_MASK (0x3 << RK817_RAMP_RATE_OFFSET) | |
71 | +#define RK817_RAMP_RATE_3MV_PER_US (0x0 << RK817_RAMP_RATE_OFFSET) | |
72 | +#define RK817_RAMP_RATE_6_3MV_PER_US (0x1 << RK817_RAMP_RATE_OFFSET) | |
73 | +#define RK817_RAMP_RATE_12_5MV_PER_US (0x2 << RK817_RAMP_RATE_OFFSET) | |
74 | +#define RK817_RAMP_RATE_25MV_PER_US (0x3 << RK817_RAMP_RATE_OFFSET) | |
75 | + | |
55 | 76 | struct rk8xx_reg_info { |
56 | 77 | uint min_uv; |
57 | 78 | uint step_uv; |
... | ... | @@ -84,6 +105,25 @@ |
84 | 105 | { 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK818_BUCK4_VSEL_MASK, }, |
85 | 106 | }; |
86 | 107 | |
108 | +static const struct rk8xx_reg_info rk817_buck[] = { | |
109 | + /* buck 1 */ | |
110 | + { 500000, 12500, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x00, }, | |
111 | + { 1500000, 100000, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x50, }, | |
112 | + { 2400000, 0, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x59, }, | |
113 | + /* buck 2 */ | |
114 | + { 500000, 12500, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x00, }, | |
115 | + { 1500000, 100000, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x50, }, | |
116 | + { 2400000, 0, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_CONFIG(2), RK817_BUCK_VSEL_MASK, 0x59, }, | |
117 | + /* buck 3 */ | |
118 | + { 500000, 12500, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x00, }, | |
119 | + { 1500000, 100000, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x50, }, | |
120 | + { 2400000, 0, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_CONFIG(3), RK817_BUCK_VSEL_MASK, 0x59, }, | |
121 | + /* buck 4 */ | |
122 | + { 500000, 12500, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x00, }, | |
123 | + { 1500000, 100000, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x50, }, | |
124 | + { 3400000, 0, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_CONFIG(4), RK817_BUCK_VSEL_MASK, 0x63, }, | |
125 | +}; | |
126 | + | |
87 | 127 | static const struct rk8xx_reg_info rk818_buck[] = { |
88 | 128 | { 712500, 12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, REG_BUCK1_CONFIG, RK818_BUCK_VSEL_MASK, }, |
89 | 129 | { 712500, 12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, REG_BUCK2_CONFIG, RK818_BUCK_VSEL_MASK, }, |
... | ... | @@ -112,6 +152,36 @@ |
112 | 152 | { 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, }, |
113 | 153 | }; |
114 | 154 | |
155 | +static const struct rk8xx_reg_info rk817_ldo[] = { | |
156 | + /* ldo1 */ | |
157 | + { 600000, 25000, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), NA, RK817_LDO_VSEL_MASK, 0x00, }, | |
158 | + { 3400000, 0, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), NA, RK817_LDO_VSEL_MASK, 0x70, }, | |
159 | + /* ldo2 */ | |
160 | + { 600000, 25000, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x00, }, | |
161 | + { 3400000, 0, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), NA, RK817_LDO_VSEL_MASK, 0x70, }, | |
162 | + /* ldo3 */ | |
163 | + { 600000, 25000, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x00, }, | |
164 | + { 3400000, 0, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), NA, RK817_LDO_VSEL_MASK, 0x70, }, | |
165 | + /* ldo4 */ | |
166 | + { 600000, 25000, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x00, }, | |
167 | + { 3400000, 0, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), NA, RK817_LDO_VSEL_MASK, 0x70, }, | |
168 | + /* ldo5 */ | |
169 | + { 600000, 25000, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x00, }, | |
170 | + { 3400000, 0, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), NA, RK817_LDO_VSEL_MASK, 0x70, }, | |
171 | + /* ldo6 */ | |
172 | + { 600000, 25000, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x00, }, | |
173 | + { 3400000, 0, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), NA, RK817_LDO_VSEL_MASK, 0x70, }, | |
174 | + /* ldo7 */ | |
175 | + { 600000, 25000, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x00, }, | |
176 | + { 3400000, 0, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), NA, RK817_LDO_VSEL_MASK, 0x70, }, | |
177 | + /* ldo8 */ | |
178 | + { 600000, 25000, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x00, }, | |
179 | + { 3400000, 0, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), NA, RK817_LDO_VSEL_MASK, 0x70, }, | |
180 | + /* ldo9 */ | |
181 | + { 600000, 25000, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x00, }, | |
182 | + { 3400000, 0, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), NA, RK817_LDO_VSEL_MASK, 0x70, }, | |
183 | +}; | |
184 | + | |
115 | 185 | static const struct rk8xx_reg_info rk818_ldo[] = { |
116 | 186 | { 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, }, |
117 | 187 | { 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, NA, RK818_LDO_VSEL_MASK, }, |
... | ... | @@ -152,6 +222,24 @@ |
152 | 222 | default: |
153 | 223 | return &rk816_buck[num + 4]; |
154 | 224 | } |
225 | + | |
226 | + case RK817_ID: | |
227 | + switch (num) { | |
228 | + case 0 ... 2: | |
229 | + if (uvolt < 1500000) | |
230 | + return &rk817_buck[num * 3 + 0]; | |
231 | + else if (uvolt < 2400000) | |
232 | + return &rk817_buck[num * 3 + 1]; | |
233 | + else | |
234 | + return &rk817_buck[num * 3 + 2]; | |
235 | + case 3: | |
236 | + if (uvolt < 1500000) | |
237 | + return &rk817_buck[num * 3 + 0]; | |
238 | + else if (uvolt < 3400000) | |
239 | + return &rk817_buck[num * 3 + 1]; | |
240 | + else | |
241 | + return &rk817_buck[num * 3 + 2]; | |
242 | + } | |
155 | 243 | case RK818_ID: |
156 | 244 | return &rk818_buck[num]; |
157 | 245 | default: |
... | ... | @@ -189,7 +277,7 @@ |
189 | 277 | static int _buck_set_enable(struct udevice *pmic, int buck, bool enable) |
190 | 278 | { |
191 | 279 | uint mask, value, en_reg; |
192 | - int ret; | |
280 | + int ret = 0; | |
193 | 281 | struct rk8xx_priv *priv = dev_get_priv(pmic); |
194 | 282 | |
195 | 283 | switch (priv->variant) { |
... | ... | @@ -220,6 +308,15 @@ |
220 | 308 | ret = pmic_clrsetbits(pmic, REG_DCDC_EN, mask, |
221 | 309 | enable ? mask : 0); |
222 | 310 | break; |
311 | + case RK817_ID: | |
312 | + if (buck < 4) { | |
313 | + if (enable) | |
314 | + value = ((1 << buck) | (1 << (buck + 4))); | |
315 | + else | |
316 | + value = ((0 << buck) | (1 << (buck + 4))); | |
317 | + ret = pmic_reg_write(pmic, RK817_POWER_EN(0), value); | |
318 | + } | |
319 | + break; | |
223 | 320 | default: |
224 | 321 | ret = -EINVAL; |
225 | 322 | } |
... | ... | @@ -272,6 +369,12 @@ |
272 | 369 | if (ret < 0) |
273 | 370 | return ret; |
274 | 371 | break; |
372 | + case RK817_ID: | |
373 | + if (buck < 4) { | |
374 | + mask = 1 << buck; | |
375 | + ret = pmic_reg_read(pmic, RK817_POWER_EN(0)); | |
376 | + } | |
377 | + break; | |
275 | 378 | } |
276 | 379 | |
277 | 380 | if (ret < 0) |
... | ... | @@ -282,7 +385,7 @@ |
282 | 385 | |
283 | 386 | static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable) |
284 | 387 | { |
285 | - uint mask; | |
388 | + uint mask = 0; | |
286 | 389 | int ret; |
287 | 390 | struct rk8xx_priv *priv = dev_get_priv(pmic); |
288 | 391 | |
... | ... | @@ -299,6 +402,12 @@ |
299 | 402 | ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask, |
300 | 403 | enable ? 0 : mask); |
301 | 404 | break; |
405 | + case RK817_ID: | |
406 | + if (buck < 4) | |
407 | + mask = 1 << buck; | |
408 | + ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask, | |
409 | + enable ? mask : 0); | |
410 | + break; | |
302 | 411 | default: |
303 | 412 | ret = -EINVAL; |
304 | 413 | } |
... | ... | @@ -310,7 +419,7 @@ |
310 | 419 | { |
311 | 420 | struct rk8xx_priv *priv = dev_get_priv(pmic); |
312 | 421 | int ret, val; |
313 | - uint mask; | |
422 | + uint mask = 0; | |
314 | 423 | |
315 | 424 | switch (priv->variant) { |
316 | 425 | case RK805_ID: |
... | ... | @@ -329,6 +438,15 @@ |
329 | 438 | return val; |
330 | 439 | ret = val & mask ? 0 : 1; |
331 | 440 | break; |
441 | + case RK817_ID: | |
442 | + if (buck < 4) | |
443 | + mask = 1 << buck; | |
444 | + | |
445 | + val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0)); | |
446 | + if (val < 0) | |
447 | + return val; | |
448 | + ret = val & mask ? 1 : 0; | |
449 | + break; | |
332 | 450 | default: |
333 | 451 | ret = -EINVAL; |
334 | 452 | } |
... | ... | @@ -345,6 +463,11 @@ |
345 | 463 | case RK805_ID: |
346 | 464 | case RK816_ID: |
347 | 465 | return &rk816_ldo[num]; |
466 | + case RK817_ID: | |
467 | + if (uvolt < 3400000) | |
468 | + return &rk817_ldo[num * 2 + 0]; | |
469 | + else | |
470 | + return &rk817_ldo[num * 2 + 1]; | |
348 | 471 | case RK818_ID: |
349 | 472 | return &rk818_ldo[num]; |
350 | 473 | default: |
... | ... | @@ -376,6 +499,20 @@ |
376 | 499 | if (ret < 0) |
377 | 500 | return ret; |
378 | 501 | break; |
502 | + case RK817_ID: | |
503 | + if (ldo < 4) { | |
504 | + mask = 1 << ldo; | |
505 | + ret = pmic_reg_read(pmic, RK817_POWER_EN(1)); | |
506 | + } else if (ldo < 8) { | |
507 | + mask = 1 << (ldo - 4); | |
508 | + ret = pmic_reg_read(pmic, RK817_POWER_EN(2)); | |
509 | + } else if (ldo == 8) { | |
510 | + mask = 1 << 0; | |
511 | + ret = pmic_reg_read(pmic, RK817_POWER_EN(3)); | |
512 | + } else { | |
513 | + return false; | |
514 | + } | |
515 | + break; | |
379 | 516 | } |
380 | 517 | |
381 | 518 | if (ret < 0) |
... | ... | @@ -412,6 +549,24 @@ |
412 | 549 | ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask, |
413 | 550 | enable ? mask : 0); |
414 | 551 | break; |
552 | + case RK817_ID: | |
553 | + if (ldo < 4) { | |
554 | + en_reg = RK817_POWER_EN(1); | |
555 | + } else if (ldo < 8) { | |
556 | + ldo -= 4; | |
557 | + en_reg = RK817_POWER_EN(2); | |
558 | + } else if (ldo == 8) { | |
559 | + ldo = 0; /* BIT 0 */ | |
560 | + en_reg = RK817_POWER_EN(3); | |
561 | + } else { | |
562 | + return -EINVAL; | |
563 | + } | |
564 | + if (enable) | |
565 | + value = ((1 << ldo) | (1 << (ldo + 4))); | |
566 | + else | |
567 | + value = ((0 << ldo) | (1 << (ldo + 4))); | |
568 | + ret = pmic_reg_write(pmic, en_reg, value); | |
569 | + break; | |
415 | 570 | } |
416 | 571 | |
417 | 572 | return ret; |
... | ... | @@ -436,6 +591,17 @@ |
436 | 591 | ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask, |
437 | 592 | enable ? 0 : mask); |
438 | 593 | break; |
594 | + case RK817_ID: | |
595 | + if (ldo == 8) { | |
596 | + mask = 1 << 4; /* LDO9 */ | |
597 | + ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask, | |
598 | + enable ? mask : 0); | |
599 | + } else { | |
600 | + mask = 1 << ldo; | |
601 | + ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(1), mask, | |
602 | + enable ? mask : 0); | |
603 | + } | |
604 | + break; | |
439 | 605 | } |
440 | 606 | |
441 | 607 | return ret; |
... | ... | @@ -463,6 +629,21 @@ |
463 | 629 | if (val < 0) |
464 | 630 | return val; |
465 | 631 | ret = val & mask ? 0 : 1; |
632 | + break; | |
633 | + case RK817_ID: | |
634 | + if (ldo == 8) { | |
635 | + mask = 1 << 4; /* LDO9 */ | |
636 | + val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0)); | |
637 | + if (val < 0) | |
638 | + return val; | |
639 | + ret = val & mask ? 1 : 0; | |
640 | + } else { | |
641 | + mask = 1 << ldo; | |
642 | + val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(1)); | |
643 | + if (val < 0) | |
644 | + return val; | |
645 | + ret = val & mask ? 1 : 0; | |
646 | + } | |
466 | 647 | break; |
467 | 648 | } |
468 | 649 |
include/power/rk8xx_pmic.h
... | ... | @@ -170,6 +170,10 @@ |
170 | 170 | }; |
171 | 171 | |
172 | 172 | enum { |
173 | + RK817_REG_SYS_CFG3 = 0xf4, | |
174 | +}; | |
175 | + | |
176 | +enum { | |
173 | 177 | RK816_REG_DCDC_EN1 = 0x23, |
174 | 178 | RK816_REG_DCDC_EN2, |
175 | 179 | RK816_REG_DCDC_SLP_EN, |
176 | 180 | |
177 | 181 | |
... | ... | @@ -182,11 +186,38 @@ |
182 | 186 | RK805_ID = 0x8050, |
183 | 187 | RK808_ID = 0x0000, |
184 | 188 | RK816_ID = 0x8160, |
189 | + RK817_ID = 0x8170, | |
185 | 190 | RK818_ID = 0x8180, |
186 | 191 | }; |
187 | 192 | |
193 | +enum { | |
194 | + RK817_POWER_EN0 = 0xb1, | |
195 | + RK817_POWER_EN1, | |
196 | + RK817_POWER_EN2, | |
197 | + RK817_POWER_EN3, | |
198 | +}; | |
199 | + | |
200 | +#define RK817_POWER_EN_SAVE0 0x99 | |
201 | +#define RK817_POWER_EN_SAVE1 0xa4 | |
202 | + | |
203 | +#define RK817_ID_MSB 0xed | |
204 | +#define RK817_ID_LSB 0xee | |
188 | 205 | #define RK8XX_ID_MSK 0xfff0 |
189 | 206 | |
207 | +#define RK817_PMIC_SYS_CFG3 0xf4 | |
208 | +#define RK817_GPIO_INT_CFG 0xfe | |
209 | + | |
210 | +#define RK8XX_ON_SOURCE 0xae | |
211 | +#define RK8XX_OFF_SOURCE 0xaf | |
212 | +#define RK817_BUCK4_CMIN 0xc6 | |
213 | +#define RK817_ON_SOURCE 0xf5 | |
214 | +#define RK817_OFF_SOURCE 0xf6 | |
215 | + | |
216 | +struct reg_data { | |
217 | + u8 reg; | |
218 | + u8 val; | |
219 | + u8 mask; | |
220 | +}; | |
190 | 221 | struct rk8xx_reg_table { |
191 | 222 | char *name; |
192 | 223 | u8 reg_ctl; |