2 * GPIO driver for the ACCES 104-DIO-48E
3 * Copyright (C) 2016 William Breathitt Gray
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2, as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 #include <linux/bitops.h>
15 #include <linux/device.h>
16 #include <linux/errno.h>
17 #include <linux/gpio/driver.h>
19 #include <linux/ioport.h>
20 #include <linux/interrupt.h>
21 #include <linux/irqdesc.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/moduleparam.h>
25 #include <linux/platform_device.h>
26 #include <linux/spinlock.h>
28 static unsigned dio_48e_base
;
29 module_param(dio_48e_base
, uint
, 0);
30 MODULE_PARM_DESC(dio_48e_base
, "ACCES 104-DIO-48E base address");
31 static unsigned dio_48e_irq
;
32 module_param(dio_48e_irq
, uint
, 0);
33 MODULE_PARM_DESC(dio_48e_irq
, "ACCES 104-DIO-48E interrupt line number");
36 * struct dio48e_gpio - GPIO device private data structure
37 * @chip: instance of the gpio_chip
38 * @io_state: bit I/O state (whether bit is set to input or output)
39 * @out_state: output bits state
40 * @control: Control registers state
41 * @lock: synchronization lock to prevent I/O race conditions
42 * @base: base port address of the GPIO device
43 * @irq: Interrupt line number
44 * @irq_mask: I/O bits affected by interrupts
47 struct gpio_chip chip
;
48 unsigned char io_state
[6];
49 unsigned char out_state
[6];
50 unsigned char control
[2];
54 unsigned char irq_mask
;
57 static int dio48e_gpio_get_direction(struct gpio_chip
*chip
, unsigned offset
)
59 struct dio48e_gpio
*const dio48egpio
= gpiochip_get_data(chip
);
60 const unsigned port
= offset
/ 8;
61 const unsigned mask
= BIT(offset
% 8);
63 return !!(dio48egpio
->io_state
[port
] & mask
);
66 static int dio48e_gpio_direction_input(struct gpio_chip
*chip
, unsigned offset
)
68 struct dio48e_gpio
*const dio48egpio
= gpiochip_get_data(chip
);
69 const unsigned io_port
= offset
/ 8;
70 const unsigned control_port
= io_port
/ 2;
71 const unsigned control_addr
= dio48egpio
->base
+ 3 + control_port
*4;
75 spin_lock_irqsave(&dio48egpio
->lock
, flags
);
77 /* Check if configuring Port C */
78 if (io_port
== 2 || io_port
== 5) {
79 /* Port C can be configured by nibble */
81 dio48egpio
->io_state
[io_port
] |= 0xF0;
82 dio48egpio
->control
[control_port
] |= BIT(3);
84 dio48egpio
->io_state
[io_port
] |= 0x0F;
85 dio48egpio
->control
[control_port
] |= BIT(0);
88 dio48egpio
->io_state
[io_port
] |= 0xFF;
89 if (io_port
== 0 || io_port
== 3)
90 dio48egpio
->control
[control_port
] |= BIT(4);
92 dio48egpio
->control
[control_port
] |= BIT(1);
95 control
= BIT(7) | dio48egpio
->control
[control_port
];
96 outb(control
, control_addr
);
98 outb(control
, control_addr
);
100 spin_unlock_irqrestore(&dio48egpio
->lock
, flags
);
105 static int dio48e_gpio_direction_output(struct gpio_chip
*chip
, unsigned offset
,
108 struct dio48e_gpio
*const dio48egpio
= gpiochip_get_data(chip
);
109 const unsigned io_port
= offset
/ 8;
110 const unsigned control_port
= io_port
/ 2;
111 const unsigned mask
= BIT(offset
% 8);
112 const unsigned control_addr
= dio48egpio
->base
+ 3 + control_port
*4;
113 const unsigned out_port
= (io_port
> 2) ? io_port
+ 1 : io_port
;
117 spin_lock_irqsave(&dio48egpio
->lock
, flags
);
119 /* Check if configuring Port C */
120 if (io_port
== 2 || io_port
== 5) {
121 /* Port C can be configured by nibble */
122 if (offset
% 8 > 3) {
123 dio48egpio
->io_state
[io_port
] &= 0x0F;
124 dio48egpio
->control
[control_port
] &= ~BIT(3);
126 dio48egpio
->io_state
[io_port
] &= 0xF0;
127 dio48egpio
->control
[control_port
] &= ~BIT(0);
130 dio48egpio
->io_state
[io_port
] &= 0x00;
131 if (io_port
== 0 || io_port
== 3)
132 dio48egpio
->control
[control_port
] &= ~BIT(4);
134 dio48egpio
->control
[control_port
] &= ~BIT(1);
138 dio48egpio
->out_state
[io_port
] |= mask
;
140 dio48egpio
->out_state
[io_port
] &= ~mask
;
142 control
= BIT(7) | dio48egpio
->control
[control_port
];
143 outb(control
, control_addr
);
145 outb(dio48egpio
->out_state
[io_port
], dio48egpio
->base
+ out_port
);
148 outb(control
, control_addr
);
150 spin_unlock_irqrestore(&dio48egpio
->lock
, flags
);
155 static int dio48e_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
157 struct dio48e_gpio
*const dio48egpio
= gpiochip_get_data(chip
);
158 const unsigned port
= offset
/ 8;
159 const unsigned mask
= BIT(offset
% 8);
160 const unsigned in_port
= (port
> 2) ? port
+ 1 : port
;
164 spin_lock_irqsave(&dio48egpio
->lock
, flags
);
166 /* ensure that GPIO is set for input */
167 if (!(dio48egpio
->io_state
[port
] & mask
)) {
168 spin_unlock_irqrestore(&dio48egpio
->lock
, flags
);
172 port_state
= inb(dio48egpio
->base
+ in_port
);
174 spin_unlock_irqrestore(&dio48egpio
->lock
, flags
);
176 return !!(port_state
& mask
);
179 static void dio48e_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
181 struct dio48e_gpio
*const dio48egpio
= gpiochip_get_data(chip
);
182 const unsigned port
= offset
/ 8;
183 const unsigned mask
= BIT(offset
% 8);
184 const unsigned out_port
= (port
> 2) ? port
+ 1 : port
;
187 spin_lock_irqsave(&dio48egpio
->lock
, flags
);
190 dio48egpio
->out_state
[port
] |= mask
;
192 dio48egpio
->out_state
[port
] &= ~mask
;
194 outb(dio48egpio
->out_state
[port
], dio48egpio
->base
+ out_port
);
196 spin_unlock_irqrestore(&dio48egpio
->lock
, flags
);
199 static void dio48e_irq_ack(struct irq_data
*data
)
203 static void dio48e_irq_mask(struct irq_data
*data
)
205 struct gpio_chip
*chip
= irq_data_get_irq_chip_data(data
);
206 struct dio48e_gpio
*const dio48egpio
= gpiochip_get_data(chip
);
207 const unsigned long offset
= irqd_to_hwirq(data
);
210 /* only bit 3 on each respective Port C supports interrupts */
211 if (offset
!= 19 && offset
!= 43)
214 spin_lock_irqsave(&dio48egpio
->lock
, flags
);
217 dio48egpio
->irq_mask
&= ~BIT(0);
219 dio48egpio
->irq_mask
&= ~BIT(1);
221 if (!dio48egpio
->irq_mask
)
222 /* disable interrupts */
223 inb(dio48egpio
->base
+ 0xB);
225 spin_unlock_irqrestore(&dio48egpio
->lock
, flags
);
228 static void dio48e_irq_unmask(struct irq_data
*data
)
230 struct gpio_chip
*chip
= irq_data_get_irq_chip_data(data
);
231 struct dio48e_gpio
*const dio48egpio
= gpiochip_get_data(chip
);
232 const unsigned long offset
= irqd_to_hwirq(data
);
235 /* only bit 3 on each respective Port C supports interrupts */
236 if (offset
!= 19 && offset
!= 43)
239 spin_lock_irqsave(&dio48egpio
->lock
, flags
);
241 if (!dio48egpio
->irq_mask
) {
242 /* enable interrupts */
243 outb(0x00, dio48egpio
->base
+ 0xF);
244 outb(0x00, dio48egpio
->base
+ 0xB);
248 dio48egpio
->irq_mask
|= BIT(0);
250 dio48egpio
->irq_mask
|= BIT(1);
252 spin_unlock_irqrestore(&dio48egpio
->lock
, flags
);
255 static int dio48e_irq_set_type(struct irq_data
*data
, unsigned flow_type
)
257 const unsigned long offset
= irqd_to_hwirq(data
);
259 /* only bit 3 on each respective Port C supports interrupts */
260 if (offset
!= 19 && offset
!= 43)
263 if (flow_type
!= IRQ_TYPE_NONE
&& flow_type
!= IRQ_TYPE_EDGE_RISING
)
269 static struct irq_chip dio48e_irqchip
= {
270 .name
= "104-dio-48e",
271 .irq_ack
= dio48e_irq_ack
,
272 .irq_mask
= dio48e_irq_mask
,
273 .irq_unmask
= dio48e_irq_unmask
,
274 .irq_set_type
= dio48e_irq_set_type
277 static irqreturn_t
dio48e_irq_handler(int irq
, void *dev_id
)
279 struct dio48e_gpio
*const dio48egpio
= dev_id
;
280 struct gpio_chip
*const chip
= &dio48egpio
->chip
;
281 const unsigned long irq_mask
= dio48egpio
->irq_mask
;
284 for_each_set_bit(gpio
, &irq_mask
, 2)
285 generic_handle_irq(irq_find_mapping(chip
->irqdomain
,
288 spin_lock(&dio48egpio
->lock
);
290 outb(0x00, dio48egpio
->base
+ 0xF);
292 spin_unlock(&dio48egpio
->lock
);
297 static int __init
dio48e_probe(struct platform_device
*pdev
)
299 struct device
*dev
= &pdev
->dev
;
300 struct dio48e_gpio
*dio48egpio
;
301 const unsigned base
= dio_48e_base
;
302 const unsigned extent
= 16;
303 const char *const name
= dev_name(dev
);
305 const unsigned irq
= dio_48e_irq
;
307 dio48egpio
= devm_kzalloc(dev
, sizeof(*dio48egpio
), GFP_KERNEL
);
311 if (!devm_request_region(dev
, base
, extent
, name
)) {
312 dev_err(dev
, "Unable to lock port addresses (0x%X-0x%X)\n",
313 base
, base
+ extent
);
317 dio48egpio
->chip
.label
= name
;
318 dio48egpio
->chip
.parent
= dev
;
319 dio48egpio
->chip
.owner
= THIS_MODULE
;
320 dio48egpio
->chip
.base
= -1;
321 dio48egpio
->chip
.ngpio
= 48;
322 dio48egpio
->chip
.get_direction
= dio48e_gpio_get_direction
;
323 dio48egpio
->chip
.direction_input
= dio48e_gpio_direction_input
;
324 dio48egpio
->chip
.direction_output
= dio48e_gpio_direction_output
;
325 dio48egpio
->chip
.get
= dio48e_gpio_get
;
326 dio48egpio
->chip
.set
= dio48e_gpio_set
;
327 dio48egpio
->base
= base
;
328 dio48egpio
->irq
= irq
;
330 spin_lock_init(&dio48egpio
->lock
);
332 dev_set_drvdata(dev
, dio48egpio
);
334 err
= gpiochip_add_data(&dio48egpio
->chip
, dio48egpio
);
336 dev_err(dev
, "GPIO registering failed (%d)\n", err
);
340 /* initialize all GPIO as output */
341 outb(0x80, base
+ 3);
343 outb(0x00, base
+ 1);
344 outb(0x00, base
+ 2);
345 outb(0x00, base
+ 3);
346 outb(0x80, base
+ 7);
347 outb(0x00, base
+ 4);
348 outb(0x00, base
+ 5);
349 outb(0x00, base
+ 6);
350 outb(0x00, base
+ 7);
352 /* disable IRQ by default */
355 err
= gpiochip_irqchip_add(&dio48egpio
->chip
, &dio48e_irqchip
, 0,
356 handle_edge_irq
, IRQ_TYPE_NONE
);
358 dev_err(dev
, "Could not add irqchip (%d)\n", err
);
359 goto err_gpiochip_remove
;
362 err
= request_irq(irq
, dio48e_irq_handler
, 0, name
, dio48egpio
);
364 dev_err(dev
, "IRQ handler registering failed (%d)\n", err
);
365 goto err_gpiochip_remove
;
371 gpiochip_remove(&dio48egpio
->chip
);
375 static int dio48e_remove(struct platform_device
*pdev
)
377 struct dio48e_gpio
*const dio48egpio
= platform_get_drvdata(pdev
);
379 free_irq(dio48egpio
->irq
, dio48egpio
);
380 gpiochip_remove(&dio48egpio
->chip
);
385 static struct platform_device
*dio48e_device
;
387 static struct platform_driver dio48e_driver
= {
389 .name
= "104-dio-48e"
391 .remove
= dio48e_remove
394 static void __exit
dio48e_exit(void)
396 platform_device_unregister(dio48e_device
);
397 platform_driver_unregister(&dio48e_driver
);
400 static int __init
dio48e_init(void)
404 dio48e_device
= platform_device_alloc(dio48e_driver
.driver
.name
, -1);
408 err
= platform_device_add(dio48e_device
);
410 goto err_platform_device
;
412 err
= platform_driver_probe(&dio48e_driver
, dio48e_probe
);
414 goto err_platform_driver
;
419 platform_device_del(dio48e_device
);
421 platform_device_put(dio48e_device
);
425 module_init(dio48e_init
);
426 module_exit(dio48e_exit
);
428 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
429 MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver");
430 MODULE_LICENSE("GPL v2");