Merge branch 'master' of git://git.denx.de/u-boot-sh
[platform/kernel/u-boot.git] / drivers / gpio / dwapb_gpio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2015 Marek Vasut <marex@denx.de>
4  *
5  * DesignWare APB GPIO driver
6  */
7
8 #include <common.h>
9 #include <malloc.h>
10 #include <asm/arch/gpio.h>
11 #include <asm/gpio.h>
12 #include <asm/io.h>
13 #include <dm.h>
14 #include <dm/device-internal.h>
15 #include <dm/lists.h>
16 #include <dm/root.h>
17 #include <errno.h>
18 #include <reset.h>
19
20 #define GPIO_SWPORT_DR(p)       (0x00 + (p) * 0xc)
21 #define GPIO_SWPORT_DDR(p)      (0x04 + (p) * 0xc)
22 #define GPIO_INTEN              0x30
23 #define GPIO_INTMASK            0x34
24 #define GPIO_INTTYPE_LEVEL      0x38
25 #define GPIO_INT_POLARITY       0x3c
26 #define GPIO_INTSTATUS          0x40
27 #define GPIO_PORTA_DEBOUNCE     0x48
28 #define GPIO_PORTA_EOI          0x4c
29 #define GPIO_EXT_PORT(p)        (0x50 + (p) * 4)
30
31 struct gpio_dwapb_priv {
32         struct reset_ctl_bulk   resets;
33 };
34
35 struct gpio_dwapb_platdata {
36         const char      *name;
37         int             bank;
38         int             pins;
39         fdt_addr_t      base;
40 };
41
42 static int dwapb_gpio_direction_input(struct udevice *dev, unsigned pin)
43 {
44         struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
45
46         clrbits_le32(plat->base + GPIO_SWPORT_DDR(plat->bank), 1 << pin);
47         return 0;
48 }
49
50 static int dwapb_gpio_direction_output(struct udevice *dev, unsigned pin,
51                                      int val)
52 {
53         struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
54
55         setbits_le32(plat->base + GPIO_SWPORT_DDR(plat->bank), 1 << pin);
56
57         if (val)
58                 setbits_le32(plat->base + GPIO_SWPORT_DR(plat->bank), 1 << pin);
59         else
60                 clrbits_le32(plat->base + GPIO_SWPORT_DR(plat->bank), 1 << pin);
61
62         return 0;
63 }
64
65 static int dwapb_gpio_get_value(struct udevice *dev, unsigned pin)
66 {
67         struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
68         return !!(readl(plat->base + GPIO_EXT_PORT(plat->bank)) & (1 << pin));
69 }
70
71
72 static int dwapb_gpio_set_value(struct udevice *dev, unsigned pin, int val)
73 {
74         struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
75
76         if (val)
77                 setbits_le32(plat->base + GPIO_SWPORT_DR(plat->bank), 1 << pin);
78         else
79                 clrbits_le32(plat->base + GPIO_SWPORT_DR(plat->bank), 1 << pin);
80
81         return 0;
82 }
83
84 static int dwapb_gpio_get_function(struct udevice *dev, unsigned offset)
85 {
86         struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
87         u32 gpio;
88
89         gpio = readl(plat->base + GPIO_SWPORT_DDR(plat->bank));
90
91         if (gpio & BIT(offset))
92                 return GPIOF_OUTPUT;
93         else
94                 return GPIOF_INPUT;
95 }
96
97 static const struct dm_gpio_ops gpio_dwapb_ops = {
98         .direction_input        = dwapb_gpio_direction_input,
99         .direction_output       = dwapb_gpio_direction_output,
100         .get_value              = dwapb_gpio_get_value,
101         .set_value              = dwapb_gpio_set_value,
102         .get_function           = dwapb_gpio_get_function,
103 };
104
105 static int gpio_dwapb_reset(struct udevice *dev)
106 {
107         int ret;
108         struct gpio_dwapb_priv *priv = dev_get_priv(dev);
109
110         ret = reset_get_bulk(dev, &priv->resets);
111         if (ret) {
112                 /* Return 0 if error due to !CONFIG_DM_RESET and reset
113                  * DT property is not present.
114                  */
115                 if (ret == -ENOENT || ret == -ENOTSUPP)
116                         return 0;
117
118                 dev_warn(dev, "Can't get reset: %d\n", ret);
119                 return ret;
120         }
121
122         ret = reset_deassert_bulk(&priv->resets);
123         if (ret) {
124                 reset_release_bulk(&priv->resets);
125                 dev_err(dev, "Failed to reset: %d\n", ret);
126                 return ret;
127         }
128
129         return 0;
130 }
131
132 static int gpio_dwapb_probe(struct udevice *dev)
133 {
134         struct gpio_dev_priv *priv = dev_get_uclass_priv(dev);
135         struct gpio_dwapb_platdata *plat = dev->platdata;
136
137         if (!plat) {
138                 /* Reset on parent device only */
139                 return gpio_dwapb_reset(dev);
140         }
141
142         priv->gpio_count = plat->pins;
143         priv->bank_name = plat->name;
144
145         return 0;
146 }
147
148 static int gpio_dwapb_bind(struct udevice *dev)
149 {
150         struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
151         struct udevice *subdev;
152         fdt_addr_t base;
153         int ret, bank = 0;
154         ofnode node;
155
156         /* If this is a child device, there is nothing to do here */
157         if (plat)
158                 return 0;
159
160         base = dev_read_addr(dev);
161         if (base == FDT_ADDR_T_NONE) {
162                 debug("Can't get the GPIO register base address\n");
163                 return -ENXIO;
164         }
165
166         for (node = dev_read_first_subnode(dev); ofnode_valid(node);
167              node = dev_read_next_subnode(node)) {
168                 if (!ofnode_read_bool(node, "gpio-controller"))
169                         continue;
170
171                 plat = devm_kcalloc(dev, 1, sizeof(*plat), GFP_KERNEL);
172                 if (!plat)
173                         return -ENOMEM;
174
175                 plat->base = base;
176                 plat->bank = bank;
177                 plat->pins = ofnode_read_u32_default(node, "snps,nr-gpios", 0);
178
179                 if (ofnode_read_string_index(node, "bank-name", 0,
180                                              &plat->name)) {
181                         /*
182                          * Fall back to node name. This means accessing pins
183                          * via bank name won't work.
184                          */
185                         plat->name = ofnode_get_name(node);
186                 }
187
188                 ret = device_bind_ofnode(dev, dev->driver, plat->name,
189                                          plat, node, &subdev);
190                 if (ret)
191                         return ret;
192
193                 bank++;
194         }
195
196         return 0;
197 }
198
199 static int gpio_dwapb_remove(struct udevice *dev)
200 {
201         struct gpio_dwapb_platdata *plat = dev_get_platdata(dev);
202         struct gpio_dwapb_priv *priv = dev_get_priv(dev);
203
204         if (!plat && priv)
205                 return reset_release_bulk(&priv->resets);
206
207         return 0;
208 }
209
210 static const struct udevice_id gpio_dwapb_ids[] = {
211         { .compatible = "snps,dw-apb-gpio" },
212         { }
213 };
214
215 U_BOOT_DRIVER(gpio_dwapb) = {
216         .name           = "gpio-dwapb",
217         .id             = UCLASS_GPIO,
218         .of_match       = gpio_dwapb_ids,
219         .ops            = &gpio_dwapb_ops,
220         .bind           = gpio_dwapb_bind,
221         .probe          = gpio_dwapb_probe,
222         .remove         = gpio_dwapb_remove,
223         .priv_auto_alloc_size   = sizeof(struct gpio_dwapb_priv),
224 };