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