1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49#include "../comedidev.h"
50
51#include <linux/delay.h>
52#include <linux/pci.h>
53#include <linux/slab.h>
54
55#include "das08.h"
56
57
58#include <pcmcia/cistpl.h>
59#include <pcmcia/ds.h>
60
61static struct pcmcia_device *cur_dev;
62
63static int das08_cs_attach(struct comedi_device *dev,
64 struct comedi_devconfig *it)
65{
66 const struct das08_board_struct *thisboard = comedi_board(dev);
67 int ret;
68 unsigned long iobase;
69 struct pcmcia_device *link = cur_dev;
70
71 ret = alloc_private(dev, sizeof(struct das08_private_struct));
72 if (ret < 0)
73 return ret;
74
75 dev_info(dev->class_dev, "das08_cs: attach\n");
76
77
78 if (thisboard->bustype == pcmcia) {
79 if (link == NULL) {
80 dev_err(dev->class_dev, "no pcmcia cards found\n");
81 return -EIO;
82 }
83 iobase = link->resource[0]->start;
84 } else {
85 dev_err(dev->class_dev,
86 "bug! board does not have PCMCIA bustype\n");
87 return -EINVAL;
88 }
89
90 return das08_common_attach(dev, iobase);
91}
92
93static struct comedi_driver driver_das08_cs = {
94 .driver_name = "das08_cs",
95 .module = THIS_MODULE,
96 .attach = das08_cs_attach,
97 .detach = das08_common_detach,
98 .board_name = &das08_cs_boards[0].name,
99 .num_names = ARRAY_SIZE(das08_cs_boards),
100 .offset = sizeof(struct das08_board_struct),
101};
102
103static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
104 void *priv_data)
105{
106 if (p_dev->config_index == 0)
107 return -EINVAL;
108
109 return pcmcia_request_io(p_dev);
110}
111
112static int das08_pcmcia_attach(struct pcmcia_device *link)
113{
114 int ret;
115
116 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
117
118 ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
119 if (ret)
120 goto failed;
121
122 if (!link->irq)
123 goto failed;
124
125 ret = pcmcia_enable_device(link);
126 if (ret)
127 goto failed;
128
129 cur_dev = link;
130 return 0;
131
132failed:
133 pcmcia_disable_device(link);
134 return ret;
135}
136
137static void das08_pcmcia_detach(struct pcmcia_device *link)
138{
139 pcmcia_disable_device(link);
140 cur_dev = NULL;
141}
142
143static const struct pcmcia_device_id das08_cs_id_table[] = {
144 PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4001),
145 PCMCIA_DEVICE_NULL
146};
147MODULE_DEVICE_TABLE(pcmcia, das08_cs_id_table);
148
149static struct pcmcia_driver das08_cs_driver = {
150 .name = "pcm-das08",
151 .owner = THIS_MODULE,
152 .probe = das08_pcmcia_attach,
153 .remove = das08_pcmcia_detach,
154 .id_table = das08_cs_id_table,
155};
156
157static int __init das08_cs_init_module(void)
158{
159 int ret;
160
161 ret = comedi_driver_register(&driver_das08_cs);
162 if (ret < 0)
163 return ret;
164
165 ret = pcmcia_register_driver(&das08_cs_driver);
166 if (ret < 0) {
167 comedi_driver_unregister(&driver_das08_cs);
168 return ret;
169 }
170
171 return 0;
172
173}
174module_init(das08_cs_init_module);
175
176static void __exit das08_cs_exit_module(void)
177{
178 pcmcia_unregister_driver(&das08_cs_driver);
179 comedi_driver_unregister(&driver_das08_cs);
180}
181module_exit(das08_cs_exit_module);
182
183MODULE_AUTHOR("David A. Schleef <ds@schleef.org>, "
184 "Frank Mori Hess <fmhess@users.sourceforge.net>");
185MODULE_DESCRIPTION("Comedi driver for ComputerBoards DAS-08 PCMCIA boards");
186MODULE_LICENSE("GPL");
187