Staging: comedi: Remove comedi_subdevice typedef
[safe/jmp/linux-2.6] / 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 "../comedidev.h"
44
45 #include <linux/ioport.h>
46
47 #include "8255.h"
48
49 #include <pcmcia/cs_types.h>
50 #include <pcmcia/cs.h>
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, comedi_devconfig * it);
60 static int dio24_detach(struct comedi_device * dev);
61
62 enum dio24_bustype { pcmcia_bustype };
63
64 typedef 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 } dio24_board;
73
74 static const dio24_board 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 dio24_board *)dev->board_ptr)
93
94 typedef struct {
95         int data;               /* number of data points left to be taken */
96 } dio24_private;
97
98 #define devpriv ((dio24_private *)dev->private)
99
100 static comedi_driver driver_dio24 = {
101       driver_name:"ni_daq_dio24",
102       module:THIS_MODULE,
103       attach:dio24_attach,
104       detach:dio24_detach,
105       num_names:sizeof(dio24_boards) / sizeof(dio24_board),
106       board_name:&dio24_boards[0].name,
107       offset:sizeof(dio24_board),
108 };
109
110 static int dio24_attach(struct comedi_device * dev, comedi_devconfig * it)
111 {
112         struct comedi_subdevice *s;
113         unsigned long iobase = 0;
114 #ifdef incomplete
115         unsigned int irq = 0;
116 #endif
117         struct pcmcia_device *link;
118
119         /* allocate and initialize dev->private */
120         if (alloc_private(dev, sizeof(dio24_private)) < 0)
121                 return -ENOMEM;
122
123         // get base address, irq etc. based on bustype
124         switch (thisboard->bustype) {
125         case pcmcia_bustype:
126                 link = pcmcia_cur_dev;  /* XXX hack */
127                 if (!link)
128                         return -EIO;
129                 iobase = link->io.BasePort1;
130 #ifdef incomplete
131                 irq = link->irq.AssignedIRQ;
132 #endif
133                 break;
134         default:
135                 printk("bug! couldn't determine board type\n");
136                 return -EINVAL;
137                 break;
138         }
139         printk("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
140                 thisboard->name, iobase);
141 #ifdef incomplete
142         if (irq) {
143                 printk(", irq %u", irq);
144         }
145 #endif
146
147         printk("\n");
148
149         if (iobase == 0) {
150                 printk("io base address is zero!\n");
151                 return -EINVAL;
152         }
153
154         dev->iobase = iobase;
155
156 #ifdef incomplete
157         /* grab our IRQ */
158         dev->irq = irq;
159 #endif
160
161         dev->board_name = thisboard->name;
162
163         if (alloc_subdevices(dev, 1) < 0)
164                 return -ENOMEM;
165
166         /* 8255 dio */
167         s = dev->subdevices + 0;
168         subdev_8255_init(dev, s, NULL, dev->iobase);
169
170         return 0;
171 };
172
173 static int dio24_detach(struct comedi_device * dev)
174 {
175         printk("comedi%d: ni_daq_dio24: remove\n", dev->minor);
176
177         if (dev->subdevices)
178                 subdev_8255_cleanup(dev, dev->subdevices + 0);
179
180         if (thisboard->bustype != pcmcia_bustype && dev->iobase)
181                 release_region(dev->iobase, DIO24_SIZE);
182         if (dev->irq)
183                 comedi_free_irq(dev->irq, dev);
184
185         return 0;
186 };
187
188 // PCMCIA crap
189
190 /*
191    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
192    you do not define PCMCIA_DEBUG at all, all the debug code will be
193    left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
194    be present but disabled -- but it can then be enabled for specific
195    modules at load time with a 'pc_debug=#' option to insmod.
196 */
197 #ifdef PCMCIA_DEBUG
198 static int pc_debug = PCMCIA_DEBUG;
199 module_param(pc_debug, int, 0644);
200 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
201 static char *version = "ni_daq_dio24.c, based on dummy_cs.c";
202 #else
203 #define DEBUG(n, args...)
204 #endif
205
206 /*====================================================================*/
207
208 static void dio24_config(struct pcmcia_device *link);
209 static void dio24_release(struct pcmcia_device *link);
210 static int dio24_cs_suspend(struct pcmcia_device *p_dev);
211 static int dio24_cs_resume(struct pcmcia_device *p_dev);
212
213 /*
214    The attach() and detach() entry points are used to create and destroy
215    "instances" of the driver, where each instance represents everything
216    needed to manage one actual PCMCIA card.
217 */
218
219 static int dio24_cs_attach(struct pcmcia_device *);
220 static void dio24_cs_detach(struct pcmcia_device *);
221
222 /*
223    You'll also need to prototype all the functions that will actually
224    be used to talk to your device.  See 'memory_cs' for a good example
225    of a fully self-sufficient driver; the other drivers rely more or
226    less on other parts of the kernel.
227 */
228
229 /*
230    The dev_info variable is the "key" that is used to match up this
231    device driver with appropriate cards, through the card configuration
232    database.
233 */
234
235 static const dev_info_t dev_info = "ni_daq_dio24";
236
237 typedef struct local_info_t {
238         struct pcmcia_device *link;
239         dev_node_t node;
240         int stop;
241         struct bus_operations *bus;
242 } local_info_t;
243
244 /*======================================================================
245
246     dio24_cs_attach() creates an "instance" of the driver, allocating
247     local data structures for one device.  The device is registered
248     with Card Services.
249
250     The dev_link structure is initialized, but we don't actually
251     configure the card at this point -- we wait until we receive a
252     card insertion event.
253
254 ======================================================================*/
255
256 static int dio24_cs_attach(struct pcmcia_device *link)
257 {
258         local_info_t *local;
259
260         printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
261
262         DEBUG(0, "dio24_cs_attach()\n");
263
264         /* Allocate space for private device-specific data */
265         local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
266         if (!local)
267                 return -ENOMEM;
268         local->link = link;
269         link->priv = local;
270
271         /* Interrupt setup */
272         link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
273         link->irq.IRQInfo1 = IRQ_LEVEL_ID;
274         link->irq.Handler = NULL;
275
276         /*
277            General socket configuration defaults can go here.  In this
278            client, we assume very little, and rely on the CIS for almost
279            everything.  In most clients, many details (i.e., number, sizes,
280            and attributes of IO windows) are fixed by the nature of the
281            device, and can be hard-wired here.
282          */
283         link->conf.Attributes = 0;
284         link->conf.IntType = INT_MEMORY_AND_IO;
285
286         pcmcia_cur_dev = link;
287
288         dio24_config(link);
289
290         return 0;
291 }                               /* dio24_cs_attach */
292
293 /*======================================================================
294
295     This deletes a driver "instance".  The device is de-registered
296     with Card Services.  If it has been released, all local data
297     structures are freed.  Otherwise, the structures will be freed
298     when the device is released.
299
300 ======================================================================*/
301
302 static void dio24_cs_detach(struct pcmcia_device *link)
303 {
304
305         printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
306
307         DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
308
309         if (link->dev_node) {
310                 ((local_info_t *) link->priv)->stop = 1;
311                 dio24_release(link);
312         }
313
314         /* This points to the parent local_info_t struct */
315         if (link->priv)
316                 kfree(link->priv);
317
318 }                               /* dio24_cs_detach */
319
320 /*======================================================================
321
322     dio24_config() is scheduled to run after a CARD_INSERTION event
323     is received, to configure the PCMCIA socket, and to make the
324     device available to the system.
325
326 ======================================================================*/
327
328 static void dio24_config(struct pcmcia_device *link)
329 {
330         local_info_t *dev = link->priv;
331         tuple_t tuple;
332         cisparse_t parse;
333         int last_ret;
334         u_char buf[64];
335         win_req_t req;
336         memreq_t map;
337         cistpl_cftable_entry_t dflt = { 0 };
338
339         printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
340
341         DEBUG(0, "dio24_config(0x%p)\n", link);
342
343         /*
344            This reads the card's CONFIG tuple to find its configuration
345            registers.
346          */
347         tuple.DesiredTuple = CISTPL_CONFIG;
348         tuple.Attributes = 0;
349         tuple.TupleData = buf;
350         tuple.TupleDataMax = sizeof(buf);
351         tuple.TupleOffset = 0;
352         if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
353                 cs_error(link, GetFirstTuple, last_ret);
354                 goto cs_failed;
355         }
356         if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
357                 cs_error(link, GetTupleData, last_ret);
358                 goto cs_failed;
359         }
360         if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
361                 cs_error(link, ParseTuple, last_ret);
362                 goto cs_failed;
363         }
364         link->conf.ConfigBase = parse.config.base;
365         link->conf.Present = parse.config.rmask[0];
366
367         /*
368            In this loop, we scan the CIS for configuration table entries,
369            each of which describes a valid card configuration, including
370            voltage, IO window, memory window, and interrupt settings.
371
372            We make no assumptions about the card to be configured: we use
373            just the information available in the CIS.  In an ideal world,
374            this would work for any PCMCIA card, but it requires a complete
375            and accurate CIS.  In practice, a driver usually "knows" most of
376            these things without consulting the CIS, and most client drivers
377            will only use the CIS to fill in implementation-defined details.
378          */
379         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
380         if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
381                 cs_error(link, GetFirstTuple, last_ret);
382                 goto cs_failed;
383         }
384         while (1) {
385                 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
386                 if (pcmcia_get_tuple_data(link, &tuple) != 0)
387                         goto next_entry;
388                 if (pcmcia_parse_tuple(&tuple, &parse) != 0)
389                         goto next_entry;
390
391                 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
392                         dflt = *cfg;
393                 if (cfg->index == 0)
394                         goto next_entry;
395                 link->conf.ConfigIndex = cfg->index;
396
397                 /* Does this card need audio output? */
398                 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
399                         link->conf.Attributes |= CONF_ENABLE_SPKR;
400                         link->conf.Status = CCSR_AUDIO_ENA;
401                 }
402
403                 /* Do we need to allocate an interrupt? */
404                 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
405                         link->conf.Attributes |= CONF_ENABLE_IRQ;
406
407                 /* IO window settings */
408                 link->io.NumPorts1 = link->io.NumPorts2 = 0;
409                 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
410                         cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
411                         link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
412                         if (!(io->flags & CISTPL_IO_8BIT))
413                                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
414                         if (!(io->flags & CISTPL_IO_16BIT))
415                                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
416                         link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
417                         link->io.BasePort1 = io->win[0].base;
418                         link->io.NumPorts1 = io->win[0].len;
419                         if (io->nwin > 1) {
420                                 link->io.Attributes2 = link->io.Attributes1;
421                                 link->io.BasePort2 = io->win[1].base;
422                                 link->io.NumPorts2 = io->win[1].len;
423                         }
424                         /* This reserves IO space but doesn't actually enable it */
425                         if (pcmcia_request_io(link, &link->io) != 0)
426                                 goto next_entry;
427                 }
428
429                 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
430                         cistpl_mem_t *mem =
431                                 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
432                         req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
433                         req.Attributes |= WIN_ENABLE;
434                         req.Base = mem->win[0].host_addr;
435                         req.Size = mem->win[0].len;
436                         if (req.Size < 0x1000)
437                                 req.Size = 0x1000;
438                         req.AccessSpeed = 0;
439                         if (pcmcia_request_window(&link, &req, &link->win))
440                                 goto next_entry;
441                         map.Page = 0;
442                         map.CardOffset = mem->win[0].card_addr;
443                         if (pcmcia_map_mem_page(link->win, &map))
444                                 goto next_entry;
445                 }
446                 /* If we got this far, we're cool! */
447                 break;
448
449               next_entry:
450                 if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
451                         cs_error(link, GetNextTuple, last_ret);
452                         goto cs_failed;
453                 }
454         }
455
456         /*
457            Allocate an interrupt line.  Note that this does not assign a
458            handler to the interrupt, unless the 'Handler' member of the
459            irq structure is initialized.
460          */
461         if (link->conf.Attributes & CONF_ENABLE_IRQ)
462                 if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
463                         cs_error(link, RequestIRQ, last_ret);
464                         goto cs_failed;
465                 }
466
467         /*
468            This actually configures the PCMCIA socket -- setting up
469            the I/O windows and the interrupt mapping, and putting the
470            card and host interface into "Memory and IO" mode.
471          */
472         if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
473                 cs_error(link, RequestConfiguration, last_ret);
474                 goto cs_failed;
475         }
476
477         /*
478            At this point, the dev_node_t structure(s) need to be
479            initialized and arranged in a linked list at link->dev.
480          */
481         sprintf(dev->node.dev_name, "ni_daq_dio24");
482         dev->node.major = dev->node.minor = 0;
483         link->dev_node = &dev->node;
484
485         /* Finally, report what we've done */
486         printk(KERN_INFO "%s: index 0x%02x",
487                 dev->node.dev_name, link->conf.ConfigIndex);
488         if (link->conf.Attributes & CONF_ENABLE_IRQ)
489                 printk(", irq %d", link->irq.AssignedIRQ);
490         if (link->io.NumPorts1)
491                 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
492                         link->io.BasePort1 + link->io.NumPorts1 - 1);
493         if (link->io.NumPorts2)
494                 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
495                         link->io.BasePort2 + link->io.NumPorts2 - 1);
496         if (link->win)
497                 printk(", mem 0x%06lx-0x%06lx", req.Base,
498                         req.Base + req.Size - 1);
499         printk("\n");
500
501         return;
502
503       cs_failed:
504         printk(KERN_INFO "Fallo");
505         dio24_release(link);
506
507 }                               /* dio24_config */
508
509 static void dio24_release(struct pcmcia_device *link)
510 {
511         DEBUG(0, "dio24_release(0x%p)\n", link);
512
513         pcmcia_disable_device(link);
514 }                               /* dio24_release */
515
516 /*======================================================================
517
518     The card status event handler.  Mostly, this schedules other
519     stuff to run after an event is received.
520
521     When a CARD_REMOVAL event is received, we immediately set a
522     private flag to block future accesses to this device.  All the
523     functions that actually access the device should check this flag
524     to make sure the card is still present.
525
526 ======================================================================*/
527
528 static int dio24_cs_suspend(struct pcmcia_device *link)
529 {
530         local_info_t *local = link->priv;
531
532         /* Mark the device as stopped, to block IO until later */
533         local->stop = 1;
534         return 0;
535 }                               /* dio24_cs_suspend */
536
537 static int dio24_cs_resume(struct pcmcia_device *link)
538 {
539         local_info_t *local = link->priv;
540
541         local->stop = 0;
542         return 0;
543 }                               /* dio24_cs_resume */
544
545 /*====================================================================*/
546
547 static struct pcmcia_device_id dio24_cs_ids[] = {
548         /* N.B. These IDs should match those in dio24_boards */
549         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c),        /* daqcard-dio24 */
550         PCMCIA_DEVICE_NULL
551 };
552
553 MODULE_DEVICE_TABLE(pcmcia, dio24_cs_ids);
554
555 struct pcmcia_driver dio24_cs_driver = {
556         .probe = dio24_cs_attach,
557         .remove = dio24_cs_detach,
558         .suspend = dio24_cs_suspend,
559         .resume = dio24_cs_resume,
560         .id_table = dio24_cs_ids,
561         .owner = THIS_MODULE,
562         .drv = {
563                         .name = dev_info,
564                 },
565 };
566
567 static int __init init_dio24_cs(void)
568 {
569         printk("ni_daq_dio24: HOLA SOY YO!\n");
570         DEBUG(0, "%s\n", version);
571         pcmcia_register_driver(&dio24_cs_driver);
572         return 0;
573 }
574
575 static void __exit exit_dio24_cs(void)
576 {
577         DEBUG(0, "ni_dio24: unloading\n");
578         pcmcia_unregister_driver(&dio24_cs_driver);
579 }
580
581 int __init init_module(void)
582 {
583         int ret;
584
585         ret = init_dio24_cs();
586         if (ret < 0)
587                 return ret;
588
589         return comedi_driver_register(&driver_dio24);
590 }
591
592 void __exit cleanup_module(void)
593 {
594         exit_dio24_cs();
595         comedi_driver_unregister(&driver_dio24);
596 }