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