These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / comedi / drivers / 8255.c
1 /*
2  * comedi/drivers/8255.c
3  * Driver for 8255
4  *
5  * COMEDI - Linux Control and Measurement Device Interface
6  * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18
19 /*
20  * Driver: 8255
21  * Description: generic 8255 support
22  * Devices: [standard] 8255 (8255)
23  * Author: ds
24  * Status: works
25  * Updated: Fri,  7 Jun 2002 12:56:45 -0700
26  *
27  * The classic in digital I/O.  The 8255 appears in Comedi as a single
28  * digital I/O subdevice with 24 channels.  The channel 0 corresponds
29  * to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
30  * 7.  Direction configuration is done in blocks, with channels 0-7,
31  * 8-15, 16-19, and 20-23 making up the 4 blocks.  The only 8255 mode
32  * supported is mode 0.
33  *
34  * You should enable compilation this driver if you plan to use a board
35  * that has an 8255 chip.  For multifunction boards, the main driver will
36  * configure the 8255 subdevice automatically.
37  *
38  * This driver also works independently with ISA and PCI cards that
39  * directly map the 8255 registers to I/O ports, including cards with
40  * multiple 8255 chips.  To configure the driver for such a card, the
41  * option list should be a list of the I/O port bases for each of the
42  * 8255 chips.  For example,
43  *
44  *   comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
45  *
46  * Note that most PCI 8255 boards do NOT work with this driver, and
47  * need a separate driver as a wrapper.  For those that do work, the
48  * I/O port base address can be found in the output of 'lspci -v'.
49  */
50
51 #include <linux/module.h>
52 #include "../comedidev.h"
53
54 #include "8255.h"
55
56 static int dev_8255_attach(struct comedi_device *dev,
57                            struct comedi_devconfig *it)
58 {
59         struct comedi_subdevice *s;
60         unsigned long iobase;
61         int ret;
62         int i;
63
64         for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) {
65                 iobase = it->options[i];
66                 if (!iobase)
67                         break;
68         }
69         if (i == 0) {
70                 dev_warn(dev->class_dev, "no devices specified\n");
71                 return -EINVAL;
72         }
73
74         ret = comedi_alloc_subdevices(dev, i);
75         if (ret)
76                 return ret;
77
78         for (i = 0; i < dev->n_subdevices; i++) {
79                 s = &dev->subdevices[i];
80                 iobase = it->options[i];
81
82                 /*
83                  * __comedi_request_region() does not set dev->iobase.
84                  *
85                  * For 8255 devices that are manually attached using
86                  * comedi_config, the 'iobase' is the actual I/O port
87                  * base address of the chip.
88                  */
89                 ret = __comedi_request_region(dev, iobase, I8255_SIZE);
90                 if (ret) {
91                         s->type = COMEDI_SUBD_UNUSED;
92                 } else {
93                         ret = subdev_8255_init(dev, s, NULL, iobase);
94                         if (ret) {
95                                 /*
96                                  * Release the I/O port region here, as the
97                                  * "detach" handler cannot find it.
98                                  */
99                                 release_region(iobase, I8255_SIZE);
100                                 s->type = COMEDI_SUBD_UNUSED;
101                                 return ret;
102                         }
103                 }
104         }
105
106         return 0;
107 }
108
109 static void dev_8255_detach(struct comedi_device *dev)
110 {
111         struct comedi_subdevice *s;
112         int i;
113
114         for (i = 0; i < dev->n_subdevices; i++) {
115                 s = &dev->subdevices[i];
116                 if (s->type != COMEDI_SUBD_UNUSED) {
117                         unsigned long regbase = subdev_8255_regbase(s);
118
119                         release_region(regbase, I8255_SIZE);
120                 }
121         }
122 }
123
124 static struct comedi_driver dev_8255_driver = {
125         .driver_name    = "8255",
126         .module         = THIS_MODULE,
127         .attach         = dev_8255_attach,
128         .detach         = dev_8255_detach,
129 };
130 module_comedi_driver(dev_8255_driver);
131
132 MODULE_AUTHOR("Comedi http://www.comedi.org");
133 MODULE_DESCRIPTION("Comedi driver for standalone 8255 devices");
134 MODULE_LICENSE("GPL");