1 /* $OpenBSD: bytgpio.c,v 1.18 2022/10/20 20:40:57 kettenis Exp $ */
2 /*
3 * Copyright (c) 2016 Mark Kettenis
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <sys/param.h>
19 #include <sys/malloc.h>
20 #include <sys/systm.h>
21
22 #include <dev/acpi/acpireg.h>
23 #include <dev/acpi/acpivar.h>
24 #include <dev/acpi/acpidev.h>
25 #include <dev/acpi/amltypes.h>
26 #include <dev/acpi/dsdt.h>
27
28 #define BYTGPIO_CONF_GD_LEVEL 0x01000000
29 #define BYTGPIO_CONF_GD_TPE 0x02000000
30 #define BYTGPIO_CONF_GD_TNE 0x04000000
31 #define BYTGPIO_CONF_GD_MASK 0x07000000
32 #define BYTGPIO_CONF_DIRECT_IRQ_EN 0x08000000
33
34 #define BYTGPIO_PAD_VAL 0x00000001
35
36 #define BYTGPIO_IRQ_TS_0 0x800
37 #define BYTGPIO_IRQ_TS_1 0x804
38 #define BYTGPIO_IRQ_TS_2 0x808
39
40 struct bytgpio_intrhand {
41 int (*ih_func)(void *);
42 void *ih_arg;
43 int ih_tflags;
44 };
45
46 struct bytgpio_softc {
47 struct device sc_dev;
48 struct acpi_softc *sc_acpi;
49 struct aml_node *sc_node;
50
51 bus_space_tag_t sc_memt;
52 bus_space_handle_t sc_memh;
53 void *sc_ih;
54
55 const int *sc_pins;
56 int sc_npins;
57 struct bytgpio_intrhand *sc_pin_ih;
58
59 struct acpi_gpio sc_gpio;
60 };
61
62 int bytgpio_match(struct device *, void *, void *);
63 void bytgpio_attach(struct device *, struct device *, void *);
64
65 const struct cfattach bytgpio_ca = {
66 sizeof(struct bytgpio_softc), bytgpio_match, bytgpio_attach
67 };
68
69 struct cfdriver bytgpio_cd = {
70 NULL, "bytgpio", DV_DULL
71 };
72
73 const char *bytgpio_hids[] = {
74 "INT33FC",
75 NULL
76 };
77
78 /*
79 * The pads for the pins are randomly ordered.
80 */
81
82 const int byt_score_pins[] = {
83 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 36, 38, 39, 35, 40,
84 84, 62, 61, 64, 59, 54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
85 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 95, 105, 70, 68, 67,
86 66, 69, 71, 65, 72, 86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
87 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 2, 1, 0, 4, 6, 7, 9,
88 8, 33, 32, 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 24, 22, 5,
89 3, 10, 11, 106, 87, 91, 104, 97, 100
90 };
91
92 const int byt_ncore_pins[] = {
93 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 14, 15, 12, 26, 27,
94 1, 4, 8, 11, 0, 3, 6, 10, 13, 2, 5, 9, 7
95 };
96
97 const int byt_sus_pins[] = {
98 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 18, 7, 11, 20, 17, 1,
99 8, 10, 19, 12, 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 26, 51,
100 56, 54, 49, 55, 48, 57, 50, 58, 52, 53, 59, 40
101 };
102
103 int bytgpio_read_pin(void *, int);
104 void bytgpio_write_pin(void *, int, int);
105 void bytgpio_intr_establish(void *, int, int, int (*)(void *), void *);
106 void bytgpio_intr_enable(void *, int);
107 void bytgpio_intr_disable(void *, int);
108 int bytgpio_intr(void *);
109
110 int
bytgpio_match(struct device * parent,void * match,void * aux)111 bytgpio_match(struct device *parent, void *match, void *aux)
112 {
113 struct acpi_attach_args *aaa = aux;
114 struct cfdata *cf = match;
115
116 if (aaa->aaa_naddr < 1 || aaa->aaa_nirq < 1)
117 return 0;
118 return acpi_matchhids(aaa, bytgpio_hids, cf->cf_driver->cd_name);
119 }
120
121 void
bytgpio_attach(struct device * parent,struct device * self,void * aux)122 bytgpio_attach(struct device *parent, struct device *self, void *aux)
123 {
124 struct bytgpio_softc *sc = (struct bytgpio_softc *)self;
125 struct acpi_attach_args *aaa = aux;
126 int64_t uid;
127 uint32_t reg;
128 int i;
129
130 sc->sc_acpi = (struct acpi_softc *)parent;
131 sc->sc_node = aaa->aaa_node;
132 printf(" %s", sc->sc_node->name);
133
134 if (aml_evalinteger(sc->sc_acpi, sc->sc_node, "_UID", 0, NULL, &uid)) {
135 printf(": can't find uid\n");
136 return;
137 }
138
139 printf(" uid %lld", uid);
140
141 switch (uid) {
142 case 1:
143 sc->sc_pins = byt_score_pins;
144 sc->sc_npins = nitems(byt_score_pins);
145 break;
146 case 2:
147 sc->sc_pins = byt_ncore_pins;
148 sc->sc_npins = nitems(byt_ncore_pins);
149 break;
150 case 3:
151 sc->sc_pins = byt_sus_pins;
152 sc->sc_npins = nitems(byt_sus_pins);
153 break;
154 default:
155 printf("\n");
156 return;
157 }
158
159 printf(" addr 0x%llx/0x%llx", aaa->aaa_addr[0], aaa->aaa_size[0]);
160 printf(" irq %d", aaa->aaa_irq[0]);
161
162 sc->sc_memt = aaa->aaa_bst[0];
163 if (bus_space_map(sc->sc_memt, aaa->aaa_addr[0], aaa->aaa_size[0],
164 0, &sc->sc_memh)) {
165 printf(": can't map registers\n");
166 return;
167 }
168
169 sc->sc_pin_ih = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_ih),
170 M_DEVBUF, M_WAITOK | M_ZERO);
171
172 sc->sc_ih = acpi_intr_establish(aaa->aaa_irq[0], aaa->aaa_irq_flags[0],
173 IPL_BIO, bytgpio_intr, sc, sc->sc_dev.dv_xname);
174 if (sc->sc_ih == NULL) {
175 printf(": can't establish interrupt\n");
176 goto unmap;
177 }
178
179 sc->sc_gpio.cookie = sc;
180 sc->sc_gpio.read_pin = bytgpio_read_pin;
181 sc->sc_gpio.write_pin = bytgpio_write_pin;
182 sc->sc_gpio.intr_establish = bytgpio_intr_establish;
183 sc->sc_gpio.intr_enable = bytgpio_intr_enable;
184 sc->sc_gpio.intr_disable = bytgpio_intr_disable;
185 sc->sc_node->gpio = &sc->sc_gpio;
186
187 /* Mask all interrupts. */
188 for (i = 0; i < sc->sc_npins; i++) {
189 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[i] * 16);
190
191 /*
192 * Skip pins configured as direct IRQ. Those are tied
193 * directly to the APIC.
194 */
195 if (reg & BYTGPIO_CONF_DIRECT_IRQ_EN)
196 continue;
197
198 reg &= ~BYTGPIO_CONF_GD_MASK;
199 bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[i] * 16, reg);
200 }
201
202 printf(", %d pins\n", sc->sc_npins);
203
204 acpi_register_gpio(sc->sc_acpi, sc->sc_node);
205 return;
206
207 unmap:
208 free(sc->sc_pin_ih, M_DEVBUF, sc->sc_npins * sizeof(*sc->sc_pin_ih));
209 bus_space_unmap(sc->sc_memt, sc->sc_memh, aaa->aaa_size[0]);
210 }
211
212 int
bytgpio_read_pin(void * cookie,int pin)213 bytgpio_read_pin(void *cookie, int pin)
214 {
215 struct bytgpio_softc *sc = cookie;
216 uint32_t reg;
217
218 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16 + 8);
219 return (reg & BYTGPIO_PAD_VAL);
220 }
221
222 void
bytgpio_write_pin(void * cookie,int pin,int value)223 bytgpio_write_pin(void *cookie, int pin, int value)
224 {
225 struct bytgpio_softc *sc = cookie;
226 uint32_t reg;
227
228 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16 + 8);
229 if (value)
230 reg |= BYTGPIO_PAD_VAL;
231 else
232 reg &= ~BYTGPIO_PAD_VAL;
233 bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16 + 8, reg);
234 }
235
236 void
bytgpio_intr_establish(void * cookie,int pin,int flags,int (* func)(void *),void * arg)237 bytgpio_intr_establish(void *cookie, int pin, int flags,
238 int (*func)(void *), void *arg)
239 {
240 struct bytgpio_softc *sc = cookie;
241
242 KASSERT(pin >= 0 && pin < sc->sc_npins);
243
244 sc->sc_pin_ih[pin].ih_func = func;
245 sc->sc_pin_ih[pin].ih_arg = arg;
246 sc->sc_pin_ih[pin].ih_tflags = flags;
247
248 bytgpio_intr_enable(cookie, pin);
249 }
250
251 void
bytgpio_intr_enable(void * cookie,int pin)252 bytgpio_intr_enable(void *cookie, int pin)
253 {
254 struct bytgpio_softc *sc = cookie;
255 uint32_t reg;
256 int flags;
257
258 KASSERT(pin >= 0 && pin < sc->sc_npins);
259
260 flags = sc->sc_pin_ih[pin].ih_tflags;
261
262 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16);
263 reg &= ~BYTGPIO_CONF_GD_MASK;
264 if ((flags & LR_GPIO_MODE) == 0)
265 reg |= BYTGPIO_CONF_GD_LEVEL;
266 if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTLO)
267 reg |= BYTGPIO_CONF_GD_TNE;
268 if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTHI)
269 reg |= BYTGPIO_CONF_GD_TPE;
270 if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH)
271 reg |= BYTGPIO_CONF_GD_TNE | BYTGPIO_CONF_GD_TPE;
272 bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16, reg);
273 }
274
275 void
bytgpio_intr_disable(void * cookie,int pin)276 bytgpio_intr_disable(void *cookie, int pin)
277 {
278 struct bytgpio_softc *sc = cookie;
279 uint32_t reg;
280
281 KASSERT(pin >= 0 && pin < sc->sc_npins);
282
283 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16);
284 reg &= ~BYTGPIO_CONF_GD_MASK;
285 bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16, reg);
286 }
287
288 int
bytgpio_intr(void * arg)289 bytgpio_intr(void *arg)
290 {
291 struct bytgpio_softc *sc = arg;
292 uint32_t reg;
293 int rc = 0;
294 int pin;
295
296 for (pin = 0; pin < sc->sc_npins; pin++) {
297 if (pin % 32 == 0) {
298 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
299 BYTGPIO_IRQ_TS_0 + (pin / 8));
300 bus_space_write_4(sc->sc_memt, sc->sc_memh,
301 BYTGPIO_IRQ_TS_0 + (pin / 8), reg);
302 }
303 if (reg & (1 << (pin % 32))) {
304 if (sc->sc_pin_ih[pin].ih_func)
305 sc->sc_pin_ih[pin].ih_func(sc->sc_pin_ih[pin].ih_arg);
306 rc = 1;
307 }
308 }
309
310 return rc;
311 }
312