Merge tag 'pm-5.5-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux-2.6-microblaze.git] / drivers / gpio / gpio-gpio-mm.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * GPIO driver for the Diamond Systems GPIO-MM
4  * Copyright (C) 2016 William Breathitt Gray
5  *
6  * This driver supports the following Diamond Systems devices: GPIO-MM and
7  * GPIO-MM-12.
8  */
9 #include <linux/bitmap.h>
10 #include <linux/bitops.h>
11 #include <linux/device.h>
12 #include <linux/errno.h>
13 #include <linux/gpio/driver.h>
14 #include <linux/io.h>
15 #include <linux/ioport.h>
16 #include <linux/isa.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/moduleparam.h>
20 #include <linux/spinlock.h>
21
22 #define GPIOMM_EXTENT 8
23 #define MAX_NUM_GPIOMM max_num_isa_dev(GPIOMM_EXTENT)
24
25 static unsigned int base[MAX_NUM_GPIOMM];
26 static unsigned int num_gpiomm;
27 module_param_hw_array(base, uint, ioport, &num_gpiomm, 0);
28 MODULE_PARM_DESC(base, "Diamond Systems GPIO-MM base addresses");
29
30 /**
31  * struct gpiomm_gpio - GPIO device private data structure
32  * @chip:       instance of the gpio_chip
33  * @io_state:   bit I/O state (whether bit is set to input or output)
34  * @out_state:  output bits state
35  * @control:    Control registers state
36  * @lock:       synchronization lock to prevent I/O race conditions
37  * @base:       base port address of the GPIO device
38  */
39 struct gpiomm_gpio {
40         struct gpio_chip chip;
41         unsigned char io_state[6];
42         unsigned char out_state[6];
43         unsigned char control[2];
44         spinlock_t lock;
45         unsigned int base;
46 };
47
48 static int gpiomm_gpio_get_direction(struct gpio_chip *chip,
49         unsigned int offset)
50 {
51         struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
52         const unsigned int port = offset / 8;
53         const unsigned int mask = BIT(offset % 8);
54
55         if (gpiommgpio->io_state[port] & mask)
56                 return GPIO_LINE_DIRECTION_IN;
57
58         return GPIO_LINE_DIRECTION_OUT;
59 }
60
61 static int gpiomm_gpio_direction_input(struct gpio_chip *chip,
62         unsigned int offset)
63 {
64         struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
65         const unsigned int io_port = offset / 8;
66         const unsigned int control_port = io_port / 3;
67         const unsigned int control_addr = gpiommgpio->base + 3 + control_port*4;
68         unsigned long flags;
69         unsigned int control;
70
71         spin_lock_irqsave(&gpiommgpio->lock, flags);
72
73         /* Check if configuring Port C */
74         if (io_port == 2 || io_port == 5) {
75                 /* Port C can be configured by nibble */
76                 if (offset % 8 > 3) {
77                         gpiommgpio->io_state[io_port] |= 0xF0;
78                         gpiommgpio->control[control_port] |= BIT(3);
79                 } else {
80                         gpiommgpio->io_state[io_port] |= 0x0F;
81                         gpiommgpio->control[control_port] |= BIT(0);
82                 }
83         } else {
84                 gpiommgpio->io_state[io_port] |= 0xFF;
85                 if (io_port == 0 || io_port == 3)
86                         gpiommgpio->control[control_port] |= BIT(4);
87                 else
88                         gpiommgpio->control[control_port] |= BIT(1);
89         }
90
91         control = BIT(7) | gpiommgpio->control[control_port];
92         outb(control, control_addr);
93
94         spin_unlock_irqrestore(&gpiommgpio->lock, flags);
95
96         return 0;
97 }
98
99 static int gpiomm_gpio_direction_output(struct gpio_chip *chip,
100         unsigned int offset, int value)
101 {
102         struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
103         const unsigned int io_port = offset / 8;
104         const unsigned int control_port = io_port / 3;
105         const unsigned int mask = BIT(offset % 8);
106         const unsigned int control_addr = gpiommgpio->base + 3 + control_port*4;
107         const unsigned int out_port = (io_port > 2) ? io_port + 1 : io_port;
108         unsigned long flags;
109         unsigned int control;
110
111         spin_lock_irqsave(&gpiommgpio->lock, flags);
112
113         /* Check if configuring Port C */
114         if (io_port == 2 || io_port == 5) {
115                 /* Port C can be configured by nibble */
116                 if (offset % 8 > 3) {
117                         gpiommgpio->io_state[io_port] &= 0x0F;
118                         gpiommgpio->control[control_port] &= ~BIT(3);
119                 } else {
120                         gpiommgpio->io_state[io_port] &= 0xF0;
121                         gpiommgpio->control[control_port] &= ~BIT(0);
122                 }
123         } else {
124                 gpiommgpio->io_state[io_port] &= 0x00;
125                 if (io_port == 0 || io_port == 3)
126                         gpiommgpio->control[control_port] &= ~BIT(4);
127                 else
128                         gpiommgpio->control[control_port] &= ~BIT(1);
129         }
130
131         if (value)
132                 gpiommgpio->out_state[io_port] |= mask;
133         else
134                 gpiommgpio->out_state[io_port] &= ~mask;
135
136         control = BIT(7) | gpiommgpio->control[control_port];
137         outb(control, control_addr);
138
139         outb(gpiommgpio->out_state[io_port], gpiommgpio->base + out_port);
140
141         spin_unlock_irqrestore(&gpiommgpio->lock, flags);
142
143         return 0;
144 }
145
146 static int gpiomm_gpio_get(struct gpio_chip *chip, unsigned int offset)
147 {
148         struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
149         const unsigned int port = offset / 8;
150         const unsigned int mask = BIT(offset % 8);
151         const unsigned int in_port = (port > 2) ? port + 1 : port;
152         unsigned long flags;
153         unsigned int port_state;
154
155         spin_lock_irqsave(&gpiommgpio->lock, flags);
156
157         /* ensure that GPIO is set for input */
158         if (!(gpiommgpio->io_state[port] & mask)) {
159                 spin_unlock_irqrestore(&gpiommgpio->lock, flags);
160                 return -EINVAL;
161         }
162
163         port_state = inb(gpiommgpio->base + in_port);
164
165         spin_unlock_irqrestore(&gpiommgpio->lock, flags);
166
167         return !!(port_state & mask);
168 }
169
170 static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
171         unsigned long *bits)
172 {
173         struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
174         size_t i;
175         static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
176         const unsigned int gpio_reg_size = 8;
177         unsigned int bits_offset;
178         size_t word_index;
179         unsigned int word_offset;
180         unsigned long word_mask;
181         const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
182         unsigned long port_state;
183
184         /* clear bits array to a clean slate */
185         bitmap_zero(bits, chip->ngpio);
186
187         /* get bits are evaluated a gpio port register at a time */
188         for (i = 0; i < ARRAY_SIZE(ports); i++) {
189                 /* gpio offset in bits array */
190                 bits_offset = i * gpio_reg_size;
191
192                 /* word index for bits array */
193                 word_index = BIT_WORD(bits_offset);
194
195                 /* gpio offset within current word of bits array */
196                 word_offset = bits_offset % BITS_PER_LONG;
197
198                 /* mask of get bits for current gpio within current word */
199                 word_mask = mask[word_index] & (port_mask << word_offset);
200                 if (!word_mask) {
201                         /* no get bits in this port so skip to next one */
202                         continue;
203                 }
204
205                 /* read bits from current gpio port */
206                 port_state = inb(gpiommgpio->base + ports[i]);
207
208                 /* store acquired bits at respective bits array offset */
209                 bits[word_index] |= (port_state << word_offset) & word_mask;
210         }
211
212         return 0;
213 }
214
215 static void gpiomm_gpio_set(struct gpio_chip *chip, unsigned int offset,
216         int value)
217 {
218         struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
219         const unsigned int port = offset / 8;
220         const unsigned int mask = BIT(offset % 8);
221         const unsigned int out_port = (port > 2) ? port + 1 : port;
222         unsigned long flags;
223
224         spin_lock_irqsave(&gpiommgpio->lock, flags);
225
226         if (value)
227                 gpiommgpio->out_state[port] |= mask;
228         else
229                 gpiommgpio->out_state[port] &= ~mask;
230
231         outb(gpiommgpio->out_state[port], gpiommgpio->base + out_port);
232
233         spin_unlock_irqrestore(&gpiommgpio->lock, flags);
234 }
235
236 static void gpiomm_gpio_set_multiple(struct gpio_chip *chip,
237         unsigned long *mask, unsigned long *bits)
238 {
239         struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
240         unsigned int i;
241         const unsigned int gpio_reg_size = 8;
242         unsigned int port;
243         unsigned int out_port;
244         unsigned int bitmask;
245         unsigned long flags;
246
247         /* set bits are evaluated a gpio register size at a time */
248         for (i = 0; i < chip->ngpio; i += gpio_reg_size) {
249                 /* no more set bits in this mask word; skip to the next word */
250                 if (!mask[BIT_WORD(i)]) {
251                         i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size;
252                         continue;
253                 }
254
255                 port = i / gpio_reg_size;
256                 out_port = (port > 2) ? port + 1 : port;
257                 bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)];
258
259                 spin_lock_irqsave(&gpiommgpio->lock, flags);
260
261                 /* update output state data and set device gpio register */
262                 gpiommgpio->out_state[port] &= ~mask[BIT_WORD(i)];
263                 gpiommgpio->out_state[port] |= bitmask;
264                 outb(gpiommgpio->out_state[port], gpiommgpio->base + out_port);
265
266                 spin_unlock_irqrestore(&gpiommgpio->lock, flags);
267
268                 /* prepare for next gpio register set */
269                 mask[BIT_WORD(i)] >>= gpio_reg_size;
270                 bits[BIT_WORD(i)] >>= gpio_reg_size;
271         }
272 }
273
274 #define GPIOMM_NGPIO 48
275 static const char *gpiomm_names[GPIOMM_NGPIO] = {
276         "Port 1A0", "Port 1A1", "Port 1A2", "Port 1A3", "Port 1A4", "Port 1A5",
277         "Port 1A6", "Port 1A7", "Port 1B0", "Port 1B1", "Port 1B2", "Port 1B3",
278         "Port 1B4", "Port 1B5", "Port 1B6", "Port 1B7", "Port 1C0", "Port 1C1",
279         "Port 1C2", "Port 1C3", "Port 1C4", "Port 1C5", "Port 1C6", "Port 1C7",
280         "Port 2A0", "Port 2A1", "Port 2A2", "Port 2A3", "Port 2A4", "Port 2A5",
281         "Port 2A6", "Port 2A7", "Port 2B0", "Port 2B1", "Port 2B2", "Port 2B3",
282         "Port 2B4", "Port 2B5", "Port 2B6", "Port 2B7", "Port 2C0", "Port 2C1",
283         "Port 2C2", "Port 2C3", "Port 2C4", "Port 2C5", "Port 2C6", "Port 2C7",
284 };
285
286 static int gpiomm_probe(struct device *dev, unsigned int id)
287 {
288         struct gpiomm_gpio *gpiommgpio;
289         const char *const name = dev_name(dev);
290         int err;
291
292         gpiommgpio = devm_kzalloc(dev, sizeof(*gpiommgpio), GFP_KERNEL);
293         if (!gpiommgpio)
294                 return -ENOMEM;
295
296         if (!devm_request_region(dev, base[id], GPIOMM_EXTENT, name)) {
297                 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
298                         base[id], base[id] + GPIOMM_EXTENT);
299                 return -EBUSY;
300         }
301
302         gpiommgpio->chip.label = name;
303         gpiommgpio->chip.parent = dev;
304         gpiommgpio->chip.owner = THIS_MODULE;
305         gpiommgpio->chip.base = -1;
306         gpiommgpio->chip.ngpio = GPIOMM_NGPIO;
307         gpiommgpio->chip.names = gpiomm_names;
308         gpiommgpio->chip.get_direction = gpiomm_gpio_get_direction;
309         gpiommgpio->chip.direction_input = gpiomm_gpio_direction_input;
310         gpiommgpio->chip.direction_output = gpiomm_gpio_direction_output;
311         gpiommgpio->chip.get = gpiomm_gpio_get;
312         gpiommgpio->chip.get_multiple = gpiomm_gpio_get_multiple;
313         gpiommgpio->chip.set = gpiomm_gpio_set;
314         gpiommgpio->chip.set_multiple = gpiomm_gpio_set_multiple;
315         gpiommgpio->base = base[id];
316
317         spin_lock_init(&gpiommgpio->lock);
318
319         err = devm_gpiochip_add_data(dev, &gpiommgpio->chip, gpiommgpio);
320         if (err) {
321                 dev_err(dev, "GPIO registering failed (%d)\n", err);
322                 return err;
323         }
324
325         /* initialize all GPIO as output */
326         outb(0x80, base[id] + 3);
327         outb(0x00, base[id]);
328         outb(0x00, base[id] + 1);
329         outb(0x00, base[id] + 2);
330         outb(0x80, base[id] + 7);
331         outb(0x00, base[id] + 4);
332         outb(0x00, base[id] + 5);
333         outb(0x00, base[id] + 6);
334
335         return 0;
336 }
337
338 static struct isa_driver gpiomm_driver = {
339         .probe = gpiomm_probe,
340         .driver = {
341                 .name = "gpio-mm"
342         },
343 };
344
345 module_isa_driver(gpiomm_driver, num_gpiomm);
346
347 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
348 MODULE_DESCRIPTION("Diamond Systems GPIO-MM GPIO driver");
349 MODULE_LICENSE("GPL v2");