]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/power/as3722.c
3aafdc96704a070c5c9ac49d7e9139626d92af68
[people/ms/u-boot.git] / drivers / power / as3722.c
1 /*
2 * Copyright (C) 2014 NVIDIA Corporation
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #define pr_fmt(fmt) "as3722: " fmt
8
9 #include <common.h>
10 #include <dm.h>
11 #include <errno.h>
12 #include <fdtdec.h>
13 #include <i2c.h>
14
15 #include <power/as3722.h>
16
17 #define AS3722_SD_VOLTAGE(n) (0x00 + (n))
18 #define AS3722_GPIO_CONTROL(n) (0x08 + (n))
19 #define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0)
20 #define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL (7 << 0)
21 #define AS3722_GPIO_CONTROL_INVERT (1 << 7)
22 #define AS3722_LDO_VOLTAGE(n) (0x10 + (n))
23 #define AS3722_GPIO_SIGNAL_OUT 0x20
24 #define AS3722_SD_CONTROL 0x4d
25 #define AS3722_LDO_CONTROL 0x4e
26 #define AS3722_ASIC_ID1 0x90
27 #define AS3722_DEVICE_ID 0x0c
28 #define AS3722_ASIC_ID2 0x91
29
30 static int as3722_read(struct udevice *pmic, u8 reg, u8 *value)
31 {
32 int err;
33
34 err = dm_i2c_read(pmic, reg, value, 1);
35 if (err < 0)
36 return err;
37
38 return 0;
39 }
40
41 static int as3722_write(struct udevice *pmic, u8 reg, u8 value)
42 {
43 int err;
44
45 err = dm_i2c_write(pmic, reg, &value, 1);
46 if (err < 0)
47 return err;
48
49 return 0;
50 }
51
52 static int as3722_read_id(struct udevice *pmic, u8 *id, u8 *revision)
53 {
54 int err;
55
56 err = as3722_read(pmic, AS3722_ASIC_ID1, id);
57 if (err) {
58 error("failed to read ID1 register: %d", err);
59 return err;
60 }
61
62 err = as3722_read(pmic, AS3722_ASIC_ID2, revision);
63 if (err) {
64 error("failed to read ID2 register: %d", err);
65 return err;
66 }
67
68 return 0;
69 }
70
71 int as3722_sd_enable(struct udevice *pmic, unsigned int sd)
72 {
73 u8 value;
74 int err;
75
76 if (sd > 6)
77 return -EINVAL;
78
79 err = as3722_read(pmic, AS3722_SD_CONTROL, &value);
80 if (err) {
81 error("failed to read SD control register: %d", err);
82 return err;
83 }
84
85 value |= 1 << sd;
86
87 err = as3722_write(pmic, AS3722_SD_CONTROL, value);
88 if (err < 0) {
89 error("failed to write SD control register: %d", err);
90 return err;
91 }
92
93 return 0;
94 }
95
96 int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 value)
97 {
98 int err;
99
100 if (sd > 6)
101 return -EINVAL;
102
103 err = as3722_write(pmic, AS3722_SD_VOLTAGE(sd), value);
104 if (err < 0) {
105 error("failed to write SD%u voltage register: %d", sd, err);
106 return err;
107 }
108
109 return 0;
110 }
111
112 int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo)
113 {
114 u8 value;
115 int err;
116
117 if (ldo > 11)
118 return -EINVAL;
119
120 err = as3722_read(pmic, AS3722_LDO_CONTROL, &value);
121 if (err) {
122 error("failed to read LDO control register: %d", err);
123 return err;
124 }
125
126 value |= 1 << ldo;
127
128 err = as3722_write(pmic, AS3722_LDO_CONTROL, value);
129 if (err < 0) {
130 error("failed to write LDO control register: %d", err);
131 return err;
132 }
133
134 return 0;
135 }
136
137 int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, u8 value)
138 {
139 int err;
140
141 if (ldo > 11)
142 return -EINVAL;
143
144 err = as3722_write(pmic, AS3722_LDO_VOLTAGE(ldo), value);
145 if (err < 0) {
146 error("failed to write LDO%u voltage register: %d", ldo,
147 err);
148 return err;
149 }
150
151 return 0;
152 }
153
154 int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio,
155 unsigned long flags)
156 {
157 u8 value = 0;
158 int err;
159
160 if (flags & AS3722_GPIO_OUTPUT_VDDH)
161 value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH;
162
163 if (flags & AS3722_GPIO_INVERT)
164 value |= AS3722_GPIO_CONTROL_INVERT;
165
166 err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value);
167 if (err) {
168 error("failed to configure GPIO#%u: %d", gpio, err);
169 return err;
170 }
171
172 return 0;
173 }
174
175 static int as3722_gpio_set(struct udevice *pmic, unsigned int gpio,
176 unsigned int level)
177 {
178 const char *l;
179 u8 value;
180 int err;
181
182 if (gpio > 7)
183 return -EINVAL;
184
185 err = as3722_read(pmic, AS3722_GPIO_SIGNAL_OUT, &value);
186 if (err < 0) {
187 error("failed to read GPIO signal out register: %d", err);
188 return err;
189 }
190
191 if (level == 0) {
192 value &= ~(1 << gpio);
193 l = "low";
194 } else {
195 value |= 1 << gpio;
196 l = "high";
197 }
198
199 err = as3722_write(pmic, AS3722_GPIO_SIGNAL_OUT, value);
200 if (err) {
201 error("failed to set GPIO#%u %s: %d", gpio, l, err);
202 return err;
203 }
204
205 return 0;
206 }
207
208 int as3722_gpio_direction_output(struct udevice *pmic, unsigned int gpio,
209 unsigned int level)
210 {
211 u8 value;
212 int err;
213
214 if (gpio > 7)
215 return -EINVAL;
216
217 if (level == 0)
218 value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL;
219 else
220 value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH;
221
222 err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value);
223 if (err) {
224 error("failed to configure GPIO#%u as output: %d", gpio, err);
225 return err;
226 }
227
228 err = as3722_gpio_set(pmic, gpio, level);
229 if (err < 0) {
230 error("failed to set GPIO#%u high: %d", gpio, err);
231 return err;
232 }
233
234 return 0;
235 }
236
237 int as3722_init(struct udevice **devp)
238 {
239 struct udevice *pmic;
240 u8 id, revision;
241 const unsigned int bus = 0;
242 const unsigned int address = 0x40;
243 int err;
244
245 err = i2c_get_chip_for_busnum(bus, address, &pmic);
246 if (err)
247 return err;
248 err = as3722_read_id(pmic, &id, &revision);
249 if (err < 0) {
250 error("failed to read ID: %d", err);
251 return err;
252 }
253
254 if (id != AS3722_DEVICE_ID) {
255 error("unknown device");
256 return -ENOENT;
257 }
258
259 debug("AS3722 revision %#x found on I2C bus %u, address %#x\n",
260 revision, bus, address);
261 *devp = pmic;
262
263 return 0;
264 }