3 Hardware driver for Winsystems PCM-A/D12 and PCM-A/D16
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000,2001 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: Winsystems PCM-A/D12, PCM-A/D16
27 Devices: [Winsystems] PCM-A/D12 (pcmad12), PCM-A/D16 (pcmad16)
30 This driver was written on a bet that I couldn't write a driver
31 in less than 2 hours. I won the bet, but never got paid. =(
33 Configuration options:
36 [2] - Analog input reference
39 [3] - Analog input encoding (must match jumpers)
44 #include <linux/interrupt.h>
45 #include "../comedidev.h"
47 #include <linux/ioport.h>
51 #define PCMAD_STATUS 0
54 #define PCMAD_CONVERT 1
56 struct pcmad_board_struct
{
60 static const struct pcmad_board_struct pcmad_boards
[] = {
71 #define this_board ((const struct pcmad_board_struct *)(dev->board_ptr))
72 #define n_pcmad_boards ARRAY_SIZE(pcmad_boards)
74 struct pcmad_priv_struct
{
78 #define devpriv ((struct pcmad_priv_struct *)dev->private)
80 static int pcmad_attach(struct comedi_device
*dev
, struct comedi_devconfig
*it
);
81 static int pcmad_detach(struct comedi_device
*dev
);
82 static struct comedi_driver driver_pcmad
= {
83 .driver_name
= "pcmad",
84 .module
= THIS_MODULE
,
85 .attach
= pcmad_attach
,
86 .detach
= pcmad_detach
,
87 .board_name
= &pcmad_boards
[0].name
,
88 .num_names
= n_pcmad_boards
,
89 .offset
= sizeof(pcmad_boards
[0]),
92 static int __init
driver_pcmad_init_module(void)
94 return comedi_driver_register(&driver_pcmad
);
97 static void __exit
driver_pcmad_cleanup_module(void)
99 comedi_driver_unregister(&driver_pcmad
);
102 module_init(driver_pcmad_init_module
);
103 module_exit(driver_pcmad_cleanup_module
);
107 static int pcmad_ai_insn_read(struct comedi_device
*dev
,
108 struct comedi_subdevice
*s
,
109 struct comedi_insn
*insn
, unsigned int *data
)
115 chan
= CR_CHAN(insn
->chanspec
);
117 for (n
= 0; n
< insn
->n
; n
++) {
118 outb(chan
, dev
->iobase
+ PCMAD_CONVERT
);
120 for (i
= 0; i
< TIMEOUT
; i
++) {
121 if ((inb(dev
->iobase
+ PCMAD_STATUS
) & 0x3) == 0x3)
124 data
[n
] = inb(dev
->iobase
+ PCMAD_LSB
);
125 data
[n
] |= (inb(dev
->iobase
+ PCMAD_MSB
) << 8);
127 if (devpriv
->twos_comp
)
128 data
[n
] ^= (1 << (this_board
->n_ai_bits
- 1));
138 * 2 0=single ended 1=differential
139 * 3 0=straight binary 1=two's comp
141 static int pcmad_attach(struct comedi_device
*dev
, struct comedi_devconfig
*it
)
144 struct comedi_subdevice
*s
;
145 unsigned long iobase
;
147 iobase
= it
->options
[0];
148 printk(KERN_INFO
"comedi%d: pcmad: 0x%04lx ", dev
->minor
, iobase
);
149 if (!request_region(iobase
, PCMAD_SIZE
, "pcmad")) {
150 printk(KERN_CONT
"I/O port conflict\n");
153 printk(KERN_CONT
"\n");
154 dev
->iobase
= iobase
;
156 ret
= alloc_subdevices(dev
, 1);
160 ret
= alloc_private(dev
, sizeof(struct pcmad_priv_struct
));
164 dev
->board_name
= this_board
->name
;
166 s
= dev
->subdevices
+ 0;
167 s
->type
= COMEDI_SUBD_AI
;
168 s
->subdev_flags
= SDF_READABLE
| AREF_GROUND
;
169 s
->n_chan
= 16; /* XXX */
171 s
->insn_read
= pcmad_ai_insn_read
;
172 s
->maxdata
= (1 << this_board
->n_ai_bits
) - 1;
173 s
->range_table
= &range_unknown
;
178 static int pcmad_detach(struct comedi_device
*dev
)
180 printk(KERN_INFO
"comedi%d: pcmad: remove\n", dev
->minor
);
183 free_irq(dev
->irq
, dev
);
186 release_region(dev
->iobase
, PCMAD_SIZE
);
191 MODULE_AUTHOR("Comedi http://www.comedi.org");
192 MODULE_DESCRIPTION("Comedi low-level driver");
193 MODULE_LICENSE("GPL");