]>
Commit | Line | Data |
---|---|---|
e184e2be | 1 | // SPDX-License-Identifier: GPL-2.0 |
b3c1e463 | 2 | /* |
e33437fc | 3 | * pcl724.c |
ee68080d | 4 | * Comedi driver for 8255 based ISA and PC/104 DIO boards |
e33437fc HS |
5 | * |
6 | * Michal Dobes <dobes@tesnet.cz> | |
7 | */ | |
b3c1e463 | 8 | |
b3c1e463 | 9 | /* |
e33437fc HS |
10 | * Driver: pcl724 |
11 | * Description: Comedi driver for 8255 based ISA DIO boards | |
e5350ef2 IA |
12 | * Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731), |
13 | * [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio), | |
14 | * [WinSystems] PCM-IO48 (pcmio48), | |
15 | * [Diamond Systems] ONYX-MM-DIO (onyx-mm-dio) | |
e33437fc HS |
16 | * Author: Michal Dobes <dobes@tesnet.cz> |
17 | * Status: untested | |
18 | * | |
19 | * Configuration options: | |
20 | * [0] - IO Base | |
21 | * [1] - IRQ (not supported) | |
22 | * [2] - number of DIO (pcl722 and acl7122 boards) | |
23 | * 0, 144: 144 DIO configuration | |
24 | * 1, 96: 96 DIO configuration | |
b3c1e463 MD |
25 | */ |
26 | ||
ce157f80 | 27 | #include <linux/module.h> |
b3c1e463 MD |
28 | #include "../comedidev.h" |
29 | ||
b3c1e463 MD |
30 | #include "8255.h" |
31 | ||
01820e02 | 32 | struct pcl724_board { |
0a0c2cb9 HS |
33 | const char *name; |
34 | unsigned int io_range; | |
35 | unsigned int can_have96:1; | |
36 | unsigned int is_pet48:1; | |
0a0c2cb9 | 37 | int numofports; |
01820e02 BP |
38 | }; |
39 | ||
0b69b449 HS |
40 | static const struct pcl724_board boardtypes[] = { |
41 | { | |
42 | .name = "pcl724", | |
0a0c2cb9 | 43 | .io_range = 0x04, |
eea410ce | 44 | .numofports = 1, /* 24 DIO channels */ |
0b69b449 HS |
45 | }, { |
46 | .name = "pcl722", | |
0a0c2cb9 HS |
47 | .io_range = 0x20, |
48 | .can_have96 = 1, | |
eea410ce | 49 | .numofports = 6, /* 144 (or 96) DIO channels */ |
0b69b449 HS |
50 | }, { |
51 | .name = "pcl731", | |
0a0c2cb9 | 52 | .io_range = 0x08, |
eea410ce | 53 | .numofports = 2, /* 48 DIO channels */ |
0b69b449 HS |
54 | }, { |
55 | .name = "acl7122", | |
0a0c2cb9 HS |
56 | .io_range = 0x20, |
57 | .can_have96 = 1, | |
eea410ce | 58 | .numofports = 6, /* 144 (or 96) DIO channels */ |
0b69b449 HS |
59 | }, { |
60 | .name = "acl7124", | |
0a0c2cb9 | 61 | .io_range = 0x04, |
eea410ce | 62 | .numofports = 1, /* 24 DIO channels */ |
0b69b449 HS |
63 | }, { |
64 | .name = "pet48dio", | |
0a0c2cb9 HS |
65 | .io_range = 0x02, |
66 | .is_pet48 = 1, | |
eea410ce | 67 | .numofports = 2, /* 48 DIO channels */ |
ee68080d HS |
68 | }, { |
69 | .name = "pcmio48", | |
70 | .io_range = 0x08, | |
71 | .numofports = 2, /* 48 DIO channels */ | |
55e51bad HS |
72 | }, { |
73 | .name = "onyx-mm-dio", | |
74 | .io_range = 0x10, | |
75 | .numofports = 2, /* 48 DIO channels */ | |
0b69b449 HS |
76 | }, |
77 | }; | |
78 | ||
09d6dd74 HS |
79 | static int pcl724_8255mapped_io(struct comedi_device *dev, |
80 | int dir, int port, int data, | |
0a85b6f0 | 81 | unsigned long iobase) |
b3c1e463 | 82 | { |
f0162091 | 83 | int movport = I8255_SIZE * (iobase >> 12); |
b3c1e463 MD |
84 | |
85 | iobase &= 0x0fff; | |
86 | ||
eeb3b4f9 | 87 | outb(port + movport, iobase); |
b3c1e463 | 88 | if (dir) { |
b3c1e463 MD |
89 | outb(data, iobase + 1); |
90 | return 0; | |
b3c1e463 | 91 | } |
eeb3b4f9 | 92 | return inb(iobase + 1); |
b3c1e463 MD |
93 | } |
94 | ||
57aade1d HS |
95 | static int pcl724_attach(struct comedi_device *dev, |
96 | struct comedi_devconfig *it) | |
b3c1e463 | 97 | { |
411b6f89 | 98 | const struct pcl724_board *board = dev->board_ptr; |
d533ef07 | 99 | struct comedi_subdevice *s; |
84f7db9d | 100 | unsigned long iobase; |
b3c1e463 | 101 | unsigned int iorange; |
57aade1d HS |
102 | int n_subdevices; |
103 | int ret; | |
104 | int i; | |
b3c1e463 | 105 | |
f21b15be | 106 | iorange = board->io_range; |
57aade1d HS |
107 | n_subdevices = board->numofports; |
108 | ||
109 | /* Handle PCL-724 in 96 DIO configuration */ | |
110 | if (board->can_have96 && | |
8091fb73 | 111 | (it->options[2] == 1 || it->options[2] == 96)) { |
57aade1d HS |
112 | iorange = 0x10; |
113 | n_subdevices = 4; | |
114 | } | |
115 | ||
15ab88b6 HS |
116 | ret = comedi_request_region(dev, it->options[0], iorange); |
117 | if (ret) | |
118 | return ret; | |
b3c1e463 | 119 | |
2f0b9d08 | 120 | ret = comedi_alloc_subdevices(dev, n_subdevices); |
8b6c5694 | 121 | if (ret) |
b3c1e463 MD |
122 | return ret; |
123 | ||
124 | for (i = 0; i < dev->n_subdevices; i++) { | |
d533ef07 | 125 | s = &dev->subdevices[i]; |
f21b15be | 126 | if (board->is_pet48) { |
84f7db9d HS |
127 | iobase = dev->iobase + (i * 0x1000); |
128 | ret = subdev_8255_init(dev, s, pcl724_8255mapped_io, | |
129 | iobase); | |
130 | } else { | |
f0162091 | 131 | ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); |
84f7db9d HS |
132 | } |
133 | if (ret) | |
134 | return ret; | |
273f4bef | 135 | } |
b3c1e463 MD |
136 | |
137 | return 0; | |
138 | } | |
139 | ||
294f930d | 140 | static struct comedi_driver pcl724_driver = { |
ccc66e0a HS |
141 | .driver_name = "pcl724", |
142 | .module = THIS_MODULE, | |
143 | .attach = pcl724_attach, | |
588ba6dc | 144 | .detach = comedi_legacy_detach, |
ccc66e0a HS |
145 | .board_name = &boardtypes[0].name, |
146 | .num_names = ARRAY_SIZE(boardtypes), | |
147 | .offset = sizeof(struct pcl724_board), | |
148 | }; | |
294f930d | 149 | module_comedi_driver(pcl724_driver); |
ccc66e0a | 150 | |
90f703d3 | 151 | MODULE_AUTHOR("Comedi http://www.comedi.org"); |
ee68080d | 152 | MODULE_DESCRIPTION("Comedi driver for 8255 based ISA and PC/104 DIO boards"); |
90f703d3 | 153 | MODULE_LICENSE("GPL"); |