2 comedi/drivers/das16cs.c
3 Skeleton code for a Comedi driver
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000, 2001, 2002 David A. Schleef <ds@schleef.org>
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.
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.
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.
25 Description: Computer Boards PC-CARD DAS16/16
26 Devices: [ComputerBoards] PC-CARD DAS16/16 (cb_das16_cs), PC-CARD DAS16/16-AO
28 Updated: Mon, 04 Nov 2002 20:04:21 -0800
34 #include <linux/comedidev.h>
35 #include <linux/delay.h>
36 #include <linux/pci.h>
38 #include <pcmcia/cs_types.h>
39 #include <pcmcia/cs.h>
40 #include <pcmcia/cistpl.h>
41 #include <pcmcia/ds.h>
45 #define DAS16CS_SIZE 18
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
58 typedef struct das16cs_board_struct{
63 static das16cs_board das16cs_boards[] = {
65 device_id: 0x0000, /* unknown */
66 name: "PC-CARD DAS16/16",
71 name: "PC-CARD DAS16/16-AO",
75 #define n_boards (sizeof(das16cs_boards)/sizeof(das16cs_boards[0]))
76 #define thisboard ((das16cs_board *)dev->board_ptr)
81 lsampl_t ao_readback[2];
82 unsigned short status1;
83 unsigned short status2;
85 #define devpriv ((das16cs_private *)dev->private)
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",
92 attach: das16cs_attach,
93 detach: das16cs_detach,
96 static dev_link_t *dev_list = NULL;
98 static comedi_lrange das16cs_ai_range = { 4, {
102 RANGE( -1.25, 1.25 ),
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,
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);
125 static int get_prodid(comedi_device *dev, dev_link_t *link)
127 client_handle_t handle = link->handle;
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]);
145 static das16cs_board *das16cs_probe(comedi_device *dev, dev_link_t *link)
150 id = get_prodid(dev,link);
152 for(i=0;i<n_boards;i++){
153 if(das16cs_boards[i].device_id==id){
154 return das16cs_boards + i;
158 printk("unknown board!\n");
163 static int das16cs_attach(comedi_device *dev,comedi_devconfig *it)
170 printk("comedi%d: cb_das16_cs: ",dev->minor);
172 link = dev_list; /* XXX hack */
173 if(!link)return -EIO;
175 dev->iobase = link->io.BasePort1;
176 printk("I/O base=0x%04lx ",dev->iobase);
178 printk("fingerprint:\n");
180 printk("%04x ",inw(dev->iobase + i));
184 ret = comedi_request_irq(link->irq.AssignedIRQ, das16cs_interrupt,
185 IRQF_SHARED, "cb_das16_cs", dev);
189 dev->irq = link->irq.AssignedIRQ;
190 printk("irq=%u ",dev->irq);
192 dev->board_ptr = das16cs_probe(dev, link);
193 if(!dev->board_ptr)return -EIO;
195 dev->board_name = thisboard->name;
197 if(alloc_private(dev,sizeof(das16cs_private))<0)
200 if(alloc_subdevices(dev, 4)<0)
205 /* analog input subdevice */
206 s->type=COMEDI_SUBD_AI;
207 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
210 s->range_table=&das16cs_ai_range;
212 s->insn_read = das16cs_ai_rinsn;
213 s->do_cmd = das16cs_ai_cmd;
214 s->do_cmdtest = das16cs_ai_cmdtest;
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;
223 s->range_table = &range_bipolar10;
224 s->insn_write = &das16cs_ao_winsn;
225 s->insn_read = &das16cs_ao_rinsn;
229 /* digital i/o subdevice */
231 s->type=COMEDI_SUBD_DIO;
232 s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
235 s->range_table=&range_digital;
236 s->insn_bits = das16cs_dio_insn_bits;
237 s->insn_config = das16cs_dio_insn_config;
239 s->type = COMEDI_SUBD_UNUSED;
243 /* timer subdevice */
245 s->type=COMEDI_SUBD_TIMER;
246 s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
249 s->range_table = &range_unknown;
250 s->insn_read = das16cs_timer_insn_read;
251 s->insn_config = das16cs_timer_insn_config;
253 s->type = COMEDI_SUBD_UNUSED;
256 printk("attached\n");
261 static int das16cs_detach(comedi_device *dev)
263 printk("comedi%d: das16cs: remove\n",dev->minor);
266 comedi_free_irq(dev->irq, dev);
273 static irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG)
275 //comedi_device *dev = d;
280 * "instructions" read/write data in "one-shot" or "software-triggered"
283 static int das16cs_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
290 static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 };
292 chan = CR_CHAN(insn->chanspec);
293 aref = CR_AREF(insn->chanspec);
294 range = CR_RANGE(insn->chanspec);
296 outw(chan, dev->iobase + 2);
298 devpriv->status1 &= ~0xf320;
299 devpriv->status1 |= (aref==AREF_DIFF)?0:0x0020;
300 outw(devpriv->status1, dev->iobase + 4);
302 devpriv->status2 &= ~0xff00;
303 devpriv->status2 |= range_bits[range];
304 outw(devpriv->status2, dev->iobase + 6);
306 for(i=0;i<insn->n;i++){
307 outw(0, dev->iobase);
310 for(to=0;to<TIMEOUT;to++){
311 if(inw(dev->iobase + 4) & 0x0080)break;
314 printk("cb_das16_cs: ai timeout\n");
317 data[i] = (unsigned short)inw(dev->iobase + 0);
323 static int das16cs_ai_cmd(comedi_device *dev,comedi_subdevice *s)
328 static int das16cs_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,
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.
338 * cmdtest returns 1,2,3,4 or 0, depending on which tests
339 * the command passes. */
341 /* step 1: make sure trigger sources are trivially valid */
344 cmd->start_src &= TRIG_NOW;
345 if(!cmd->start_src || tmp!=cmd->start_src)err++;
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++;
351 tmp=cmd->convert_src;
352 cmd->convert_src &= TRIG_TIMER|TRIG_EXT;
353 if(!cmd->convert_src || tmp!=cmd->convert_src)err++;
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++;
360 cmd->stop_src &= TRIG_COUNT|TRIG_NONE;
361 if(!cmd->stop_src || tmp!=cmd->stop_src)err++;
365 /* step 2: make sure trigger sources are unique and mutually compatible */
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++;
377 /* step 3: make sure arguments are trivially compatible */
379 if(cmd->start_arg!=0){
384 #define MAX_SPEED 10000 /* in nanoseconds */
385 #define MIN_SPEED 1000000000 /* in nanoseconds */
387 if(cmd->scan_begin_src==TRIG_TIMER){
388 if(cmd->scan_begin_arg<MAX_SPEED){
389 cmd->scan_begin_arg=MAX_SPEED;
392 if(cmd->scan_begin_arg>MIN_SPEED){
393 cmd->scan_begin_arg=MIN_SPEED;
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;
405 if(cmd->convert_src==TRIG_TIMER){
406 if(cmd->convert_arg<MAX_SPEED){
407 cmd->convert_arg=MAX_SPEED;
410 if(cmd->convert_arg>MIN_SPEED){
411 cmd->convert_arg=MIN_SPEED;
415 /* external trigger */
417 if(cmd->convert_arg>9){
423 if(cmd->scan_end_arg!=cmd->chanlist_len){
424 cmd->scan_end_arg=cmd->chanlist_len;
427 if(cmd->stop_src==TRIG_COUNT){
428 if(cmd->stop_arg>0x00ffffff){
429 cmd->stop_arg=0x00ffffff;
434 if(cmd->stop_arg!=0){
442 /* step 4: fix up any arguments */
444 if(cmd->scan_begin_src==TRIG_TIMER){
445 unsigned int div1, div2;
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++;
452 if(cmd->convert_src==TRIG_TIMER){
453 unsigned int div1, div2;
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;
471 static int das16cs_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
474 int chan = CR_CHAN(insn->chanspec);
475 unsigned short status1;
479 for(i=0;i<insn->n;i++){
480 devpriv->ao_readback[chan] = data[i];
483 outw(devpriv->status1, dev->iobase + 4);
486 status1 = devpriv->status1 & ~0xf;
487 if(chan) status1 |= 0x0001;
488 else status1 |= 0x0008;
490 /* printk("0x%04x\n",status1);*/
491 outw(status1, dev->iobase + 4);
494 for(bit=15;bit>=0;bit--){
495 int b = (d >> bit) & 0x1;
497 /* printk("0x%04x\n",status1 | b | 0x0000);*/
498 outw(status1 | b | 0x0000, dev->iobase + 4);
500 /* printk("0x%04x\n",status1 | b | 0x0004);*/
501 outw(status1 | b | 0x0004, dev->iobase + 4);
504 /* make high both DAC0CS and DAC1CS to load
505 new data and update analog output*/
506 outw(status1 | 0x9, dev->iobase + 4);
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)
517 int chan = CR_CHAN(insn->chanspec);
519 for(i=0;i<insn->n;i++)
520 data[i] = devpriv->ao_readback[chan];
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)
533 if(insn->n!=2)return -EINVAL;
536 s->state &= ~data[0];
537 s->state |= data[0]&data[1];
539 outw(s->state,dev->iobase + 16);
542 /* on return, data[1] contains the value of the digital
543 * input and output lines. */
544 data[1]=inw(dev->iobase + 16);
549 static int das16cs_dio_insn_config(comedi_device *dev,comedi_subdevice *s,
550 comedi_insn *insn,lsampl_t *data)
552 int chan=CR_CHAN(insn->chanspec);
560 case INSN_CONFIG_DIO_OUTPUT:
563 case INSN_CONFIG_DIO_INPUT:
566 case INSN_CONFIG_DIO_QUERY:
567 data[1] = (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
575 devpriv->status2 &= ~0x00c0;
576 devpriv->status2 |= (s->io_bits&0xf0)?0x0080:0;
577 devpriv->status2 |= (s->io_bits&0x0f)?0x0040:0;
579 outw(devpriv->status2,dev->iobase + 6);
584 static int das16cs_timer_insn_read(comedi_device *dev,comedi_subdevice *s,
585 comedi_insn *insn,lsampl_t *data)
590 static int das16cs_timer_insn_config(comedi_device *dev,comedi_subdevice *s,
591 comedi_insn *insn,lsampl_t *data)
601 /*======================================================================
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.
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.
610 ======================================================================*/
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.
619 #if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
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)";
628 #define DEBUG(n, args...)
631 /*====================================================================*/
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);
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.
644 static int das16cs_pcmcia_attach(struct pcmcia_device *);
645 static void das16cs_pcmcia_detach(struct pcmcia_device *);
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.
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
660 static dev_info_t dev_info = "cb_das16_cs";
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.
669 To simplify the data structure handling, we actually include the
670 dev_link_t structure in the device's private data structure.
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.
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.
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.
691 typedef struct local_info_t {
695 struct bus_operations *bus;
698 /*======================================================================
700 das16cs_pcmcia_attach() creates an "instance" of the driver, allocating
701 local data structures for one device. The device is registered
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.
708 ======================================================================*/
710 static int das16cs_pcmcia_attach(struct pcmcia_device *p_dev)
715 DEBUG(0, "das16cs_pcmcia_attach()\n");
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;
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;
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.
736 link->conf.Attributes = 0;
738 link->conf.IntType = INT_MEMORY_AND_IO;
740 link->next = dev_list;
743 link->handle = p_dev;
744 p_dev->instance = link;
745 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
746 das16cs_pcmcia_config(link);
749 } /* das16cs_pcmcia_attach */
751 /*======================================================================
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.
758 ======================================================================*/
760 static void das16cs_pcmcia_detach(struct pcmcia_device *p_dev)
762 dev_link_t *link = dev_to_instance(p_dev);
765 DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
767 /* Locate device structure */
768 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
769 if (*linkp == link) break;
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
779 if (link->state & DEV_CONFIG)
781 ((local_info_t *)link->priv)->stop = 1;
782 das16cs_pcmcia_release((u_long)link);
784 /* Unlink device structure, and free it */
786 /* This points to the parent local_info_t struct */
788 } /* das16cs_pcmcia_detach */
790 /*======================================================================
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.
796 ======================================================================*/
798 static void das16cs_pcmcia_config(dev_link_t *link)
800 client_handle_t handle = link->handle;
801 local_info_t *dev = link->priv;
804 int last_fn, last_ret;
807 cistpl_cftable_entry_t dflt = { 0 };
809 DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);
812 This reads the card's CONFIG tuple to find its configuration
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];
830 link->state |= DEV_CONFIG;
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;
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.
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.
849 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
850 last_fn = GetFirstTuple;
851 if((last_ret = pcmcia_get_first_tuple(handle, &tuple)) != 0) goto cs_failed;
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;
857 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
858 if (cfg->index == 0) goto next_entry;
859 link->conf.ConfigIndex = cfg->index;
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;
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)
872 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
873 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
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;
884 /* Do we need to allocate an interrupt? */
885 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
886 link->conf.Attributes |= CONF_ENABLE_IRQ;
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;
901 link->io.Attributes2 = link->io.Attributes1;
902 link->io.BasePort2 = io->win[1].base;
903 link->io.NumPorts2 = io->win[1].len;
905 /* This reserves IO space but doesn't actually enable it */
906 if(pcmcia_request_io(link->handle, &link->io)) goto next_entry;
909 /* If we got this far, we're cool! */
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;
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.
924 if (link->conf.Attributes & CONF_ENABLE_IRQ)
926 last_fn = RequestIRQ;
927 if((last_ret = pcmcia_request_irq(link->handle, &link->irq)) != 0) goto cs_failed;
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.
934 last_fn = RequestConfiguration;
935 if((last_ret = pcmcia_request_configuration(link->handle, &link->conf)) != 0) goto cs_failed;
938 At this point, the dev_node_t structure(s) need to be
939 initialized and arranged in a linked list at link->dev.
941 sprintf(dev->node.dev_name, "cb_das16_cs");
942 dev->node.major = dev->node.minor = 0;
943 link->dev = &dev->node;
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);
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);
961 link->state &= ~DEV_CONFIG_PENDING;
965 cs_error(link->handle, last_fn, last_ret);
966 das16cs_pcmcia_release((u_long)link);
968 } /* das16cs_pcmcia_config */
970 /*======================================================================
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.
976 ======================================================================*/
978 static void das16cs_pcmcia_release(u_long arg)
980 dev_link_t *link = (dev_link_t *)arg;
982 DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link);
984 /* Unlink the device chain */
988 In a normal driver, additional code may be needed to release
989 other kernel data structures associated with this device.
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 */
1001 static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev)
1003 dev_link_t *link = dev_to_instance(p_dev);
1004 local_info_t *local = link->priv;
1006 link->state |= DEV_SUSPEND;
1007 /* Mark the device as stopped, to block IO until later */
1009 if (link->state & DEV_CONFIG)
1010 pcmcia_release_configuration(link->handle);
1013 } /* das16cs_pcmcia_suspend */
1015 static int das16cs_pcmcia_resume(struct pcmcia_device *p_dev)
1017 dev_link_t *link = dev_to_instance(p_dev);
1018 local_info_t *local = link->priv;
1020 link->state &= ~DEV_SUSPEND;
1021 if (link->state & DEV_CONFIG)
1022 pcmcia_request_configuration(link->handle, &link->conf);
1025 } /* das16cs_pcmcia_resume */
1027 /*====================================================================*/
1029 static struct pcmcia_device_id das16cs_id_table[] =
1031 PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039),
1034 MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table);
1036 struct pcmcia_driver das16cs_driver =
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,
1049 static int __init init_das16cs_pcmcia_cs(void)
1051 DEBUG(0, "%s\n", version);
1052 pcmcia_register_driver(&das16cs_driver);
1056 static void __exit exit_das16cs_pcmcia_cs(void)
1058 DEBUG(0, "das16cs_pcmcia_cs: unloading\n");
1059 pcmcia_unregister_driver(&das16cs_driver);
1060 while (dev_list != NULL)
1062 if (dev_list->state & DEV_CONFIG)
1063 das16cs_pcmcia_release((u_long)dev_list);
1064 das16cs_pcmcia_detach(dev_list->handle);
1068 int __init init_module(void)
1072 ret = init_das16cs_pcmcia_cs();
1076 return comedi_driver_register(&driver_das16cs);
1079 void __exit cleanup_module(void)
1081 exit_das16cs_pcmcia_cs();
1082 comedi_driver_unregister(&driver_das16cs);
1086 COMEDI_INITCLEANUP(driver_das16cs);
1087 #endif //CONFIG_PCMCIA