2 comedi/drivers/me4000.c
3 Source code for the Meilhaus ME-4000 board family.
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 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: Meilhaus ME-4000 series boards
26 Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i, ME-4680is
27 Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
28 Updated: Mon, 18 Mar 2002 15:34:01 -0800
29 Status: broken (no support for loading firmware)
38 Configuration Options:
40 [0] - PCI bus number (optional)
41 [1] - PCI slot number (optional)
43 If bus/slot is not specified, the first available PCI
46 The firmware required by these boards is available in the
47 comedi_nonfree_firmware tarball available from
48 http://www.comedi.org. However, the driver's support for
49 loading the firmware through comedi_config is currently
54 #include <linux/interrupt.h>
55 #include "../comedidev.h"
57 #include <linux/delay.h>
58 #include <linux/list.h>
59 #include <linux/spinlock.h>
61 #include "comedi_pci.h"
64 /* file removed due to GPL incompatibility */
65 #include "me4000_fw.h"
68 /*=============================================================================
70 This is used by modprobe to translate PCI IDs to drivers.
71 ===========================================================================*/
73 static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table
) = {
75 PCI_VENDOR_ID_MEILHAUS
, 0x4650, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
76 PCI_VENDOR_ID_MEILHAUS
, 0x4660, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
77 PCI_VENDOR_ID_MEILHAUS
, 0x4661, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
78 PCI_VENDOR_ID_MEILHAUS
, 0x4662, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
79 PCI_VENDOR_ID_MEILHAUS
, 0x4663, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
80 PCI_VENDOR_ID_MEILHAUS
, 0x4670, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
81 PCI_VENDOR_ID_MEILHAUS
, 0x4671, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
82 PCI_VENDOR_ID_MEILHAUS
, 0x4672, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
83 PCI_VENDOR_ID_MEILHAUS
, 0x4673, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
84 PCI_VENDOR_ID_MEILHAUS
, 0x4680, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
85 PCI_VENDOR_ID_MEILHAUS
, 0x4681, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
86 PCI_VENDOR_ID_MEILHAUS
, 0x4682, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
87 PCI_VENDOR_ID_MEILHAUS
, 0x4683, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, {
91 MODULE_DEVICE_TABLE(pci
, me4000_pci_table
);
93 static const struct me4000_board me4000_boards
[] = {
94 {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0} },
96 {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3} },
97 {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3} },
98 {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3} },
99 {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3} },
101 {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3} },
102 {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3} },
103 {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3} },
104 {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3} },
106 {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3} },
107 {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3} },
108 {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3} },
109 {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3} },
114 #define ME4000_BOARD_VERSIONS (ARRAY_SIZE(me4000_boards) - 1)
116 /*-----------------------------------------------------------------------------
117 Comedi function prototypes
118 ---------------------------------------------------------------------------*/
119 static int me4000_attach(struct comedi_device
*dev
,
120 struct comedi_devconfig
*it
);
121 static int me4000_detach(struct comedi_device
*dev
);
122 static struct comedi_driver driver_me4000
= {
123 driver_name
: "me4000",
124 module
: THIS_MODULE
,
125 attach
: me4000_attach
,
126 detach
: me4000_detach
,
129 /*-----------------------------------------------------------------------------
130 Meilhaus function prototypes
131 ---------------------------------------------------------------------------*/
132 static int me4000_probe(struct comedi_device
*dev
, struct comedi_devconfig
*it
);
133 static int get_registers(struct comedi_device
*dev
, struct pci_dev
*pci_dev_p
);
134 static int init_board_info(struct comedi_device
*dev
,
135 struct pci_dev
*pci_dev_p
);
136 static int init_ao_context(struct comedi_device
*dev
);
137 static int init_ai_context(struct comedi_device
*dev
);
138 static int init_dio_context(struct comedi_device
*dev
);
139 static int init_cnt_context(struct comedi_device
*dev
);
140 static int xilinx_download(struct comedi_device
*dev
);
141 static int reset_board(struct comedi_device
*dev
);
143 static int me4000_dio_insn_bits(struct comedi_device
*dev
,
144 struct comedi_subdevice
*s
,
145 struct comedi_insn
*insn
, unsigned int *data
);
147 static int me4000_dio_insn_config(struct comedi_device
*dev
,
148 struct comedi_subdevice
*s
,
149 struct comedi_insn
*insn
, unsigned int *data
);
151 static int cnt_reset(struct comedi_device
*dev
, unsigned int channel
);
153 static int cnt_config(struct comedi_device
*dev
,
154 unsigned int channel
, unsigned int mode
);
156 static int me4000_cnt_insn_config(struct comedi_device
*dev
,
157 struct comedi_subdevice
*s
,
158 struct comedi_insn
*insn
, unsigned int *data
);
160 static int me4000_cnt_insn_write(struct comedi_device
*dev
,
161 struct comedi_subdevice
*s
,
162 struct comedi_insn
*insn
, unsigned int *data
);
164 static int me4000_cnt_insn_read(struct comedi_device
*dev
,
165 struct comedi_subdevice
*s
,
166 struct comedi_insn
*insn
, unsigned int *data
);
168 static int me4000_ai_insn_read(struct comedi_device
*dev
,
169 struct comedi_subdevice
*subdevice
,
170 struct comedi_insn
*insn
, unsigned int *data
);
172 static int me4000_ai_cancel(struct comedi_device
*dev
,
173 struct comedi_subdevice
*s
);
175 static int ai_check_chanlist(struct comedi_device
*dev
,
176 struct comedi_subdevice
*s
,
177 struct comedi_cmd
*cmd
);
179 static int ai_round_cmd_args(struct comedi_device
*dev
,
180 struct comedi_subdevice
*s
,
181 struct comedi_cmd
*cmd
,
182 unsigned int *init_ticks
,
183 unsigned int *scan_ticks
,
184 unsigned int *chan_ticks
);
186 static int ai_prepare(struct comedi_device
*dev
,
187 struct comedi_subdevice
*s
,
188 struct comedi_cmd
*cmd
,
189 unsigned int init_ticks
,
190 unsigned int scan_ticks
, unsigned int chan_ticks
);
192 static int ai_write_chanlist(struct comedi_device
*dev
,
193 struct comedi_subdevice
*s
,
194 struct comedi_cmd
*cmd
);
196 static irqreturn_t
me4000_ai_isr(int irq
, void *dev_id
);
198 static int me4000_ai_do_cmd_test(struct comedi_device
*dev
,
199 struct comedi_subdevice
*s
,
200 struct comedi_cmd
*cmd
);
202 static int me4000_ai_do_cmd(struct comedi_device
*dev
,
203 struct comedi_subdevice
*s
);
205 static int me4000_ao_insn_write(struct comedi_device
*dev
,
206 struct comedi_subdevice
*s
,
207 struct comedi_insn
*insn
, unsigned int *data
);
209 static int me4000_ao_insn_read(struct comedi_device
*dev
,
210 struct comedi_subdevice
*s
,
211 struct comedi_insn
*insn
, unsigned int *data
);
213 /*-----------------------------------------------------------------------------
214 Meilhaus inline functions
215 ---------------------------------------------------------------------------*/
217 static inline void me4000_outb(struct comedi_device
*dev
, unsigned char value
,
220 PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value
, port
);
224 static inline void me4000_outl(struct comedi_device
*dev
, unsigned long value
,
227 PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value
, port
);
231 static inline unsigned long me4000_inl(struct comedi_device
*dev
,
236 PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value
, port
);
240 static inline unsigned char me4000_inb(struct comedi_device
*dev
,
245 PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value
, port
);
249 static const struct comedi_lrange me4000_ai_range
= {
259 static const struct comedi_lrange me4000_ao_range
= {
266 static int me4000_attach(struct comedi_device
*dev
, struct comedi_devconfig
*it
)
268 struct comedi_subdevice
*s
;
271 CALL_PDEBUG("In me4000_attach()\n");
273 result
= me4000_probe(dev
, it
);
278 * Allocate the subdevice structures. alloc_subdevice() is a
279 * convenient macro defined in comedidev.h. It relies on
280 * n_subdevices being set correctly.
282 if (alloc_subdevices(dev
, 4) < 0)
285 /*=========================================================================
286 Analog input subdevice
287 ========================================================================*/
289 s
= dev
->subdevices
+ 0;
291 if (thisboard
->ai
.count
) {
292 s
->type
= COMEDI_SUBD_AI
;
294 SDF_READABLE
| SDF_COMMON
| SDF_GROUND
| SDF_DIFF
;
295 s
->n_chan
= thisboard
->ai
.count
;
296 s
->maxdata
= 0xFFFF; /* 16 bit ADC */
297 s
->len_chanlist
= ME4000_AI_CHANNEL_LIST_COUNT
;
298 s
->range_table
= &me4000_ai_range
;
299 s
->insn_read
= me4000_ai_insn_read
;
302 if (request_irq(info
->irq
, me4000_ai_isr
,
303 IRQF_SHARED
, "ME-4000", dev
)) {
305 ("comedi%d: me4000: me4000_attach(): "
306 "Unable to allocate irq\n", dev
->minor
);
308 dev
->read_subdev
= s
;
309 s
->subdev_flags
|= SDF_CMD_READ
;
310 s
->cancel
= me4000_ai_cancel
;
311 s
->do_cmdtest
= me4000_ai_do_cmd_test
;
312 s
->do_cmd
= me4000_ai_do_cmd
;
316 "comedi%d: me4000: me4000_attach(): "
317 "No interrupt available\n", dev
->minor
);
320 s
->type
= COMEDI_SUBD_UNUSED
;
323 /*=========================================================================
324 Analog output subdevice
325 ========================================================================*/
327 s
= dev
->subdevices
+ 1;
329 if (thisboard
->ao
.count
) {
330 s
->type
= COMEDI_SUBD_AO
;
331 s
->subdev_flags
= SDF_WRITEABLE
| SDF_COMMON
| SDF_GROUND
;
332 s
->n_chan
= thisboard
->ao
.count
;
333 s
->maxdata
= 0xFFFF; /* 16 bit DAC */
334 s
->range_table
= &me4000_ao_range
;
335 s
->insn_write
= me4000_ao_insn_write
;
336 s
->insn_read
= me4000_ao_insn_read
;
338 s
->type
= COMEDI_SUBD_UNUSED
;
341 /*=========================================================================
342 Digital I/O subdevice
343 ========================================================================*/
345 s
= dev
->subdevices
+ 2;
347 if (thisboard
->dio
.count
) {
348 s
->type
= COMEDI_SUBD_DIO
;
349 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
350 s
->n_chan
= thisboard
->dio
.count
* 8;
352 s
->range_table
= &range_digital
;
353 s
->insn_bits
= me4000_dio_insn_bits
;
354 s
->insn_config
= me4000_dio_insn_config
;
356 s
->type
= COMEDI_SUBD_UNUSED
;
360 * Check for optoisolated ME-4000 version. If one the first
361 * port is a fixed output port and the second is a fixed input port.
363 if (!me4000_inl(dev
, info
->dio_context
.dir_reg
)) {
365 me4000_outl(dev
, ME4000_DIO_CTRL_BIT_MODE_0
,
366 info
->dio_context
.dir_reg
);
369 /*=========================================================================
371 ========================================================================*/
373 s
= dev
->subdevices
+ 3;
375 if (thisboard
->cnt
.count
) {
376 s
->type
= COMEDI_SUBD_COUNTER
;
377 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
378 s
->n_chan
= thisboard
->cnt
.count
;
379 s
->maxdata
= 0xFFFF; /* 16 bit counters */
380 s
->insn_read
= me4000_cnt_insn_read
;
381 s
->insn_write
= me4000_cnt_insn_write
;
382 s
->insn_config
= me4000_cnt_insn_config
;
384 s
->type
= COMEDI_SUBD_UNUSED
;
390 static int me4000_probe(struct comedi_device
*dev
, struct comedi_devconfig
*it
)
392 struct pci_dev
*pci_device
;
394 struct me4000_board
*board
;
396 CALL_PDEBUG("In me4000_probe()\n");
398 /* Allocate private memory */
399 if (alloc_private(dev
, sizeof(struct me4000_info
)) < 0)
403 * Probe the device to determine what device in the series it is.
405 for (pci_device
= pci_get_device(PCI_ANY_ID
, PCI_ANY_ID
, NULL
);
407 pci_device
= pci_get_device(PCI_ANY_ID
, PCI_ANY_ID
, pci_device
)) {
408 if (pci_device
->vendor
== PCI_VENDOR_ID_MEILHAUS
) {
409 for (i
= 0; i
< ME4000_BOARD_VERSIONS
; i
++) {
410 if (me4000_boards
[i
].device_id
==
411 pci_device
->device
) {
414 * bus/slot requested?
416 if ((it
->options
[0] != 0)
417 || (it
->options
[1] != 0)) {
419 * Are we on the wrong
422 if (pci_device
->bus
->number
!=
425 PCI_SLOT(pci_device
->devfn
)
430 dev
->board_ptr
= me4000_boards
+ i
;
432 (struct me4000_board
*)
434 info
->pci_dev_p
= pci_device
;
442 "comedi%d: me4000: me4000_probe(): "
443 "No supported board found (req. bus/slot : %d/%d)\n",
444 dev
->minor
, it
->options
[0], it
->options
[1]);
450 "comedi%d: me4000: me4000_probe(): "
451 "Found %s at PCI bus %d, slot %d\n",
452 dev
->minor
, me4000_boards
[i
].name
, pci_device
->bus
->number
,
453 PCI_SLOT(pci_device
->devfn
));
455 /* Set data in device structure */
456 dev
->board_name
= board
->name
;
458 /* Enable PCI device and request regions */
459 result
= comedi_pci_enable(pci_device
, dev
->board_name
);
462 "comedi%d: me4000: me4000_probe(): Cannot enable PCI "
463 "device and request I/O regions\n", dev
->minor
);
467 /* Get the PCI base registers */
468 result
= get_registers(dev
, pci_device
);
471 "comedi%d: me4000: me4000_probe(): "
472 "Cannot get registers\n", dev
->minor
);
475 /* Initialize board info */
476 result
= init_board_info(dev
, pci_device
);
479 "comedi%d: me4000: me4000_probe(): "
480 "Cannot init baord info\n", dev
->minor
);
484 /* Init analog output context */
485 result
= init_ao_context(dev
);
488 "comedi%d: me4000: me4000_probe(): "
489 "Cannot init ao context\n", dev
->minor
);
493 /* Init analog input context */
494 result
= init_ai_context(dev
);
497 "comedi%d: me4000: me4000_probe(): "
498 "Cannot init ai context\n", dev
->minor
);
502 /* Init digital I/O context */
503 result
= init_dio_context(dev
);
506 "comedi%d: me4000: me4000_probe(): "
507 "Cannot init dio context\n", dev
->minor
);
511 /* Init counter context */
512 result
= init_cnt_context(dev
);
515 "comedi%d: me4000: me4000_probe(): "
516 "Cannot init cnt context\n", dev
->minor
);
520 /* Download the xilinx firmware */
521 result
= xilinx_download(dev
);
524 "comedi%d: me4000: me4000_probe(): "
525 "Can't download firmware\n", dev
->minor
);
529 /* Make a hardware reset */
530 result
= reset_board(dev
);
533 "comedi%d: me4000: me4000_probe(): Can't reset board\n",
541 static int get_registers(struct comedi_device
*dev
, struct pci_dev
*pci_dev_p
)
544 CALL_PDEBUG("In get_registers()\n");
546 /*--------------------------- plx regbase -------------------------------*/
548 info
->plx_regbase
= pci_resource_start(pci_dev_p
, 1);
549 if (info
->plx_regbase
== 0) {
551 "comedi%d: me4000: get_registers(): "
552 "PCI base address 1 is not available\n", dev
->minor
);
555 info
->plx_regbase_size
= pci_resource_len(pci_dev_p
, 1);
557 /*--------------------------- me4000 regbase ----------------------------*/
559 info
->me4000_regbase
= pci_resource_start(pci_dev_p
, 2);
560 if (info
->me4000_regbase
== 0) {
562 "comedi%d: me4000: get_registers(): "
563 "PCI base address 2 is not available\n", dev
->minor
);
566 info
->me4000_regbase_size
= pci_resource_len(pci_dev_p
, 2);
568 /*--------------------------- timer regbase ------------------------------*/
570 info
->timer_regbase
= pci_resource_start(pci_dev_p
, 3);
571 if (info
->timer_regbase
== 0) {
573 "comedi%d: me4000: get_registers(): "
574 "PCI base address 3 is not available\n", dev
->minor
);
577 info
->timer_regbase_size
= pci_resource_len(pci_dev_p
, 3);
579 /*--------------------------- program regbase ----------------------------*/
581 info
->program_regbase
= pci_resource_start(pci_dev_p
, 5);
582 if (info
->program_regbase
== 0) {
584 "comedi%d: me4000: get_registers(): "
585 "PCI base address 5 is not available\n", dev
->minor
);
588 info
->program_regbase_size
= pci_resource_len(pci_dev_p
, 5);
593 static int init_board_info(struct comedi_device
*dev
, struct pci_dev
*pci_dev_p
)
597 CALL_PDEBUG("In init_board_info()\n");
599 /* Init spin locks */
600 /* spin_lock_init(&info->preload_lock); */
601 /* spin_lock_init(&info->ai_ctrl_lock); */
603 /* Get the serial number */
604 result
= pci_read_config_dword(pci_dev_p
, 0x2C, &info
->serial_no
);
605 if (result
!= PCIBIOS_SUCCESSFUL
)
608 /* Get the hardware revision */
609 result
= pci_read_config_byte(pci_dev_p
, 0x08, &info
->hw_revision
);
610 if (result
!= PCIBIOS_SUCCESSFUL
)
613 /* Get the vendor id */
614 info
->vendor_id
= pci_dev_p
->vendor
;
616 /* Get the device id */
617 info
->device_id
= pci_dev_p
->device
;
619 /* Get the irq assigned to the board */
620 info
->irq
= pci_dev_p
->irq
;
625 static int init_ao_context(struct comedi_device
*dev
)
629 CALL_PDEBUG("In init_ao_context()\n");
631 for (i
= 0; i
< thisboard
->ao
.count
; i
++) {
632 /* spin_lock_init(&info->ao_context[i].use_lock); */
633 info
->ao_context
[i
].irq
= info
->irq
;
637 info
->ao_context
[i
].ctrl_reg
=
638 info
->me4000_regbase
+ ME4000_AO_00_CTRL_REG
;
639 info
->ao_context
[i
].status_reg
=
640 info
->me4000_regbase
+ ME4000_AO_00_STATUS_REG
;
641 info
->ao_context
[i
].fifo_reg
=
642 info
->me4000_regbase
+ ME4000_AO_00_FIFO_REG
;
643 info
->ao_context
[i
].single_reg
=
644 info
->me4000_regbase
+ ME4000_AO_00_SINGLE_REG
;
645 info
->ao_context
[i
].timer_reg
=
646 info
->me4000_regbase
+ ME4000_AO_00_TIMER_REG
;
647 info
->ao_context
[i
].irq_status_reg
=
648 info
->me4000_regbase
+ ME4000_IRQ_STATUS_REG
;
649 info
->ao_context
[i
].preload_reg
=
650 info
->me4000_regbase
+ ME4000_AO_LOADSETREG_XX
;
653 info
->ao_context
[i
].ctrl_reg
=
654 info
->me4000_regbase
+ ME4000_AO_01_CTRL_REG
;
655 info
->ao_context
[i
].status_reg
=
656 info
->me4000_regbase
+ ME4000_AO_01_STATUS_REG
;
657 info
->ao_context
[i
].fifo_reg
=
658 info
->me4000_regbase
+ ME4000_AO_01_FIFO_REG
;
659 info
->ao_context
[i
].single_reg
=
660 info
->me4000_regbase
+ ME4000_AO_01_SINGLE_REG
;
661 info
->ao_context
[i
].timer_reg
=
662 info
->me4000_regbase
+ ME4000_AO_01_TIMER_REG
;
663 info
->ao_context
[i
].irq_status_reg
=
664 info
->me4000_regbase
+ ME4000_IRQ_STATUS_REG
;
665 info
->ao_context
[i
].preload_reg
=
666 info
->me4000_regbase
+ ME4000_AO_LOADSETREG_XX
;
669 info
->ao_context
[i
].ctrl_reg
=
670 info
->me4000_regbase
+ ME4000_AO_02_CTRL_REG
;
671 info
->ao_context
[i
].status_reg
=
672 info
->me4000_regbase
+ ME4000_AO_02_STATUS_REG
;
673 info
->ao_context
[i
].fifo_reg
=
674 info
->me4000_regbase
+ ME4000_AO_02_FIFO_REG
;
675 info
->ao_context
[i
].single_reg
=
676 info
->me4000_regbase
+ ME4000_AO_02_SINGLE_REG
;
677 info
->ao_context
[i
].timer_reg
=
678 info
->me4000_regbase
+ ME4000_AO_02_TIMER_REG
;
679 info
->ao_context
[i
].irq_status_reg
=
680 info
->me4000_regbase
+ ME4000_IRQ_STATUS_REG
;
681 info
->ao_context
[i
].preload_reg
=
682 info
->me4000_regbase
+ ME4000_AO_LOADSETREG_XX
;
685 info
->ao_context
[i
].ctrl_reg
=
686 info
->me4000_regbase
+ ME4000_AO_03_CTRL_REG
;
687 info
->ao_context
[i
].status_reg
=
688 info
->me4000_regbase
+ ME4000_AO_03_STATUS_REG
;
689 info
->ao_context
[i
].fifo_reg
=
690 info
->me4000_regbase
+ ME4000_AO_03_FIFO_REG
;
691 info
->ao_context
[i
].single_reg
=
692 info
->me4000_regbase
+ ME4000_AO_03_SINGLE_REG
;
693 info
->ao_context
[i
].timer_reg
=
694 info
->me4000_regbase
+ ME4000_AO_03_TIMER_REG
;
695 info
->ao_context
[i
].irq_status_reg
=
696 info
->me4000_regbase
+ ME4000_IRQ_STATUS_REG
;
697 info
->ao_context
[i
].preload_reg
=
698 info
->me4000_regbase
+ ME4000_AO_LOADSETREG_XX
;
708 static int init_ai_context(struct comedi_device
*dev
)
711 CALL_PDEBUG("In init_ai_context()\n");
713 info
->ai_context
.irq
= info
->irq
;
715 info
->ai_context
.ctrl_reg
= info
->me4000_regbase
+ ME4000_AI_CTRL_REG
;
716 info
->ai_context
.status_reg
=
717 info
->me4000_regbase
+ ME4000_AI_STATUS_REG
;
718 info
->ai_context
.channel_list_reg
=
719 info
->me4000_regbase
+ ME4000_AI_CHANNEL_LIST_REG
;
720 info
->ai_context
.data_reg
= info
->me4000_regbase
+ ME4000_AI_DATA_REG
;
721 info
->ai_context
.chan_timer_reg
=
722 info
->me4000_regbase
+ ME4000_AI_CHAN_TIMER_REG
;
723 info
->ai_context
.chan_pre_timer_reg
=
724 info
->me4000_regbase
+ ME4000_AI_CHAN_PRE_TIMER_REG
;
725 info
->ai_context
.scan_timer_low_reg
=
726 info
->me4000_regbase
+ ME4000_AI_SCAN_TIMER_LOW_REG
;
727 info
->ai_context
.scan_timer_high_reg
=
728 info
->me4000_regbase
+ ME4000_AI_SCAN_TIMER_HIGH_REG
;
729 info
->ai_context
.scan_pre_timer_low_reg
=
730 info
->me4000_regbase
+ ME4000_AI_SCAN_PRE_TIMER_LOW_REG
;
731 info
->ai_context
.scan_pre_timer_high_reg
=
732 info
->me4000_regbase
+ ME4000_AI_SCAN_PRE_TIMER_HIGH_REG
;
733 info
->ai_context
.start_reg
= info
->me4000_regbase
+ ME4000_AI_START_REG
;
734 info
->ai_context
.irq_status_reg
=
735 info
->me4000_regbase
+ ME4000_IRQ_STATUS_REG
;
736 info
->ai_context
.sample_counter_reg
=
737 info
->me4000_regbase
+ ME4000_AI_SAMPLE_COUNTER_REG
;
742 static int init_dio_context(struct comedi_device
*dev
)
745 CALL_PDEBUG("In init_dio_context()\n");
747 info
->dio_context
.dir_reg
= info
->me4000_regbase
+ ME4000_DIO_DIR_REG
;
748 info
->dio_context
.ctrl_reg
= info
->me4000_regbase
+ ME4000_DIO_CTRL_REG
;
749 info
->dio_context
.port_0_reg
=
750 info
->me4000_regbase
+ ME4000_DIO_PORT_0_REG
;
751 info
->dio_context
.port_1_reg
=
752 info
->me4000_regbase
+ ME4000_DIO_PORT_1_REG
;
753 info
->dio_context
.port_2_reg
=
754 info
->me4000_regbase
+ ME4000_DIO_PORT_2_REG
;
755 info
->dio_context
.port_3_reg
=
756 info
->me4000_regbase
+ ME4000_DIO_PORT_3_REG
;
761 static int init_cnt_context(struct comedi_device
*dev
)
764 CALL_PDEBUG("In init_cnt_context()\n");
766 info
->cnt_context
.ctrl_reg
= info
->timer_regbase
+ ME4000_CNT_CTRL_REG
;
767 info
->cnt_context
.counter_0_reg
=
768 info
->timer_regbase
+ ME4000_CNT_COUNTER_0_REG
;
769 info
->cnt_context
.counter_1_reg
=
770 info
->timer_regbase
+ ME4000_CNT_COUNTER_1_REG
;
771 info
->cnt_context
.counter_2_reg
=
772 info
->timer_regbase
+ ME4000_CNT_COUNTER_2_REG
;
777 #define FIRMWARE_NOT_AVAILABLE 1
778 #if FIRMWARE_NOT_AVAILABLE
779 extern unsigned char *xilinx_firm
;
782 static int xilinx_download(struct comedi_device
*dev
)
785 wait_queue_head_t queue
;
789 CALL_PDEBUG("In xilinx_download()\n");
791 init_waitqueue_head(&queue
);
794 * Set PLX local interrupt 2 polarity to high.
795 * Interrupt is thrown by init pin of xilinx.
797 outl(0x10, info
->plx_regbase
+ PLX_INTCSR
);
799 /* Set /CS and /WRITE of the Xilinx */
800 value
= inl(info
->plx_regbase
+ PLX_ICR
);
802 outl(value
, info
->plx_regbase
+ PLX_ICR
);
804 /* Init Xilinx with CS1 */
805 inb(info
->program_regbase
+ 0xC8);
807 /* Wait until /INIT pin is set */
809 if (!(inl(info
->plx_regbase
+ PLX_INTCSR
) & 0x20)) {
811 "comedi%d: me4000: xilinx_download(): "
812 "Can't init Xilinx\n", dev
->minor
);
816 /* Reset /CS and /WRITE of the Xilinx */
817 value
= inl(info
->plx_regbase
+ PLX_ICR
);
819 outl(value
, info
->plx_regbase
+ PLX_ICR
);
820 if (FIRMWARE_NOT_AVAILABLE
) {
821 comedi_error(dev
, "xilinx firmware unavailable "
822 "due to licensing, aborting");
825 /* Download Xilinx firmware */
826 size
= (xilinx_firm
[0] << 24) + (xilinx_firm
[1] << 16) +
827 (xilinx_firm
[2] << 8) + xilinx_firm
[3];
830 for (idx
= 0; idx
< size
; idx
++) {
831 outb(xilinx_firm
[16 + idx
], info
->program_regbase
);
834 /* Check if BUSY flag is low */
835 if (inl(info
->plx_regbase
+ PLX_ICR
) & 0x20) {
837 "comedi%d: me4000: xilinx_download(): "
838 "Xilinx is still busy (idx = %d)\n",
845 /* If done flag is high download was successful */
846 if (inl(info
->plx_regbase
+ PLX_ICR
) & 0x4) {
849 "comedi%d: me4000: xilinx_download(): "
850 "DONE flag is not set\n", dev
->minor
);
852 "comedi%d: me4000: xilinx_download(): "
853 "Download not successful\n", dev
->minor
);
857 /* Set /CS and /WRITE */
858 value
= inl(info
->plx_regbase
+ PLX_ICR
);
860 outl(value
, info
->plx_regbase
+ PLX_ICR
);
865 static int reset_board(struct comedi_device
*dev
)
869 CALL_PDEBUG("In reset_board()\n");
871 /* Make a hardware reset */
872 icr
= me4000_inl(dev
, info
->plx_regbase
+ PLX_ICR
);
874 me4000_outl(dev
, icr
, info
->plx_regbase
+ PLX_ICR
);
876 me4000_outl(dev
, icr
, info
->plx_regbase
+ PLX_ICR
);
878 /* 0x8000 to the DACs means an output voltage of 0V */
879 me4000_outl(dev
, 0x8000,
880 info
->me4000_regbase
+ ME4000_AO_00_SINGLE_REG
);
881 me4000_outl(dev
, 0x8000,
882 info
->me4000_regbase
+ ME4000_AO_01_SINGLE_REG
);
883 me4000_outl(dev
, 0x8000,
884 info
->me4000_regbase
+ ME4000_AO_02_SINGLE_REG
);
885 me4000_outl(dev
, 0x8000,
886 info
->me4000_regbase
+ ME4000_AO_03_SINGLE_REG
);
888 /* Set both stop bits in the analog input control register */
890 ME4000_AI_CTRL_BIT_IMMEDIATE_STOP
| ME4000_AI_CTRL_BIT_STOP
,
891 info
->me4000_regbase
+ ME4000_AI_CTRL_REG
);
893 /* Set both stop bits in the analog output control register */
895 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP
| ME4000_AO_CTRL_BIT_STOP
,
896 info
->me4000_regbase
+ ME4000_AO_00_CTRL_REG
);
898 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP
| ME4000_AO_CTRL_BIT_STOP
,
899 info
->me4000_regbase
+ ME4000_AO_01_CTRL_REG
);
901 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP
| ME4000_AO_CTRL_BIT_STOP
,
902 info
->me4000_regbase
+ ME4000_AO_02_CTRL_REG
);
904 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP
| ME4000_AO_CTRL_BIT_STOP
,
905 info
->me4000_regbase
+ ME4000_AO_03_CTRL_REG
);
907 /* Enable interrupts on the PLX */
908 me4000_outl(dev
, 0x43, info
->plx_regbase
+ PLX_INTCSR
);
910 /* Set the adustment register for AO demux */
911 me4000_outl(dev
, ME4000_AO_DEMUX_ADJUST_VALUE
,
912 info
->me4000_regbase
+ ME4000_AO_DEMUX_ADJUST_REG
);
915 * Set digital I/O direction for port 0
916 * to output on isolated versions
918 if (!(me4000_inl(dev
, info
->me4000_regbase
+ ME4000_DIO_DIR_REG
) & 0x1)) {
919 me4000_outl(dev
, 0x1,
920 info
->me4000_regbase
+ ME4000_DIO_CTRL_REG
);
926 static int me4000_detach(struct comedi_device
*dev
)
928 CALL_PDEBUG("In me4000_detach()\n");
931 if (info
->pci_dev_p
) {
933 if (info
->plx_regbase
)
934 comedi_pci_disable(info
->pci_dev_p
);
935 pci_dev_put(info
->pci_dev_p
);
942 /*=============================================================================
944 ===========================================================================*/
946 static int me4000_ai_insn_read(struct comedi_device
*dev
,
947 struct comedi_subdevice
*subdevice
,
948 struct comedi_insn
*insn
, unsigned int *data
)
951 int chan
= CR_CHAN(insn
->chanspec
);
952 int rang
= CR_RANGE(insn
->chanspec
);
953 int aref
= CR_AREF(insn
->chanspec
);
955 unsigned long entry
= 0;
959 CALL_PDEBUG("In me4000_ai_insn_read()\n");
963 } else if (insn
->n
> 1) {
965 "comedi%d: me4000: me4000_ai_insn_read(): "
966 "Invalid instruction length %d\n", dev
->minor
, insn
->n
);
972 entry
|= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5
;
975 entry
|= ME4000_AI_LIST_RANGE_UNIPOLAR_10
;
978 entry
|= ME4000_AI_LIST_RANGE_BIPOLAR_2_5
;
981 entry
|= ME4000_AI_LIST_RANGE_BIPOLAR_10
;
985 "comedi%d: me4000: me4000_ai_insn_read(): "
986 "Invalid range specified\n", dev
->minor
);
993 if (chan
>= thisboard
->ai
.count
) {
995 "comedi%d: me4000: me4000_ai_insn_read(): "
996 "Analog input is not available\n", dev
->minor
);
999 entry
|= ME4000_AI_LIST_INPUT_SINGLE_ENDED
| chan
;
1003 if (rang
== 0 || rang
== 1) {
1005 "comedi%d: me4000: me4000_ai_insn_read(): "
1006 "Range must be bipolar when aref = diff\n",
1011 if (chan
>= thisboard
->ai
.diff_count
) {
1013 "comedi%d: me4000: me4000_ai_insn_read(): "
1014 "Analog input is not available\n", dev
->minor
);
1017 entry
|= ME4000_AI_LIST_INPUT_DIFFERENTIAL
| chan
;
1021 "comedi%d: me4000: me4000_ai_insn_read(): "
1022 "Invalid aref specified\n", dev
->minor
);
1026 entry
|= ME4000_AI_LIST_LAST_ENTRY
;
1028 /* Clear channel list, data fifo and both stop bits */
1029 tmp
= me4000_inl(dev
, info
->ai_context
.ctrl_reg
);
1030 tmp
&= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO
|
1031 ME4000_AI_CTRL_BIT_DATA_FIFO
|
1032 ME4000_AI_CTRL_BIT_STOP
| ME4000_AI_CTRL_BIT_IMMEDIATE_STOP
);
1033 me4000_outl(dev
, tmp
, info
->ai_context
.ctrl_reg
);
1035 /* Set the acquisition mode to single */
1036 tmp
&= ~(ME4000_AI_CTRL_BIT_MODE_0
| ME4000_AI_CTRL_BIT_MODE_1
|
1037 ME4000_AI_CTRL_BIT_MODE_2
);
1038 me4000_outl(dev
, tmp
, info
->ai_context
.ctrl_reg
);
1040 /* Enable channel list and data fifo */
1041 tmp
|= ME4000_AI_CTRL_BIT_CHANNEL_FIFO
| ME4000_AI_CTRL_BIT_DATA_FIFO
;
1042 me4000_outl(dev
, tmp
, info
->ai_context
.ctrl_reg
);
1044 /* Generate channel list entry */
1045 me4000_outl(dev
, entry
, info
->ai_context
.channel_list_reg
);
1047 /* Set the timer to maximum sample rate */
1048 me4000_outl(dev
, ME4000_AI_MIN_TICKS
, info
->ai_context
.chan_timer_reg
);
1049 me4000_outl(dev
, ME4000_AI_MIN_TICKS
,
1050 info
->ai_context
.chan_pre_timer_reg
);
1052 /* Start conversion by dummy read */
1053 me4000_inl(dev
, info
->ai_context
.start_reg
);
1055 /* Wait until ready */
1058 (me4000_inl(dev
, info
->ai_context
.status_reg
) &
1059 ME4000_AI_STATUS_BIT_EF_DATA
)) {
1061 "comedi%d: me4000: me4000_ai_insn_read(): "
1062 "Value not available after wait\n", dev
->minor
);
1066 /* Read value from data fifo */
1067 lval
= me4000_inl(dev
, info
->ai_context
.data_reg
) & 0xFFFF;
1068 data
[0] = lval
^ 0x8000;
1073 static int me4000_ai_cancel(struct comedi_device
*dev
,
1074 struct comedi_subdevice
*s
)
1078 CALL_PDEBUG("In me4000_ai_cancel()\n");
1080 /* Stop any running conversion */
1081 tmp
= me4000_inl(dev
, info
->ai_context
.ctrl_reg
);
1082 tmp
&= ~(ME4000_AI_CTRL_BIT_STOP
| ME4000_AI_CTRL_BIT_IMMEDIATE_STOP
);
1083 me4000_outl(dev
, tmp
, info
->ai_context
.ctrl_reg
);
1085 /* Clear the control register */
1086 me4000_outl(dev
, 0x0, info
->ai_context
.ctrl_reg
);
1091 static int ai_check_chanlist(struct comedi_device
*dev
,
1092 struct comedi_subdevice
*s
, struct comedi_cmd
*cmd
)
1097 CALL_PDEBUG("In ai_check_chanlist()\n");
1099 /* Check whether a channel list is available */
1100 if (!cmd
->chanlist_len
) {
1102 "comedi%d: me4000: ai_check_chanlist(): "
1103 "No channel list available\n", dev
->minor
);
1107 /* Check the channel list size */
1108 if (cmd
->chanlist_len
> ME4000_AI_CHANNEL_LIST_COUNT
) {
1110 "comedi%d: me4000: ai_check_chanlist(): "
1111 "Channel list is to large\n", dev
->minor
);
1115 /* Check the pointer */
1116 if (!cmd
->chanlist
) {
1118 "comedi%d: me4000: ai_check_chanlist(): "
1119 "NULL pointer to channel list\n", dev
->minor
);
1123 /* Check whether aref is equal for all entries */
1124 aref
= CR_AREF(cmd
->chanlist
[0]);
1125 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
1126 if (CR_AREF(cmd
->chanlist
[i
]) != aref
) {
1128 "comedi%d: me4000: ai_check_chanlist(): "
1129 "Mode is not equal for all entries\n",
1135 /* Check whether channels are available for this ending */
1136 if (aref
== SDF_DIFF
) {
1137 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
1138 if (CR_CHAN(cmd
->chanlist
[i
]) >=
1139 thisboard
->ai
.diff_count
) {
1141 "comedi%d: me4000: ai_check_chanlist():"
1142 " Channel number to high\n", dev
->minor
);
1147 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
1148 if (CR_CHAN(cmd
->chanlist
[i
]) >= thisboard
->ai
.count
) {
1150 "comedi%d: me4000: ai_check_chanlist(): "
1151 "Channel number to high\n", dev
->minor
);
1157 /* Check if bipolar is set for all entries when in differential mode */
1158 if (aref
== SDF_DIFF
) {
1159 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
1160 if (CR_RANGE(cmd
->chanlist
[i
]) != 1 &&
1161 CR_RANGE(cmd
->chanlist
[i
]) != 2) {
1163 "comedi%d: me4000: ai_check_chanlist(): "
1164 "Bipolar is not selected in "
1165 "differential mode\n",
1175 static int ai_round_cmd_args(struct comedi_device
*dev
,
1176 struct comedi_subdevice
*s
,
1177 struct comedi_cmd
*cmd
,
1178 unsigned int *init_ticks
,
1179 unsigned int *scan_ticks
, unsigned int *chan_ticks
)
1184 CALL_PDEBUG("In ai_round_cmd_args()\n");
1190 PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd
->start_arg
);
1191 PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n",
1192 cmd
->scan_begin_arg
);
1193 PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd
->convert_arg
);
1195 if (cmd
->start_arg
) {
1196 *init_ticks
= (cmd
->start_arg
* 33) / 1000;
1197 rest
= (cmd
->start_arg
* 33) % 1000;
1199 if (cmd
->flags
& TRIG_ROUND_NEAREST
) {
1202 } else if (cmd
->flags
& TRIG_ROUND_UP
) {
1208 if (cmd
->scan_begin_arg
) {
1209 *scan_ticks
= (cmd
->scan_begin_arg
* 33) / 1000;
1210 rest
= (cmd
->scan_begin_arg
* 33) % 1000;
1212 if (cmd
->flags
& TRIG_ROUND_NEAREST
) {
1215 } else if (cmd
->flags
& TRIG_ROUND_UP
) {
1221 if (cmd
->convert_arg
) {
1222 *chan_ticks
= (cmd
->convert_arg
* 33) / 1000;
1223 rest
= (cmd
->convert_arg
* 33) % 1000;
1225 if (cmd
->flags
& TRIG_ROUND_NEAREST
) {
1228 } else if (cmd
->flags
& TRIG_ROUND_UP
) {
1234 PDEBUG("ai_round_cmd_args(): init_ticks = %d\n", *init_ticks
);
1235 PDEBUG("ai_round_cmd_args(): scan_ticks = %d\n", *scan_ticks
);
1236 PDEBUG("ai_round_cmd_args(): chan_ticks = %d\n", *chan_ticks
);
1241 static void ai_write_timer(struct comedi_device
*dev
,
1242 unsigned int init_ticks
,
1243 unsigned int scan_ticks
, unsigned int chan_ticks
)
1246 CALL_PDEBUG("In ai_write_timer()\n");
1248 me4000_outl(dev
, init_ticks
- 1,
1249 info
->ai_context
.scan_pre_timer_low_reg
);
1250 me4000_outl(dev
, 0x0, info
->ai_context
.scan_pre_timer_high_reg
);
1253 me4000_outl(dev
, scan_ticks
- 1,
1254 info
->ai_context
.scan_timer_low_reg
);
1255 me4000_outl(dev
, 0x0, info
->ai_context
.scan_timer_high_reg
);
1258 me4000_outl(dev
, chan_ticks
- 1, info
->ai_context
.chan_pre_timer_reg
);
1259 me4000_outl(dev
, chan_ticks
- 1, info
->ai_context
.chan_timer_reg
);
1262 static int ai_prepare(struct comedi_device
*dev
,
1263 struct comedi_subdevice
*s
,
1264 struct comedi_cmd
*cmd
,
1265 unsigned int init_ticks
,
1266 unsigned int scan_ticks
, unsigned int chan_ticks
)
1269 unsigned long tmp
= 0;
1271 CALL_PDEBUG("In ai_prepare()\n");
1273 /* Write timer arguments */
1274 ai_write_timer(dev
, init_ticks
, scan_ticks
, chan_ticks
);
1276 /* Reset control register */
1277 me4000_outl(dev
, tmp
, info
->ai_context
.ctrl_reg
);
1280 if ((cmd
->start_src
== TRIG_EXT
&&
1281 cmd
->scan_begin_src
== TRIG_TIMER
&&
1282 cmd
->convert_src
== TRIG_TIMER
) ||
1283 (cmd
->start_src
== TRIG_EXT
&&
1284 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
1285 cmd
->convert_src
== TRIG_TIMER
)) {
1286 tmp
= ME4000_AI_CTRL_BIT_MODE_1
|
1287 ME4000_AI_CTRL_BIT_CHANNEL_FIFO
|
1288 ME4000_AI_CTRL_BIT_DATA_FIFO
;
1289 } else if (cmd
->start_src
== TRIG_EXT
&&
1290 cmd
->scan_begin_src
== TRIG_EXT
&&
1291 cmd
->convert_src
== TRIG_TIMER
) {
1292 tmp
= ME4000_AI_CTRL_BIT_MODE_2
|
1293 ME4000_AI_CTRL_BIT_CHANNEL_FIFO
|
1294 ME4000_AI_CTRL_BIT_DATA_FIFO
;
1295 } else if (cmd
->start_src
== TRIG_EXT
&&
1296 cmd
->scan_begin_src
== TRIG_EXT
&&
1297 cmd
->convert_src
== TRIG_EXT
) {
1298 tmp
= ME4000_AI_CTRL_BIT_MODE_0
|
1299 ME4000_AI_CTRL_BIT_MODE_1
|
1300 ME4000_AI_CTRL_BIT_CHANNEL_FIFO
|
1301 ME4000_AI_CTRL_BIT_DATA_FIFO
;
1303 tmp
= ME4000_AI_CTRL_BIT_MODE_0
|
1304 ME4000_AI_CTRL_BIT_CHANNEL_FIFO
|
1305 ME4000_AI_CTRL_BIT_DATA_FIFO
;
1309 if (cmd
->stop_src
== TRIG_COUNT
) {
1310 me4000_outl(dev
, cmd
->chanlist_len
* cmd
->stop_arg
,
1311 info
->ai_context
.sample_counter_reg
);
1312 tmp
|= ME4000_AI_CTRL_BIT_HF_IRQ
| ME4000_AI_CTRL_BIT_SC_IRQ
;
1313 } else if (cmd
->stop_src
== TRIG_NONE
&&
1314 cmd
->scan_end_src
== TRIG_COUNT
) {
1315 me4000_outl(dev
, cmd
->scan_end_arg
,
1316 info
->ai_context
.sample_counter_reg
);
1317 tmp
|= ME4000_AI_CTRL_BIT_HF_IRQ
| ME4000_AI_CTRL_BIT_SC_IRQ
;
1319 tmp
|= ME4000_AI_CTRL_BIT_HF_IRQ
;
1322 /* Write the setup to the control register */
1323 me4000_outl(dev
, tmp
, info
->ai_context
.ctrl_reg
);
1325 /* Write the channel list */
1326 ai_write_chanlist(dev
, s
, cmd
);
1331 static int ai_write_chanlist(struct comedi_device
*dev
,
1332 struct comedi_subdevice
*s
, struct comedi_cmd
*cmd
)
1340 CALL_PDEBUG("In ai_write_chanlist()\n");
1342 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
1343 chan
= CR_CHAN(cmd
->chanlist
[i
]);
1344 rang
= CR_RANGE(cmd
->chanlist
[i
]);
1345 aref
= CR_AREF(cmd
->chanlist
[i
]);
1350 entry
|= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5
;
1352 entry
|= ME4000_AI_LIST_RANGE_UNIPOLAR_10
;
1354 entry
|= ME4000_AI_LIST_RANGE_BIPOLAR_2_5
;
1356 entry
|= ME4000_AI_LIST_RANGE_BIPOLAR_10
;
1358 if (aref
== SDF_DIFF
)
1359 entry
|= ME4000_AI_LIST_INPUT_DIFFERENTIAL
;
1361 entry
|= ME4000_AI_LIST_INPUT_SINGLE_ENDED
;
1363 me4000_outl(dev
, entry
, info
->ai_context
.channel_list_reg
);
1369 static int me4000_ai_do_cmd(struct comedi_device
*dev
,
1370 struct comedi_subdevice
*s
)
1373 unsigned int init_ticks
= 0;
1374 unsigned int scan_ticks
= 0;
1375 unsigned int chan_ticks
= 0;
1376 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
1378 CALL_PDEBUG("In me4000_ai_do_cmd()\n");
1380 /* Reset the analog input */
1381 err
= me4000_ai_cancel(dev
, s
);
1385 /* Round the timer arguments */
1386 err
= ai_round_cmd_args(dev
,
1387 s
, cmd
, &init_ticks
, &scan_ticks
, &chan_ticks
);
1391 /* Prepare the AI for acquisition */
1392 err
= ai_prepare(dev
, s
, cmd
, init_ticks
, scan_ticks
, chan_ticks
);
1396 /* Start acquistion by dummy read */
1397 me4000_inl(dev
, info
->ai_context
.start_reg
);
1403 * me4000_ai_do_cmd_test():
1405 * The demo cmd.c in ./comedilib/demo specifies 6 return values:
1409 * - invalid argument
1410 * - argument conflict
1411 * - invalid chanlist
1412 * So I tried to adopt this scheme.
1414 static int me4000_ai_do_cmd_test(struct comedi_device
*dev
,
1415 struct comedi_subdevice
*s
,
1416 struct comedi_cmd
*cmd
)
1419 unsigned int init_ticks
;
1420 unsigned int chan_ticks
;
1421 unsigned int scan_ticks
;
1424 CALL_PDEBUG("In me4000_ai_do_cmd_test()\n");
1426 PDEBUG("me4000_ai_do_cmd_test(): subdev = %d\n", cmd
->subdev
);
1427 PDEBUG("me4000_ai_do_cmd_test(): flags = %08X\n", cmd
->flags
);
1428 PDEBUG("me4000_ai_do_cmd_test(): start_src = %08X\n",
1430 PDEBUG("me4000_ai_do_cmd_test(): start_arg = %d\n",
1432 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n",
1433 cmd
->scan_begin_src
);
1434 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n",
1435 cmd
->scan_begin_arg
);
1436 PDEBUG("me4000_ai_do_cmd_test(): convert_src = %08X\n",
1438 PDEBUG("me4000_ai_do_cmd_test(): convert_arg = %d\n",
1440 PDEBUG("me4000_ai_do_cmd_test(): scan_end_src = %08X\n",
1442 PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg = %d\n",
1444 PDEBUG("me4000_ai_do_cmd_test(): stop_src = %08X\n",
1446 PDEBUG("me4000_ai_do_cmd_test(): stop_arg = %d\n", cmd
->stop_arg
);
1447 PDEBUG("me4000_ai_do_cmd_test(): chanlist = %d\n",
1448 (unsigned int)cmd
->chanlist
);
1449 PDEBUG("me4000_ai_do_cmd_test(): chanlist_len = %d\n",
1452 /* Only rounding flags are implemented */
1453 cmd
->flags
&= TRIG_ROUND_NEAREST
| TRIG_ROUND_UP
| TRIG_ROUND_DOWN
;
1455 /* Round the timer arguments */
1456 ai_round_cmd_args(dev
, s
, cmd
, &init_ticks
, &scan_ticks
, &chan_ticks
);
1459 * Stage 1. Check if the trigger sources are generally valid.
1461 switch (cmd
->start_src
) {
1466 cmd
->start_src
&= TRIG_NOW
| TRIG_EXT
;
1471 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1472 "Invalid start source\n", dev
->minor
);
1473 cmd
->start_src
= TRIG_NOW
;
1476 switch (cmd
->scan_begin_src
) {
1482 cmd
->scan_begin_src
&= TRIG_FOLLOW
| TRIG_TIMER
| TRIG_EXT
;
1487 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1488 "Invalid scan begin source\n", dev
->minor
);
1489 cmd
->scan_begin_src
= TRIG_FOLLOW
;
1492 switch (cmd
->convert_src
) {
1497 cmd
->convert_src
&= TRIG_TIMER
| TRIG_EXT
;
1502 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1503 "Invalid convert source\n", dev
->minor
);
1504 cmd
->convert_src
= TRIG_TIMER
;
1507 switch (cmd
->scan_end_src
) {
1512 cmd
->scan_end_src
&= TRIG_NONE
| TRIG_COUNT
;
1517 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1518 "Invalid scan end source\n", dev
->minor
);
1519 cmd
->scan_end_src
= TRIG_NONE
;
1522 switch (cmd
->stop_src
) {
1527 cmd
->stop_src
&= TRIG_NONE
| TRIG_COUNT
;
1532 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1533 "Invalid stop source\n", dev
->minor
);
1534 cmd
->stop_src
= TRIG_NONE
;
1541 * Stage 2. Check for trigger source conflicts.
1543 if (cmd
->start_src
== TRIG_NOW
&&
1544 cmd
->scan_begin_src
== TRIG_TIMER
&&
1545 cmd
->convert_src
== TRIG_TIMER
) {
1546 } else if (cmd
->start_src
== TRIG_NOW
&&
1547 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
1548 cmd
->convert_src
== TRIG_TIMER
) {
1549 } else if (cmd
->start_src
== TRIG_EXT
&&
1550 cmd
->scan_begin_src
== TRIG_TIMER
&&
1551 cmd
->convert_src
== TRIG_TIMER
) {
1552 } else if (cmd
->start_src
== TRIG_EXT
&&
1553 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
1554 cmd
->convert_src
== TRIG_TIMER
) {
1555 } else if (cmd
->start_src
== TRIG_EXT
&&
1556 cmd
->scan_begin_src
== TRIG_EXT
&&
1557 cmd
->convert_src
== TRIG_TIMER
) {
1558 } else if (cmd
->start_src
== TRIG_EXT
&&
1559 cmd
->scan_begin_src
== TRIG_EXT
&&
1560 cmd
->convert_src
== TRIG_EXT
) {
1563 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1564 "Invalid start trigger combination\n", dev
->minor
);
1565 cmd
->start_src
= TRIG_NOW
;
1566 cmd
->scan_begin_src
= TRIG_FOLLOW
;
1567 cmd
->convert_src
= TRIG_TIMER
;
1571 if (cmd
->stop_src
== TRIG_NONE
&& cmd
->scan_end_src
== TRIG_NONE
) {
1572 } else if (cmd
->stop_src
== TRIG_COUNT
&&
1573 cmd
->scan_end_src
== TRIG_NONE
) {
1574 } else if (cmd
->stop_src
== TRIG_NONE
&&
1575 cmd
->scan_end_src
== TRIG_COUNT
) {
1576 } else if (cmd
->stop_src
== TRIG_COUNT
&&
1577 cmd
->scan_end_src
== TRIG_COUNT
) {
1580 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1581 "Invalid stop trigger combination\n", dev
->minor
);
1582 cmd
->stop_src
= TRIG_NONE
;
1583 cmd
->scan_end_src
= TRIG_NONE
;
1590 * Stage 3. Check if arguments are generally valid.
1592 if (cmd
->chanlist_len
< 1) {
1594 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1595 "No channel list\n", dev
->minor
);
1596 cmd
->chanlist_len
= 1;
1599 if (init_ticks
< 66) {
1601 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1602 "Start arg to low\n", dev
->minor
);
1603 cmd
->start_arg
= 2000;
1606 if (scan_ticks
&& scan_ticks
< 67) {
1608 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1609 "Scan begin arg to low\n", dev
->minor
);
1610 cmd
->scan_begin_arg
= 2031;
1613 if (chan_ticks
< 66) {
1615 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1616 "Convert arg to low\n", dev
->minor
);
1617 cmd
->convert_arg
= 2000;
1625 * Stage 4. Check for argument conflicts.
1627 if (cmd
->start_src
== TRIG_NOW
&&
1628 cmd
->scan_begin_src
== TRIG_TIMER
&&
1629 cmd
->convert_src
== TRIG_TIMER
) {
1631 /* Check timer arguments */
1632 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
1634 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1635 "Invalid start arg\n", dev
->minor
);
1636 cmd
->start_arg
= 2000; /* 66 ticks at least */
1639 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
1641 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1642 "Invalid convert arg\n", dev
->minor
);
1643 cmd
->convert_arg
= 2000; /* 66 ticks at least */
1646 if (scan_ticks
<= cmd
->chanlist_len
* chan_ticks
) {
1648 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1649 "Invalid scan end arg\n", dev
->minor
);
1651 /* At least one tick more */
1652 cmd
->scan_end_arg
= 2000 * cmd
->chanlist_len
+ 31;
1655 } else if (cmd
->start_src
== TRIG_NOW
&&
1656 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
1657 cmd
->convert_src
== TRIG_TIMER
) {
1659 /* Check timer arguments */
1660 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
1662 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1663 "Invalid start arg\n", dev
->minor
);
1664 cmd
->start_arg
= 2000; /* 66 ticks at least */
1667 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
1669 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1670 "Invalid convert arg\n", dev
->minor
);
1671 cmd
->convert_arg
= 2000; /* 66 ticks at least */
1674 } else if (cmd
->start_src
== TRIG_EXT
&&
1675 cmd
->scan_begin_src
== TRIG_TIMER
&&
1676 cmd
->convert_src
== TRIG_TIMER
) {
1678 /* Check timer arguments */
1679 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
1681 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1682 "Invalid start arg\n", dev
->minor
);
1683 cmd
->start_arg
= 2000; /* 66 ticks at least */
1686 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
1688 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1689 "Invalid convert arg\n", dev
->minor
);
1690 cmd
->convert_arg
= 2000; /* 66 ticks at least */
1693 if (scan_ticks
<= cmd
->chanlist_len
* chan_ticks
) {
1695 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1696 "Invalid scan end arg\n", dev
->minor
);
1698 /* At least one tick more */
1699 cmd
->scan_end_arg
= 2000 * cmd
->chanlist_len
+ 31;
1702 } else if (cmd
->start_src
== TRIG_EXT
&&
1703 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
1704 cmd
->convert_src
== TRIG_TIMER
) {
1706 /* Check timer arguments */
1707 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
1709 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1710 "Invalid start arg\n", dev
->minor
);
1711 cmd
->start_arg
= 2000; /* 66 ticks at least */
1714 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
1716 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1717 "Invalid convert arg\n", dev
->minor
);
1718 cmd
->convert_arg
= 2000; /* 66 ticks at least */
1721 } else if (cmd
->start_src
== TRIG_EXT
&&
1722 cmd
->scan_begin_src
== TRIG_EXT
&&
1723 cmd
->convert_src
== TRIG_TIMER
) {
1725 /* Check timer arguments */
1726 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
1728 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1729 "Invalid start arg\n", dev
->minor
);
1730 cmd
->start_arg
= 2000; /* 66 ticks at least */
1733 if (chan_ticks
< ME4000_AI_MIN_TICKS
) {
1735 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1736 "Invalid convert arg\n", dev
->minor
);
1737 cmd
->convert_arg
= 2000; /* 66 ticks at least */
1740 } else if (cmd
->start_src
== TRIG_EXT
&&
1741 cmd
->scan_begin_src
== TRIG_EXT
&&
1742 cmd
->convert_src
== TRIG_EXT
) {
1744 /* Check timer arguments */
1745 if (init_ticks
< ME4000_AI_MIN_TICKS
) {
1747 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1748 "Invalid start arg\n", dev
->minor
);
1749 cmd
->start_arg
= 2000; /* 66 ticks at least */
1753 if (cmd
->stop_src
== TRIG_COUNT
) {
1754 if (cmd
->stop_arg
== 0) {
1756 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1757 "Invalid stop arg\n", dev
->minor
);
1762 if (cmd
->scan_end_src
== TRIG_COUNT
) {
1763 if (cmd
->scan_end_arg
== 0) {
1765 "comedi%d: me4000: me4000_ai_do_cmd_test(): "
1766 "Invalid scan end arg\n", dev
->minor
);
1767 cmd
->scan_end_arg
= 1;
1776 * Stage 5. Check the channel list.
1778 if (ai_check_chanlist(dev
, s
, cmd
))
1784 static irqreturn_t
me4000_ai_isr(int irq
, void *dev_id
)
1787 struct comedi_device
*dev
= dev_id
;
1788 struct comedi_subdevice
*s
= dev
->subdevices
;
1789 struct me4000_ai_context
*ai_context
= &info
->ai_context
;
1794 ISR_PDEBUG("me4000_ai_isr() is executed\n");
1796 if (!dev
->attached
) {
1797 ISR_PDEBUG("me4000_ai_isr() premature interrupt\n");
1801 /* Reset all events */
1802 s
->async
->events
= 0;
1804 /* Check if irq number is right */
1805 if (irq
!= ai_context
->irq
) {
1807 "comedi%d: me4000: me4000_ai_isr(): "
1808 "Incorrect interrupt num: %d\n", dev
->minor
, irq
);
1813 ai_context
->irq_status_reg
) &
1814 ME4000_IRQ_STATUS_BIT_AI_HF
) {
1816 ("me4000_ai_isr(): Fifo half full interrupt occured\n");
1818 /* Read status register to find out what happened */
1819 tmp
= me4000_inl(dev
, ai_context
->ctrl_reg
);
1821 if (!(tmp
& ME4000_AI_STATUS_BIT_FF_DATA
) &&
1822 !(tmp
& ME4000_AI_STATUS_BIT_HF_DATA
) &&
1823 (tmp
& ME4000_AI_STATUS_BIT_EF_DATA
)) {
1824 ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
1825 c
= ME4000_AI_FIFO_COUNT
;
1828 * FIFO overflow, so stop conversion
1829 * and disable all interrupts
1831 tmp
|= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP
;
1832 tmp
&= ~(ME4000_AI_CTRL_BIT_HF_IRQ
|
1833 ME4000_AI_CTRL_BIT_SC_IRQ
);
1834 me4000_outl(dev
, tmp
, ai_context
->ctrl_reg
);
1836 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
1839 "comedi%d: me4000: me4000_ai_isr(): "
1840 "FIFO overflow\n", dev
->minor
);
1841 } else if ((tmp
& ME4000_AI_STATUS_BIT_FF_DATA
)
1842 && !(tmp
& ME4000_AI_STATUS_BIT_HF_DATA
)
1843 && (tmp
& ME4000_AI_STATUS_BIT_EF_DATA
)) {
1844 ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n");
1846 s
->async
->events
|= COMEDI_CB_BLOCK
;
1848 c
= ME4000_AI_FIFO_COUNT
/ 2;
1851 "comedi%d: me4000: me4000_ai_isr(): "
1852 "Can't determine state of fifo\n", dev
->minor
);
1856 * Undefined state, so stop conversion
1857 * and disable all interrupts
1859 tmp
|= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP
;
1860 tmp
&= ~(ME4000_AI_CTRL_BIT_HF_IRQ
|
1861 ME4000_AI_CTRL_BIT_SC_IRQ
);
1862 me4000_outl(dev
, tmp
, ai_context
->ctrl_reg
);
1864 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
1867 "comedi%d: me4000: me4000_ai_isr(): "
1868 "Undefined FIFO state\n", dev
->minor
);
1871 ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c
);
1873 for (i
= 0; i
< c
; i
++) {
1874 /* Read value from data fifo */
1875 lval
= inl(ai_context
->data_reg
) & 0xFFFF;
1878 if (!comedi_buf_put(s
->async
, lval
)) {
1880 * Buffer overflow, so stop conversion
1881 * and disable all interrupts
1883 tmp
|= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP
;
1884 tmp
&= ~(ME4000_AI_CTRL_BIT_HF_IRQ
|
1885 ME4000_AI_CTRL_BIT_SC_IRQ
);
1886 me4000_outl(dev
, tmp
, ai_context
->ctrl_reg
);
1888 s
->async
->events
|= COMEDI_CB_OVERFLOW
;
1891 "comedi%d: me4000: me4000_ai_isr(): "
1892 "Buffer overflow\n", dev
->minor
);
1898 /* Work is done, so reset the interrupt */
1899 ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n");
1900 tmp
|= ME4000_AI_CTRL_BIT_HF_IRQ_RESET
;
1901 me4000_outl(dev
, tmp
, ai_context
->ctrl_reg
);
1902 tmp
&= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET
;
1903 me4000_outl(dev
, tmp
, ai_context
->ctrl_reg
);
1907 ai_context
->irq_status_reg
) & ME4000_IRQ_STATUS_BIT_SC
) {
1909 ("me4000_ai_isr(): Sample counter interrupt occured\n");
1911 s
->async
->events
|= COMEDI_CB_BLOCK
| COMEDI_CB_EOA
;
1914 * Acquisition is complete, so stop
1915 * conversion and disable all interrupts
1917 tmp
= me4000_inl(dev
, ai_context
->ctrl_reg
);
1918 tmp
|= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP
;
1919 tmp
&= ~(ME4000_AI_CTRL_BIT_HF_IRQ
| ME4000_AI_CTRL_BIT_SC_IRQ
);
1920 me4000_outl(dev
, tmp
, ai_context
->ctrl_reg
);
1922 /* Poll data until fifo empty */
1923 while (inl(ai_context
->ctrl_reg
) & ME4000_AI_STATUS_BIT_EF_DATA
) {
1924 /* Read value from data fifo */
1925 lval
= inl(ai_context
->data_reg
) & 0xFFFF;
1928 if (!comedi_buf_put(s
->async
, lval
)) {
1930 "comedi%d: me4000: me4000_ai_isr(): "
1931 "Buffer overflow\n", dev
->minor
);
1932 s
->async
->events
|= COMEDI_CB_OVERFLOW
;
1937 /* Work is done, so reset the interrupt */
1939 ("me4000_ai_isr(): Reset interrupt from sample counter\n");
1940 tmp
|= ME4000_AI_CTRL_BIT_SC_IRQ_RESET
;
1941 me4000_outl(dev
, tmp
, ai_context
->ctrl_reg
);
1942 tmp
&= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET
;
1943 me4000_outl(dev
, tmp
, ai_context
->ctrl_reg
);
1946 ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s
->async
->events
);
1948 if (s
->async
->events
)
1949 comedi_event(dev
, s
);
1954 /*=============================================================================
1955 Analog output section
1956 ===========================================================================*/
1958 static int me4000_ao_insn_write(struct comedi_device
*dev
,
1959 struct comedi_subdevice
*s
,
1960 struct comedi_insn
*insn
, unsigned int *data
)
1963 int chan
= CR_CHAN(insn
->chanspec
);
1964 int rang
= CR_RANGE(insn
->chanspec
);
1965 int aref
= CR_AREF(insn
->chanspec
);
1968 CALL_PDEBUG("In me4000_ao_insn_write()\n");
1972 } else if (insn
->n
> 1) {
1974 "comedi%d: me4000: me4000_ao_insn_write(): "
1975 "Invalid instruction length %d\n", dev
->minor
, insn
->n
);
1979 if (chan
>= thisboard
->ao
.count
) {
1981 "comedi%d: me4000: me4000_ao_insn_write(): "
1982 "Invalid channel %d\n", dev
->minor
, insn
->n
);
1988 "comedi%d: me4000: me4000_ao_insn_write(): "
1989 "Invalid range %d\n", dev
->minor
, insn
->n
);
1993 if (aref
!= AREF_GROUND
&& aref
!= AREF_COMMON
) {
1995 "comedi%d: me4000: me4000_ao_insn_write(): "
1996 "Invalid aref %d\n", dev
->minor
, insn
->n
);
2000 /* Stop any running conversion */
2001 tmp
= me4000_inl(dev
, info
->ao_context
[chan
].ctrl_reg
);
2002 tmp
|= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP
;
2003 me4000_outl(dev
, tmp
, info
->ao_context
[chan
].ctrl_reg
);
2005 /* Clear control register and set to single mode */
2006 me4000_outl(dev
, 0x0, info
->ao_context
[chan
].ctrl_reg
);
2008 /* Write data value */
2009 me4000_outl(dev
, data
[0], info
->ao_context
[chan
].single_reg
);
2011 /* Store in the mirror */
2012 info
->ao_context
[chan
].mirror
= data
[0];
2017 static int me4000_ao_insn_read(struct comedi_device
*dev
,
2018 struct comedi_subdevice
*s
,
2019 struct comedi_insn
*insn
, unsigned int *data
)
2021 int chan
= CR_CHAN(insn
->chanspec
);
2025 } else if (insn
->n
> 1) {
2027 ("comedi%d: me4000: me4000_ao_insn_read(): "
2028 "Invalid instruction length\n", dev
->minor
);
2032 data
[0] = info
->ao_context
[chan
].mirror
;
2037 /*=============================================================================
2039 ===========================================================================*/
2041 static int me4000_dio_insn_bits(struct comedi_device
*dev
,
2042 struct comedi_subdevice
*s
,
2043 struct comedi_insn
*insn
, unsigned int *data
)
2046 CALL_PDEBUG("In me4000_dio_insn_bits()\n");
2048 /* Length of data must be 2 (mask and new data, see below) */
2054 ("comedi%d: me4000: me4000_dio_insn_bits(): "
2055 "Invalid instruction length\n", dev
->minor
);
2060 * The insn data consists of a mask in data[0] and the new data
2061 * in data[1]. The mask defines which bits we are concerning about.
2062 * The new data must be anded with the mask.
2063 * Each channel corresponds to a bit.
2066 /* Check if requested ports are configured for output */
2067 if ((s
->io_bits
& data
[0]) != data
[0])
2070 s
->state
&= ~data
[0];
2071 s
->state
|= data
[0] & data
[1];
2073 /* Write out the new digital output lines */
2074 me4000_outl(dev
, (s
->state
>> 0) & 0xFF,
2075 info
->dio_context
.port_0_reg
);
2076 me4000_outl(dev
, (s
->state
>> 8) & 0xFF,
2077 info
->dio_context
.port_1_reg
);
2078 me4000_outl(dev
, (s
->state
>> 16) & 0xFF,
2079 info
->dio_context
.port_2_reg
);
2080 me4000_outl(dev
, (s
->state
>> 24) & 0xFF,
2081 info
->dio_context
.port_3_reg
);
2084 /* On return, data[1] contains the value of
2085 the digital input and output lines. */
2087 ((me4000_inl(dev
, info
->dio_context
.port_0_reg
) & 0xFF) << 0) |
2088 ((me4000_inl(dev
, info
->dio_context
.port_1_reg
) & 0xFF) << 8) |
2089 ((me4000_inl(dev
, info
->dio_context
.port_2_reg
) & 0xFF) << 16) |
2090 ((me4000_inl(dev
, info
->dio_context
.port_3_reg
) & 0xFF) << 24);
2095 static int me4000_dio_insn_config(struct comedi_device
*dev
,
2096 struct comedi_subdevice
*s
,
2097 struct comedi_insn
*insn
, unsigned int *data
)
2100 int chan
= CR_CHAN(insn
->chanspec
);
2102 CALL_PDEBUG("In me4000_dio_insn_config()\n");
2104 if (data
[0] == INSN_CONFIG_DIO_QUERY
) {
2106 (s
->io_bits
& (1 << chan
)) ? COMEDI_OUTPUT
: COMEDI_INPUT
;
2111 * The input or output configuration of each digital line is
2112 * configured by a special insn_config instruction. chanspec
2113 * contains the channel to be changed, and data[0] contains the
2114 * value COMEDI_INPUT or COMEDI_OUTPUT.
2115 * On the ME-4000 it is only possible to switch port wise (8 bit)
2118 tmp
= me4000_inl(dev
, info
->dio_context
.ctrl_reg
);
2120 if (data
[0] == COMEDI_OUTPUT
) {
2123 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_0
|
2124 ME4000_DIO_CTRL_BIT_MODE_1
);
2125 tmp
|= ME4000_DIO_CTRL_BIT_MODE_0
;
2126 } else if (chan
< 16) {
2128 * Chech for optoisolated ME-4000 version.
2129 * If one the first port is a fixed output
2130 * port and the second is a fixed input port.
2132 if (!me4000_inl(dev
, info
->dio_context
.dir_reg
))
2135 s
->io_bits
|= 0xFF00;
2136 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_2
|
2137 ME4000_DIO_CTRL_BIT_MODE_3
);
2138 tmp
|= ME4000_DIO_CTRL_BIT_MODE_2
;
2139 } else if (chan
< 24) {
2140 s
->io_bits
|= 0xFF0000;
2141 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_4
|
2142 ME4000_DIO_CTRL_BIT_MODE_5
);
2143 tmp
|= ME4000_DIO_CTRL_BIT_MODE_4
;
2144 } else if (chan
< 32) {
2145 s
->io_bits
|= 0xFF000000;
2146 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_6
|
2147 ME4000_DIO_CTRL_BIT_MODE_7
);
2148 tmp
|= ME4000_DIO_CTRL_BIT_MODE_6
;
2155 * Chech for optoisolated ME-4000 version.
2156 * If one the first port is a fixed output
2157 * port and the second is a fixed input port.
2159 if (!me4000_inl(dev
, info
->dio_context
.dir_reg
))
2162 s
->io_bits
&= ~0xFF;
2163 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_0
|
2164 ME4000_DIO_CTRL_BIT_MODE_1
);
2165 } else if (chan
< 16) {
2166 s
->io_bits
&= ~0xFF00;
2167 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_2
|
2168 ME4000_DIO_CTRL_BIT_MODE_3
);
2169 } else if (chan
< 24) {
2170 s
->io_bits
&= ~0xFF0000;
2171 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_4
|
2172 ME4000_DIO_CTRL_BIT_MODE_5
);
2173 } else if (chan
< 32) {
2174 s
->io_bits
&= ~0xFF000000;
2175 tmp
&= ~(ME4000_DIO_CTRL_BIT_MODE_6
|
2176 ME4000_DIO_CTRL_BIT_MODE_7
);
2182 me4000_outl(dev
, tmp
, info
->dio_context
.ctrl_reg
);
2187 /*=============================================================================
2189 ===========================================================================*/
2191 static int cnt_reset(struct comedi_device
*dev
, unsigned int channel
)
2194 CALL_PDEBUG("In cnt_reset()\n");
2198 me4000_outb(dev
, 0x30, info
->cnt_context
.ctrl_reg
);
2199 me4000_outb(dev
, 0x00, info
->cnt_context
.counter_0_reg
);
2200 me4000_outb(dev
, 0x00, info
->cnt_context
.counter_0_reg
);
2203 me4000_outb(dev
, 0x70, info
->cnt_context
.ctrl_reg
);
2204 me4000_outb(dev
, 0x00, info
->cnt_context
.counter_1_reg
);
2205 me4000_outb(dev
, 0x00, info
->cnt_context
.counter_1_reg
);
2208 me4000_outb(dev
, 0xB0, info
->cnt_context
.ctrl_reg
);
2209 me4000_outb(dev
, 0x00, info
->cnt_context
.counter_2_reg
);
2210 me4000_outb(dev
, 0x00, info
->cnt_context
.counter_2_reg
);
2214 "comedi%d: me4000: cnt_reset(): Invalid channel\n",
2222 static int cnt_config(struct comedi_device
*dev
, unsigned int channel
,
2227 CALL_PDEBUG("In cnt_config()\n");
2231 tmp
|= ME4000_CNT_COUNTER_0
;
2234 tmp
|= ME4000_CNT_COUNTER_1
;
2237 tmp
|= ME4000_CNT_COUNTER_2
;
2241 "comedi%d: me4000: cnt_config(): Invalid channel\n",
2248 tmp
|= ME4000_CNT_MODE_0
;
2251 tmp
|= ME4000_CNT_MODE_1
;
2254 tmp
|= ME4000_CNT_MODE_2
;
2257 tmp
|= ME4000_CNT_MODE_3
;
2260 tmp
|= ME4000_CNT_MODE_4
;
2263 tmp
|= ME4000_CNT_MODE_5
;
2267 "comedi%d: me4000: cnt_config(): Invalid counter mode\n",
2272 /* Write the control word */
2274 me4000_outb(dev
, tmp
, info
->cnt_context
.ctrl_reg
);
2279 static int me4000_cnt_insn_config(struct comedi_device
*dev
,
2280 struct comedi_subdevice
*s
,
2281 struct comedi_insn
*insn
, unsigned int *data
)
2286 CALL_PDEBUG("In me4000_cnt_insn_config()\n");
2292 "comedi%d: me4000: me4000_cnt_insn_config(): "
2293 "Invalid instruction length%d\n",
2294 dev
->minor
, insn
->n
);
2298 err
= cnt_reset(dev
, insn
->chanspec
);
2302 case GPCT_SET_OPERATION
:
2305 "comedi%d: me4000: me4000_cnt_insn_config(): "
2306 "Invalid instruction length%d\n",
2307 dev
->minor
, insn
->n
);
2311 err
= cnt_config(dev
, insn
->chanspec
, data
[1]);
2317 "comedi%d: me4000: me4000_cnt_insn_config(): "
2318 "Invalid instruction\n", dev
->minor
);
2325 static int me4000_cnt_insn_read(struct comedi_device
*dev
,
2326 struct comedi_subdevice
*s
,
2327 struct comedi_insn
*insn
, unsigned int *data
)
2332 CALL_PDEBUG("In me4000_cnt_insn_read()\n");
2339 "comedi%d: me4000: me4000_cnt_insn_read(): "
2340 "Invalid instruction length %d\n",
2341 dev
->minor
, insn
->n
);
2345 switch (insn
->chanspec
) {
2347 tmp
= me4000_inb(dev
, info
->cnt_context
.counter_0_reg
);
2349 tmp
= me4000_inb(dev
, info
->cnt_context
.counter_0_reg
);
2350 data
[0] |= tmp
<< 8;
2353 tmp
= me4000_inb(dev
, info
->cnt_context
.counter_1_reg
);
2355 tmp
= me4000_inb(dev
, info
->cnt_context
.counter_1_reg
);
2356 data
[0] |= tmp
<< 8;
2359 tmp
= me4000_inb(dev
, info
->cnt_context
.counter_2_reg
);
2361 tmp
= me4000_inb(dev
, info
->cnt_context
.counter_2_reg
);
2362 data
[0] |= tmp
<< 8;
2366 "comedi%d: me4000: me4000_cnt_insn_read(): "
2367 "Invalid channel %d\n",
2368 dev
->minor
, insn
->chanspec
);
2375 static int me4000_cnt_insn_write(struct comedi_device
*dev
,
2376 struct comedi_subdevice
*s
,
2377 struct comedi_insn
*insn
, unsigned int *data
)
2382 CALL_PDEBUG("In me4000_cnt_insn_write()\n");
2386 } else if (insn
->n
> 1) {
2388 "comedi%d: me4000: me4000_cnt_insn_write(): "
2389 "Invalid instruction length %d\n",
2390 dev
->minor
, insn
->n
);
2394 switch (insn
->chanspec
) {
2396 tmp
= data
[0] & 0xFF;
2397 me4000_outb(dev
, tmp
, info
->cnt_context
.counter_0_reg
);
2398 tmp
= (data
[0] >> 8) & 0xFF;
2399 me4000_outb(dev
, tmp
, info
->cnt_context
.counter_0_reg
);
2402 tmp
= data
[0] & 0xFF;
2403 me4000_outb(dev
, tmp
, info
->cnt_context
.counter_1_reg
);
2404 tmp
= (data
[0] >> 8) & 0xFF;
2405 me4000_outb(dev
, tmp
, info
->cnt_context
.counter_1_reg
);
2408 tmp
= data
[0] & 0xFF;
2409 me4000_outb(dev
, tmp
, info
->cnt_context
.counter_2_reg
);
2410 tmp
= (data
[0] >> 8) & 0xFF;
2411 me4000_outb(dev
, tmp
, info
->cnt_context
.counter_2_reg
);
2415 "comedi%d: me4000: me4000_cnt_insn_write(): "
2416 "Invalid channel %d\n",
2417 dev
->minor
, insn
->chanspec
);
2424 static int __devinit
driver_me4000_pci_probe(struct pci_dev
*dev
,
2425 const struct pci_device_id
*ent
)
2427 return comedi_pci_auto_config(dev
, driver_me4000
.driver_name
);
2430 static void __devexit
driver_me4000_pci_remove(struct pci_dev
*dev
)
2432 comedi_pci_auto_unconfig(dev
);
2435 static struct pci_driver driver_me4000_pci_driver
= {
2436 .id_table
= me4000_pci_table
,
2437 .probe
= &driver_me4000_pci_probe
,
2438 .remove
= __devexit_p(&driver_me4000_pci_remove
)
2441 static int __init
driver_me4000_init_module(void)
2445 retval
= comedi_driver_register(&driver_me4000
);
2449 driver_me4000_pci_driver
.name
= (char *)driver_me4000
.driver_name
;
2450 return pci_register_driver(&driver_me4000_pci_driver
);
2453 static void __exit
driver_me4000_cleanup_module(void)
2455 pci_unregister_driver(&driver_me4000_pci_driver
);
2456 comedi_driver_unregister(&driver_me4000
);
2459 module_init(driver_me4000_init_module
);
2460 module_exit(driver_me4000_cleanup_module
);
2462 MODULE_AUTHOR("Comedi http://www.comedi.org");
2463 MODULE_DESCRIPTION("Comedi low-level driver");
2464 MODULE_LICENSE("GPL");