Added some ack'ing of b interrupts, and do acks before handling
[comedi.git] / comedi / drivers / cb_das16_cs.c
1 /*
2     comedi/drivers/das16cs.c
3     Skeleton code for a Comedi driver
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 2000, 2001, 2002 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     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23 /*
24 Driver: cb_das16_cs.o
25 Description: Computer Boards PC-CARD DAS16/16
26 Devices: [ComputerBoards] PC-CARD DAS16/16 (cb_das16_cs), PC-CARD DAS16/16-AO
27 Author: ds
28 Updated: Mon, 04 Nov 2002 20:04:21 -0800
29 Status: experimental
30
31
32 */
33
34 #include <linux/comedidev.h>
35 #include <linux/delay.h>
36 #include <linux/pci.h>
37
38 #include <pcmcia/cs_types.h>
39 #include <pcmcia/cs.h>
40 #include <pcmcia/cistpl.h>
41 #include <pcmcia/ds.h>
42
43 #include "8253.h"
44
45 #define DAS16CS_SIZE                    18
46
47 #define DAS16CS_ADC_DATA                0
48 #define DAS16CS_DIO_MUX                 2
49 #define DAS16CS_MISC1                   4
50 #define DAS16CS_MISC2                   6
51 #define DAS16CS_CTR0                    8
52 #define DAS16CS_CTR1                    10
53 #define DAS16CS_CTR2                    12
54 #define DAS16CS_CTR_CONTROL             14
55 #define DAS16CS_DIO                     16
56
57
58 typedef struct das16cs_board_struct{
59         char *name;
60         int device_id;
61         int n_ao_chans;
62 }das16cs_board;
63 static das16cs_board das16cs_boards[] = {
64         {
65         device_id:      0x0000, /* unknown */
66         name:           "PC-CARD DAS16/16",
67         n_ao_chans:     0,
68         },
69         {
70         device_id:      0x0039,
71         name:           "PC-CARD DAS16/16-AO",
72         n_ao_chans:     2,
73         },
74 };
75 #define n_boards (sizeof(das16cs_boards)/sizeof(das16cs_boards[0]))
76 #define thisboard ((das16cs_board *)dev->board_ptr)
77
78 typedef struct{
79         dev_link_t *link;
80
81         lsampl_t ao_readback[2];
82         unsigned short status1;
83         unsigned short status2;
84 }das16cs_private;
85 #define devpriv ((das16cs_private *)dev->private)
86
87 static int das16cs_attach(comedi_device *dev,comedi_devconfig *it);
88 static int das16cs_detach(comedi_device *dev);
89 static comedi_driver driver_das16cs={
90         driver_name:    "cb_das16_cs",
91         module:         THIS_MODULE,
92         attach:         das16cs_attach,
93         detach:         das16cs_detach,
94 };
95
96 static dev_link_t *dev_list = NULL;
97
98 static comedi_lrange das16cs_ai_range = { 4, {
99         RANGE( -10, 10 ),
100         RANGE( -5, 5 ),
101         RANGE( -2.5, 2.5 ),
102         RANGE( -1.25, 1.25 ),
103 }};
104
105
106 static irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG);
107 static int das16cs_ai_rinsn(comedi_device *dev,comedi_subdevice *s,
108         comedi_insn *insn,lsampl_t *data);
109 static int das16cs_ai_cmd(comedi_device *dev,comedi_subdevice *s);
110 static int das16cs_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,
111         comedi_cmd *cmd);
112 static int das16cs_ao_winsn(comedi_device *dev,comedi_subdevice *s,
113         comedi_insn *insn,lsampl_t *data);
114 static int das16cs_ao_rinsn(comedi_device *dev,comedi_subdevice *s,
115         comedi_insn *insn,lsampl_t *data);
116 static int das16cs_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,
117         comedi_insn *insn,lsampl_t *data);
118 static int das16cs_dio_insn_config(comedi_device *dev,comedi_subdevice *s,
119         comedi_insn *insn,lsampl_t *data);
120 static int das16cs_timer_insn_read(comedi_device *dev,comedi_subdevice *s,
121         comedi_insn *insn,lsampl_t *data);
122 static int das16cs_timer_insn_config(comedi_device *dev,comedi_subdevice *s,
123         comedi_insn *insn,lsampl_t *data);
124
125 static int get_prodid(comedi_device *dev, dev_link_t *link)
126 {
127         client_handle_t handle = link->handle;
128         tuple_t tuple;
129         u_short buf[128];
130         int prodid = 0;
131
132         tuple.TupleData = (cisdata_t *) buf;
133         tuple.TupleOffset = 0;
134         tuple.TupleDataMax = 255;
135         tuple.DesiredTuple = CISTPL_MANFID;
136         tuple.Attributes = TUPLE_RETURN_COMMON;
137         if((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) &&
138            (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)){
139                 prodid = le16_to_cpu(buf[1]);
140         }
141
142         return prodid;
143 }
144
145 static das16cs_board *das16cs_probe(comedi_device *dev, dev_link_t *link)
146 {
147         int id;
148         int i;
149
150         id = get_prodid(dev,link);
151
152         for(i=0;i<n_boards;i++){
153                 if(das16cs_boards[i].device_id==id){
154                         return das16cs_boards + i;
155                 }
156         }
157
158         printk("unknown board!\n");
159
160         return NULL;
161 }
162
163 static int das16cs_attach(comedi_device *dev,comedi_devconfig *it)
164 {
165         dev_link_t *link;
166         comedi_subdevice *s;
167         int ret;
168         int i;
169
170         printk("comedi%d: cb_das16_cs: ",dev->minor);
171
172         link = dev_list; /* XXX hack */
173         if(!link)return -EIO;
174
175         dev->iobase = link->io.BasePort1;
176         printk("I/O base=0x%04lx ",dev->iobase);
177
178         printk("fingerprint:\n");
179         for(i=0;i<48;i+=2){
180                 printk("%04x ",inw(dev->iobase + i));
181         }
182         printk("\n");
183
184         ret = comedi_request_irq(link->irq.AssignedIRQ, das16cs_interrupt,
185                 IRQF_SHARED, "cb_das16_cs", dev);
186         if(ret<0){
187                 return ret;
188         }
189         dev->irq = link->irq.AssignedIRQ;
190         printk("irq=%u ",dev->irq);
191
192         dev->board_ptr = das16cs_probe(dev, link);
193         if(!dev->board_ptr)return -EIO;
194
195         dev->board_name = thisboard->name;
196
197         if(alloc_private(dev,sizeof(das16cs_private))<0)
198                 return -ENOMEM;
199
200         if(alloc_subdevices(dev, 4)<0)
201                 return -ENOMEM;
202
203         s=dev->subdevices+0;
204         dev->read_subdev=s;
205         /* analog input subdevice */
206         s->type=COMEDI_SUBD_AI;
207         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
208         s->n_chan=16;
209         s->maxdata=0xffff;
210         s->range_table=&das16cs_ai_range;
211         s->len_chanlist=16;
212         s->insn_read = das16cs_ai_rinsn;
213         s->do_cmd = das16cs_ai_cmd;
214         s->do_cmdtest = das16cs_ai_cmdtest;
215
216         s=dev->subdevices+1;
217         /* analog output subdevice */
218         if(thisboard->n_ao_chans){
219                 s->type=COMEDI_SUBD_AO;
220                 s->subdev_flags=SDF_WRITABLE;
221                 s->n_chan=thisboard->n_ao_chans;
222                 s->maxdata=0xffff;
223                 s->range_table = &range_bipolar10;
224                 s->insn_write = &das16cs_ao_winsn;
225                 s->insn_read = &das16cs_ao_rinsn;
226         }
227
228         s=dev->subdevices+2;
229         /* digital i/o subdevice */
230         if(1){
231                 s->type=COMEDI_SUBD_DIO;
232                 s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
233                 s->n_chan=8;
234                 s->maxdata=1;
235                 s->range_table=&range_digital;
236                 s->insn_bits = das16cs_dio_insn_bits;
237                 s->insn_config = das16cs_dio_insn_config;
238         }else{
239                 s->type = COMEDI_SUBD_UNUSED;
240         }
241
242         s=dev->subdevices+3;
243         /* timer subdevice */
244         if(0){
245                 s->type=COMEDI_SUBD_TIMER;
246                 s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
247                 s->n_chan=1;
248                 s->maxdata=0xff;
249                 s->range_table = &range_unknown;
250                 s->insn_read = das16cs_timer_insn_read;
251                 s->insn_config = das16cs_timer_insn_config;
252         }else{
253                 s->type = COMEDI_SUBD_UNUSED;
254         }
255
256         printk("attached\n");
257
258         return 1;
259 }
260
261 static int das16cs_detach(comedi_device *dev)
262 {
263         printk("comedi%d: das16cs: remove\n",dev->minor);
264
265         if(dev->irq){
266                 comedi_free_irq(dev->irq, dev);
267         }
268
269         return 0;
270 }
271
272
273 static irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG)
274 {
275         //comedi_device *dev = d;
276         return IRQ_HANDLED;
277 }
278
279 /*
280  * "instructions" read/write data in "one-shot" or "software-triggered"
281  * mode.
282  */
283 static int das16cs_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
284 {
285         int i;
286         int to;
287         int aref;
288         int range;
289         int chan;
290         static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 };
291
292         chan = CR_CHAN(insn->chanspec);
293         aref = CR_AREF(insn->chanspec);
294         range = CR_RANGE(insn->chanspec);
295
296         outw(chan, dev->iobase + 2);
297
298         devpriv->status1 &= ~0xf320;
299         devpriv->status1 |= (aref==AREF_DIFF)?0:0x0020;
300         outw(devpriv->status1, dev->iobase + 4);
301
302         devpriv->status2 &= ~0xff00;
303         devpriv->status2 |= range_bits[range];
304         outw(devpriv->status2, dev->iobase + 6);
305
306         for(i=0;i<insn->n;i++){
307                 outw(0, dev->iobase);
308
309 #define TIMEOUT 1000
310                 for(to=0;to<TIMEOUT;to++){
311                         if(inw(dev->iobase + 4) & 0x0080)break;
312                 }
313                 if(to==TIMEOUT){
314                         printk("cb_das16_cs: ai timeout\n");
315                         return -ETIME;
316                 }
317                 data[i] = (unsigned short)inw(dev->iobase + 0);
318         }
319
320         return i;
321 }
322
323 static int das16cs_ai_cmd(comedi_device *dev,comedi_subdevice *s)
324 {
325         return -EINVAL;
326 }
327
328 static int das16cs_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,
329         comedi_cmd *cmd)
330 {
331         int err=0;
332         int tmp;
333
334         /* cmdtest tests a particular command to see if it is valid.
335          * Using the cmdtest ioctl, a user can create a valid cmd
336          * and then have it executes by the cmd ioctl.
337          *
338          * cmdtest returns 1,2,3,4 or 0, depending on which tests
339          * the command passes. */
340
341         /* step 1: make sure trigger sources are trivially valid */
342
343         tmp=cmd->start_src;
344         cmd->start_src &= TRIG_NOW;
345         if(!cmd->start_src || tmp!=cmd->start_src)err++;
346
347         tmp=cmd->scan_begin_src;
348         cmd->scan_begin_src &= TRIG_TIMER|TRIG_EXT;
349         if(!cmd->scan_begin_src || tmp!=cmd->scan_begin_src)err++;
350
351         tmp=cmd->convert_src;
352         cmd->convert_src &= TRIG_TIMER|TRIG_EXT;
353         if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
354
355         tmp=cmd->scan_end_src;
356         cmd->scan_end_src &= TRIG_COUNT;
357         if(!cmd->scan_end_src || tmp!=cmd->scan_end_src)err++;
358
359         tmp=cmd->stop_src;
360         cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
361         if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
362
363         if(err)return 1;
364
365         /* step 2: make sure trigger sources are unique and mutually compatible */
366
367         /* note that mutual compatiblity is not an issue here */
368         if(cmd->scan_begin_src!=TRIG_TIMER &&
369            cmd->scan_begin_src!=TRIG_EXT)err++;
370         if(cmd->convert_src!=TRIG_TIMER &&
371            cmd->convert_src!=TRIG_EXT)err++;
372         if(cmd->stop_src!=TRIG_COUNT &&
373            cmd->stop_src!=TRIG_NONE)err++;
374
375         if(err)return 2;
376
377         /* step 3: make sure arguments are trivially compatible */
378
379         if(cmd->start_arg!=0){
380                 cmd->start_arg=0;
381                 err++;
382         }
383
384 #define MAX_SPEED       10000           /* in nanoseconds */
385 #define MIN_SPEED       1000000000      /* in nanoseconds */
386
387         if(cmd->scan_begin_src==TRIG_TIMER){
388                 if(cmd->scan_begin_arg<MAX_SPEED){
389                         cmd->scan_begin_arg=MAX_SPEED;
390                         err++;
391                 }
392                 if(cmd->scan_begin_arg>MIN_SPEED){
393                         cmd->scan_begin_arg=MIN_SPEED;
394                         err++;
395                 }
396         }else{
397                 /* external trigger */
398                 /* should be level/edge, hi/lo specification here */
399                 /* should specify multiple external triggers */
400                 if(cmd->scan_begin_arg>9){
401                         cmd->scan_begin_arg=9;
402                         err++;
403                 }
404         }
405         if(cmd->convert_src==TRIG_TIMER){
406                 if(cmd->convert_arg<MAX_SPEED){
407                         cmd->convert_arg=MAX_SPEED;
408                         err++;
409                 }
410                 if(cmd->convert_arg>MIN_SPEED){
411                         cmd->convert_arg=MIN_SPEED;
412                         err++;
413                 }
414         }else{
415                 /* external trigger */
416                 /* see above */
417                 if(cmd->convert_arg>9){
418                         cmd->convert_arg=9;
419                         err++;
420                 }
421         }
422
423         if(cmd->scan_end_arg!=cmd->chanlist_len){
424                 cmd->scan_end_arg=cmd->chanlist_len;
425                 err++;
426         }
427         if(cmd->stop_src==TRIG_COUNT){
428                 if(cmd->stop_arg>0x00ffffff){
429                         cmd->stop_arg=0x00ffffff;
430                         err++;
431                 }
432         }else{
433                 /* TRIG_NONE */
434                 if(cmd->stop_arg!=0){
435                         cmd->stop_arg=0;
436                         err++;
437                 }
438         }
439
440         if(err)return 3;
441
442         /* step 4: fix up any arguments */
443
444         if(cmd->scan_begin_src==TRIG_TIMER){
445                 unsigned int div1, div2;
446
447                 tmp=cmd->scan_begin_arg;
448                 i8253_cascade_ns_to_timer(100, &div1, &div2,
449                         &cmd->scan_begin_arg, cmd->flags&TRIG_ROUND_MASK);
450                 if(tmp!=cmd->scan_begin_arg)err++;
451         }
452         if(cmd->convert_src==TRIG_TIMER){
453                 unsigned int div1, div2;
454
455                 tmp=cmd->convert_arg;
456                 i8253_cascade_ns_to_timer(100, &div1, &div2,
457                         &cmd->scan_begin_arg, cmd->flags&TRIG_ROUND_MASK);
458                 if(tmp!=cmd->convert_arg)err++;
459                 if(cmd->scan_begin_src==TRIG_TIMER &&
460                   cmd->scan_begin_arg<cmd->convert_arg*cmd->scan_end_arg){
461                         cmd->scan_begin_arg=cmd->convert_arg*cmd->scan_end_arg;
462                         err++;
463                 }
464         }
465
466         if(err)return 4;
467
468         return 0;
469 }
470
471 static int das16cs_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
472 {
473         int i;
474         int chan = CR_CHAN(insn->chanspec);
475         unsigned short status1;
476         unsigned short d;
477         int bit;
478
479         for(i=0;i<insn->n;i++){
480                 devpriv->ao_readback[chan] = data[i];
481                 d = data[i];
482
483                 outw(devpriv->status1, dev->iobase + 4);
484                 comedi_udelay(1);
485
486                 status1 = devpriv->status1 & ~0xf;
487                 if(chan) status1 |= 0x0001;
488                 else status1 |= 0x0008;
489
490 /*              printk("0x%04x\n",status1);*/
491                 outw(status1, dev->iobase + 4);
492                 comedi_udelay(1);
493
494                 for(bit=15;bit>=0;bit--){
495                         int b = (d >> bit) & 0x1;
496                         b <<= 1;
497 /*                      printk("0x%04x\n",status1 | b | 0x0000);*/
498                         outw(status1 | b | 0x0000, dev->iobase + 4);
499                         comedi_udelay(1);
500 /*                      printk("0x%04x\n",status1 | b | 0x0004);*/
501                         outw(status1 | b | 0x0004, dev->iobase + 4);
502                         comedi_udelay(1);
503                 }
504 /*              make high both DAC0CS and DAC1CS to load
505                 new data and update analog output*/
506                 outw(status1 | 0x9, dev->iobase + 4);
507         }
508
509         return i;
510 }
511
512 /* AO subdevices should have a read insn as well as a write insn.
513  * Usually this means copying a value stored in devpriv. */
514 static int das16cs_ao_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
515 {
516         int i;
517         int chan = CR_CHAN(insn->chanspec);
518
519         for(i=0;i<insn->n;i++)
520                 data[i] = devpriv->ao_readback[chan];
521
522         return i;
523 }
524
525 /* DIO devices are slightly special.  Although it is possible to
526  * implement the insn_read/insn_write interface, it is much more
527  * useful to applications if you implement the insn_bits interface.
528  * This allows packed reading/writing of the DIO channels.  The
529  * comedi core can convert between insn_bits and insn_read/write */
530 static int das16cs_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,
531         comedi_insn *insn,lsampl_t *data)
532 {
533         if(insn->n!=2)return -EINVAL;
534
535         if(data[0]){
536                 s->state &= ~data[0];
537                 s->state |= data[0]&data[1];
538
539                 outw(s->state,dev->iobase + 16);
540         }
541
542         /* on return, data[1] contains the value of the digital
543          * input and output lines. */
544         data[1]=inw(dev->iobase + 16);
545
546         return 2;
547 }
548
549 static int das16cs_dio_insn_config(comedi_device *dev,comedi_subdevice *s,
550         comedi_insn *insn,lsampl_t *data)
551 {
552         int chan=CR_CHAN(insn->chanspec);
553         int bits;
554
555         if(chan<4)bits=0x0f;
556         else bits=0xf0;
557
558         switch(data[0])
559         {
560         case INSN_CONFIG_DIO_OUTPUT:
561                 s->io_bits |= bits;
562                 break;
563         case INSN_CONFIG_DIO_INPUT:
564                 s->io_bits &= bits;
565                 break;
566         case INSN_CONFIG_DIO_QUERY:
567                 data[1] = (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
568                 return insn->n;
569                 break;
570         default:
571                 return -EINVAL;
572                 break;
573         }
574
575         devpriv->status2 &= ~0x00c0;
576         devpriv->status2 |= (s->io_bits&0xf0)?0x0080:0;
577         devpriv->status2 |= (s->io_bits&0x0f)?0x0040:0;
578
579         outw(devpriv->status2,dev->iobase + 6);
580
581         return insn->n;
582 }
583
584 static int das16cs_timer_insn_read(comedi_device *dev,comedi_subdevice *s,
585         comedi_insn *insn,lsampl_t *data)
586 {
587         return -EINVAL;
588 }
589
590 static int das16cs_timer_insn_config(comedi_device *dev,comedi_subdevice *s,
591         comedi_insn *insn,lsampl_t *data)
592 {
593         return -EINVAL;
594 }
595
596
597
598
599 /* PCMCIA stuff */
600
601 /*======================================================================
602
603     The following pcmcia code for the pcm-das08 is adapted from the
604     dummy_cs.c driver of the Linux PCMCIA Card Services package.
605
606     The initial developer of the original code is David A. Hinds
607     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
608     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
609
610 ======================================================================*/
611
612 /*
613    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
614    you do not define PCMCIA_DEBUG at all, all the debug code will be
615    left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
616    be present but disabled -- but it can then be enabled for specific
617    modules at load time with a 'pc_debug=#' option to insmod.
618 */
619 #if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
620
621 #ifdef PCMCIA_DEBUG
622 static int pc_debug = PCMCIA_DEBUG;
623 module_param(pc_debug, int, 0644);
624 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
625 static char *version =
626 "cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
627 #else
628 #define DEBUG(n, args...)
629 #endif
630
631 /*====================================================================*/
632
633 static void das16cs_pcmcia_config(dev_link_t *link);
634 static void das16cs_pcmcia_release(u_long arg);
635 static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev);
636 static int das16cs_pcmcia_resume(struct pcmcia_device *p_dev);
637
638 /*
639    The attach() and detach() entry points are used to create and destroy
640    "instances" of the driver, where each instance represents everything
641    needed to manage one actual PCMCIA card.
642 */
643
644 static int das16cs_pcmcia_attach(struct pcmcia_device *);
645 static void das16cs_pcmcia_detach(struct pcmcia_device *);
646
647 /*
648    You'll also need to prototype all the functions that will actually
649    be used to talk to your device.  See 'memory_cs' for a good example
650    of a fully self-sufficient driver; the other drivers rely more or
651    less on other parts of the kernel.
652 */
653
654 /*
655    The dev_info variable is the "key" that is used to match up this
656    device driver with appropriate cards, through the card configuration
657    database.
658 */
659
660 static dev_info_t dev_info = "cb_das16_cs";
661
662 /*
663    A dev_link_t structure has fields for most things that are needed
664    to keep track of a socket, but there will usually be some device
665    specific information that also needs to be kept track of.  The
666    'priv' pointer in a dev_link_t structure can be used to point to
667    a device-specific private data structure, like this.
668
669    To simplify the data structure handling, we actually include the
670    dev_link_t structure in the device's private data structure.
671
672    A driver needs to provide a dev_node_t structure for each device
673    on a card.  In some cases, there is only one device per card (for
674    example, ethernet cards, modems).  In other cases, there may be
675    many actual or logical devices (SCSI adapters, memory cards with
676    multiple partitions).  The dev_node_t structures need to be kept
677    in a linked list starting at the 'dev' field of a dev_link_t
678    structure.  We allocate them in the card's private data structure,
679    because they generally shouldn't be allocated dynamically.
680
681    In this case, we also provide a flag to indicate if a device is
682    "stopped" due to a power management event, or card ejection.  The
683    device IO routines can use a flag like this to throttle IO to a
684    card that is not ready to accept it.
685
686    The bus_operations pointer is used on platforms for which we need
687    to use special socket-specific versions of normal IO primitives
688    (inb, outb, readb, writeb, etc) for card IO.
689 */
690
691 typedef struct local_info_t {
692     dev_link_t          link;
693     dev_node_t          node;
694     int                 stop;
695     struct bus_operations *bus;
696 } local_info_t;
697
698 /*======================================================================
699
700     das16cs_pcmcia_attach() creates an "instance" of the driver, allocating
701     local data structures for one device.  The device is registered
702     with Card Services.
703
704     The dev_link structure is initialized, but we don't actually
705     configure the card at this point -- we wait until we receive a
706     card insertion event.
707
708 ======================================================================*/
709
710 static int das16cs_pcmcia_attach(struct pcmcia_device *p_dev)
711 {
712     local_info_t *local;
713     dev_link_t *link;
714
715     DEBUG(0, "das16cs_pcmcia_attach()\n");
716
717     /* Allocate space for private device-specific data */
718     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
719     if (!local) return -ENOMEM;
720     memset(local, 0, sizeof(local_info_t));
721     link = &local->link; link->priv = local;
722
723     /* Initialize the dev_link_t structure */
724     /* Interrupt setup */
725     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
726     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
727     link->irq.Handler = NULL;
728
729     /*
730       General socket configuration defaults can go here.  In this
731       client, we assume very little, and rely on the CIS for almost
732       everything.  In most clients, many details (i.e., number, sizes,
733       and attributes of IO windows) are fixed by the nature of the
734       device, and can be hard-wired here.
735     */
736     link->conf.Attributes = 0;
737     link->conf.Vcc = 50;
738     link->conf.IntType = INT_MEMORY_AND_IO;
739
740     link->next = dev_list;
741     dev_list = link;
742
743     link->handle = p_dev;
744     p_dev->instance = link;
745     link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
746     das16cs_pcmcia_config(link);
747
748     return 0;
749 } /* das16cs_pcmcia_attach */
750
751 /*======================================================================
752
753     This deletes a driver "instance".  The device is de-registered
754     with Card Services.  If it has been released, all local data
755     structures are freed.  Otherwise, the structures will be freed
756     when the device is released.
757
758 ======================================================================*/
759
760 static void das16cs_pcmcia_detach(struct pcmcia_device *p_dev)
761 {
762         dev_link_t *link = dev_to_instance(p_dev);
763         dev_link_t **linkp;
764
765         DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
766
767         /* Locate device structure */
768         for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
769         if (*linkp == link) break;
770         if (*linkp == NULL)
771                 return;
772
773         /*
774         If the device is currently configured and active, we won't
775         actually delete it yet.  Instead, it is marked so that when
776         the release() function is called, that will trigger a proper
777         detach().
778         */
779         if (link->state & DEV_CONFIG)
780         {
781                 ((local_info_t *)link->priv)->stop = 1;
782                 das16cs_pcmcia_release((u_long)link);
783         }
784         /* Unlink device structure, and free it */
785         *linkp = link->next;
786         /* This points to the parent local_info_t struct */
787         kfree(link->priv);
788 } /* das16cs_pcmcia_detach */
789
790 /*======================================================================
791
792     das16cs_pcmcia_config() is scheduled to run after a CARD_INSERTION event
793     is received, to configure the PCMCIA socket, and to make the
794     device available to the system.
795
796 ======================================================================*/
797
798 static void das16cs_pcmcia_config(dev_link_t *link)
799 {
800         client_handle_t handle = link->handle;
801         local_info_t *dev = link->priv;
802         tuple_t tuple;
803         cisparse_t parse;
804         int last_fn, last_ret;
805         u_char buf[64];
806         config_info_t conf;
807         cistpl_cftable_entry_t dflt = { 0 };
808
809         DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);
810
811         /*
812                 This reads the card's CONFIG tuple to find its configuration
813                 registers.
814         */
815         tuple.DesiredTuple = CISTPL_CONFIG;
816         tuple.Attributes = 0;
817         tuple.TupleData = buf;
818         tuple.TupleDataMax = sizeof(buf);
819         tuple.TupleOffset = 0;
820         last_fn = GetFirstTuple;
821         if((last_ret = pcmcia_get_first_tuple(handle, &tuple)) != 0) goto cs_failed;
822         last_fn = GetTupleData;
823         if((last_ret = pcmcia_get_tuple_data(handle, &tuple)) != 0) goto cs_failed;
824         last_fn = ParseTuple;
825         if((last_ret = pcmcia_parse_tuple(handle, &tuple, &parse)) != 0) goto cs_failed;
826         link->conf.ConfigBase = parse.config.base;
827         link->conf.Present = parse.config.rmask[0];
828
829         /* Configure card */
830         link->state |= DEV_CONFIG;
831
832         /* Look up the current Vcc */
833         last_fn = GetConfigurationInfo;
834         if((last_ret = pcmcia_get_configuration_info(handle, &conf)) != 0) goto cs_failed;
835         link->conf.Vcc = conf.Vcc;
836
837         /*
838         In this loop, we scan the CIS for configuration table entries,
839         each of which describes a valid card configuration, including
840         voltage, IO window, memory window, and interrupt settings.
841
842         We make no assumptions about the card to be configured: we use
843         just the information available in the CIS.  In an ideal world,
844         this would work for any PCMCIA card, but it requires a complete
845         and accurate CIS.  In practice, a driver usually "knows" most of
846         these things without consulting the CIS, and most client drivers
847         will only use the CIS to fill in implementation-defined details.
848         */
849         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
850         last_fn = GetFirstTuple;
851         if((last_ret = pcmcia_get_first_tuple(handle, &tuple)) != 0) goto cs_failed;
852         while (1) {
853         cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
854         if(pcmcia_get_tuple_data(handle, &tuple)) goto next_entry;
855         if(pcmcia_parse_tuple(handle, &tuple, &parse)) goto next_entry;
856
857         if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
858         if (cfg->index == 0) goto next_entry;
859         link->conf.ConfigIndex = cfg->index;
860
861         /* Does this card need audio output? */
862 /*      if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
863                 link->conf.Attributes |= CONF_ENABLE_SPKR;
864                 link->conf.Status = CCSR_AUDIO_ENA;
865         }
866 */
867         /* Use power settings for Vcc and Vpp if present */
868         /*  Note that the CIS values need to be rescaled */
869         if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
870                 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
871                 goto next_entry;
872         } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
873                 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
874                 goto next_entry;
875         }
876
877         if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
878                 link->conf.Vpp1 = link->conf.Vpp2 =
879                 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
880         else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
881                 link->conf.Vpp1 = link->conf.Vpp2 =
882                 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
883
884         /* Do we need to allocate an interrupt? */
885         if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
886                 link->conf.Attributes |= CONF_ENABLE_IRQ;
887
888         /* IO window settings */
889         link->io.NumPorts1 = link->io.NumPorts2 = 0;
890         if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
891                 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
892                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
893                 if (!(io->flags & CISTPL_IO_8BIT))
894                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
895                 if (!(io->flags & CISTPL_IO_16BIT))
896                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
897                 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
898                 link->io.BasePort1 = io->win[0].base;
899                 link->io.NumPorts1 = io->win[0].len;
900                 if (io->nwin > 1) {
901                 link->io.Attributes2 = link->io.Attributes1;
902                 link->io.BasePort2 = io->win[1].base;
903                 link->io.NumPorts2 = io->win[1].len;
904                 }
905                 /* This reserves IO space but doesn't actually enable it */
906                 if(pcmcia_request_io(link->handle, &link->io)) goto next_entry;
907         }
908
909         /* If we got this far, we're cool! */
910         break;
911
912         next_entry:
913         if (link->io.NumPorts1)
914                 pcmcia_release_io(link->handle, &link->io);
915         last_fn = GetNextTuple;
916         if((last_ret = pcmcia_get_next_tuple(handle, &tuple)) != 0) goto cs_failed;
917         }
918
919         /*
920                 Allocate an interrupt line.  Note that this does not assign a
921                 handler to the interrupt, unless the 'Handler' member of the
922                 irq structure is initialized.
923         */
924         if (link->conf.Attributes & CONF_ENABLE_IRQ)
925         {
926                 last_fn = RequestIRQ;
927                 if((last_ret = pcmcia_request_irq(link->handle, &link->irq)) != 0) goto cs_failed;
928         }
929         /*
930                 This actually configures the PCMCIA socket -- setting up
931                 the I/O windows and the interrupt mapping, and putting the
932                 card and host interface into "Memory and IO" mode.
933         */
934         last_fn = RequestConfiguration;
935         if((last_ret = pcmcia_request_configuration(link->handle, &link->conf)) != 0) goto cs_failed;
936
937         /*
938                 At this point, the dev_node_t structure(s) need to be
939                 initialized and arranged in a linked list at link->dev.
940         */
941         sprintf(dev->node.dev_name, "cb_das16_cs");
942         dev->node.major = dev->node.minor = 0;
943         link->dev = &dev->node;
944
945         /* Finally, report what we've done */
946         printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
947                 dev->node.dev_name, link->conf.ConfigIndex,
948                 link->conf.Vcc/10, link->conf.Vcc%10);
949         if (link->conf.Vpp1)
950         printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
951         if (link->conf.Attributes & CONF_ENABLE_IRQ)
952         printk(", irq %u", link->irq.AssignedIRQ);
953         if (link->io.NumPorts1)
954         printk(", io 0x%04x-0x%04x", link->io.BasePort1,
955                         link->io.BasePort1+link->io.NumPorts1-1);
956         if (link->io.NumPorts2)
957         printk(" & 0x%04x-0x%04x", link->io.BasePort2,
958                         link->io.BasePort2+link->io.NumPorts2-1);
959         printk("\n");
960
961         link->state &= ~DEV_CONFIG_PENDING;
962         return;
963
964 cs_failed:
965         cs_error(link->handle, last_fn, last_ret);
966         das16cs_pcmcia_release((u_long)link);
967
968 } /* das16cs_pcmcia_config */
969
970 /*======================================================================
971
972     After a card is removed, das16cs_pcmcia_release() will unregister the
973     device, and release the PCMCIA configuration.  If the device is
974     still open, this will be postponed until it is closed.
975
976 ======================================================================*/
977
978 static void das16cs_pcmcia_release(u_long arg)
979 {
980         dev_link_t *link = (dev_link_t *)arg;
981
982         DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link);
983
984         /* Unlink the device chain */
985         link->dev = NULL;
986
987     /*
988       In a normal driver, additional code may be needed to release
989       other kernel data structures associated with this device.
990     */
991
992     /* Don't bother checking to see if these succeed or not */
993         pcmcia_release_configuration(link->handle);
994         if (link->io.NumPorts1)
995                 pcmcia_release_io(link->handle, &link->io);
996         if (link->irq.AssignedIRQ)
997                 pcmcia_release_irq(link->handle, &link->irq);
998         link->state &= ~DEV_CONFIG;
999 } /* das16cs_pcmcia_release */
1000
1001 static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev)
1002 {
1003         dev_link_t *link = dev_to_instance(p_dev);
1004         local_info_t *local = link->priv;
1005
1006         link->state |= DEV_SUSPEND;
1007         /* Mark the device as stopped, to block IO until later */
1008         local->stop = 1;
1009         if (link->state & DEV_CONFIG)
1010                 pcmcia_release_configuration(link->handle);
1011
1012         return 0;
1013 } /* das16cs_pcmcia_suspend */
1014
1015 static int das16cs_pcmcia_resume(struct pcmcia_device *p_dev)
1016 {
1017         dev_link_t *link = dev_to_instance(p_dev);
1018         local_info_t *local = link->priv;
1019
1020         link->state &= ~DEV_SUSPEND;
1021         if (link->state & DEV_CONFIG)
1022                 pcmcia_request_configuration(link->handle, &link->conf);
1023         local->stop = 0;
1024         return 0;
1025 } /* das16cs_pcmcia_resume */
1026
1027 /*====================================================================*/
1028
1029 static struct pcmcia_device_id das16cs_id_table[] =
1030 {
1031         PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039),
1032         PCMCIA_DEVICE_NULL
1033 };
1034 MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table);
1035
1036 struct pcmcia_driver das16cs_driver =
1037 {
1038         .probe = das16cs_pcmcia_attach,
1039         .remove = das16cs_pcmcia_detach,
1040         .suspend = das16cs_pcmcia_suspend,
1041         .resume = das16cs_pcmcia_resume,
1042         .id_table = das16cs_id_table,
1043         .owner = THIS_MODULE,
1044         .drv = {
1045                 .name = dev_info,
1046         },
1047 };
1048
1049 static int __init init_das16cs_pcmcia_cs(void)
1050 {
1051         DEBUG(0, "%s\n", version);
1052         pcmcia_register_driver(&das16cs_driver);
1053         return 0;
1054 }
1055
1056 static void __exit exit_das16cs_pcmcia_cs(void)
1057 {
1058         DEBUG(0, "das16cs_pcmcia_cs: unloading\n");
1059         pcmcia_unregister_driver(&das16cs_driver);
1060         while (dev_list != NULL)
1061         {
1062                 if (dev_list->state & DEV_CONFIG)
1063                         das16cs_pcmcia_release((u_long)dev_list);
1064                 das16cs_pcmcia_detach(dev_list->handle);
1065         }
1066 }
1067
1068 int __init init_module(void)
1069 {
1070         int ret;
1071
1072         ret = init_das16cs_pcmcia_cs();
1073         if(ret < 0)
1074                 return ret;
1075
1076         return comedi_driver_register(&driver_das16cs);
1077 }
1078
1079 void __exit cleanup_module(void)
1080 {
1081         exit_das16cs_pcmcia_cs();
1082         comedi_driver_unregister(&driver_das16cs);
1083 }
1084
1085 #else
1086 COMEDI_INITCLEANUP(driver_das16cs);
1087 #endif //CONFIG_PCMCIA