1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <assert.h>
4 #include <device/mmio.h>
5 #include <gpio.h>
6
gpio_configure(gpio_t gpio,uint32_t func,uint32_t pull,uint32_t drive_str,uint32_t enable)7 void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull,
8 uint32_t drive_str, uint32_t enable)
9 {
10 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
11 uint32_t reg_val;
12
13 /* gpio pull only PULLNONE, PULLUP, KEEPER, PULLDOWN status */
14 assert(pull <= GPIO_PULL_UP);
15
16 reg_val = ((enable & GPIO_BMSK) << GPIO_CFG_OE_SHFT) |
17 ((drive_str & GPIO_CFG_DRV_BMSK) << GPIO_CFG_DRV_SHFT) |
18 ((func & GPIO_CFG_FUNC_BMSK) << GPIO_CFG_FUNC_SHFT) |
19 ((pull & GPIO_CFG_PULL_BMSK) << GPIO_CFG_PULL_SHFT) |
20 ((read32(®s->cfg) & GPIO_CFG_EGPIO_BMSK)
21 << GPIO_CFG_EGPIO_SHFT);
22
23 write32(®s->cfg, reg_val);
24 }
25
gpio_set(gpio_t gpio,int value)26 void gpio_set(gpio_t gpio, int value)
27 {
28 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
29
30 write32(®s->in_out, (!!value) << GPIO_IO_OUT_SHFT);
31 }
32
gpio_get(gpio_t gpio)33 int gpio_get(gpio_t gpio)
34 {
35 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
36
37 return ((read32(®s->in_out) >> GPIO_IO_IN_SHFT) & GPIO_BMSK);
38 }
39
gpio_input_pulldown(gpio_t gpio)40 void gpio_input_pulldown(gpio_t gpio)
41 {
42 gpio_configure(gpio, GPIO_FUNC_GPIO,
43 GPIO_PULL_DOWN, GPIO_2MA, GPIO_INPUT);
44 }
45
gpio_input_pullup(gpio_t gpio)46 void gpio_input_pullup(gpio_t gpio)
47 {
48 gpio_configure(gpio, GPIO_FUNC_GPIO,
49 GPIO_PULL_UP, GPIO_2MA, GPIO_INPUT);
50 }
51
gpio_input(gpio_t gpio)52 void gpio_input(gpio_t gpio)
53 {
54 gpio_configure(gpio, GPIO_FUNC_GPIO,
55 GPIO_NO_PULL, GPIO_2MA, GPIO_INPUT);
56 }
57
gpio_output(gpio_t gpio,int value)58 void gpio_output(gpio_t gpio, int value)
59 {
60 gpio_set(gpio, value);
61 gpio_configure(gpio, GPIO_FUNC_GPIO,
62 GPIO_NO_PULL, GPIO_2MA, GPIO_OUTPUT);
63 }
64
gpio_input_irq(gpio_t gpio,enum gpio_irq_type type,uint32_t pull)65 void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, uint32_t pull)
66 {
67 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
68
69 gpio_configure(gpio, GPIO_FUNC_GPIO,
70 pull, GPIO_2MA, GPIO_INPUT);
71
72 clrsetbits32(®s->intr_cfg, GPIO_INTR_DECT_CTL_MASK <<
73 GPIO_INTR_DECT_CTL_SHFT, type << GPIO_INTR_DECT_CTL_SHFT);
74 clrsetbits32(®s->intr_cfg, GPIO_INTR_STATUS_ENABLE
75 << GPIO_INTR_RAW_STATUS_EN_SHFT, GPIO_INTR_STATUS_ENABLE
76 << GPIO_INTR_RAW_STATUS_EN_SHFT);
77 }
78
gpio_irq_status(gpio_t gpio)79 int gpio_irq_status(gpio_t gpio)
80 {
81 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
82
83 if (!(read32(®s->intr_status) & GPIO_INTR_STATUS_MASK))
84 return GPIO_INTR_STATUS_DISABLE;
85
86 write32(®s->intr_status, GPIO_INTR_STATUS_DISABLE);
87
88 return GPIO_INTR_STATUS_ENABLE;
89 }
90