doc: replace @return by Return:
[platform/kernel/u-boot.git] / drivers / gpio / iproc_gpio.c
1 // SPDX-License-Identifier:      GPL-2.0+
2 /*
3  * Copyright (C) 2020 Broadcom
4  */
5
6 #include <common.h>
7 #include <errno.h>
8 #include <asm/gpio.h>
9 #include <asm/io.h>
10 #include <dm.h>
11 #include <dm/device_compat.h>
12 #include <dm/devres.h>
13 #include <dm/pinctrl.h>
14
15 /*
16  * There are five GPIO bank register. Each bank can configure max of 32 gpios.
17  * BANK0 - gpios 0 to 31
18  * BANK1 - gpios 32 to 63
19  * BANK2 - gpios 64 to 95
20  * BANK3 - gpios 96 to 127
21  * BANK4 - gpios 128 to 150
22  *
23  * Offset difference between consecutive bank register is 0x200
24  */
25 #define NGPIO_PER_BANK          32
26 #define GPIO_BANK_SIZE          0x200
27 #define GPIO_BANK(pin)          ((pin) / NGPIO_PER_BANK)
28 #define GPIO_SHIFT(pin)         ((pin) % NGPIO_PER_BANK)
29 #define GPIO_REG(pin, reg)      (GPIO_BANK_SIZE * GPIO_BANK(pin) + (reg))
30
31 /* device register offset */
32 #define DATA_IN_OFFSET   0x00
33 #define DATA_OUT_OFFSET  0x04
34 #define OUT_EN_OFFSET    0x08
35
36 /**
37  * struct iproc_gpio_pctrl_map - gpio and pinctrl mapping
38  * @gpio_pin:   start of gpio number in gpio-ranges
39  * @pctrl_pin:  start of pinctrl number in gpio-ranges
40  * @npins:      total number of pins in gpio-ranges
41  * @node:       list node
42  */
43 struct iproc_gpio_pctrl_map {
44         u32 gpio_pin;
45         u32 pctrl_pin;
46         u32 npins;
47         struct list_head node;
48 };
49
50 /**
51  * struct iproc_gpio_pctrl_map - gpio device instance
52  * @pinctrl_dev:pointer to pinctrl device
53  * @gpiomap:    list node having mapping between gpio and pinctrl
54  * @base:       I/O register base address of gpio device
55  * @name:       gpio device name, ex GPIO0, GPIO1
56  * @ngpios:     total number of gpios
57  */
58 struct iproc_gpio_plat {
59         struct udevice *pinctrl_dev;
60         struct list_head gpiomap;
61         void __iomem *base;
62         char *name;
63         u32 ngpios;
64 };
65
66 /**
67  * iproc_gpio_set_bit - set or clear one bit in an iproc GPIO register.
68  *
69  * The bit relates to a GPIO pin.
70  *
71  * @plat: iproc GPIO device
72  * @reg: register offset
73  * @gpio: GPIO pin
74  * @set: set or clear
75  */
76 static inline void iproc_gpio_set_bit(struct iproc_gpio_plat *plat,
77                                       u32 reg, u32 gpio, bool set)
78 {
79         u32 offset = GPIO_REG(gpio, reg);
80         u32 shift = GPIO_SHIFT(gpio);
81
82         clrsetbits_le32(plat->base + offset, BIT(shift),
83                         (set ? BIT(shift) : 0));
84 }
85
86 static inline bool iproc_gpio_get_bit(struct iproc_gpio_plat *plat,
87                                       u32 reg, u32 gpio)
88 {
89         u32 offset = GPIO_REG(gpio, reg);
90         u32 shift = GPIO_SHIFT(gpio);
91
92         return readl(plat->base + offset) & BIT(shift);
93 }
94
95 /**
96  * iproc_get_gpio_pctrl_mapping() - get associated pinctrl pin from gpio pin
97  *
98  * @plat: iproc GPIO device
99  * @gpio: GPIO pin
100  */
101 static u32 iproc_get_pctrl_from_gpio(struct iproc_gpio_plat *plat, u32 gpio)
102 {
103         struct iproc_gpio_pctrl_map *range = NULL;
104         struct list_head *pos, *tmp;
105         u32 ret = 0;
106
107         list_for_each_safe(pos, tmp, &plat->gpiomap) {
108                 range = list_entry(pos, struct iproc_gpio_pctrl_map, node);
109                 if (gpio == range->gpio_pin ||
110                     gpio < (range->gpio_pin + range->npins)) {
111                         ret = range->pctrl_pin + (gpio - range->gpio_pin);
112                         break;
113                 }
114         }
115
116         return ret;
117 }
118
119 /**
120  * iproc_get_gpio_pctrl_mapping() - get mapping between gpio and pinctrl
121  *
122  * Read dt node "gpio-ranges" to get gpio and pinctrl mapping and store
123  * in private data structure to use it later while enabling gpio.
124  *
125  * @dev: pointer to GPIO device
126  * Return: 0 on success and -ENOMEM on failure
127  */
128 static int iproc_get_gpio_pctrl_mapping(struct udevice *dev)
129 {
130         struct iproc_gpio_plat *plat = dev_get_plat(dev);
131         struct iproc_gpio_pctrl_map *range = NULL;
132         struct ofnode_phandle_args args;
133         int index = 0, ret;
134
135         for (;; index++) {
136                 ret = dev_read_phandle_with_args(dev, "gpio-ranges",
137                                                  NULL, 3, index, &args);
138                 if (ret)
139                         break;
140
141                 range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
142                 if (!range)
143                         return -ENOMEM;
144
145                 range->gpio_pin = args.args[0];
146                 range->pctrl_pin = args.args[1];
147                 range->npins = args.args[2];
148                 list_add_tail(&range->node, &plat->gpiomap);
149         }
150
151         return 0;
152 }
153
154 static int iproc_gpio_request(struct udevice *dev, u32 gpio, const char *label)
155 {
156         struct iproc_gpio_plat *plat = dev_get_plat(dev);
157         u32 pctrl;
158
159         /* nothing to do if there is no corresponding pinctrl device */
160         if (!plat->pinctrl_dev)
161                 return 0;
162
163         pctrl = iproc_get_pctrl_from_gpio(plat, gpio);
164
165         return pinctrl_request(plat->pinctrl_dev, pctrl, 0);
166 }
167
168 static int iproc_gpio_direction_input(struct udevice *dev, u32 gpio)
169 {
170         struct iproc_gpio_plat *plat = dev_get_plat(dev);
171
172         iproc_gpio_set_bit(plat, OUT_EN_OFFSET, gpio, false);
173         dev_dbg(dev, "gpio:%u set input\n", gpio);
174
175         return 0;
176 }
177
178 static int iproc_gpio_direction_output(struct udevice *dev, u32 gpio, int value)
179 {
180         struct iproc_gpio_plat *plat = dev_get_plat(dev);
181
182         iproc_gpio_set_bit(plat, OUT_EN_OFFSET, gpio, true);
183         iproc_gpio_set_bit(plat, DATA_OUT_OFFSET, gpio, value);
184         dev_dbg(dev, "gpio:%u set output, value:%d\n", gpio, value);
185
186         return 0;
187 }
188
189 static int iproc_gpio_get_value(struct udevice *dev, u32 gpio)
190 {
191         struct iproc_gpio_plat *plat = dev_get_plat(dev);
192         int value;
193
194         value = iproc_gpio_get_bit(plat, DATA_IN_OFFSET, gpio);
195         dev_dbg(dev, "gpio:%u get, value:%d\n", gpio, value);
196
197         return value;
198 }
199
200 static int iproc_gpio_set_value(struct udevice *dev, u32 gpio, int value)
201 {
202         struct iproc_gpio_plat *plat = dev_get_plat(dev);
203
204         if (iproc_gpio_get_bit(plat, OUT_EN_OFFSET, gpio))
205                 iproc_gpio_set_bit(plat, DATA_OUT_OFFSET, gpio, value);
206
207         dev_dbg(dev, "gpio:%u set, value:%d\n", gpio, value);
208         return 0;
209 }
210
211 static int iproc_gpio_get_function(struct udevice *dev, u32 gpio)
212 {
213         struct iproc_gpio_plat *plat = dev_get_plat(dev);
214
215         if (iproc_gpio_get_bit(plat, OUT_EN_OFFSET, gpio))
216                 return GPIOF_OUTPUT;
217         else
218                 return GPIOF_INPUT;
219 }
220
221 static int iproc_gpio_of_to_plat(struct udevice *dev)
222 {
223         struct iproc_gpio_plat *plat = dev_get_plat(dev);
224         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
225         int ret;
226         char name[10];
227
228         plat->base = dev_read_addr_ptr(dev);
229         if (!plat->base) {
230                 debug("%s: Failed to get base address\n", __func__);
231                 return -EINVAL;
232         }
233
234         ret = dev_read_u32(dev, "ngpios", &plat->ngpios);
235         if (ret < 0) {
236                 dev_err(dev, "%s: Failed to get ngpios\n", __func__);
237                 return ret;
238         }
239
240         uclass_get_device_by_phandle(UCLASS_PINCTRL, dev, "gpio-ranges",
241                                      &plat->pinctrl_dev);
242         if (ret < 0) {
243                 dev_err(dev, "%s: Failed to get pinctrl phandle\n", __func__);
244                 return ret;
245         }
246
247         INIT_LIST_HEAD(&plat->gpiomap);
248         ret = iproc_get_gpio_pctrl_mapping(dev);
249         if (ret < 0) {
250                 dev_err(dev, "%s: Failed to get gpio to pctrl map ret(%d)\n",
251                         __func__, ret);
252                 return ret;
253         }
254
255         snprintf(name, sizeof(name), "GPIO%d", dev_seq(dev));
256         plat->name = strdup(name);
257         if (!plat->name)
258                 return -ENOMEM;
259
260         uc_priv->gpio_count = plat->ngpios;
261         uc_priv->bank_name = plat->name;
262
263         dev_info(dev, ":bank name(%s) base %p, #gpios %d\n",
264                  plat->name, plat->base, plat->ngpios);
265
266         return 0;
267 }
268
269 static const struct dm_gpio_ops iproc_gpio_ops = {
270         .request                = iproc_gpio_request,
271         .direction_input        = iproc_gpio_direction_input,
272         .direction_output       = iproc_gpio_direction_output,
273         .get_value              = iproc_gpio_get_value,
274         .set_value              = iproc_gpio_set_value,
275         .get_function           = iproc_gpio_get_function,
276 };
277
278 static const struct udevice_id iproc_gpio_ids[] = {
279         { .compatible = "brcm,iproc-gpio" },
280         { }
281 };
282
283 U_BOOT_DRIVER(iproc_gpio) = {
284         .name                   = "iproc_gpio",
285         .id                     = UCLASS_GPIO,
286         .of_match               = iproc_gpio_ids,
287         .ops                    = &iproc_gpio_ops,
288         .of_to_plat     = iproc_gpio_of_to_plat,
289         .plat_auto      = sizeof(struct iproc_gpio_plat),
290 };