]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/power/axp809.c
mmc: omap_hsmmc: implement send_init_stream callback
[people/ms/u-boot.git] / drivers / power / axp809.c
1 /*
2 * AXP809 driver based on AXP221 driver
3 *
4 *
5 * (C) Copyright 2016 Chen-Yu Tsai <wens@csie.org>
6 *
7 * Based on axp221.c
8 * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
9 * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
10 *
11 * SPDX-License-Identifier: GPL-2.0+
12 */
13
14 #include <common.h>
15 #include <errno.h>
16 #include <asm/arch/gpio.h>
17 #include <asm/arch/pmic_bus.h>
18 #include <axp_pmic.h>
19
20 static u8 axp809_mvolt_to_cfg(int mvolt, int min, int max, int div)
21 {
22 if (mvolt < min)
23 mvolt = min;
24 else if (mvolt > max)
25 mvolt = max;
26
27 return (mvolt - min) / div;
28 }
29
30 int axp_set_dcdc1(unsigned int mvolt)
31 {
32 int ret;
33 u8 cfg = axp809_mvolt_to_cfg(mvolt, 1600, 3400, 100);
34
35 if (mvolt == 0)
36 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
37 AXP809_OUTPUT_CTRL1_DCDC1_EN);
38
39 ret = pmic_bus_write(AXP809_DCDC1_CTRL, cfg);
40 if (ret)
41 return ret;
42
43 ret = pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
44 AXP809_OUTPUT_CTRL2_DC1SW_EN);
45 if (ret)
46 return ret;
47
48 return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
49 AXP809_OUTPUT_CTRL1_DCDC1_EN);
50 }
51
52 int axp_set_dcdc2(unsigned int mvolt)
53 {
54 int ret;
55 u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1540, 20);
56
57 if (mvolt == 0)
58 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
59 AXP809_OUTPUT_CTRL1_DCDC2_EN);
60
61 ret = pmic_bus_write(AXP809_DCDC2_CTRL, cfg);
62 if (ret)
63 return ret;
64
65 return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
66 AXP809_OUTPUT_CTRL1_DCDC2_EN);
67 }
68
69 int axp_set_dcdc3(unsigned int mvolt)
70 {
71 int ret;
72 u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1860, 20);
73
74 if (mvolt == 0)
75 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
76 AXP809_OUTPUT_CTRL1_DCDC3_EN);
77
78 ret = pmic_bus_write(AXP809_DCDC3_CTRL, cfg);
79 if (ret)
80 return ret;
81
82 return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
83 AXP809_OUTPUT_CTRL1_DCDC3_EN);
84 }
85
86 int axp_set_dcdc4(unsigned int mvolt)
87 {
88 int ret;
89 u8 cfg = axp809_mvolt_to_cfg(mvolt, 600, 1540, 20);
90
91 if (mvolt >= 1540)
92 cfg = 0x30 + axp809_mvolt_to_cfg(mvolt, 1800, 2600, 100);
93
94 if (mvolt == 0)
95 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
96 AXP809_OUTPUT_CTRL1_DCDC4_EN);
97
98 ret = pmic_bus_write(AXP809_DCDC5_CTRL, cfg);
99 if (ret)
100 return ret;
101
102 return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
103 AXP809_OUTPUT_CTRL1_DCDC4_EN);
104 }
105
106 int axp_set_dcdc5(unsigned int mvolt)
107 {
108 int ret;
109 u8 cfg = axp809_mvolt_to_cfg(mvolt, 1000, 2550, 50);
110
111 if (mvolt == 0)
112 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
113 AXP809_OUTPUT_CTRL1_DCDC5_EN);
114
115 ret = pmic_bus_write(AXP809_DCDC5_CTRL, cfg);
116 if (ret)
117 return ret;
118
119 return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
120 AXP809_OUTPUT_CTRL1_DCDC5_EN);
121 }
122
123 int axp_set_aldo(int aldo_num, unsigned int mvolt)
124 {
125 int ret;
126 u8 cfg;
127
128 if (aldo_num < 1 || aldo_num > 3)
129 return -EINVAL;
130
131 if (mvolt == 0 && aldo_num == 3)
132 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2,
133 AXP809_OUTPUT_CTRL2_ALDO3_EN);
134 if (mvolt == 0)
135 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL1,
136 AXP809_OUTPUT_CTRL1_ALDO1_EN << (aldo_num - 1));
137
138 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100);
139 ret = pmic_bus_write(AXP809_ALDO1_CTRL + (aldo_num - 1), cfg);
140 if (ret)
141 return ret;
142
143 if (aldo_num == 3)
144 return pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
145 AXP809_OUTPUT_CTRL2_ALDO3_EN);
146 return pmic_bus_setbits(AXP809_OUTPUT_CTRL1,
147 AXP809_OUTPUT_CTRL1_ALDO1_EN << (aldo_num - 1));
148 }
149
150 /* TODO: re-work other AXP drivers to consolidate ALDO functions. */
151 int axp_set_aldo1(unsigned int mvolt)
152 {
153 return axp_set_aldo(1, mvolt);
154 }
155
156 int axp_set_aldo2(unsigned int mvolt)
157 {
158 return axp_set_aldo(2, mvolt);
159 }
160
161 int axp_set_aldo3(unsigned int mvolt)
162 {
163 return axp_set_aldo(3, mvolt);
164 }
165
166 int axp_set_dldo(int dldo_num, unsigned int mvolt)
167 {
168 u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100);
169 int ret;
170
171 if (dldo_num < 1 || dldo_num > 2)
172 return -EINVAL;
173
174 if (mvolt == 0)
175 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2,
176 AXP809_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1));
177
178 if (dldo_num == 1 && mvolt > 3300)
179 cfg += 1 + axp809_mvolt_to_cfg(mvolt, 3400, 4200, 200);
180 ret = pmic_bus_write(AXP809_DLDO1_CTRL + (dldo_num - 1), cfg);
181 if (ret)
182 return ret;
183
184 return pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
185 AXP809_OUTPUT_CTRL2_DLDO1_EN << (dldo_num - 1));
186 }
187
188 int axp_set_eldo(int eldo_num, unsigned int mvolt)
189 {
190 int ret;
191 u8 cfg = axp809_mvolt_to_cfg(mvolt, 700, 3300, 100);
192
193 if (eldo_num < 1 || eldo_num > 3)
194 return -EINVAL;
195
196 if (mvolt == 0)
197 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2,
198 AXP809_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1));
199
200 ret = pmic_bus_write(AXP809_ELDO1_CTRL + (eldo_num - 1), cfg);
201 if (ret)
202 return ret;
203
204 return pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
205 AXP809_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1));
206 }
207
208 int axp_set_sw(bool on)
209 {
210 if (on)
211 return pmic_bus_setbits(AXP809_OUTPUT_CTRL2,
212 AXP809_OUTPUT_CTRL2_SWOUT_EN);
213
214 return pmic_bus_clrbits(AXP809_OUTPUT_CTRL2,
215 AXP809_OUTPUT_CTRL2_SWOUT_EN);
216 }
217
218 int axp_init(void)
219 {
220 return pmic_bus_init();
221 }
222
223 int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
224 {
225 pmic_bus_write(AXP809_SHUTDOWN, AXP809_SHUTDOWN_POWEROFF);
226
227 /* infinite loop during shutdown */
228 while (1) {}
229
230 /* not reached */
231 return 0;
232 }