blob: 67204e87e71d3094fce5f80c64d98382528f961c [file] [log] [blame]
Angel Pons7c1d70e2020-04-04 18:51:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Taniya Das09c3bfe2019-08-07 11:34:57 +05302
Taniya Das09c3bfe2019-08-07 11:34:57 +05303#include <assert.h>
Julius Werner55009af2019-12-02 22:03:27 -08004#include <device/mmio.h>
Taniya Das09c3bfe2019-08-07 11:34:57 +05305#include <types.h>
6
7#include <gpio.h>
8
9void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull,
10 uint32_t drive_str, uint32_t enable)
11{
12 uint32_t reg_val;
13 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
14
15 /* gpio pull only PULLNONE, PULLUP, KEEPER, PULLDOWN status */
16 assert(pull <= GPIO_PULL_UP);
17
18 reg_val = ((enable & GPIO_CFG_OE_BMSK) << GPIO_CFG_OE_SHFT) |
19 ((drive_str & GPIO_CFG_DRV_BMSK) << GPIO_CFG_DRV_SHFT) |
20 ((func & GPIO_CFG_FUNC_BMSK) << GPIO_CFG_FUNC_SHFT) |
21 ((pull & GPIO_CFG_PULL_BMSK) << GPIO_CFG_PULL_SHFT);
22
23 write32(&regs->cfg, reg_val);
24}
25
26void gpio_set(gpio_t gpio, int value)
27{
28 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
29
30 write32(&regs->in_out, (!!value) << GPIO_IO_OUT_SHFT);
31}
32
33int gpio_get(gpio_t gpio)
34{
35 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
36
37 return ((read32(&regs->in_out) >> GPIO_IO_IN_SHFT) &
38 GPIO_IO_IN_BMSK);
39}
40
41void gpio_input_pulldown(gpio_t gpio)
42{
43 gpio_configure(gpio, GPIO_FUNC_GPIO,
44 GPIO_PULL_DOWN, GPIO_2MA, GPIO_OUTPUT_DISABLE);
45}
46
47void gpio_input_pullup(gpio_t gpio)
48{
49 gpio_configure(gpio, GPIO_FUNC_GPIO,
50 GPIO_PULL_UP, GPIO_2MA, GPIO_OUTPUT_DISABLE);
51}
52
53void gpio_input(gpio_t gpio)
54{
55 gpio_configure(gpio, GPIO_FUNC_GPIO,
56 GPIO_NO_PULL, GPIO_2MA, GPIO_OUTPUT_DISABLE);
57}
58
59void gpio_output(gpio_t gpio, int value)
60{
61 gpio_set(gpio, value);
62 gpio_configure(gpio, GPIO_FUNC_GPIO,
63 GPIO_NO_PULL, GPIO_2MA, GPIO_OUTPUT_ENABLE);
64}
65
66void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, uint32_t pull)
67{
68 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
69
70 gpio_configure(gpio, GPIO_FUNC_GPIO,
71 pull, GPIO_2MA, GPIO_OUTPUT_DISABLE);
72
Julius Werner55009af2019-12-02 22:03:27 -080073 clrsetbits32(&regs->intr_cfg, GPIO_INTR_DECT_CTL_MASK <<
Taniya Das09c3bfe2019-08-07 11:34:57 +053074 GPIO_INTR_DECT_CTL_SHIFT, type << GPIO_INTR_DECT_CTL_SHIFT);
Julius Werner55009af2019-12-02 22:03:27 -080075 clrsetbits32(&regs->intr_cfg, GPIO_INTR_RAW_STATUS_ENABLE
Taniya Das09c3bfe2019-08-07 11:34:57 +053076 << GPIO_INTR_RAW_STATUS_EN_SHIFT, GPIO_INTR_RAW_STATUS_ENABLE
77 << GPIO_INTR_RAW_STATUS_EN_SHIFT);
78}
79
80int gpio_irq_status(gpio_t gpio)
81{
82 struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr;
83
84 if (!(read32(&regs->intr_status) & GPIO_INTR_STATUS_MASK))
85 return 0;
86
87 write32(&regs->intr_status, GPIO_INTR_STATUS_DISABLE);
88 return 1;
89}