Angel Pons | 7c1d70e | 2020-04-04 18:51:19 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Nitheesh Sekar | ea4c7d0 | 2018-09-16 19:01:01 +0530 | [diff] [blame] | 2 | |
| 3 | #include <device/mmio.h> |
| 4 | #include <types.h> |
Nitheesh Sekar | ea4c7d0 | 2018-09-16 19:01:01 +0530 | [diff] [blame] | 5 | #include <gpio.h> |
| 6 | |
| 7 | void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull, |
| 8 | uint32_t drive_str, uint32_t enable) |
| 9 | { |
| 10 | uint32_t reg_val; |
| 11 | struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; |
| 12 | |
| 13 | reg_val = ((enable & GPIO_CFG_OE_BMSK) << GPIO_CFG_OE_SHFT) | |
| 14 | ((drive_str & GPIO_CFG_DRV_BMSK) << GPIO_CFG_DRV_SHFT) | |
| 15 | ((func & GPIO_CFG_FUNC_BMSK) << GPIO_CFG_FUNC_SHFT) | |
| 16 | ((pull & GPIO_CFG_PULL_BMSK) << GPIO_CFG_PULL_SHFT); |
| 17 | |
| 18 | write32(®s->cfg, reg_val); |
| 19 | } |
| 20 | |
| 21 | void gpio_set(gpio_t gpio, int value) |
| 22 | { |
| 23 | struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; |
| 24 | write32(®s->in_out, (!!value) << GPIO_IO_OUT_SHFT); |
| 25 | } |
| 26 | |
| 27 | int gpio_get(gpio_t gpio) |
| 28 | { |
| 29 | struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; |
| 30 | |
| 31 | return ((read32(®s->in_out) >> GPIO_IO_IN_SHFT) & |
| 32 | GPIO_IO_IN_BMSK); |
| 33 | } |
| 34 | |
| 35 | void gpio_input_pulldown(gpio_t gpio) |
| 36 | { |
| 37 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 38 | GPIO_PULL_DOWN, GPIO_2MA, GPIO_DISABLE); |
| 39 | } |
| 40 | |
| 41 | void gpio_input_pullup(gpio_t gpio) |
| 42 | { |
| 43 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 44 | GPIO_PULL_UP, GPIO_2MA, GPIO_DISABLE); |
| 45 | } |
| 46 | |
| 47 | void gpio_input(gpio_t gpio) |
| 48 | { |
| 49 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 50 | GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE); |
| 51 | } |
| 52 | |
| 53 | void gpio_output(gpio_t gpio, int value) |
| 54 | { |
| 55 | gpio_set(gpio, value); |
| 56 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 57 | GPIO_NO_PULL, GPIO_2MA, GPIO_ENABLE); |
| 58 | } |
Taniya Das | 4b76639 | 2019-04-04 15:28:36 +0530 | [diff] [blame] | 59 | |
| 60 | void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, uint32_t pull) |
| 61 | { |
| 62 | struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; |
| 63 | |
| 64 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 65 | pull, GPIO_2MA, GPIO_DISABLE); |
| 66 | |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 67 | clrsetbits32(®s->intr_cfg, GPIO_INTR_DECT_CTL_MASK << |
Taniya Das | 4b76639 | 2019-04-04 15:28:36 +0530 | [diff] [blame] | 68 | GPIO_INTR_DECT_CTL_SHIFT, type << GPIO_INTR_DECT_CTL_SHIFT); |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 69 | clrsetbits32(®s->intr_cfg, GPIO_INTR_RAW_STATUS_ENABLE |
Taniya Das | 4b76639 | 2019-04-04 15:28:36 +0530 | [diff] [blame] | 70 | << GPIO_INTR_RAW_STATUS_EN_SHIFT, GPIO_INTR_RAW_STATUS_ENABLE |
| 71 | << GPIO_INTR_RAW_STATUS_EN_SHIFT); |
| 72 | } |
| 73 | |
| 74 | int gpio_irq_status(gpio_t gpio) |
| 75 | { |
| 76 | struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; |
| 77 | |
| 78 | if (!(read32(®s->intr_status) & GPIO_INTR_STATUS_MASK)) |
| 79 | return 0; |
| 80 | |
| 81 | write32(®s->intr_status, GPIO_INTR_STATUS_DISABLE); |
| 82 | return 1; |
| 83 | } |