1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright 2020 Michal Meloun <mmel@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/bus.h>
34 #include <sys/gpio.h>
35 #include <sys/kernel.h>
36 #include <sys/malloc.h>
37 #include <sys/sx.h>
38
39 #include <machine/bus.h>
40
41 #include <dev/fdt/fdt_common.h>
42 #include <dev/gpio/gpiobusvar.h>
43
44 #include "max77620.h"
45
46 MALLOC_DEFINE(M_MAX77620_GPIO, "MAX77620 gpio", "MAX77620 GPIO");
47
48 #define NGPIO 8
49
50 #define GPIO_LOCK(_sc) sx_slock(&(_sc)->gpio_lock)
51 #define GPIO_UNLOCK(_sc) sx_unlock(&(_sc)->gpio_lock)
52 #define GPIO_ASSERT(_sc) sx_assert(&(_sc)->gpio_lock, SA_LOCKED)
53
54 enum prop_id {
55 CFG_BIAS_PULL_UP,
56 CFG_BIAS_PULL_DOWN,
57 CFG_OPEN_DRAIN,
58 CFG_PUSH_PULL,
59
60 CFG_ACTIVE_FPS_SRC,
61 CFG_ACTIVE_PWRUP_SLOT,
62 CFG_ACTIVE_PWRDOWN_SLOT,
63 CFG_SUSPEND_FPS_SRC,
64 CFG_SUSPEND_PWRUP_SLOT,
65 CFG_SUSPEND_PWRDOWN_SLOT,
66
67 PROP_ID_MAX_ID
68 };
69
70 static const struct {
71 const char *name;
72 enum prop_id id;
73 } max77620_prop_names[] = {
74 {"bias-pull-up", CFG_BIAS_PULL_UP},
75 {"bias-pull-down", CFG_BIAS_PULL_DOWN},
76 {"drive-open-drain", CFG_OPEN_DRAIN},
77 {"drive-push-pull", CFG_PUSH_PULL},
78 {"maxim,active-fps-source", CFG_ACTIVE_FPS_SRC},
79 {"maxim,active-fps-power-up-slot", CFG_ACTIVE_PWRUP_SLOT},
80 {"maxim,active-fps-power-down-slot", CFG_ACTIVE_PWRDOWN_SLOT},
81 {"maxim,suspend-fps-source", CFG_SUSPEND_FPS_SRC},
82 {"maxim,suspend-fps-power-up-slot", CFG_SUSPEND_PWRUP_SLOT},
83 {"maxim,suspend-fps-power-down-slot", CFG_SUSPEND_PWRDOWN_SLOT},
84 };
85
86 /* Configuration for one pin group. */
87 struct max77620_pincfg {
88 bool alt_func;
89 int params[PROP_ID_MAX_ID];
90 };
91
92 static char *altfnc_table[] = {
93 "lpm-control-in",
94 "fps-out",
95 "32k-out1",
96 "sd0-dvs-in",
97 "sd1-dvs-in",
98 "reference-out",
99 };
100
101 struct max77620_gpio_pin {
102 int pin_caps;
103 char pin_name[GPIOMAXNAME];
104 uint8_t reg;
105
106 /* Runtime data */
107 bool alt_func; /* GPIO or alternate function */
108 };
109
110 /* --------------------------------------------------------------------------
111 *
112 * Pinmux functions.
113 */
114 static int
115 max77620_pinmux_get_function(struct max77620_softc *sc, char *name,
116 struct max77620_pincfg *cfg)
117 {
118 int i;
119
120 if (strcmp("gpio", name) == 0) {
121 cfg->alt_func = false;
122 return (0);
123 }
124 for (i = 0; i < nitems(altfnc_table); i++) {
125 if (strcmp(altfnc_table[i], name) == 0) {
126 cfg->alt_func = true;
127 return (0);
128 }
129 }
130 return (-1);
131 }
132
133 static int
134 max77620_pinmux_set_fps(struct max77620_softc *sc, int pin_num,
135 struct max77620_gpio_pin *pin)
136 {
137 #if 0
138 struct max77620_fps_config *fps_config = &mpci->fps_config[pin];
139 int addr, ret;
140 int param_val;
141 int mask, shift;
142
143 if ((pin < 1) || (pin > 3))
144 return (0);
145
146 switch (param) {
147 case MAX77620_ACTIVE_FPS_SOURCE:
148 case MAX77620_SUSPEND_FPS_SOURCE:
149 mask = MAX77620_FPS_SRC_MASK;
150 shift = MAX77620_FPS_SRC_SHIFT;
151 param_val = fps_config->active_fps_src;
152 if (param == MAX77620_SUSPEND_FPS_SOURCE)
153 param_val = fps_config->suspend_fps_src;
154 break;
155
156 case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS:
157 case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS:
158 mask = MAX77620_FPS_PU_PERIOD_MASK;
159 shift = MAX77620_FPS_PU_PERIOD_SHIFT;
160 param_val = fps_config->active_power_up_slots;
161 if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS)
162 param_val = fps_config->suspend_power_up_slots;
163 break;
164
165 case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS:
166 case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS:
167 mask = MAX77620_FPS_PD_PERIOD_MASK;
168 shift = MAX77620_FPS_PD_PERIOD_SHIFT;
169 param_val = fps_config->active_power_down_slots;
170 if (param == MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS)
171 param_val = fps_config->suspend_power_down_slots;
172 break;
173
174 default:
175 dev_err(mpci->dev, "Invalid parameter %d for pin %d\n",
176 param, pin);
177 return -EINVAL;
178 }
179
180 if (param_val < 0)
181 return 0;
182
183 ret = regmap_update_bits(mpci->rmap, addr, mask, param_val << shift);
184 if (ret < 0)
185 dev_err(mpci->dev, "Reg 0x%02x update failed %d\n", addr, ret);
186
187 return ret;
188 #endif
189 return (0);
190 }
191
192 static int
193 max77620_pinmux_config_node(struct max77620_softc *sc, char *pin_name,
194 struct max77620_pincfg *cfg)
195 {
196 struct max77620_gpio_pin *pin;
197 uint8_t reg;
198 int pin_num, rv;
199
200 for (pin_num = 0; pin_num < sc->gpio_npins; pin_num++) {
201 if (strcmp(sc->gpio_pins[pin_num]->pin_name, pin_name) == 0)
202 break;
203 }
204 if (pin_num >= sc->gpio_npins) {
205 device_printf(sc->dev, "Unknown pin: %s\n", pin_name);
206 return (ENXIO);
207 }
208 pin = sc->gpio_pins[pin_num];
209
210 rv = max77620_pinmux_set_fps(sc, pin_num, pin);
211 if (rv != 0)
212 return (rv);
213
214 rv = RD1(sc, pin->reg, ®);
215 if (rv != 0) {
216 device_printf(sc->dev, "Cannot read GIPO_CFG register\n");
217 return (ENXIO);
218 }
219
220 if (cfg->alt_func) {
221 pin->alt_func = true;
222 sc->gpio_reg_ame |= 1 << pin_num;
223 } else {
224 pin->alt_func = false;
225 sc->gpio_reg_ame &= ~(1 << pin_num);
226 }
227
228 /* Pull up/down. */
229 switch (cfg->params[CFG_BIAS_PULL_UP]) {
230 case 1:
231 sc->gpio_reg_pue |= 1 << pin_num;
232 break;
233 case 0:
234 sc->gpio_reg_pue &= ~(1 << pin_num);
235 break;
236 default:
237 break;
238 }
239
240 switch (cfg->params[CFG_BIAS_PULL_DOWN]) {
241 case 1:
242 sc->gpio_reg_pde |= 1 << pin_num;
243 break;
244 case 0:
245 sc->gpio_reg_pde &= ~(1 << pin_num);
246 break;
247 default:
248 break;
249 }
250
251 /* Open drain/push-pull modes. */
252 if (cfg->params[CFG_OPEN_DRAIN] == 1) {
253 reg &= ~MAX77620_REG_GPIO_DRV(~0);
254 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_OPENDRAIN);
255 }
256
257 if (cfg->params[CFG_PUSH_PULL] == 1) {
258 reg &= ~MAX77620_REG_GPIO_DRV(~0);
259 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_PUSHPULL);
260 }
261
262 rv = WR1(sc, pin->reg, reg);
263 if (rv != 0) {
264 device_printf(sc->dev, "Cannot read GIPO_CFG register\n");
265 return (ENXIO);
266 }
267
268 return (0);
269 }
270
271 static int
272 max77620_pinmux_read_node(struct max77620_softc *sc, phandle_t node,
273 struct max77620_pincfg *cfg, char **pins, int *lpins)
274 {
275 char *function;
276 int rv, i;
277
278 *lpins = OF_getprop_alloc(node, "pins", (void **)pins);
279 if (*lpins <= 0)
280 return (ENOENT);
281
282 /* Read function (mux) settings. */
283 rv = OF_getprop_alloc(node, "function", (void **)&function);
284 if (rv > 0) {
285 rv = max77620_pinmux_get_function(sc, function, cfg);
286 if (rv == -1) {
287 device_printf(sc->dev,
288 "Unknown function %s\n", function);
289 OF_prop_free(function);
290 return (ENXIO);
291 }
292 }
293
294 /* Read numeric properties. */
295 for (i = 0; i < PROP_ID_MAX_ID; i++) {
296 rv = OF_getencprop(node, max77620_prop_names[i].name,
297 &cfg->params[i], sizeof(cfg->params[i]));
298 if (rv <= 0)
299 cfg->params[i] = -1;
300 }
301
302 OF_prop_free(function);
303 return (0);
304 }
305
306 static int
307 max77620_pinmux_process_node(struct max77620_softc *sc, phandle_t node)
308 {
309 struct max77620_pincfg cfg;
310 char *pins, *pname;
311 int i, len, lpins, rv;
312
313 rv = max77620_pinmux_read_node(sc, node, &cfg, &pins, &lpins);
314 if (rv != 0)
315 return (rv);
316
317 len = 0;
318 pname = pins;
319 do {
320 i = strlen(pname) + 1;
321 rv = max77620_pinmux_config_node(sc, pname, &cfg);
322 if (rv != 0) {
323 device_printf(sc->dev,
324 "Cannot configure pin: %s: %d\n", pname, rv);
325 }
326 len += i;
327 pname += i;
328 } while (len < lpins);
329
330 if (pins != NULL)
331 OF_prop_free(pins);
332
333 return (rv);
334 }
335
336 int max77620_pinmux_configure(device_t dev, phandle_t cfgxref)
337 {
338 struct max77620_softc *sc;
339 phandle_t node, cfgnode;
340 uint8_t old_reg_pue, old_reg_pde, old_reg_ame;
341 int rv;
342
343 sc = device_get_softc(dev);
344 cfgnode = OF_node_from_xref(cfgxref);
345
346 old_reg_pue = sc->gpio_reg_pue;
347 old_reg_pde = sc->gpio_reg_pde;
348 old_reg_ame = sc->gpio_reg_ame;
349
350 for (node = OF_child(cfgnode); node != 0; node = OF_peer(node)) {
351 if (!ofw_bus_node_status_okay(node))
352 continue;
353 rv = max77620_pinmux_process_node(sc, node);
354 if (rv != 0)
355 device_printf(dev, "Failed to process pinmux");
356
357 }
358
359 if (old_reg_pue != sc->gpio_reg_pue) {
360 rv = WR1(sc, MAX77620_REG_PUE_GPIO, sc->gpio_reg_pue);
361 if (rv != 0) {
362 device_printf(sc->dev,
363 "Cannot update PUE_GPIO register\n");
364 return (ENXIO);
365 }
366 }
367
368 if (old_reg_pde != sc->gpio_reg_pde) {
369 rv = WR1(sc, MAX77620_REG_PDE_GPIO, sc->gpio_reg_pde);
370 if (rv != 0) {
371 device_printf(sc->dev,
372 "Cannot update PDE_GPIO register\n");
373 return (ENXIO);
374 }
375 }
376
377 if (old_reg_ame != sc->gpio_reg_ame) {
378 rv = WR1(sc, MAX77620_REG_AME_GPIO, sc->gpio_reg_ame);
379 if (rv != 0) {
380 device_printf(sc->dev,
381 "Cannot update PDE_GPIO register\n");
382 return (ENXIO);
383 }
384 }
385
386 return (0);
387 }
388
389 /* --------------------------------------------------------------------------
390 *
391 * GPIO
392 */
393 device_t
394 max77620_gpio_get_bus(device_t dev)
395 {
396 struct max77620_softc *sc;
397
398 sc = device_get_softc(dev);
399 return (sc->gpio_busdev);
400 }
401
402 int
403 max77620_gpio_pin_max(device_t dev, int *maxpin)
404 {
405
406 *maxpin = NGPIO - 1;
407 return (0);
408 }
409
410 int
411 max77620_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
412 {
413 struct max77620_softc *sc;
414
415 sc = device_get_softc(dev);
416 if (pin >= sc->gpio_npins)
417 return (EINVAL);
418 GPIO_LOCK(sc);
419 *caps = sc->gpio_pins[pin]->pin_caps;
420 GPIO_UNLOCK(sc);
421 return (0);
422 }
423
424 int
425 max77620_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
426 {
427 struct max77620_softc *sc;
428
429 sc = device_get_softc(dev);
430 if (pin >= sc->gpio_npins)
431 return (EINVAL);
432 GPIO_LOCK(sc);
433 memcpy(name, sc->gpio_pins[pin]->pin_name, GPIOMAXNAME);
434 GPIO_UNLOCK(sc);
435 return (0);
436 }
437
438 static int
439 max77620_gpio_get_mode(struct max77620_softc *sc, uint32_t pin_num,
440 uint32_t *out_flags)
441 {
442 struct max77620_gpio_pin *pin;
443 uint8_t reg;
444 int rv;
445
446 pin = sc->gpio_pins[pin_num];
447 *out_flags = 0;
448
449 rv = RD1(sc, pin->reg, ®);
450 if (rv != 0) {
451 device_printf(sc->dev, "Cannot read GIPO_CFG register\n");
452 return (ENXIO);
453 }
454
455 /* Pin function */
456 pin->alt_func = sc->gpio_reg_ame & (1 << pin_num);
457
458 /* Pull up/down. */
459 if (sc->gpio_reg_pue & (1 << pin_num))
460 *out_flags |= GPIO_PIN_PULLUP;
461 if (sc->gpio_reg_pde & (1 << pin_num))
462 *out_flags |= GPIO_PIN_PULLDOWN;
463
464 /* Open drain/push-pull modes. */
465 if (MAX77620_REG_GPIO_DRV_GET(reg) == MAX77620_REG_GPIO_DRV_PUSHPULL)
466 *out_flags |= GPIO_PIN_PUSHPULL;
467 else
468 *out_flags |= GPIO_PIN_OPENDRAIN;
469
470 /* Input/output modes. */
471 if (MAX77620_REG_GPIO_DRV_GET(reg) == MAX77620_REG_GPIO_DRV_PUSHPULL)
472 *out_flags |= GPIO_PIN_OUTPUT;
473 else
474 *out_flags |= GPIO_PIN_OUTPUT | GPIO_PIN_INPUT;
475 return (0);
476 }
477
478 int
479 max77620_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *out_flags)
480 {
481 struct max77620_softc *sc;
482 int rv;
483
484 sc = device_get_softc(dev);
485 if (pin >= sc->gpio_npins)
486 return (EINVAL);
487
488 GPIO_LOCK(sc);
489 #if 0 /* It colide with GPIO regulators */
490 /* Is pin in GPIO mode ? */
491 if (sc->gpio_pins[pin]->alt_func) {
492 GPIO_UNLOCK(sc);
493 return (ENXIO);
494 }
495 #endif
496 rv = max77620_gpio_get_mode(sc, pin, out_flags);
497 GPIO_UNLOCK(sc);
498
499 return (rv);
500 }
501
502 int
503 max77620_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags)
504 {
505 struct max77620_softc *sc;
506 struct max77620_gpio_pin *pin;
507 uint8_t reg;
508 uint8_t old_reg_pue, old_reg_pde;
509 int rv;
510
511 sc = device_get_softc(dev);
512 if (pin_num >= sc->gpio_npins)
513 return (EINVAL);
514
515 pin = sc->gpio_pins[pin_num];
516
517 GPIO_LOCK(sc);
518
519 #if 0 /* It colide with GPIO regulators */
520 /* Is pin in GPIO mode ? */
521 if (pin->alt_func) {
522 GPIO_UNLOCK(sc);
523 return (ENXIO);
524 }
525 #endif
526
527 old_reg_pue = sc->gpio_reg_pue;
528 old_reg_pde = sc->gpio_reg_pde;
529
530 rv = RD1(sc, pin->reg, ®);
531 if (rv != 0) {
532 device_printf(sc->dev, "Cannot read GIPO_CFG register\n");
533 GPIO_UNLOCK(sc);
534 return (ENXIO);
535 }
536
537 if (flags & GPIO_PIN_PULLUP)
538 sc->gpio_reg_pue |= 1 << pin_num;
539 else
540 sc->gpio_reg_pue &= ~(1 << pin_num);
541
542 if (flags & GPIO_PIN_PULLDOWN)
543 sc->gpio_reg_pde |= 1 << pin_num;
544 else
545 sc->gpio_reg_pde &= ~(1 << pin_num);
546
547 if (flags & GPIO_PIN_INPUT) {
548 reg &= ~MAX77620_REG_GPIO_DRV(~0);
549 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_OPENDRAIN);
550 reg &= ~MAX77620_REG_GPIO_OUTPUT_VAL(~0);
551 reg |= MAX77620_REG_GPIO_OUTPUT_VAL(1);
552
553 } else if (((flags & GPIO_PIN_OUTPUT) &&
554 (flags & GPIO_PIN_OPENDRAIN) == 0) ||
555 (flags & GPIO_PIN_PUSHPULL)) {
556 reg &= ~MAX77620_REG_GPIO_DRV(~0);
557 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_PUSHPULL);
558 } else {
559 reg &= ~MAX77620_REG_GPIO_DRV(~0);
560 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_OPENDRAIN);
561 }
562
563 rv = WR1(sc, pin->reg, reg);
564 if (rv != 0) {
565 device_printf(sc->dev, "Cannot read GIPO_CFG register\n");
566 return (ENXIO);
567 }
568 if (old_reg_pue != sc->gpio_reg_pue) {
569 rv = WR1(sc, MAX77620_REG_PUE_GPIO, sc->gpio_reg_pue);
570 if (rv != 0) {
571 device_printf(sc->dev,
572 "Cannot update PUE_GPIO register\n");
573 GPIO_UNLOCK(sc);
574 return (ENXIO);
575 }
576 }
577
578 if (old_reg_pde != sc->gpio_reg_pde) {
579 rv = WR1(sc, MAX77620_REG_PDE_GPIO, sc->gpio_reg_pde);
580 if (rv != 0) {
581 device_printf(sc->dev,
582 "Cannot update PDE_GPIO register\n");
583 GPIO_UNLOCK(sc);
584 return (ENXIO);
585 }
586 }
587
588 GPIO_UNLOCK(sc);
589 return (0);
590 }
591
592 int
593 max77620_gpio_pin_set(device_t dev, uint32_t pin, uint32_t val)
594 {
595 struct max77620_softc *sc;
596 int rv;
597
598 sc = device_get_softc(dev);
599 if (pin >= sc->gpio_npins)
600 return (EINVAL);
601
602 GPIO_LOCK(sc);
603 rv = RM1(sc, sc->gpio_pins[pin]->reg, MAX77620_REG_GPIO_OUTPUT_VAL(~0),
604 MAX77620_REG_GPIO_OUTPUT_VAL(val));
605 GPIO_UNLOCK(sc);
606 return (rv);
607 }
608
609 int
610 max77620_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *val)
611 {
612 struct max77620_softc *sc;
613 uint8_t tmp;
614 int rv;
615
616 sc = device_get_softc(dev);
617 if (pin >= sc->gpio_npins)
618 return (EINVAL);
619
620 GPIO_LOCK(sc);
621 rv = RD1(sc, sc->gpio_pins[pin]->reg, &tmp);
622
623 if (MAX77620_REG_GPIO_DRV_GET(tmp) == MAX77620_REG_GPIO_DRV_PUSHPULL)
624 *val = MAX77620_REG_GPIO_OUTPUT_VAL_GET(tmp);
625 else
626 *val = MAX77620_REG_GPIO_INPUT_VAL_GET(tmp);
627 GPIO_UNLOCK(sc);
628 if (rv != 0)
629 return (rv);
630
631 return (0);
632 }
633
634 int
635 max77620_gpio_pin_toggle(device_t dev, uint32_t pin)
636 {
637 struct max77620_softc *sc;
638 uint8_t tmp;
639 int rv;
640
641 sc = device_get_softc(dev);
642 if (pin >= sc->gpio_npins)
643 return (EINVAL);
644
645 GPIO_LOCK(sc);
646 rv = RD1(sc, sc->gpio_pins[pin]->reg, &tmp);
647 if (rv != 0) {
648 GPIO_UNLOCK(sc);
649 return (rv);
650 }
651 tmp ^= MAX77620_REG_GPIO_OUTPUT_VAL(~0);
652 rv = RM1(sc, sc->gpio_pins[pin]->reg, MAX77620_REG_GPIO_OUTPUT_VAL(~0),
653 tmp);
654 GPIO_UNLOCK(sc);
655 return (0);
656 }
657
658 int
659 max77620_gpio_map_gpios(device_t dev, phandle_t pdev, phandle_t gparent,
660 int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags)
661 {
662
663 if (gcells != 2)
664 return (ERANGE);
665 *pin = gpios[0];
666 *flags= gpios[1];
667 return (0);
668 }
669
670 int
671 max77620_gpio_attach(struct max77620_softc *sc, phandle_t node)
672 {
673 struct max77620_gpio_pin *pin;
674 int i, rv;
675
676 sx_init(&sc->gpio_lock, "MAX77620 GPIO lock");
677
678 sc->gpio_busdev = gpiobus_attach_bus(sc->dev);
679 if (sc->gpio_busdev == NULL)
680 return (ENXIO);
681
682 rv = RD1(sc, MAX77620_REG_PUE_GPIO, &sc->gpio_reg_pue);
683 if (rv != 0) {
684 device_printf(sc->dev, "Cannot read PUE_GPIO register\n");
685 return (ENXIO);
686 }
687
688 rv = RD1(sc, MAX77620_REG_PDE_GPIO, &sc->gpio_reg_pde);
689 if (rv != 0) {
690 device_printf(sc->dev, "Cannot read PDE_GPIO register\n");
691 return (ENXIO);
692 }
693
694 rv = RD1(sc, MAX77620_REG_AME_GPIO, &sc->gpio_reg_ame);
695 if (rv != 0) {
696 device_printf(sc->dev, "Cannot read AME_GPIO register\n");
697 return (ENXIO);
698 }
699
700 sc->gpio_npins = NGPIO;
701 sc->gpio_pins = malloc(sizeof(struct max77620_gpio_pin *) *
702 sc->gpio_npins, M_MAX77620_GPIO, M_WAITOK | M_ZERO);
703 for (i = 0; i < sc->gpio_npins; i++) {
704 sc->gpio_pins[i] = malloc(sizeof(struct max77620_gpio_pin),
705 M_MAX77620_GPIO, M_WAITOK | M_ZERO);
706 pin = sc->gpio_pins[i];
707 sprintf(pin->pin_name, "gpio%d", i);
708 pin->pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
709 GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL |
710 GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
711 pin->reg = MAX77620_REG_GPIO0 + i;
712 }
713
714 return (0);
715 }
Cache object: 21955ad2c8670f272cf83f54b423a848
|