pcmcia: convert pcmcia_request_configuration to pcmcia_enable_device
[linux-2.6.git] / drivers / staging / comedi / drivers / ni_daq_dio24.c
1 /*
2     comedi/drivers/ni_daq_dio24.c
3     Driver for National Instruments PCMCIA DAQ-Card DIO-24
4     Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es>
5
6     PCMCIA crap at end of file is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
7     from the pcmcia package.
8     The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
9     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
10     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
11
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20     GNU General Public License for more details.
21
22     You should have received a copy of the GNU General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 ************************************************************************
27 */
28 /*
29 Driver: ni_daq_dio24
30 Description: National Instruments PCMCIA DAQ-Card DIO-24
31 Author: Daniel Vecino Castel <dvecino@able.es>
32 Devices: [National Instruments] PCMCIA DAQ-Card DIO-24 (ni_daq_dio24)
33 Status: ?
34 Updated: Thu, 07 Nov 2002 21:53:06 -0800
35
36 This is just a wrapper around the 8255.o driver to properly handle
37 the PCMCIA interface.
38 */
39
40                             /* #define LABPC_DEBUG *//*  enable debugging messages */
41 #undef LABPC_DEBUG
42
43 #include <linux/interrupt.h>
44 #include <linux/slab.h>
45 #include "../comedidev.h"
46
47 #include <linux/ioport.h>
48
49 #include "8255.h"
50
51 #include <pcmcia/cistpl.h>
52 #include <pcmcia/cisreg.h>
53 #include <pcmcia/ds.h>
54
55 static struct pcmcia_device *pcmcia_cur_dev = NULL;
56
57 #define DIO24_SIZE 4            /*  size of io region used by board */
58
59 static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it);
60 static int dio24_detach(struct comedi_device *dev);
61
62 enum dio24_bustype { pcmcia_bustype };
63
64 struct dio24_board_struct {
65         const char *name;
66         int device_id;          /*  device id for pcmcia board */
67         enum dio24_bustype bustype;     /*  PCMCIA */
68         int have_dio;           /*  have 8255 chip */
69         /*  function pointers so we can use inb/outb or readb/writeb as appropriate */
70         unsigned int (*read_byte) (unsigned int address);
71         void (*write_byte) (unsigned int byte, unsigned int address);
72 };
73
74 static const struct dio24_board_struct dio24_boards[] = {
75         {
76          .name = "daqcard-dio24",
77          .device_id = 0x475c,   /*  0x10b is manufacturer id, 0x475c is device id */
78          .bustype = pcmcia_bustype,
79          .have_dio = 1,
80          },
81         {
82          .name = "ni_daq_dio24",
83          .device_id = 0x475c,   /*  0x10b is manufacturer id, 0x475c is device id */
84          .bustype = pcmcia_bustype,
85          .have_dio = 1,
86          },
87 };
88
89 /*
90  * Useful for shorthand access to the particular board structure
91  */
92 #define thisboard ((const struct dio24_board_struct *)dev->board_ptr)
93
94 struct dio24_private {
95
96         int data;               /* number of data points left to be taken */
97 };
98
99 #define devpriv ((struct dio24_private *)dev->private)
100
101 static struct comedi_driver driver_dio24 = {
102         .driver_name = "ni_daq_dio24",
103         .module = THIS_MODULE,
104         .attach = dio24_attach,
105         .detach = dio24_detach,
106         .num_names = ARRAY_SIZE(dio24_boards),
107         .board_name = &dio24_boards[0].name,
108         .offset = sizeof(struct dio24_board_struct),
109 };
110
111 static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it)
112 {
113         struct comedi_subdevice *s;
114         unsigned long iobase = 0;
115 #ifdef incomplete
116         unsigned int irq = 0;
117 #endif
118         struct pcmcia_device *link;
119
120         /* allocate and initialize dev->private */
121         if (alloc_private(dev, sizeof(struct dio24_private)) < 0)
122                 return -ENOMEM;
123
124         /*  get base address, irq etc. based on bustype */
125         switch (thisboard->bustype) {
126         case pcmcia_bustype:
127                 link = pcmcia_cur_dev;  /* XXX hack */
128                 if (!link)
129                         return -EIO;
130                 iobase = link->resource[0]->start;
131 #ifdef incomplete
132                 irq = link->irq;
133 #endif
134                 break;
135         default:
136                 printk("bug! couldn't determine board type\n");
137                 return -EINVAL;
138                 break;
139         }
140         printk("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
141                thisboard->name, iobase);
142 #ifdef incomplete
143         if (irq) {
144                 printk(", irq %u", irq);
145         }
146 #endif
147
148         printk("\n");
149
150         if (iobase == 0) {
151                 printk("io base address is zero!\n");
152                 return -EINVAL;
153         }
154
155         dev->iobase = iobase;
156
157 #ifdef incomplete
158         /* grab our IRQ */
159         dev->irq = irq;
160 #endif
161
162         dev->board_name = thisboard->name;
163
164         if (alloc_subdevices(dev, 1) < 0)
165                 return -ENOMEM;
166
167         /* 8255 dio */
168         s = dev->subdevices + 0;
169         subdev_8255_init(dev, s, NULL, dev->iobase);
170
171         return 0;
172 };
173
174 static int dio24_detach(struct comedi_device *dev)
175 {
176         printk("comedi%d: ni_daq_dio24: remove\n", dev->minor);
177
178         if (dev->subdevices)
179                 subdev_8255_cleanup(dev, dev->subdevices + 0);
180
181         if (thisboard->bustype != pcmcia_bustype && dev->iobase)
182                 release_region(dev->iobase, DIO24_SIZE);
183         if (dev->irq)
184                 free_irq(dev->irq, dev);
185
186         return 0;
187 };
188
189 /* PCMCIA crap -- watch your words! */
190
191 static void dio24_config(struct pcmcia_device *link);
192 static void dio24_release(struct pcmcia_device *link);
193 static int dio24_cs_suspend(struct pcmcia_device *p_dev);
194 static int dio24_cs_resume(struct pcmcia_device *p_dev);
195
196 /*
197    The attach() and detach() entry points are used to create and destroy
198    "instances" of the driver, where each instance represents everything
199    needed to manage one actual PCMCIA card.
200 */
201
202 static int dio24_cs_attach(struct pcmcia_device *);
203 static void dio24_cs_detach(struct pcmcia_device *);
204
205 /*
206    You'll also need to prototype all the functions that will actually
207    be used to talk to your device.  See 'memory_cs' for a good example
208    of a fully self-sufficient driver; the other drivers rely more or
209    less on other parts of the kernel.
210 */
211
212 struct local_info_t {
213         struct pcmcia_device *link;
214         int stop;
215         struct bus_operations *bus;
216 };
217
218 /*======================================================================
219
220     dio24_cs_attach() creates an "instance" of the driver, allocating
221     local data structures for one device.  The device is registered
222     with Card Services.
223
224     The dev_link structure is initialized, but we don't actually
225     configure the card at this point -- we wait until we receive a
226     card insertion event.
227
228 ======================================================================*/
229
230 static int dio24_cs_attach(struct pcmcia_device *link)
231 {
232         struct local_info_t *local;
233
234         printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
235
236         dev_dbg(&link->dev, "dio24_cs_attach()\n");
237
238         /* Allocate space for private device-specific data */
239         local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
240         if (!local)
241                 return -ENOMEM;
242         local->link = link;
243         link->priv = local;
244
245         pcmcia_cur_dev = link;
246
247         dio24_config(link);
248
249         return 0;
250 }                               /* dio24_cs_attach */
251
252 /*======================================================================
253
254     This deletes a driver "instance".  The device is de-registered
255     with Card Services.  If it has been released, all local data
256     structures are freed.  Otherwise, the structures will be freed
257     when the device is released.
258
259 ======================================================================*/
260
261 static void dio24_cs_detach(struct pcmcia_device *link)
262 {
263
264         printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
265
266         dev_dbg(&link->dev, "dio24_cs_detach\n");
267
268         ((struct local_info_t *)link->priv)->stop = 1;
269         dio24_release(link);
270
271         /* This points to the parent local_info_t struct */
272         kfree(link->priv);
273
274 }                               /* dio24_cs_detach */
275
276 /*======================================================================
277
278     dio24_config() is scheduled to run after a CARD_INSERTION event
279     is received, to configure the PCMCIA socket, and to make the
280     device available to the system.
281
282 ======================================================================*/
283
284 static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
285                                 cistpl_cftable_entry_t *cfg,
286                                 cistpl_cftable_entry_t *dflt,
287                                 unsigned int vcc,
288                                 void *priv_data)
289 {
290         if (cfg->index == 0)
291                 return -ENODEV;
292
293         /* Does this card need audio output? */
294         if (cfg->flags & CISTPL_CFTABLE_AUDIO)
295                 p_dev->config_flags |= CONF_ENABLE_SPKR;
296
297         /* Do we need to allocate an interrupt? */
298         p_dev->config_flags |= CONF_ENABLE_IRQ;
299
300         /* IO window settings */
301         p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
302         if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
303                 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
304                 p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
305                 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
306                 p_dev->resource[0]->flags |=
307                         pcmcia_io_cfg_data_width(io->flags);
308                 p_dev->resource[0]->start = io->win[0].base;
309                 p_dev->resource[0]->end = io->win[0].len;
310                 if (io->nwin > 1) {
311                         p_dev->resource[1]->flags = p_dev->resource[0]->flags;
312                         p_dev->resource[1]->start = io->win[1].base;
313                         p_dev->resource[1]->end = io->win[1].len;
314                 }
315                 /* This reserves IO space but doesn't actually enable it */
316                 if (pcmcia_request_io(p_dev) != 0)
317                         return -ENODEV;
318         }
319
320         /* If we got this far, we're cool! */
321         return 0;
322 }
323
324 static void dio24_config(struct pcmcia_device *link)
325 {
326         int ret;
327
328         printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
329
330         dev_dbg(&link->dev, "dio24_config\n");
331
332         ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, NULL);
333         if (ret) {
334                 dev_warn(&link->dev, "no configuration found\n");
335                 goto failed;
336         }
337
338         if (!link->irq)
339                 goto failed;
340
341         /*
342            This actually configures the PCMCIA socket -- setting up
343            the I/O windows and the interrupt mapping, and putting the
344            card and host interface into "Memory and IO" mode.
345          */
346         ret = pcmcia_enable_device(link);
347         if (ret)
348                 goto failed;
349
350         /* Finally, report what we've done */
351         dev_info(&link->dev, "index 0x%02x", link->config_index);
352         printk(", irq %d", link->irq);
353         if (link->resource[0])
354                 printk(" & %pR", link->resource[0]);
355         if (link->resource[1])
356                 printk(" & %pR", link->resource[1]);
357         printk("\n");
358
359         return;
360
361 failed:
362         printk(KERN_INFO "Fallo");
363         dio24_release(link);
364
365 }                               /* dio24_config */
366
367 static void dio24_release(struct pcmcia_device *link)
368 {
369         dev_dbg(&link->dev, "dio24_release\n");
370
371         pcmcia_disable_device(link);
372 }                               /* dio24_release */
373
374 /*======================================================================
375
376     The card status event handler.  Mostly, this schedules other
377     stuff to run after an event is received.
378
379     When a CARD_REMOVAL event is received, we immediately set a
380     private flag to block future accesses to this device.  All the
381     functions that actually access the device should check this flag
382     to make sure the card is still present.
383
384 ======================================================================*/
385
386 static int dio24_cs_suspend(struct pcmcia_device *link)
387 {
388         struct local_info_t *local = link->priv;
389
390         /* Mark the device as stopped, to block IO until later */
391         local->stop = 1;
392         return 0;
393 }                               /* dio24_cs_suspend */
394
395 static int dio24_cs_resume(struct pcmcia_device *link)
396 {
397         struct local_info_t *local = link->priv;
398
399         local->stop = 0;
400         return 0;
401 }                               /* dio24_cs_resume */
402
403 /*====================================================================*/
404
405 static struct pcmcia_device_id dio24_cs_ids[] = {
406         /* N.B. These IDs should match those in dio24_boards */
407         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c),        /* daqcard-dio24 */
408         PCMCIA_DEVICE_NULL
409 };
410
411 MODULE_DEVICE_TABLE(pcmcia, dio24_cs_ids);
412 MODULE_AUTHOR("Daniel Vecino Castel <dvecino@able.es>");
413 MODULE_DESCRIPTION("Comedi driver for National Instruments "
414                    "PCMCIA DAQ-Card DIO-24");
415 MODULE_LICENSE("GPL");
416
417 struct pcmcia_driver dio24_cs_driver = {
418         .probe = dio24_cs_attach,
419         .remove = dio24_cs_detach,
420         .suspend = dio24_cs_suspend,
421         .resume = dio24_cs_resume,
422         .id_table = dio24_cs_ids,
423         .owner = THIS_MODULE,
424         .drv = {
425                 .name = "ni_daq_dio24",
426                 },
427 };
428
429 static int __init init_dio24_cs(void)
430 {
431         printk("ni_daq_dio24: HOLA SOY YO!\n");
432         pcmcia_register_driver(&dio24_cs_driver);
433         return 0;
434 }
435
436 static void __exit exit_dio24_cs(void)
437 {
438         pcmcia_unregister_driver(&dio24_cs_driver);
439 }
440
441 int __init init_module(void)
442 {
443         int ret;
444
445         ret = init_dio24_cs();
446         if (ret < 0)
447                 return ret;
448
449         return comedi_driver_register(&driver_dio24);
450 }
451
452 void __exit cleanup_module(void)
453 {
454         exit_dio24_cs();
455         comedi_driver_unregister(&driver_dio24);
456 }