]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/gpio/kona_gpio.c
dm: Add GPIO support and tests
[karo-tx-uboot.git] / drivers / gpio / kona_gpio.c
1 /*
2  * Copyright 2013 Broadcom Corporation.
3  *
4  * SPDX-License-Identifier:      GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <asm/io.h>
9 #include <asm/arch/sysmap.h>
10
11 #define GPIO_BASE                               (void *)GPIO2_BASE_ADDR
12
13 #define GPIO_PASSWD                             0x00a5a501
14 #define GPIO_PER_BANK                           32
15 #define GPIO_MAX_BANK_NUM                       8
16
17 #define GPIO_BANK(gpio)                         ((gpio) >> 5)
18 #define GPIO_BITMASK(gpio)      \
19         (1UL << ((gpio) & (GPIO_PER_BANK - 1)))
20
21 #define GPIO_OUT_STATUS(bank)                   (0x00000000 + ((bank) << 2))
22 #define GPIO_IN_STATUS(bank)                    (0x00000020 + ((bank) << 2))
23 #define GPIO_OUT_SET(bank)                      (0x00000040 + ((bank) << 2))
24 #define GPIO_OUT_CLEAR(bank)                    (0x00000060 + ((bank) << 2))
25 #define GPIO_INT_STATUS(bank)                   (0x00000080 + ((bank) << 2))
26 #define GPIO_INT_MASK(bank)                     (0x000000a0 + ((bank) << 2))
27 #define GPIO_INT_MSKCLR(bank)                   (0x000000c0 + ((bank) << 2))
28 #define GPIO_CONTROL(bank)                      (0x00000100 + ((bank) << 2))
29 #define GPIO_PWD_STATUS(bank)                   (0x00000500 + ((bank) << 2))
30
31 #define GPIO_GPPWR_OFFSET                       0x00000520
32
33 #define GPIO_GPCTR0_DBR_SHIFT                   5
34 #define GPIO_GPCTR0_DBR_MASK                    0x000001e0
35
36 #define GPIO_GPCTR0_ITR_SHIFT                   3
37 #define GPIO_GPCTR0_ITR_MASK                    0x00000018
38 #define GPIO_GPCTR0_ITR_CMD_RISING_EDGE         0x00000001
39 #define GPIO_GPCTR0_ITR_CMD_FALLING_EDGE        0x00000002
40 #define GPIO_GPCTR0_ITR_CMD_BOTH_EDGE           0x00000003
41
42 #define GPIO_GPCTR0_IOTR_MASK                   0x00000001
43 #define GPIO_GPCTR0_IOTR_CMD_0UTPUT             0x00000000
44 #define GPIO_GPCTR0_IOTR_CMD_INPUT              0x00000001
45
46 int gpio_request(unsigned gpio, const char *label)
47 {
48         unsigned int value, off;
49
50         writel(GPIO_PASSWD, GPIO_BASE + GPIO_GPPWR_OFFSET);
51         off = GPIO_PWD_STATUS(GPIO_BANK(gpio));
52         value = readl(GPIO_BASE + off) & ~GPIO_BITMASK(gpio);
53         writel(value, GPIO_BASE + off);
54
55         return 0;
56 }
57
58 int gpio_free(unsigned gpio)
59 {
60         unsigned int value, off;
61
62         writel(GPIO_PASSWD, GPIO_BASE + GPIO_GPPWR_OFFSET);
63         off = GPIO_PWD_STATUS(GPIO_BANK(gpio));
64         value = readl(GPIO_BASE + off) | GPIO_BITMASK(gpio);
65         writel(value, GPIO_BASE + off);
66
67         return 0;
68 }
69
70 int gpio_direction_input(unsigned gpio)
71 {
72         u32 val;
73
74         val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
75         val &= ~GPIO_GPCTR0_IOTR_MASK;
76         val |= GPIO_GPCTR0_IOTR_CMD_INPUT;
77         writel(val, GPIO_BASE + GPIO_CONTROL(gpio));
78
79         return 0;
80 }
81
82 int gpio_direction_output(unsigned gpio, int value)
83 {
84         int bank_id = GPIO_BANK(gpio);
85         int bitmask = GPIO_BITMASK(gpio);
86         u32 val, off;
87
88         val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
89         val &= ~GPIO_GPCTR0_IOTR_MASK;
90         val |= GPIO_GPCTR0_IOTR_CMD_0UTPUT;
91         writel(val, GPIO_BASE + GPIO_CONTROL(gpio));
92         off = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id);
93
94         val = readl(GPIO_BASE + off);
95         val |= bitmask;
96         writel(val, GPIO_BASE + off);
97
98         return 0;
99 }
100
101 int gpio_get_value(unsigned gpio)
102 {
103         int bank_id = GPIO_BANK(gpio);
104         int bitmask = GPIO_BITMASK(gpio);
105         u32 val, off;
106
107         /* determine the GPIO pin direction */
108         val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
109         val &= GPIO_GPCTR0_IOTR_MASK;
110
111         /* read the GPIO bank status */
112         off = (GPIO_GPCTR0_IOTR_CMD_INPUT == val) ?
113             GPIO_IN_STATUS(bank_id) : GPIO_OUT_STATUS(bank_id);
114         val = readl(GPIO_BASE + off);
115
116         /* return the specified bit status */
117         return !!(val & bitmask);
118 }
119
120 void gpio_set_value(unsigned gpio, int value)
121 {
122         int bank_id = GPIO_BANK(gpio);
123         int bitmask = GPIO_BITMASK(gpio);
124         u32 val, off;
125
126         /* determine the GPIO pin direction */
127         val = readl(GPIO_BASE + GPIO_CONTROL(gpio));
128         val &= GPIO_GPCTR0_IOTR_MASK;
129
130         /* this function only applies to output pin */
131         if (GPIO_GPCTR0_IOTR_CMD_INPUT == val) {
132                 printf("%s: Cannot set an input pin %d\n", __func__, gpio);
133                 return;
134         }
135
136         off = value ? GPIO_OUT_SET(bank_id) : GPIO_OUT_CLEAR(bank_id);
137
138         val = readl(GPIO_BASE + off);
139         val |= bitmask;
140         writel(val, GPIO_BASE + off);
141 }