2 * This file is part of the coreboot project.
4 * Copyright (C) 2015 Google Inc.
5 * Copyright (C) 2015 Intel Corporation
6 * Copyright (C) 2017 Advanced Micro Devices, Inc.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
19 #include <console/console.h>
23 static uintptr_t gpio_get_address(gpio_t gpio_num
)
25 uintptr_t gpio_address
;
28 gpio_address
= GPIO_BANK0_CONTROL(gpio_num
);
29 else if (gpio_num
< 128)
30 gpio_address
= GPIO_BANK1_CONTROL(gpio_num
);
32 gpio_address
= GPIO_BANK2_CONTROL(gpio_num
);
37 int gpio_get(gpio_t gpio_num
)
40 uintptr_t gpio_address
= gpio_get_address(gpio_num
);
42 reg
= read32((void *)gpio_address
);
44 return !!(reg
& GPIO_PIN_STS
);
47 void gpio_set(gpio_t gpio_num
, int value
)
50 uintptr_t gpio_address
= gpio_get_address(gpio_num
);
52 reg
= read32((void *)gpio_address
);
53 reg
&= ~GPIO_OUTPUT_MASK
;
54 reg
|= !!value
<< GPIO_OUTPUT_SHIFT
;
55 write32((void *)(uintptr_t)gpio_num
, reg
);
58 void gpio_input_pulldown(gpio_t gpio_num
)
61 uintptr_t gpio_address
= gpio_get_address(gpio_num
);
63 reg
= read32((void *)gpio_address
);
64 reg
&= ~GPIO_PULLUP_ENABLE
;
65 reg
|= GPIO_PULLDOWN_ENABLE
;
66 write32((void *)(uintptr_t)gpio_num
, reg
);
69 void gpio_input_pullup(gpio_t gpio_num
)
72 uintptr_t gpio_address
= gpio_get_address(gpio_num
);
74 reg
= read32((void *)gpio_address
);
75 reg
&= ~GPIO_PULLDOWN_ENABLE
;
76 reg
|= GPIO_PULLUP_ENABLE
;
77 write32((void *)(uintptr_t)gpio_num
, reg
);
80 void gpio_input(gpio_t gpio_num
)
83 uintptr_t gpio_address
= gpio_get_address(gpio_num
);
85 reg
= read32((void *)gpio_address
);
86 reg
&= ~GPIO_OUTPUT_ENABLE
;
87 write32((void *)(uintptr_t)gpio_num
, reg
);
90 void gpio_output(gpio_t gpio_num
, int value
)
93 uintptr_t gpio_address
= gpio_get_address(gpio_num
);
95 reg
= read32((void *)gpio_address
);
96 reg
|= GPIO_OUTPUT_ENABLE
;
97 write32((void *)(uintptr_t)gpio_num
, reg
);
98 gpio_set(gpio_num
, value
);
101 const char *gpio_acpi_path(gpio_t gpio
)
106 uint16_t gpio_acpi_pin(gpio_t gpio
)
111 void gpio_set_interrupt(gpio_t gpio
, uint32_t flags
)
113 uintptr_t gpio_address
= gpio_get_address(gpio
);
114 uint32_t reg
= read32((void *)gpio_address
);
116 /* Clear registers that are being updated */
117 reg
&= ~(GPIO_TRIGGER_MASK
| GPIO_ACTIVE_MASK
| GPIO_INTERRUPT_MASK
);
119 /* Clear any extra bits in the flags */
120 flags
&= (GPIO_TRIGGER_MASK
| GPIO_ACTIVE_MASK
| GPIO_INTERRUPT_MASK
);
122 write32((void *)gpio_address
, reg
| flags
);
125 int gpio_interrupt_status(gpio_t gpio
)
127 uintptr_t gpio_address
= gpio_get_address(gpio
);
128 uint32_t reg
= read32((void *)gpio_address
);
130 if (reg
& GPIO_INT_STATUS
) {
131 /* Clear interrupt status, preserve wake status */
132 reg
&= ~GPIO_WAKE_STATUS
;
133 write32((void *)gpio_address
, reg
);