Taniya Das | 017c590 | 2021-05-07 10:20:19 +0530 | [diff] [blame^] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | |
| 3 | #include <assert.h> |
| 4 | #include <device/mmio.h> |
| 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 | 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 | |
| 21 | write32(®s->cfg, reg_val); |
| 22 | } |
| 23 | |
| 24 | void gpio_set(gpio_t gpio, int value) |
| 25 | { |
| 26 | struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; |
| 27 | |
| 28 | write32(®s->in_out, (!!value) << GPIO_IO_OUT_SHFT); |
| 29 | } |
| 30 | |
| 31 | int gpio_get(gpio_t gpio) |
| 32 | { |
| 33 | struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; |
| 34 | |
| 35 | return ((read32(®s->in_out) >> GPIO_IO_IN_SHFT) & GPIO_BMSK); |
| 36 | } |
| 37 | |
| 38 | void gpio_input_pulldown(gpio_t gpio) |
| 39 | { |
| 40 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 41 | GPIO_PULL_DOWN, GPIO_2MA, GPIO_INPUT); |
| 42 | } |
| 43 | |
| 44 | void gpio_input_pullup(gpio_t gpio) |
| 45 | { |
| 46 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 47 | GPIO_PULL_UP, GPIO_2MA, GPIO_INPUT); |
| 48 | } |
| 49 | |
| 50 | void gpio_input(gpio_t gpio) |
| 51 | { |
| 52 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 53 | GPIO_NO_PULL, GPIO_2MA, GPIO_INPUT); |
| 54 | } |
| 55 | |
| 56 | void gpio_output(gpio_t gpio, int value) |
| 57 | { |
| 58 | gpio_set(gpio, value); |
| 59 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 60 | GPIO_NO_PULL, GPIO_2MA, GPIO_OUTPUT); |
| 61 | } |
| 62 | |
| 63 | void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, uint32_t pull) |
| 64 | { |
| 65 | struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; |
| 66 | |
| 67 | gpio_configure(gpio, GPIO_FUNC_GPIO, |
| 68 | pull, GPIO_2MA, GPIO_INPUT); |
| 69 | |
| 70 | clrsetbits32(®s->intr_cfg, GPIO_INTR_DECT_CTL_MASK << |
| 71 | GPIO_INTR_DECT_CTL_SHFT, type << GPIO_INTR_DECT_CTL_SHFT); |
| 72 | clrsetbits32(®s->intr_cfg, GPIO_INTR_STATUS_ENABLE |
| 73 | << GPIO_INTR_RAW_STATUS_EN_SHFT, GPIO_INTR_STATUS_ENABLE |
| 74 | << GPIO_INTR_RAW_STATUS_EN_SHFT); |
| 75 | } |
| 76 | |
| 77 | int gpio_irq_status(gpio_t gpio) |
| 78 | { |
| 79 | struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; |
| 80 | |
| 81 | if (!(read32(®s->intr_status) & GPIO_INTR_STATUS_MASK)) |
| 82 | return GPIO_INTR_STATUS_DISABLE; |
| 83 | |
| 84 | write32(®s->intr_status, GPIO_INTR_STATUS_DISABLE); |
| 85 | |
| 86 | return GPIO_INTR_STATUS_ENABLE; |
| 87 | } |