Merge tag 'docs-5.9-2' of git://git.lwn.net/linux
[linux-2.6-microblaze.git] / drivers / gpio / gpio-104-idio-16.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * GPIO driver for the ACCES 104-IDIO-16 family
4  * Copyright (C) 2015 William Breathitt Gray
5  *
6  * This driver supports the following ACCES devices: 104-IDIO-16,
7  * 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8.
8  */
9 #include <linux/bitops.h>
10 #include <linux/device.h>
11 #include <linux/errno.h>
12 #include <linux/gpio/driver.h>
13 #include <linux/io.h>
14 #include <linux/ioport.h>
15 #include <linux/interrupt.h>
16 #include <linux/irqdesc.h>
17 #include <linux/isa.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/moduleparam.h>
21 #include <linux/spinlock.h>
22
23 #define IDIO_16_EXTENT 8
24 #define MAX_NUM_IDIO_16 max_num_isa_dev(IDIO_16_EXTENT)
25
26 static unsigned int base[MAX_NUM_IDIO_16];
27 static unsigned int num_idio_16;
28 module_param_hw_array(base, uint, ioport, &num_idio_16, 0);
29 MODULE_PARM_DESC(base, "ACCES 104-IDIO-16 base addresses");
30
31 static unsigned int irq[MAX_NUM_IDIO_16];
32 module_param_hw_array(irq, uint, irq, NULL, 0);
33 MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers");
34
35 /**
36  * struct idio_16_gpio - GPIO device private data structure
37  * @chip:       instance of the gpio_chip
38  * @lock:       synchronization lock to prevent I/O race conditions
39  * @irq_mask:   I/O bits affected by interrupts
40  * @base:       base port address of the GPIO device
41  * @out_state:  output bits state
42  */
43 struct idio_16_gpio {
44         struct gpio_chip chip;
45         raw_spinlock_t lock;
46         unsigned long irq_mask;
47         unsigned base;
48         unsigned out_state;
49 };
50
51 static int idio_16_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
52 {
53         if (offset > 15)
54                 return GPIO_LINE_DIRECTION_IN;
55
56         return GPIO_LINE_DIRECTION_OUT;
57 }
58
59 static int idio_16_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
60 {
61         return 0;
62 }
63
64 static int idio_16_gpio_direction_output(struct gpio_chip *chip,
65         unsigned offset, int value)
66 {
67         chip->set(chip, offset, value);
68         return 0;
69 }
70
71 static int idio_16_gpio_get(struct gpio_chip *chip, unsigned offset)
72 {
73         struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
74         const unsigned mask = BIT(offset-16);
75
76         if (offset < 16)
77                 return -EINVAL;
78
79         if (offset < 24)
80                 return !!(inb(idio16gpio->base + 1) & mask);
81
82         return !!(inb(idio16gpio->base + 5) & (mask>>8));
83 }
84
85 static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
86         unsigned long *mask, unsigned long *bits)
87 {
88         struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
89
90         *bits = 0;
91         if (*mask & GENMASK(23, 16))
92                 *bits |= (unsigned long)inb(idio16gpio->base + 1) << 16;
93         if (*mask & GENMASK(31, 24))
94                 *bits |= (unsigned long)inb(idio16gpio->base + 5) << 24;
95
96         return 0;
97 }
98
99 static void idio_16_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
100 {
101         struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
102         const unsigned mask = BIT(offset);
103         unsigned long flags;
104
105         if (offset > 15)
106                 return;
107
108         raw_spin_lock_irqsave(&idio16gpio->lock, flags);
109
110         if (value)
111                 idio16gpio->out_state |= mask;
112         else
113                 idio16gpio->out_state &= ~mask;
114
115         if (offset > 7)
116                 outb(idio16gpio->out_state >> 8, idio16gpio->base + 4);
117         else
118                 outb(idio16gpio->out_state, idio16gpio->base);
119
120         raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
121 }
122
123 static void idio_16_gpio_set_multiple(struct gpio_chip *chip,
124         unsigned long *mask, unsigned long *bits)
125 {
126         struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
127         unsigned long flags;
128
129         raw_spin_lock_irqsave(&idio16gpio->lock, flags);
130
131         idio16gpio->out_state &= ~*mask;
132         idio16gpio->out_state |= *mask & *bits;
133
134         if (*mask & 0xFF)
135                 outb(idio16gpio->out_state, idio16gpio->base);
136         if ((*mask >> 8) & 0xFF)
137                 outb(idio16gpio->out_state >> 8, idio16gpio->base + 4);
138
139         raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
140 }
141
142 static void idio_16_irq_ack(struct irq_data *data)
143 {
144 }
145
146 static void idio_16_irq_mask(struct irq_data *data)
147 {
148         struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
149         struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
150         const unsigned long mask = BIT(irqd_to_hwirq(data));
151         unsigned long flags;
152
153         idio16gpio->irq_mask &= ~mask;
154
155         if (!idio16gpio->irq_mask) {
156                 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
157
158                 outb(0, idio16gpio->base + 2);
159
160                 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
161         }
162 }
163
164 static void idio_16_irq_unmask(struct irq_data *data)
165 {
166         struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
167         struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip);
168         const unsigned long mask = BIT(irqd_to_hwirq(data));
169         const unsigned long prev_irq_mask = idio16gpio->irq_mask;
170         unsigned long flags;
171
172         idio16gpio->irq_mask |= mask;
173
174         if (!prev_irq_mask) {
175                 raw_spin_lock_irqsave(&idio16gpio->lock, flags);
176
177                 inb(idio16gpio->base + 2);
178
179                 raw_spin_unlock_irqrestore(&idio16gpio->lock, flags);
180         }
181 }
182
183 static int idio_16_irq_set_type(struct irq_data *data, unsigned flow_type)
184 {
185         /* The only valid irq types are none and both-edges */
186         if (flow_type != IRQ_TYPE_NONE &&
187                 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
188                 return -EINVAL;
189
190         return 0;
191 }
192
193 static struct irq_chip idio_16_irqchip = {
194         .name = "104-idio-16",
195         .irq_ack = idio_16_irq_ack,
196         .irq_mask = idio_16_irq_mask,
197         .irq_unmask = idio_16_irq_unmask,
198         .irq_set_type = idio_16_irq_set_type
199 };
200
201 static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
202 {
203         struct idio_16_gpio *const idio16gpio = dev_id;
204         struct gpio_chip *const chip = &idio16gpio->chip;
205         int gpio;
206
207         for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
208                 generic_handle_irq(irq_find_mapping(chip->irq.domain, gpio));
209
210         raw_spin_lock(&idio16gpio->lock);
211
212         outb(0, idio16gpio->base + 1);
213
214         raw_spin_unlock(&idio16gpio->lock);
215
216         return IRQ_HANDLED;
217 }
218
219 #define IDIO_16_NGPIO 32
220 static const char *idio_16_names[IDIO_16_NGPIO] = {
221         "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
222         "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
223         "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
224         "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15"
225 };
226
227 static int idio_16_irq_init_hw(struct gpio_chip *gc)
228 {
229         struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc);
230
231         /* Disable IRQ by default */
232         outb(0, idio16gpio->base + 2);
233         outb(0, idio16gpio->base + 1);
234
235         return 0;
236 }
237
238 static int idio_16_probe(struct device *dev, unsigned int id)
239 {
240         struct idio_16_gpio *idio16gpio;
241         const char *const name = dev_name(dev);
242         struct gpio_irq_chip *girq;
243         int err;
244
245         idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL);
246         if (!idio16gpio)
247                 return -ENOMEM;
248
249         if (!devm_request_region(dev, base[id], IDIO_16_EXTENT, name)) {
250                 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
251                         base[id], base[id] + IDIO_16_EXTENT);
252                 return -EBUSY;
253         }
254
255         idio16gpio->chip.label = name;
256         idio16gpio->chip.parent = dev;
257         idio16gpio->chip.owner = THIS_MODULE;
258         idio16gpio->chip.base = -1;
259         idio16gpio->chip.ngpio = IDIO_16_NGPIO;
260         idio16gpio->chip.names = idio_16_names;
261         idio16gpio->chip.get_direction = idio_16_gpio_get_direction;
262         idio16gpio->chip.direction_input = idio_16_gpio_direction_input;
263         idio16gpio->chip.direction_output = idio_16_gpio_direction_output;
264         idio16gpio->chip.get = idio_16_gpio_get;
265         idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple;
266         idio16gpio->chip.set = idio_16_gpio_set;
267         idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple;
268         idio16gpio->base = base[id];
269         idio16gpio->out_state = 0xFFFF;
270
271         girq = &idio16gpio->chip.irq;
272         girq->chip = &idio_16_irqchip;
273         /* This will let us handle the parent IRQ in the driver */
274         girq->parent_handler = NULL;
275         girq->num_parents = 0;
276         girq->parents = NULL;
277         girq->default_type = IRQ_TYPE_NONE;
278         girq->handler = handle_edge_irq;
279         girq->init_hw = idio_16_irq_init_hw;
280
281         raw_spin_lock_init(&idio16gpio->lock);
282
283         err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio);
284         if (err) {
285                 dev_err(dev, "GPIO registering failed (%d)\n", err);
286                 return err;
287         }
288
289         err = devm_request_irq(dev, irq[id], idio_16_irq_handler, 0, name,
290                 idio16gpio);
291         if (err) {
292                 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
293                 return err;
294         }
295
296         return 0;
297 }
298
299 static struct isa_driver idio_16_driver = {
300         .probe = idio_16_probe,
301         .driver = {
302                 .name = "104-idio-16"
303         },
304 };
305
306 module_isa_driver(idio_16_driver, num_idio_16);
307
308 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
309 MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver");
310 MODULE_LICENSE("GPL v2");