1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
11 static void gpio_set_dir(gpio_t gpio
, enum gpio_dir dir
)
13 clrsetbits32(&gpio_port
[gpio
.port
]->swporta_ddr
,
14 1 << gpio
.num
, dir
<< gpio
.num
);
17 static void gpio_set_pull(gpio_t gpio
, enum gpio_pull pull
)
19 u32 pull_val
= gpio_get_pull_val(gpio
, pull
);
20 if (is_pmu_gpio(gpio
) && CONFIG(SOC_ROCKCHIP_RK3288
))
21 clrsetbits32(gpio_grf_reg(gpio
), 3 << (gpio
.idx
* 2),
22 pull_val
<< (gpio
.idx
* 2));
24 write32(gpio_grf_reg(gpio
), RK_CLRSETBITS(3 << (gpio
.idx
* 2),
25 pull_val
<< (gpio
.idx
* 2)));
28 void gpio_input(gpio_t gpio
)
30 gpio_set_pull(gpio
, GPIO_PULLNONE
);
31 gpio_set_dir(gpio
, GPIO_INPUT
);
34 void gpio_input_pulldown(gpio_t gpio
)
36 gpio_set_pull(gpio
, GPIO_PULLDOWN
);
37 gpio_set_dir(gpio
, GPIO_INPUT
);
40 void gpio_input_pullup(gpio_t gpio
)
42 gpio_set_pull(gpio
, GPIO_PULLUP
);
43 gpio_set_dir(gpio
, GPIO_INPUT
);
46 void gpio_input_irq(gpio_t gpio
, enum gpio_irq_type type
, enum gpio_pull pull
)
48 uint32_t int_polarity
, inttype_level
;
49 uint32_t mask
= BIT(gpio
.num
);
51 /* gpio pull only PULLNONE, PULLUP, PULLDOWN status */
52 assert(pull
<= GPIO_PULLDOWN
);
54 gpio_set_dir(gpio
, GPIO_INPUT
);
55 gpio_set_pull(gpio
, pull
);
57 int_polarity
= inttype_level
= 0;
59 case IRQ_TYPE_EDGE_RISING
:
63 case IRQ_TYPE_EDGE_FALLING
:
66 case IRQ_TYPE_LEVEL_HIGH
:
69 case IRQ_TYPE_LEVEL_LOW
:
72 clrsetbits32(&gpio_port
[gpio
.port
]->int_polarity
,
74 clrsetbits32(&gpio_port
[gpio
.port
]->inttype_level
,
77 setbits32(&gpio_port
[gpio
.port
]->inten
, mask
);
78 clrbits32(&gpio_port
[gpio
.port
]->intmask
, mask
);
81 int gpio_irq_status(gpio_t gpio
)
83 uint32_t mask
= BIT(gpio
.num
);
84 uint32_t int_status
= read32(&gpio_port
[gpio
.port
]->int_status
);
86 if (!(int_status
& mask
))
89 setbits32(&gpio_port
[gpio
.port
]->porta_eoi
, mask
);
93 int gpio_get(gpio_t gpio
)
95 return (read32(&gpio_port
[gpio
.port
]->ext_porta
) >> gpio
.num
) & 0x1;
98 void gpio_set(gpio_t gpio
, int value
)
100 clrsetbits32(&gpio_port
[gpio
.port
]->swporta_dr
, 1 << gpio
.num
,
101 !!value
<< gpio
.num
);
104 void gpio_output(gpio_t gpio
, int value
)
106 gpio_set(gpio
, value
);
107 gpio_set_dir(gpio
, GPIO_OUTPUT
);
108 gpio_set_pull(gpio
, GPIO_PULLNONE
);