2
comedi/drivers/amplc_pci224.c
3
Driver for Amplicon PCI224 and PCI234 AO boards.
5
Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
7
COMEDI - Linux Control and Measurement Device Interface
8
Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation; either version 2 of the License, or
13
(at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
Description: Amplicon PCI224, PCI234
28
Author: Ian Abbott <abbotti@mev.co.uk>
29
Devices: [Amplicon] PCI224 (amplc_pci224 or pci224),
30
PCI234 (amplc_pci224 or pci234)
31
Updated: Wed, 22 Oct 2008 12:25:08 +0100
32
Status: works, but see caveats
37
- ao_do_cmd mode with the following sources:
39
- start_src TRIG_INT TRIG_EXT
40
- scan_begin_src TRIG_TIMER TRIG_EXT
41
- convert_src TRIG_NOW
42
- scan_end_src TRIG_COUNT
43
- stop_src TRIG_COUNT TRIG_EXT TRIG_NONE
45
The channel list must contain at least one channel with no repeated
46
channels. The scan end count must equal the number of channels in
49
There is only one external trigger source so only one of start_src,
50
scan_begin_src or stop_src may use TRIG_EXT.
52
Configuration options - PCI224:
53
[0] - PCI bus of device (optional).
54
[1] - PCI slot of device (optional).
55
If bus/slot is not specified, the first available PCI device
57
[2] - Select available ranges according to jumper LK1. All channels
58
are set to the same range:
59
0=Jumper position 1-2 (factory default), 4 software-selectable
60
internal voltage references, giving 4 bipolar and 4 unipolar
62
[-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V],
63
[0,+10V], [0,+5V], [0,+2.5V], [0,1.25V].
64
1=Jumper position 2-3, 1 external voltage reference, giving
65
1 bipolar and 1 unipolar range:
66
[-Vext,+Vext], [0,+Vext].
68
Configuration options - PCI234:
69
[0] - PCI bus of device (optional).
70
[1] - PCI slot of device (optional).
71
If bus/slot is not specified, the first available PCI device
73
[2] - Select internal or external voltage reference according to
74
jumper LK1. This affects all channels:
75
0=Jumper position 1-2 (factory default), Vref=5V internal.
76
1=Jumper position 2-3, Vref=Vext external.
77
[3] - Select channel 0 range according to jumper LK2:
78
0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref]
79
(10V bipolar when options[2]=0).
80
1=Jumper position 1-2, range [-Vref,+Vref]
81
(5V bipolar when options[2]=0).
82
[4] - Select channel 1 range according to jumper LK3: cf. options[3].
83
[5] - Select channel 2 range according to jumper LK4: cf. options[3].
84
[6] - Select channel 3 range according to jumper LK5: cf. options[3].
86
Passing a zero for an option is the same as leaving it unspecified.
90
1) All channels on the PCI224 share the same range. Any change to the
91
range as a result of insn_write or a streaming command will affect
92
the output voltages of all channels, including those not specified
93
by the instruction or command.
95
2) For the analog output command, the first scan may be triggered
96
falsely at the start of acquisition. This occurs when the DAC scan
97
trigger source is switched from 'none' to 'timer' (scan_begin_src =
98
TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
99
of acquisition and the trigger source is at logic level 1 at the
100
time of the switch. This is very likely for TRIG_TIMER. For
101
TRIG_EXT, it depends on the state of the external line and whether
102
the CR_INVERT flag has been set. The remaining scans are triggered
106
#include <linux/interrupt.h>
107
#include <linux/slab.h>
109
#include "../comedidev.h"
111
#include "comedi_pci.h"
113
#include "comedi_fc.h"
116
#define DRIVER_NAME "amplc_pci224"
121
#define PCI_VENDOR_ID_AMPLICON 0x14dc
122
#define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
123
#define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
124
#define PCI_DEVICE_ID_INVALID 0xffff
127
* PCI224/234 i/o space 1 (PCIBAR2) registers.
129
#define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
130
#define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
131
#define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
132
#define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
133
#define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
134
#define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
135
#define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
136
#define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
137
/* /Interrupt status */
140
* PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
142
#define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
143
#define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
144
#define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
145
#define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
146
#define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
147
#define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
152
/* (r/w) Scan trigger. */
153
#define PCI224_DACCON_TRIG_MASK (7 << 0)
154
#define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
155
#define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
156
#define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
157
#define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
158
#define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
159
#define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
160
#define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
161
/* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
162
#define PCI224_DACCON_POLAR_MASK (1 << 3)
163
#define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
164
#define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
165
/* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
166
#define PCI224_DACCON_VREF_MASK (3 << 4)
167
#define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
168
#define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
169
#define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
170
#define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
171
/* (r/w) Wraparound mode enable (to play back stored waveform). */
172
#define PCI224_DACCON_FIFOWRAP (1 << 7)
173
/* (r/w) FIFO enable. It MUST be set! */
174
#define PCI224_DACCON_FIFOENAB (1 << 8)
175
/* (r/w) FIFO interrupt trigger level (most values are not very useful). */
176
#define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
177
#define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
178
#define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
179
#define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
180
#define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
181
#define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
182
#define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
183
/* (r-o) FIFO fill level. */
184
#define PCI224_DACCON_FIFOFL_MASK (7 << 12)
185
#define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
186
#define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
187
#define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
188
#define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
189
/* (r-o) DAC busy flag. */
190
#define PCI224_DACCON_BUSY (1 << 15)
191
/* (w-o) FIFO reset. */
192
#define PCI224_DACCON_FIFORESET (1 << 12)
193
/* (w-o) Global reset (not sure what it does). */
194
#define PCI224_DACCON_GLOBALRESET (1 << 13)
199
#define PCI224_FIFO_SIZE 4096
202
* DAC FIFO guaranteed minimum room available, depending on reported fill level.
203
* The maximum room available depends on the reported fill level and how much
206
#define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
207
#define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
208
#define PCI224_FIFO_ROOM_HALFTOFULL 1
209
#define PCI224_FIFO_ROOM_FULL 0
212
* Counter/timer clock input configuration sources.
214
#define CLK_CLK 0 /* reserved (channel-specific clock) */
215
#define CLK_10MHZ 1 /* internal 10 MHz clock */
216
#define CLK_1MHZ 2 /* internal 1 MHz clock */
217
#define CLK_100KHZ 3 /* internal 100 kHz clock */
218
#define CLK_10KHZ 4 /* internal 10 kHz clock */
219
#define CLK_1KHZ 5 /* internal 1 kHz clock */
220
#define CLK_OUTNM1 6 /* output of channel-1 modulo total */
221
#define CLK_EXT 7 /* external clock */
222
/* Macro to construct clock input configuration register value. */
223
#define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
224
/* Timebases in ns. */
225
#define TIMEBASE_10MHZ 100
226
#define TIMEBASE_1MHZ 1000
227
#define TIMEBASE_100KHZ 10000
228
#define TIMEBASE_10KHZ 100000
229
#define TIMEBASE_1KHZ 1000000
232
* Counter/timer gate input configuration sources.
234
#define GAT_VCC 0 /* VCC (i.e. enabled) */
235
#define GAT_GND 1 /* GND (i.e. disabled) */
236
#define GAT_EXT 2 /* reserved (external gate input) */
237
#define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
238
/* Macro to construct gate input configuration register value. */
239
#define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
242
* Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
244
* Channel's Channel's
245
* clock input gate input
246
* Channel CLK_OUTNM1 GAT_NOUTNM2
247
* ------- ---------- -----------
248
* Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
249
* Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
250
* Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
254
* Interrupt enable/status bits
256
#define PCI224_INTR_EXT 0x01 /* rising edge on external input */
257
#define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
258
#define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
260
#define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
261
#define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
267
/* Combine old and new bits. */
268
#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
270
/* A generic null function pointer value. */
273
/* Current CPU. XXX should this be hard_smp_processor_id()? */
274
#define THISCPU smp_processor_id()
276
/* State bits for use with atomic bit operations. */
277
#define AO_CMD_STARTED 0
283
/* The software selectable internal ranges for PCI224 (option[2] == 0). */
284
static const struct comedi_lrange range_pci224_internal = {
298
static const unsigned short hwrange_pci224_internal[8] = {
299
PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
300
PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
301
PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
302
PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
303
PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
304
PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
305
PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
306
PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
309
/* The software selectable external ranges for PCI224 (option[2] == 1). */
310
static const struct comedi_lrange range_pci224_external = {
313
RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
314
RANGE_ext(0, 1), /* unipolar [0,+Vref] */
318
static const unsigned short hwrange_pci224_external[2] = {
319
PCI224_DACCON_POLAR_BI,
320
PCI224_DACCON_POLAR_UNI,
323
/* The hardware selectable Vref*2 external range for PCI234
324
* (option[2] == 1, option[3+n] == 0). */
325
static const struct comedi_lrange range_pci234_ext2 = {
332
/* The hardware selectable Vref external range for PCI234
333
* (option[2] == 1, option[3+n] == 1). */
334
static const struct comedi_lrange range_pci234_ext = {
341
/* This serves for all the PCI234 ranges. */
342
static const unsigned short hwrange_pci234[1] = {
343
PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
347
* Board descriptions.
350
enum pci224_model { any_model, pci224_model, pci234_model };
352
struct pci224_board {
354
unsigned short devid;
355
enum pci224_model model;
356
unsigned int ao_chans;
357
unsigned int ao_bits;
360
static const struct pci224_board pci224_boards[] = {
363
.devid = PCI_DEVICE_ID_AMPLICON_PCI224,
364
.model = pci224_model,
370
.devid = PCI_DEVICE_ID_AMPLICON_PCI234,
371
.model = pci234_model,
377
.devid = PCI_DEVICE_ID_INVALID,
378
.model = any_model, /* wildcard */
386
static DEFINE_PCI_DEVICE_TABLE(pci224_pci_table) = {
388
PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
389
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
390
PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
391
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
395
MODULE_DEVICE_TABLE(pci, pci224_pci_table);
398
* Useful for shorthand access to the particular board structure
400
#define thisboard ((struct pci224_board *)dev->board_ptr)
402
/* this structure is for data unique to this hardware driver. If
403
several hardware drivers keep similar information in this structure,
404
feel free to suggest moving the variable to the struct comedi_device struct. */
405
struct pci224_private {
406
struct pci_dev *pci_dev; /* PCI device */
407
const unsigned short *hwrange;
408
unsigned long iobase1;
410
spinlock_t ao_spinlock;
411
unsigned int *ao_readback;
413
unsigned char *ao_scan_order;
416
unsigned short daccon;
417
unsigned int cached_div1;
418
unsigned int cached_div2;
419
unsigned int ao_stop_count;
420
short ao_stop_continuous;
421
unsigned short ao_enab; /* max 16 channels so 'short' will do */
422
unsigned char intsce;
425
#define devpriv ((struct pci224_private *)dev->private)
428
* The struct comedi_driver structure tells the Comedi core module
429
* which functions to call to configure/deconfigure (attach/detach)
430
* the board, and also about the kernel module that contains
433
static int pci224_attach(struct comedi_device *dev,
434
struct comedi_devconfig *it);
435
static int pci224_detach(struct comedi_device *dev);
436
static struct comedi_driver driver_amplc_pci224 = {
437
.driver_name = DRIVER_NAME,
438
.module = THIS_MODULE,
439
.attach = pci224_attach,
440
.detach = pci224_detach,
441
.board_name = &pci224_boards[0].name,
442
.offset = sizeof(struct pci224_board),
443
.num_names = ARRAY_SIZE(pci224_boards),
446
static int __devinit driver_amplc_pci224_pci_probe(struct pci_dev *dev,
447
const struct pci_device_id
450
return comedi_pci_auto_config(dev, driver_amplc_pci224.driver_name);
453
static void __devexit driver_amplc_pci224_pci_remove(struct pci_dev *dev)
455
comedi_pci_auto_unconfig(dev);
458
static struct pci_driver driver_amplc_pci224_pci_driver = {
459
.id_table = pci224_pci_table,
460
.probe = &driver_amplc_pci224_pci_probe,
461
.remove = __devexit_p(&driver_amplc_pci224_pci_remove)
464
static int __init driver_amplc_pci224_init_module(void)
468
retval = comedi_driver_register(&driver_amplc_pci224);
472
driver_amplc_pci224_pci_driver.name =
473
(char *)driver_amplc_pci224.driver_name;
474
return pci_register_driver(&driver_amplc_pci224_pci_driver);
477
static void __exit driver_amplc_pci224_cleanup_module(void)
479
pci_unregister_driver(&driver_amplc_pci224_pci_driver);
480
comedi_driver_unregister(&driver_amplc_pci224);
483
module_init(driver_amplc_pci224_init_module);
484
module_exit(driver_amplc_pci224_cleanup_module);
487
* Called from the 'insn_write' function to perform a single write.
490
pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
493
unsigned short mangled;
495
/* Store unmangled data for readback. */
496
devpriv->ao_readback[chan] = data;
497
/* Enable the channel. */
498
outw(1 << chan, dev->iobase + PCI224_DACCEN);
499
/* Set range and reset FIFO. */
500
devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
501
(PCI224_DACCON_POLAR_MASK |
502
PCI224_DACCON_VREF_MASK));
503
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
504
dev->iobase + PCI224_DACCON);
506
* Mangle the data. The hardware expects:
507
* - bipolar: 16-bit 2's complement
508
* - unipolar: 16-bit unsigned
510
mangled = (unsigned short)data << (16 - thisboard->ao_bits);
511
if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
512
PCI224_DACCON_POLAR_BI) {
515
/* Write mangled data to the FIFO. */
516
outw(mangled, dev->iobase + PCI224_DACDATA);
517
/* Trigger the conversion. */
518
inw(dev->iobase + PCI224_SOFTTRIG);
522
* 'insn_write' function for AO subdevice.
525
pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
526
struct comedi_insn *insn, unsigned int *data)
531
/* Unpack channel and range. */
532
chan = CR_CHAN(insn->chanspec);
533
range = CR_RANGE(insn->chanspec);
535
/* Writing a list of values to an AO channel is probably not
536
* very useful, but that's how the interface is defined. */
537
for (i = 0; i < insn->n; i++)
538
pci224_ao_set_data(dev, chan, range, data[i]);
544
* 'insn_read' function for AO subdevice.
546
* N.B. The value read will not be valid if the DAC channel has
547
* never been written successfully since the device was attached
548
* or since the channel has been used by an AO streaming write
552
pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
553
struct comedi_insn *insn, unsigned int *data)
558
chan = CR_CHAN(insn->chanspec);
560
for (i = 0; i < insn->n; i++)
561
data[i] = devpriv->ao_readback[chan];
568
* Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
571
pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
572
unsigned int *nanosec, int round_mode)
574
i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
578
* Kills a command running on the AO subdevice.
580
static void pci224_ao_stop(struct comedi_device *dev,
581
struct comedi_subdevice *s)
585
if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state))
589
spin_lock_irqsave(&devpriv->ao_spinlock, flags);
590
/* Kill the interrupts. */
592
outb(0, devpriv->iobase1 + PCI224_INT_SCE);
594
* Interrupt routine may or may not be running. We may or may not
595
* have been called from the interrupt routine (directly or
596
* indirectly via a comedi_events() callback routine). It's highly
597
* unlikely that we've been called from some other interrupt routine
598
* but who knows what strange things coders get up to!
600
* If the interrupt routine is currently running, wait for it to
601
* finish, unless we appear to have been called via the interrupt
604
while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
605
spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
606
spin_lock_irqsave(&devpriv->ao_spinlock, flags);
608
spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
609
/* Reconfigure DAC for insn_write usage. */
610
outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
611
devpriv->daccon = COMBINE(devpriv->daccon,
612
PCI224_DACCON_TRIG_SW |
613
PCI224_DACCON_FIFOINTR_EMPTY,
614
PCI224_DACCON_TRIG_MASK |
615
PCI224_DACCON_FIFOINTR_MASK);
616
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
617
dev->iobase + PCI224_DACCON);
621
* Handles start of acquisition for the AO subdevice.
623
static void pci224_ao_start(struct comedi_device *dev,
624
struct comedi_subdevice *s)
626
struct comedi_cmd *cmd = &s->async->cmd;
629
set_bit(AO_CMD_STARTED, &devpriv->state);
630
if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
631
/* An empty acquisition! */
632
pci224_ao_stop(dev, s);
633
s->async->events |= COMEDI_CB_EOA;
634
comedi_event(dev, s);
636
/* Enable interrupts. */
637
spin_lock_irqsave(&devpriv->ao_spinlock, flags);
638
if (cmd->stop_src == TRIG_EXT)
639
devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
641
devpriv->intsce = PCI224_INTR_DAC;
643
outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
644
spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
649
* Handles interrupts from the DAC FIFO.
651
static void pci224_ao_handle_fifo(struct comedi_device *dev,
652
struct comedi_subdevice *s)
654
struct comedi_cmd *cmd = &s->async->cmd;
655
unsigned int num_scans;
657
unsigned short dacstat;
659
unsigned int bytes_per_scan;
661
if (cmd->chanlist_len) {
662
bytes_per_scan = cmd->chanlist_len * sizeof(short);
664
/* Shouldn't get here! */
665
bytes_per_scan = sizeof(short);
667
/* Determine number of scans available in buffer. */
668
num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
669
if (!devpriv->ao_stop_continuous) {
670
/* Fixed number of scans. */
671
if (num_scans > devpriv->ao_stop_count)
672
num_scans = devpriv->ao_stop_count;
676
/* Determine how much room is in the FIFO (in samples). */
677
dacstat = inw(dev->iobase + PCI224_DACCON);
678
switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
679
case PCI224_DACCON_FIFOFL_EMPTY:
680
room = PCI224_FIFO_ROOM_EMPTY;
681
if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
682
/* FIFO empty at end of counted acquisition. */
683
pci224_ao_stop(dev, s);
684
s->async->events |= COMEDI_CB_EOA;
685
comedi_event(dev, s);
689
case PCI224_DACCON_FIFOFL_ONETOHALF:
690
room = PCI224_FIFO_ROOM_ONETOHALF;
692
case PCI224_DACCON_FIFOFL_HALFTOFULL:
693
room = PCI224_FIFO_ROOM_HALFTOFULL;
696
room = PCI224_FIFO_ROOM_FULL;
699
if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
700
/* FIFO is less than half-full. */
701
if (num_scans == 0) {
702
/* Nothing left to put in the FIFO. */
703
pci224_ao_stop(dev, s);
704
s->async->events |= COMEDI_CB_OVERFLOW;
705
printk(KERN_ERR "comedi%d: "
706
"AO buffer underrun\n", dev->minor);
709
/* Determine how many new scans can be put in the FIFO. */
710
if (cmd->chanlist_len)
711
room /= cmd->chanlist_len;
713
/* Determine how many scans to process. */
714
if (num_scans > room)
718
for (n = 0; n < num_scans; n++) {
719
cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
721
for (i = 0; i < cmd->chanlist_len; i++) {
722
outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
723
dev->iobase + PCI224_DACDATA);
726
if (!devpriv->ao_stop_continuous) {
727
devpriv->ao_stop_count -= num_scans;
728
if (devpriv->ao_stop_count == 0) {
730
* Change FIFO interrupt trigger level to wait
731
* until FIFO is empty.
733
devpriv->daccon = COMBINE(devpriv->daccon,
734
PCI224_DACCON_FIFOINTR_EMPTY,
735
PCI224_DACCON_FIFOINTR_MASK);
736
outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
739
if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
740
PCI224_DACCON_TRIG_NONE) {
744
* This is the initial DAC FIFO interrupt at the
745
* start of the acquisition. The DAC's scan trigger
746
* has been set to 'none' up until now.
748
* Now that data has been written to the FIFO, the
749
* DAC's scan trigger source can be set to the
752
* BUG: The first scan will be triggered immediately
753
* if the scan trigger source is at logic level 1.
755
if (cmd->scan_begin_src == TRIG_TIMER) {
756
trig = PCI224_DACCON_TRIG_Z2CT0;
758
/* cmd->scan_begin_src == TRIG_EXT */
759
if (cmd->scan_begin_arg & CR_INVERT)
760
trig = PCI224_DACCON_TRIG_EXTN;
762
trig = PCI224_DACCON_TRIG_EXTP;
765
devpriv->daccon = COMBINE(devpriv->daccon, trig,
766
PCI224_DACCON_TRIG_MASK);
767
outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
769
if (s->async->events)
770
comedi_event(dev, s);
775
* Internal trigger function to start acquisition on AO subdevice.
778
pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
779
unsigned int trignum)
784
s->async->inttrig = NULLFUNC;
785
pci224_ao_start(dev, s);
790
#define MAX_SCAN_PERIOD 0xFFFFFFFFU
791
#define MIN_SCAN_PERIOD 2500
792
#define CONVERT_PERIOD 625
795
* 'do_cmdtest' function for AO subdevice.
798
pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
799
struct comedi_cmd *cmd)
804
/* Step 1: make sure trigger sources are trivially valid. */
806
tmp = cmd->start_src;
807
cmd->start_src &= TRIG_INT | TRIG_EXT;
808
if (!cmd->start_src || tmp != cmd->start_src)
811
tmp = cmd->scan_begin_src;
812
cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
813
if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
816
tmp = cmd->convert_src;
817
cmd->convert_src &= TRIG_NOW;
818
if (!cmd->convert_src || tmp != cmd->convert_src)
821
tmp = cmd->scan_end_src;
822
cmd->scan_end_src &= TRIG_COUNT;
823
if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
827
cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
828
if (!cmd->stop_src || tmp != cmd->stop_src)
834
/* Step 2: make sure trigger sources are unique and mutually
837
/* these tests are true if more than one _src bit is set */
838
if ((cmd->start_src & (cmd->start_src - 1)) != 0)
840
if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
842
if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
844
if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
846
if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
849
/* There's only one external trigger signal (which makes these
850
* tests easier). Only one thing can use it. */
852
if (cmd->start_src & TRIG_EXT)
854
if (cmd->scan_begin_src & TRIG_EXT)
856
if (cmd->stop_src & TRIG_EXT)
864
/* Step 3: make sure arguments are trivially compatible. */
866
switch (cmd->start_src) {
868
if (cmd->start_arg != 0) {
874
/* Force to external trigger 0. */
875
if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
876
cmd->start_arg = COMBINE(cmd->start_arg, 0,
880
/* The only flag allowed is CR_EDGE, which is ignored. */
881
if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
882
cmd->start_arg = COMBINE(cmd->start_arg, 0,
883
CR_FLAGS_MASK & ~CR_EDGE);
889
switch (cmd->scan_begin_src) {
891
if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
892
cmd->scan_begin_arg = MAX_SCAN_PERIOD;
895
tmp = cmd->chanlist_len * CONVERT_PERIOD;
896
if (tmp < MIN_SCAN_PERIOD)
897
tmp = MIN_SCAN_PERIOD;
899
if (cmd->scan_begin_arg < tmp) {
900
cmd->scan_begin_arg = tmp;
905
/* Force to external trigger 0. */
906
if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
907
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
911
/* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
912
if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
913
~(CR_EDGE | CR_INVERT)) != 0) {
914
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
915
CR_FLAGS_MASK & ~(CR_EDGE
923
/* cmd->convert_src == TRIG_NOW */
924
if (cmd->convert_arg != 0) {
925
cmd->convert_arg = 0;
929
/* cmd->scan_end_arg == TRIG_COUNT */
930
if (cmd->scan_end_arg != cmd->chanlist_len) {
931
cmd->scan_end_arg = cmd->chanlist_len;
935
switch (cmd->stop_src) {
937
/* Any count allowed. */
940
/* Force to external trigger 0. */
941
if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
942
cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
946
/* The only flag allowed is CR_EDGE, which is ignored. */
947
if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
948
cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
949
CR_FLAGS_MASK & ~CR_EDGE);
953
if (cmd->stop_arg != 0) {
963
/* Step 4: fix up any arguments. */
965
if (cmd->scan_begin_src == TRIG_TIMER) {
966
unsigned int div1, div2, round;
967
int round_mode = cmd->flags & TRIG_ROUND_MASK;
969
tmp = cmd->scan_begin_arg;
970
/* Check whether to use a single timer. */
971
switch (round_mode) {
972
case TRIG_ROUND_NEAREST:
974
round = TIMEBASE_10MHZ / 2;
976
case TRIG_ROUND_DOWN:
980
round = TIMEBASE_10MHZ - 1;
983
/* Be careful to avoid overflow! */
984
div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
985
div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
987
if (div2 <= 0x10000) {
988
/* A single timer will suffice. */
991
cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
992
if (cmd->scan_begin_arg < div2 ||
993
cmd->scan_begin_arg < TIMEBASE_10MHZ) {
995
cmd->scan_begin_arg = MAX_SCAN_PERIOD;
998
/* Use two timers. */
999
div1 = devpriv->cached_div1;
1000
div2 = devpriv->cached_div2;
1001
pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1002
&cmd->scan_begin_arg,
1004
devpriv->cached_div1 = div1;
1005
devpriv->cached_div2 = div2;
1007
if (tmp != cmd->scan_begin_arg)
1015
/* Step 5: check channel list. */
1017
if (cmd->chanlist && (cmd->chanlist_len > 0)) {
1019
enum { range_err = 1, dupchan_err = 2, };
1025
* Check all channels have the same range index. Don't care
1026
* about analogue reference, as we can't configure it.
1028
* Check the list has no duplicate channels.
1030
range = CR_RANGE(cmd->chanlist[0]);
1033
for (n = 0; n < cmd->chanlist_len; n++) {
1034
ch = CR_CHAN(cmd->chanlist[n]);
1035
if (tmp & (1U << ch))
1036
errors |= dupchan_err;
1039
if (CR_RANGE(cmd->chanlist[n]) != range)
1040
errors |= range_err;
1044
if (errors & dupchan_err) {
1045
DPRINTK("comedi%d: " DRIVER_NAME
1047
"entries in chanlist must contain no "
1048
"duplicate channels\n", dev->minor);
1050
if (errors & range_err) {
1051
DPRINTK("comedi%d: " DRIVER_NAME
1053
"entries in chanlist must all have "
1054
"the same range index\n", dev->minor);
1067
* 'do_cmd' function for AO subdevice.
1069
static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1071
struct comedi_cmd *cmd = &s->async->cmd;
1076
unsigned long flags;
1078
/* Cannot handle null/empty chanlist. */
1079
if (cmd->chanlist == NULL || cmd->chanlist_len == 0)
1083
/* Determine which channels are enabled and their load order. */
1084
devpriv->ao_enab = 0;
1086
for (i = 0; i < cmd->chanlist_len; i++) {
1087
ch = CR_CHAN(cmd->chanlist[i]);
1088
devpriv->ao_enab |= 1U << ch;
1090
for (j = 0; j < cmd->chanlist_len; j++) {
1091
if (CR_CHAN(cmd->chanlist[j]) < ch)
1095
devpriv->ao_scan_order[rank] = i;
1098
/* Set enabled channels. */
1099
outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
1101
/* Determine range and polarity. All channels the same. */
1102
range = CR_RANGE(cmd->chanlist[0]);
1105
* Set DAC range and polarity.
1106
* Set DAC scan trigger source to 'none'.
1107
* Set DAC FIFO interrupt trigger level to 'not half full'.
1110
* N.B. DAC FIFO interrupts are currently disabled.
1112
devpriv->daccon = COMBINE(devpriv->daccon,
1114
hwrange[range] | PCI224_DACCON_TRIG_NONE |
1115
PCI224_DACCON_FIFOINTR_NHALF),
1116
(PCI224_DACCON_POLAR_MASK |
1117
PCI224_DACCON_VREF_MASK |
1118
PCI224_DACCON_TRIG_MASK |
1119
PCI224_DACCON_FIFOINTR_MASK));
1120
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1121
dev->iobase + PCI224_DACCON);
1123
if (cmd->scan_begin_src == TRIG_TIMER) {
1124
unsigned int div1, div2, round;
1125
unsigned int ns = cmd->scan_begin_arg;
1126
int round_mode = cmd->flags & TRIG_ROUND_MASK;
1128
/* Check whether to use a single timer. */
1129
switch (round_mode) {
1130
case TRIG_ROUND_NEAREST:
1132
round = TIMEBASE_10MHZ / 2;
1134
case TRIG_ROUND_DOWN:
1138
round = TIMEBASE_10MHZ - 1;
1141
/* Be careful to avoid overflow! */
1142
div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
1143
div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
1145
if (div2 <= 0x10000) {
1146
/* A single timer will suffice. */
1150
div1 = 1; /* Flag that single timer to be used. */
1152
/* Use two timers. */
1153
div1 = devpriv->cached_div1;
1154
div2 = devpriv->cached_div2;
1155
pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
1160
* The output of timer Z2-0 will be used as the scan trigger
1163
/* Make sure Z2-0 is gated on. */
1164
outb(GAT_CONFIG(0, GAT_VCC),
1165
devpriv->iobase1 + PCI224_ZGAT_SCE);
1167
/* Not cascading. Z2-0 needs 10 MHz clock. */
1168
outb(CLK_CONFIG(0, CLK_10MHZ),
1169
devpriv->iobase1 + PCI224_ZCLK_SCE);
1171
/* Cascading with Z2-2. */
1172
/* Make sure Z2-2 is gated on. */
1173
outb(GAT_CONFIG(2, GAT_VCC),
1174
devpriv->iobase1 + PCI224_ZGAT_SCE);
1175
/* Z2-2 needs 10 MHz clock. */
1176
outb(CLK_CONFIG(2, CLK_10MHZ),
1177
devpriv->iobase1 + PCI224_ZCLK_SCE);
1178
/* Load Z2-2 mode (2) and counter (div1). */
1179
i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
1181
/* Z2-0 is clocked from Z2-2's output. */
1182
outb(CLK_CONFIG(0, CLK_OUTNM1),
1183
devpriv->iobase1 + PCI224_ZCLK_SCE);
1185
/* Load Z2-0 mode (2) and counter (div2). */
1186
i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
1190
* Sort out end of acquisition.
1192
switch (cmd->stop_src) {
1194
/* Fixed number of scans. */
1195
devpriv->ao_stop_continuous = 0;
1196
devpriv->ao_stop_count = cmd->stop_arg;
1199
/* Continuous scans. */
1200
devpriv->ao_stop_continuous = 1;
1201
devpriv->ao_stop_count = 0;
1206
* Sort out start of acquisition.
1208
switch (cmd->start_src) {
1210
spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1211
s->async->inttrig = &pci224_ao_inttrig_start;
1212
spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1215
/* Enable external interrupt trigger to start acquisition. */
1216
spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1217
devpriv->intsce |= PCI224_INTR_EXT;
1218
outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
1219
spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1227
* 'cancel' function for AO subdevice.
1229
static int pci224_ao_cancel(struct comedi_device *dev,
1230
struct comedi_subdevice *s)
1232
pci224_ao_stop(dev, s);
1237
* 'munge' data for AO command.
1240
pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1241
void *data, unsigned int num_bytes, unsigned int chan_index)
1243
struct comedi_async *async = s->async;
1244
short *array = data;
1245
unsigned int length = num_bytes / sizeof(*array);
1246
unsigned int offset;
1250
/* The hardware expects 16-bit numbers. */
1251
shift = 16 - thisboard->ao_bits;
1252
/* Channels will be all bipolar or all unipolar. */
1253
if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
1254
PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
1261
/* Munge the data. */
1262
for (i = 0; i < length; i++)
1263
array[i] = (array[i] << shift) - offset;
1268
* Interrupt handler.
1270
static irqreturn_t pci224_interrupt(int irq, void *d)
1272
struct comedi_device *dev = d;
1273
struct comedi_subdevice *s = &dev->subdevices[0];
1274
struct comedi_cmd *cmd;
1275
unsigned char intstat, valid_intstat;
1276
unsigned char curenab;
1278
unsigned long flags;
1280
intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
1283
spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1284
valid_intstat = devpriv->intsce & intstat;
1285
/* Temporarily disable interrupt sources. */
1286
curenab = devpriv->intsce & ~intstat;
1287
outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
1288
devpriv->intr_running = 1;
1289
devpriv->intr_cpuid = THISCPU;
1290
spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1291
if (valid_intstat != 0) {
1292
cmd = &s->async->cmd;
1293
if (valid_intstat & PCI224_INTR_EXT) {
1294
devpriv->intsce &= ~PCI224_INTR_EXT;
1295
if (cmd->start_src == TRIG_EXT)
1296
pci224_ao_start(dev, s);
1297
else if (cmd->stop_src == TRIG_EXT)
1298
pci224_ao_stop(dev, s);
1301
if (valid_intstat & PCI224_INTR_DAC)
1302
pci224_ao_handle_fifo(dev, s);
1305
/* Reenable interrupt sources. */
1306
spin_lock_irqsave(&devpriv->ao_spinlock, flags);
1307
if (curenab != devpriv->intsce) {
1308
outb(devpriv->intsce,
1309
devpriv->iobase1 + PCI224_INT_SCE);
1311
devpriv->intr_running = 0;
1312
spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
1314
return IRQ_RETVAL(retval);
1318
* This function looks for a PCI device matching the requested board name,
1322
pci224_find_pci(struct comedi_device *dev, int bus, int slot,
1323
struct pci_dev **pci_dev_p)
1325
struct pci_dev *pci_dev = NULL;
1329
/* Look for matching PCI device. */
1330
for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
1332
pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
1334
/* If bus/slot specified, check them. */
1336
if (bus != pci_dev->bus->number
1337
|| slot != PCI_SLOT(pci_dev->devfn))
1340
if (thisboard->model == any_model) {
1341
/* Match any supported model. */
1344
for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) {
1345
if (pci_dev->device == pci224_boards[i].devid) {
1346
/* Change board_ptr to matched board. */
1347
dev->board_ptr = &pci224_boards[i];
1351
if (i == ARRAY_SIZE(pci224_boards))
1354
/* Match specific model name. */
1355
if (thisboard->devid != pci_dev->device)
1359
/* Found a match. */
1360
*pci_dev_p = pci_dev;
1363
/* No match found. */
1365
printk(KERN_ERR "comedi%d: error! "
1366
"no %s found at pci %02x:%02x!\n",
1367
dev->minor, thisboard->name, bus, slot);
1369
printk(KERN_ERR "comedi%d: error! no %s found!\n",
1370
dev->minor, thisboard->name);
1376
* Attach is called by the Comedi core to configure the driver
1377
* for a particular board. If you specified a board_name array
1378
* in the driver structure, dev->board_ptr contains that
1381
static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1383
struct comedi_subdevice *s;
1384
struct pci_dev *pci_dev;
1386
int bus = 0, slot = 0;
1390
printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME);
1392
bus = it->options[0];
1393
slot = it->options[1];
1394
ret = alloc_private(dev, sizeof(struct pci224_private));
1396
printk(KERN_ERR "comedi%d: error! out of memory!\n",
1401
ret = pci224_find_pci(dev, bus, slot, &pci_dev);
1405
devpriv->pci_dev = pci_dev;
1406
ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
1409
"comedi%d: error! cannot enable PCI device "
1410
"and request regions!\n", dev->minor);
1413
spin_lock_init(&devpriv->ao_spinlock);
1415
devpriv->iobase1 = pci_resource_start(pci_dev, 2);
1416
dev->iobase = pci_resource_start(pci_dev, 3);
1419
/* Allocate readback buffer for AO channels. */
1420
devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
1421
thisboard->ao_chans, GFP_KERNEL);
1422
if (!devpriv->ao_readback)
1426
/* Allocate buffer to hold values for AO channel scan. */
1427
devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
1428
thisboard->ao_chans, GFP_KERNEL);
1429
if (!devpriv->ao_scan_vals)
1433
/* Allocate buffer to hold AO channel scan order. */
1434
devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
1435
thisboard->ao_chans, GFP_KERNEL);
1436
if (!devpriv->ao_scan_order)
1440
/* Disable interrupt sources. */
1441
devpriv->intsce = 0;
1442
outb(0, devpriv->iobase1 + PCI224_INT_SCE);
1444
/* Initialize the DAC hardware. */
1445
outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
1446
outw(0, dev->iobase + PCI224_DACCEN);
1447
outw(0, dev->iobase + PCI224_FIFOSIZ);
1448
devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
1449
PCI224_DACCON_FIFOENAB |
1450
PCI224_DACCON_FIFOINTR_EMPTY);
1451
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
1452
dev->iobase + PCI224_DACCON);
1454
/* Allocate subdevices. There is only one! */
1455
ret = alloc_subdevices(dev, 1);
1457
printk(KERN_ERR "comedi%d: error! out of memory!\n",
1462
s = dev->subdevices + 0;
1463
/* Analog output subdevice. */
1464
s->type = COMEDI_SUBD_AO;
1465
s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
1466
s->n_chan = thisboard->ao_chans;
1467
s->maxdata = (1 << thisboard->ao_bits) - 1;
1468
s->insn_write = &pci224_ao_insn_write;
1469
s->insn_read = &pci224_ao_insn_read;
1470
s->len_chanlist = s->n_chan;
1472
dev->write_subdev = s;
1473
s->do_cmd = &pci224_ao_cmd;
1474
s->do_cmdtest = &pci224_ao_cmdtest;
1475
s->cancel = &pci224_ao_cancel;
1476
s->munge = &pci224_ao_munge;
1478
/* Sort out channel range options. */
1479
if (thisboard->model == pci234_model) {
1480
/* PCI234 range options. */
1481
const struct comedi_lrange **range_table_list;
1483
s->range_table_list = range_table_list =
1484
kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
1486
if (!s->range_table_list)
1489
for (n = 2; n < 3 + s->n_chan; n++) {
1490
if (it->options[n] < 0 || it->options[n] > 1) {
1491
printk(KERN_WARNING "comedi%d: %s: warning! "
1492
"bad options[%u]=%d\n",
1493
dev->minor, DRIVER_NAME, n,
1497
for (n = 0; n < s->n_chan; n++) {
1498
if (n < COMEDI_NDEVCONFOPTS - 3 &&
1499
it->options[3 + n] == 1) {
1500
if (it->options[2] == 1)
1501
range_table_list[n] = &range_pci234_ext;
1503
range_table_list[n] = &range_bipolar5;
1506
if (it->options[2] == 1) {
1507
range_table_list[n] =
1510
range_table_list[n] = &range_bipolar10;
1514
devpriv->hwrange = hwrange_pci234;
1516
/* PCI224 range options. */
1517
if (it->options[2] == 1) {
1518
s->range_table = &range_pci224_external;
1519
devpriv->hwrange = hwrange_pci224_external;
1521
if (it->options[2] != 0) {
1522
printk(KERN_WARNING "comedi%d: %s: warning! "
1523
"bad options[2]=%d\n",
1524
dev->minor, DRIVER_NAME, it->options[2]);
1526
s->range_table = &range_pci224_internal;
1527
devpriv->hwrange = hwrange_pci224_internal;
1531
dev->board_name = thisboard->name;
1534
ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
1537
printk(KERN_ERR "comedi%d: error! "
1538
"unable to allocate irq %u\n", dev->minor, irq);
1545
printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1546
printk("(pci %s) ", pci_name(pci_dev));
1548
printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1550
printk("(no irq) ");
1553
printk("attached\n");
1559
* _detach is called to deconfigure a device. It should deallocate
1561
* This function is also called when _attach() fails, so it should be
1562
* careful not to release resources that were not necessarily
1563
* allocated by _attach(). dev->private and dev->subdevices are
1564
* deallocated automatically by the core.
1566
static int pci224_detach(struct comedi_device *dev)
1568
printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, DRIVER_NAME);
1571
free_irq(dev->irq, dev);
1573
if (dev->subdevices) {
1574
struct comedi_subdevice *s;
1576
s = dev->subdevices + 0;
1578
kfree(s->range_table_list);
1581
kfree(devpriv->ao_readback);
1582
kfree(devpriv->ao_scan_vals);
1583
kfree(devpriv->ao_scan_order);
1584
if (devpriv->pci_dev) {
1586
comedi_pci_disable(devpriv->pci_dev);
1588
pci_dev_put(devpriv->pci_dev);
1591
if (dev->board_name) {
1592
printk(KERN_INFO "comedi%d: %s removed\n",
1593
dev->minor, dev->board_name);
1599
MODULE_AUTHOR("Comedi http://www.comedi.org");
1600
MODULE_DESCRIPTION("Comedi low-level driver");
1601
MODULE_LICENSE("GPL");