xref: /aosp_15_r20/external/coreboot/src/soc/sifive/fu740/gpio.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <soc/addressmap.h>
4 #include <stdint.h>
5 #include <arch/mmio.h>
6 #include <assert.h>
7 #include <device/mmio.h>
8 #include <gpio.h>
9 
10 #define SIFIVE_GPIO_INPUT_VAL  (FU740_GPIO + 0x00)
11 #define SIFIVE_GPIO_INPUT_EN   (FU740_GPIO + 0x04)
12 #define SIFIVE_GPIO_OUTPUT_EN  (FU740_GPIO + 0x08)
13 #define SIFIVE_GPIO_OUTPUT_VAL (FU740_GPIO + 0x0C)
14 #define SIFIVE_GPIO_PUE        (FU740_GPIO + 0x10)
15 #define SIFIVE_GPIO_DS         (FU740_GPIO + 0x14)
16 #define SIFIVE_GPIO_RISE_IE    (FU740_GPIO + 0x18)
17 #define SIFIVE_GPIO_RISE_IP    (FU740_GPIO + 0x1C)
18 #define SIFIVE_GPIO_FALL_IE    (FU740_GPIO + 0x20)
19 #define SIFIVE_GPIO_FALL_IP    (FU740_GPIO + 0x24)
20 #define SIFIVE_GPIO_HIGH_IE    (FU740_GPIO + 0x28)
21 #define SIFIVE_GPIO_HIGH_IP    (FU740_GPIO + 0x2C)
22 #define SIFIVE_GPIO_LOW_IE     (FU740_GPIO + 0x30)
23 #define SIFIVE_GPIO_LOW_IP     (FU740_GPIO + 0x34)
24 #define SIFIVE_GPIO_IOF_EN     (FU740_GPIO + 0x38)
25 #define SIFIVE_GPIO_IOF_SEL    (FU740_GPIO + 0x3C)
26 #define SIFIVE_GPIO_OUT_XOR    (FU740_GPIO + 0x40)
27 
gpio_set(gpio_t gpio,int value)28 void gpio_set(gpio_t gpio, int value)
29 {
30 	uint32_t output_val = read32((void *)SIFIVE_GPIO_OUTPUT_VAL);
31 
32 	if (value)
33 		output_val |= (1 << gpio);
34 	else
35 		output_val &= ~(1 << gpio);
36 
37 	write32((void *)SIFIVE_GPIO_OUTPUT_VAL, output_val);
38 }
39 
gpio_get(gpio_t gpio)40 int gpio_get(gpio_t gpio)
41 {
42 	uint32_t input_val = read32((void *)SIFIVE_GPIO_INPUT_VAL);
43 	return !!(input_val & (1 << gpio));
44 }
45 
gpio_set_direction(gpio_t gpio,enum gpio_direction gpio_dir)46 void gpio_set_direction(gpio_t gpio, enum gpio_direction gpio_dir)
47 {
48 	uint32_t input_en  = read32((void *)SIFIVE_GPIO_INPUT_EN);
49 	uint32_t output_en = read32((void *)SIFIVE_GPIO_OUTPUT_EN);
50 
51 	if (gpio_dir == GPIO_OUTPUT) {
52 		input_en  &= ~(1 << gpio);
53 		output_en |=  (1 << gpio);
54 	} else if (gpio_dir == GPIO_INPUT) {
55 		input_en  |=  (1 << gpio);
56 		output_en &= ~(1 << gpio);
57 	}
58 
59 	write32((void *)SIFIVE_GPIO_INPUT_EN, input_en);
60 	write32((void *)SIFIVE_GPIO_OUTPUT_EN, output_en);
61 }
62