Staging: comedi: Remove lsampl_t and sampl_t typedefs
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / comedi / drivers / me4000.c
1 /*
2 comedi/drivers/me4000.c
3 Source code for the Meilhaus ME-4000 board family.
4
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23 /*
24 Driver: me4000
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)
30
31 Supports:
32
33 - Analog Input
34 - Analog Output
35 - Digital I/O
36 - Counter
37
38 Configuration Options:
39
40 [0] - PCI bus number (optional)
41 [1] - PCI slot number (optional)
42
43 If bus/slot is not specified, the first available PCI
44 device will be used.
45
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
50 broken.
51
52 */
53
54 #include "../comedidev.h"
55
56 #include <linux/delay.h>
57 #include <linux/list.h>
58 #include <linux/spinlock.h>
59
60 #include "comedi_pci.h"
61 #include "me4000.h"
62 #if 0
63 /* file removed due to GPL incompatibility */
64 #include "me4000_fw.h"
65 #endif
66
67 /*=============================================================================
68 PCI device table.
69 This is used by modprobe to translate PCI IDs to drivers.
70 ===========================================================================*/
71
72 static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
73 {PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
74
75 {PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
76 {PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
77 {PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
78 {PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
79
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
85 {PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
86 {PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
87 {PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
88 {PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
89
90 {0}
91 };
92
93 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
94
95 static const me4000_board_t me4000_boards[] = {
96 {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
97
98 {"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
99 {"ME-4660i", 0x4661, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
100 {"ME-4660s", 0x4662, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
101 {"ME-4660is", 0x4663, {0, 0}, {32, 8, 16, 0}, {4}, {3}},
102
103 {"ME-4670", 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
104 {"ME-4670i", 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
105 {"ME-4670s", 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
106 {"ME-4670is", 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
107
108 {"ME-4680", 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
109 {"ME-4680i", 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
110 {"ME-4680s", 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
111 {"ME-4680is", 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
112
113 {0},
114 };
115
116 #define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
117
118 /*-----------------------------------------------------------------------------
119 Comedi function prototypes
120 ---------------------------------------------------------------------------*/
121 static int me4000_attach(comedi_device *dev, comedi_devconfig *it);
122 static int me4000_detach(comedi_device *dev);
123 static comedi_driver driver_me4000 = {
124 driver_name:"me4000",
125 module : THIS_MODULE,
126 attach : me4000_attach,
127 detach : me4000_detach,
128 };
129
130 /*-----------------------------------------------------------------------------
131 Meilhaus function prototypes
132 ---------------------------------------------------------------------------*/
133 static int me4000_probe(comedi_device *dev, comedi_devconfig *it);
134 static int get_registers(comedi_device *dev, struct pci_dev *pci_dev_p);
135 static int init_board_info(comedi_device *dev, struct pci_dev *pci_dev_p);
136 static int init_ao_context(comedi_device *dev);
137 static int init_ai_context(comedi_device *dev);
138 static int init_dio_context(comedi_device *dev);
139 static int init_cnt_context(comedi_device *dev);
140 static int xilinx_download(comedi_device *dev);
141 static int reset_board(comedi_device *dev);
142
143 static int me4000_dio_insn_bits(comedi_device *dev,
144 comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
145
146 static int me4000_dio_insn_config(comedi_device *dev,
147 comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
148
149 static int cnt_reset(comedi_device *dev, unsigned int channel);
150
151 static int cnt_config(comedi_device *dev,
152 unsigned int channel, unsigned int mode);
153
154 static int me4000_cnt_insn_config(comedi_device *dev,
155 comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
156
157 static int me4000_cnt_insn_write(comedi_device *dev,
158 comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
159
160 static int me4000_cnt_insn_read(comedi_device *dev,
161 comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
162
163 static int me4000_ai_insn_read(comedi_device *dev,
164 comedi_subdevice *subdevice, comedi_insn *insn, unsigned int *data);
165
166 static int me4000_ai_cancel(comedi_device *dev, comedi_subdevice *s);
167
168 static int ai_check_chanlist(comedi_device *dev,
169 comedi_subdevice *s, comedi_cmd *cmd);
170
171 static int ai_round_cmd_args(comedi_device *dev,
172 comedi_subdevice *s,
173 comedi_cmd *cmd,
174 unsigned int *init_ticks,
175 unsigned int *scan_ticks, unsigned int *chan_ticks);
176
177 static int ai_prepare(comedi_device *dev,
178 comedi_subdevice *s,
179 comedi_cmd *cmd,
180 unsigned int init_ticks,
181 unsigned int scan_ticks, unsigned int chan_ticks);
182
183 static int ai_write_chanlist(comedi_device *dev,
184 comedi_subdevice *s, comedi_cmd *cmd);
185
186 static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG);
187
188 static int me4000_ai_do_cmd_test(comedi_device *dev,
189 comedi_subdevice *s, comedi_cmd *cmd);
190
191 static int me4000_ai_do_cmd(comedi_device *dev, comedi_subdevice *s);
192
193 static int me4000_ao_insn_write(comedi_device *dev,
194 comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
195
196 static int me4000_ao_insn_read(comedi_device *dev,
197 comedi_subdevice *s, comedi_insn *insn, unsigned int *data);
198
199 /*-----------------------------------------------------------------------------
200 Meilhaus inline functions
201 ---------------------------------------------------------------------------*/
202
203 static inline void me4000_outb(comedi_device *dev, unsigned char value,
204 unsigned long port)
205 {
206 PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
207 outb(value, port);
208 }
209
210 static inline void me4000_outl(comedi_device *dev, unsigned long value,
211 unsigned long port)
212 {
213 PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
214 outl(value, port);
215 }
216
217 static inline unsigned long me4000_inl(comedi_device *dev, unsigned long port)
218 {
219 unsigned long value;
220 value = inl(port);
221 PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port);
222 return value;
223 }
224
225 static inline unsigned char me4000_inb(comedi_device *dev, unsigned long port)
226 {
227 unsigned char value;
228 value = inb(port);
229 PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port);
230 return value;
231 }
232
233 static const comedi_lrange me4000_ai_range = {
234 4,
235 {
236 UNI_RANGE(2.5),
237 UNI_RANGE(10),
238 BIP_RANGE(2.5),
239 BIP_RANGE(10),
240 }
241 };
242
243 static const comedi_lrange me4000_ao_range = {
244 1,
245 {
246 BIP_RANGE(10),
247 }
248 };
249
250 static int me4000_attach(comedi_device *dev, comedi_devconfig *it)
251 {
252 comedi_subdevice *s;
253 int result;
254
255 CALL_PDEBUG("In me4000_attach()\n");
256
257 result = me4000_probe(dev, it);
258 if (result)
259 return result;
260
261 /*
262 * Allocate the subdevice structures. alloc_subdevice() is a
263 * convenient macro defined in comedidev.h. It relies on
264 * n_subdevices being set correctly.
265 */
266 if (alloc_subdevices(dev, 4) < 0)
267 return -ENOMEM;
268
269 /*=========================================================================
270 Analog input subdevice
271 ========================================================================*/
272
273 s = dev->subdevices + 0;
274
275 if (thisboard->ai.count) {
276 s->type = COMEDI_SUBD_AI;
277 s->subdev_flags =
278 SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
279 s->n_chan = thisboard->ai.count;
280 s->maxdata = 0xFFFF; /* 16 bit ADC */
281 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
282 s->range_table = &me4000_ai_range;
283 s->insn_read = me4000_ai_insn_read;
284
285 if (info->irq > 0) {
286 if (comedi_request_irq(info->irq, me4000_ai_isr,
287 IRQF_SHARED, "ME-4000", dev)) {
288 printk("comedi%d: me4000: me4000_attach(): Unable to allocate irq\n", dev->minor);
289 } else {
290 dev->read_subdev = s;
291 s->subdev_flags |= SDF_CMD_READ;
292 s->cancel = me4000_ai_cancel;
293 s->do_cmdtest = me4000_ai_do_cmd_test;
294 s->do_cmd = me4000_ai_do_cmd;
295 }
296 } else {
297 printk(KERN_WARNING
298 "comedi%d: me4000: me4000_attach(): No interrupt available\n",
299 dev->minor);
300 }
301 } else {
302 s->type = COMEDI_SUBD_UNUSED;
303 }
304
305 /*=========================================================================
306 Analog output subdevice
307 ========================================================================*/
308
309 s = dev->subdevices + 1;
310
311 if (thisboard->ao.count) {
312 s->type = COMEDI_SUBD_AO;
313 s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
314 s->n_chan = thisboard->ao.count;
315 s->maxdata = 0xFFFF; /* 16 bit DAC */
316 s->range_table = &me4000_ao_range;
317 s->insn_write = me4000_ao_insn_write;
318 s->insn_read = me4000_ao_insn_read;
319 } else {
320 s->type = COMEDI_SUBD_UNUSED;
321 }
322
323 /*=========================================================================
324 Digital I/O subdevice
325 ========================================================================*/
326
327 s = dev->subdevices + 2;
328
329 if (thisboard->dio.count) {
330 s->type = COMEDI_SUBD_DIO;
331 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
332 s->n_chan = thisboard->dio.count * 8;
333 s->maxdata = 1;
334 s->range_table = &range_digital;
335 s->insn_bits = me4000_dio_insn_bits;
336 s->insn_config = me4000_dio_insn_config;
337 } else {
338 s->type = COMEDI_SUBD_UNUSED;
339 }
340
341 /*
342 * Check for optoisolated ME-4000 version. If one the first
343 * port is a fixed output port and the second is a fixed input port.
344 */
345 if (!me4000_inl(dev, info->dio_context.dir_reg)) {
346 s->io_bits |= 0xFF;
347 me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0,
348 info->dio_context.dir_reg);
349 }
350
351 /*=========================================================================
352 Counter subdevice
353 ========================================================================*/
354
355 s = dev->subdevices + 3;
356
357 if (thisboard->cnt.count) {
358 s->type = COMEDI_SUBD_COUNTER;
359 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
360 s->n_chan = thisboard->cnt.count;
361 s->maxdata = 0xFFFF; /* 16 bit counters */
362 s->insn_read = me4000_cnt_insn_read;
363 s->insn_write = me4000_cnt_insn_write;
364 s->insn_config = me4000_cnt_insn_config;
365 } else {
366 s->type = COMEDI_SUBD_UNUSED;
367 }
368
369 return 0;
370 }
371
372 static int me4000_probe(comedi_device *dev, comedi_devconfig *it)
373 {
374 struct pci_dev *pci_device;
375 int result, i;
376 me4000_board_t *board;
377
378 CALL_PDEBUG("In me4000_probe()\n");
379
380 /* Allocate private memory */
381 if (alloc_private(dev, sizeof(me4000_info_t)) < 0)
382 return -ENOMEM;
383
384 /*
385 * Probe the device to determine what device in the series it is.
386 */
387 for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
388 pci_device != NULL;
389 pci_device =
390 pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
391 if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
392 for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
393 if (me4000_boards[i].device_id ==
394 pci_device->device) {
395 /* Was a particular bus/slot requested? */
396 if ((it->options[0] != 0)
397 || (it->options[1] != 0)) {
398 /* Are we on the wrong bus/slot? */
399 if (pci_device->bus->number !=
400 it->options[0]
401 || PCI_SLOT(pci_device->
402 devfn) !=
403 it->options[1]) {
404 continue;
405 }
406 }
407 dev->board_ptr = me4000_boards + i;
408 board = (me4000_board_t *) dev->
409 board_ptr;
410 info->pci_dev_p = pci_device;
411 goto found;
412 }
413 }
414 }
415 }
416
417 printk(KERN_ERR
418 "comedi%d: me4000: me4000_probe(): No supported board found (req. bus/slot : %d/%d)\n",
419 dev->minor, it->options[0], it->options[1]);
420 return -ENODEV;
421
422 found:
423
424 printk(KERN_INFO
425 "comedi%d: me4000: me4000_probe(): Found %s at PCI bus %d, slot %d\n",
426 dev->minor, me4000_boards[i].name, pci_device->bus->number,
427 PCI_SLOT(pci_device->devfn));
428
429 /* Set data in device structure */
430 dev->board_name = board->name;
431
432 /* Enable PCI device and request regions */
433 result = comedi_pci_enable(pci_device, dev->board_name);
434 if (result) {
435 printk(KERN_ERR
436 "comedi%d: me4000: me4000_probe(): Cannot enable PCI device and request I/O regions\n",
437 dev->minor);
438 return result;
439 }
440
441 /* Get the PCI base registers */
442 result = get_registers(dev, pci_device);
443 if (result) {
444 printk(KERN_ERR
445 "comedi%d: me4000: me4000_probe(): Cannot get registers\n",
446 dev->minor);
447 return result;
448 }
449 /* Initialize board info */
450 result = init_board_info(dev, pci_device);
451 if (result) {
452 printk(KERN_ERR
453 "comedi%d: me4000: me4000_probe(): Cannot init baord info\n",
454 dev->minor);
455 return result;
456 }
457
458 /* Init analog output context */
459 result = init_ao_context(dev);
460 if (result) {
461 printk(KERN_ERR
462 "comedi%d: me4000: me4000_probe(): Cannot init ao context\n",
463 dev->minor);
464 return result;
465 }
466
467 /* Init analog input context */
468 result = init_ai_context(dev);
469 if (result) {
470 printk(KERN_ERR
471 "comedi%d: me4000: me4000_probe(): Cannot init ai context\n",
472 dev->minor);
473 return result;
474 }
475
476 /* Init digital I/O context */
477 result = init_dio_context(dev);
478 if (result) {
479 printk(KERN_ERR
480 "comedi%d: me4000: me4000_probe(): Cannot init dio context\n",
481 dev->minor);
482 return result;
483 }
484
485 /* Init counter context */
486 result = init_cnt_context(dev);
487 if (result) {
488 printk(KERN_ERR
489 "comedi%d: me4000: me4000_probe(): Cannot init cnt context\n",
490 dev->minor);
491 return result;
492 }
493
494 /* Download the xilinx firmware */
495 result = xilinx_download(dev);
496 if (result) {
497 printk(KERN_ERR
498 "comedi%d: me4000: me4000_probe(): Can't download firmware\n",
499 dev->minor);
500 return result;
501 }
502
503 /* Make a hardware reset */
504 result = reset_board(dev);
505 if (result) {
506 printk(KERN_ERR
507 "comedi%d: me4000: me4000_probe(): Can't reset board\n",
508 dev->minor);
509 return result;
510 }
511
512 return 0;
513 }
514
515 static int get_registers(comedi_device *dev, struct pci_dev *pci_dev_p)
516 {
517
518 CALL_PDEBUG("In get_registers()\n");
519
520 /*--------------------------- plx regbase ---------------------------------*/
521
522 info->plx_regbase = pci_resource_start(pci_dev_p, 1);
523 if (info->plx_regbase == 0) {
524 printk(KERN_ERR
525 "comedi%d: me4000: get_registers(): PCI base address 1 is not available\n",
526 dev->minor);
527 return -ENODEV;
528 }
529 info->plx_regbase_size = pci_resource_len(pci_dev_p, 1);
530
531 /*--------------------------- me4000 regbase ------------------------------*/
532
533 info->me4000_regbase = pci_resource_start(pci_dev_p, 2);
534 if (info->me4000_regbase == 0) {
535 printk(KERN_ERR
536 "comedi%d: me4000: get_registers(): PCI base address 2 is not available\n",
537 dev->minor);
538 return -ENODEV;
539 }
540 info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2);
541
542 /*--------------------------- timer regbase ------------------------------*/
543
544 info->timer_regbase = pci_resource_start(pci_dev_p, 3);
545 if (info->timer_regbase == 0) {
546 printk(KERN_ERR
547 "comedi%d: me4000: get_registers(): PCI base address 3 is not available\n",
548 dev->minor);
549 return -ENODEV;
550 }
551 info->timer_regbase_size = pci_resource_len(pci_dev_p, 3);
552
553 /*--------------------------- program regbase ------------------------------*/
554
555 info->program_regbase = pci_resource_start(pci_dev_p, 5);
556 if (info->program_regbase == 0) {
557 printk(KERN_ERR
558 "comedi%d: me4000: get_registers(): PCI base address 5 is not available\n",
559 dev->minor);
560 return -ENODEV;
561 }
562 info->program_regbase_size = pci_resource_len(pci_dev_p, 5);
563
564 return 0;
565 }
566
567 static int init_board_info(comedi_device *dev, struct pci_dev *pci_dev_p)
568 {
569 int result;
570
571 CALL_PDEBUG("In init_board_info()\n");
572
573 /* Init spin locks */
574 /* spin_lock_init(&info->preload_lock); */
575 /* spin_lock_init(&info->ai_ctrl_lock); */
576
577 /* Get the serial number */
578 result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
579 if (result != PCIBIOS_SUCCESSFUL)
580 return result;
581
582 /* Get the hardware revision */
583 result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision);
584 if (result != PCIBIOS_SUCCESSFUL)
585 return result;
586
587 /* Get the vendor id */
588 info->vendor_id = pci_dev_p->vendor;
589
590 /* Get the device id */
591 info->device_id = pci_dev_p->device;
592
593 /* Get the irq assigned to the board */
594 info->irq = pci_dev_p->irq;
595
596 return 0;
597 }
598
599 static int init_ao_context(comedi_device *dev)
600 {
601 int i;
602
603 CALL_PDEBUG("In init_ao_context()\n");
604
605 for (i = 0; i < thisboard->ao.count; i++) {
606 /* spin_lock_init(&info->ao_context[i].use_lock); */
607 info->ao_context[i].irq = info->irq;
608
609 switch (i) {
610 case 0:
611 info->ao_context[i].ctrl_reg =
612 info->me4000_regbase + ME4000_AO_00_CTRL_REG;
613 info->ao_context[i].status_reg =
614 info->me4000_regbase + ME4000_AO_00_STATUS_REG;
615 info->ao_context[i].fifo_reg =
616 info->me4000_regbase + ME4000_AO_00_FIFO_REG;
617 info->ao_context[i].single_reg =
618 info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
619 info->ao_context[i].timer_reg =
620 info->me4000_regbase + ME4000_AO_00_TIMER_REG;
621 info->ao_context[i].irq_status_reg =
622 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
623 info->ao_context[i].preload_reg =
624 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
625 break;
626 case 1:
627 info->ao_context[i].ctrl_reg =
628 info->me4000_regbase + ME4000_AO_01_CTRL_REG;
629 info->ao_context[i].status_reg =
630 info->me4000_regbase + ME4000_AO_01_STATUS_REG;
631 info->ao_context[i].fifo_reg =
632 info->me4000_regbase + ME4000_AO_01_FIFO_REG;
633 info->ao_context[i].single_reg =
634 info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
635 info->ao_context[i].timer_reg =
636 info->me4000_regbase + ME4000_AO_01_TIMER_REG;
637 info->ao_context[i].irq_status_reg =
638 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
639 info->ao_context[i].preload_reg =
640 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
641 break;
642 case 2:
643 info->ao_context[i].ctrl_reg =
644 info->me4000_regbase + ME4000_AO_02_CTRL_REG;
645 info->ao_context[i].status_reg =
646 info->me4000_regbase + ME4000_AO_02_STATUS_REG;
647 info->ao_context[i].fifo_reg =
648 info->me4000_regbase + ME4000_AO_02_FIFO_REG;
649 info->ao_context[i].single_reg =
650 info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
651 info->ao_context[i].timer_reg =
652 info->me4000_regbase + ME4000_AO_02_TIMER_REG;
653 info->ao_context[i].irq_status_reg =
654 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
655 info->ao_context[i].preload_reg =
656 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
657 break;
658 case 3:
659 info->ao_context[i].ctrl_reg =
660 info->me4000_regbase + ME4000_AO_03_CTRL_REG;
661 info->ao_context[i].status_reg =
662 info->me4000_regbase + ME4000_AO_03_STATUS_REG;
663 info->ao_context[i].fifo_reg =
664 info->me4000_regbase + ME4000_AO_03_FIFO_REG;
665 info->ao_context[i].single_reg =
666 info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
667 info->ao_context[i].timer_reg =
668 info->me4000_regbase + ME4000_AO_03_TIMER_REG;
669 info->ao_context[i].irq_status_reg =
670 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
671 info->ao_context[i].preload_reg =
672 info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
673 break;
674 default:
675 break;
676 }
677 }
678
679 return 0;
680 }
681
682 static int init_ai_context(comedi_device *dev)
683 {
684
685 CALL_PDEBUG("In init_ai_context()\n");
686
687 info->ai_context.irq = info->irq;
688
689 info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG;
690 info->ai_context.status_reg =
691 info->me4000_regbase + ME4000_AI_STATUS_REG;
692 info->ai_context.channel_list_reg =
693 info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
694 info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG;
695 info->ai_context.chan_timer_reg =
696 info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
697 info->ai_context.chan_pre_timer_reg =
698 info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
699 info->ai_context.scan_timer_low_reg =
700 info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
701 info->ai_context.scan_timer_high_reg =
702 info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
703 info->ai_context.scan_pre_timer_low_reg =
704 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
705 info->ai_context.scan_pre_timer_high_reg =
706 info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
707 info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG;
708 info->ai_context.irq_status_reg =
709 info->me4000_regbase + ME4000_IRQ_STATUS_REG;
710 info->ai_context.sample_counter_reg =
711 info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
712
713 return 0;
714 }
715
716 static int init_dio_context(comedi_device *dev)
717 {
718
719 CALL_PDEBUG("In init_dio_context()\n");
720
721 info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG;
722 info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG;
723 info->dio_context.port_0_reg =
724 info->me4000_regbase + ME4000_DIO_PORT_0_REG;
725 info->dio_context.port_1_reg =
726 info->me4000_regbase + ME4000_DIO_PORT_1_REG;
727 info->dio_context.port_2_reg =
728 info->me4000_regbase + ME4000_DIO_PORT_2_REG;
729 info->dio_context.port_3_reg =
730 info->me4000_regbase + ME4000_DIO_PORT_3_REG;
731
732 return 0;
733 }
734
735 static int init_cnt_context(comedi_device *dev)
736 {
737
738 CALL_PDEBUG("In init_cnt_context()\n");
739
740 info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG;
741 info->cnt_context.counter_0_reg =
742 info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
743 info->cnt_context.counter_1_reg =
744 info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
745 info->cnt_context.counter_2_reg =
746 info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
747
748 return 0;
749 }
750
751 #define FIRMWARE_NOT_AVAILABLE 1
752 #if FIRMWARE_NOT_AVAILABLE
753 extern unsigned char *xilinx_firm;
754 #endif
755
756 static int xilinx_download(comedi_device *dev)
757 {
758 u32 value = 0;
759 wait_queue_head_t queue;
760 int idx = 0;
761 int size = 0;
762
763 CALL_PDEBUG("In xilinx_download()\n");
764
765 init_waitqueue_head(&queue);
766
767 /*
768 * Set PLX local interrupt 2 polarity to high.
769 * Interrupt is thrown by init pin of xilinx.
770 */
771 outl(0x10, info->plx_regbase + PLX_INTCSR);
772
773 /* Set /CS and /WRITE of the Xilinx */
774 value = inl(info->plx_regbase + PLX_ICR);
775 value |= 0x100;
776 outl(value, info->plx_regbase + PLX_ICR);
777
778 /* Init Xilinx with CS1 */
779 inb(info->program_regbase + 0xC8);
780
781 /* Wait until /INIT pin is set */
782 udelay(20);
783 if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
784 printk(KERN_ERR
785 "comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
786 dev->minor);
787 return -EIO;
788 }
789
790 /* Reset /CS and /WRITE of the Xilinx */
791 value = inl(info->plx_regbase + PLX_ICR);
792 value &= ~0x100;
793 outl(value, info->plx_regbase + PLX_ICR);
794 if (FIRMWARE_NOT_AVAILABLE) {
795 comedi_error(dev,
796 "xilinx firmware unavailable due to licensing, aborting");
797 return -EIO;
798 } else {
799 /* Download Xilinx firmware */
800 size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
801 (xilinx_firm[2] << 8) + xilinx_firm[3];
802 udelay(10);
803
804 for (idx = 0; idx < size; idx++) {
805 outb(xilinx_firm[16 + idx], info->program_regbase);
806 udelay(10);
807
808 /* Check if BUSY flag is low */
809 if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
810 printk(KERN_ERR
811 "comedi%d: me4000: xilinx_download(): Xilinx is still busy (idx = %d)\n",
812 dev->minor, idx);
813 return -EIO;
814 }
815 }
816 }
817
818 /* If done flag is high download was successful */
819 if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
820 } else {
821 printk(KERN_ERR
822 "comedi%d: me4000: xilinx_download(): DONE flag is not set\n",
823 dev->minor);
824 printk(KERN_ERR
825 "comedi%d: me4000: xilinx_download(): Download not succesful\n",
826 dev->minor);
827 return -EIO;
828 }
829
830 /* Set /CS and /WRITE */
831 value = inl(info->plx_regbase + PLX_ICR);
832 value |= 0x100;
833 outl(value, info->plx_regbase + PLX_ICR);
834
835 return 0;
836 }
837
838 static int reset_board(comedi_device *dev)
839 {
840 unsigned long icr;
841
842 CALL_PDEBUG("In reset_board()\n");
843
844 /* Make a hardware reset */
845 icr = me4000_inl(dev, info->plx_regbase + PLX_ICR);
846 icr |= 0x40000000;
847 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
848 icr &= ~0x40000000;
849 me4000_outl(dev, icr, info->plx_regbase + PLX_ICR);
850
851 /* 0x8000 to the DACs means an output voltage of 0V */
852 me4000_outl(dev, 0x8000,
853 info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
854 me4000_outl(dev, 0x8000,
855 info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
856 me4000_outl(dev, 0x8000,
857 info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
858 me4000_outl(dev, 0x8000,
859 info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
860
861 /* Set both stop bits in the analog input control register */
862 me4000_outl(dev,
863 ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
864 info->me4000_regbase + ME4000_AI_CTRL_REG);
865
866 /* Set both stop bits in the analog output control register */
867 me4000_outl(dev,
868 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
869 info->me4000_regbase + ME4000_AO_00_CTRL_REG);
870 me4000_outl(dev,
871 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
872 info->me4000_regbase + ME4000_AO_01_CTRL_REG);
873 me4000_outl(dev,
874 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
875 info->me4000_regbase + ME4000_AO_02_CTRL_REG);
876 me4000_outl(dev,
877 ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
878 info->me4000_regbase + ME4000_AO_03_CTRL_REG);
879
880 /* Enable interrupts on the PLX */
881 me4000_outl(dev, 0x43, info->plx_regbase + PLX_INTCSR);
882
883 /* Set the adustment register for AO demux */
884 me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE,
885 info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
886
887 /* Set digital I/O direction for port 0 to output on isolated versions */
888 if (!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
889 me4000_outl(dev, 0x1,
890 info->me4000_regbase + ME4000_DIO_CTRL_REG);
891 }
892
893 return 0;
894 }
895
896 static int me4000_detach(comedi_device *dev)
897 {
898 CALL_PDEBUG("In me4000_detach()\n");
899
900 if (info) {
901 if (info->pci_dev_p) {
902 reset_board(dev);
903 if (info->plx_regbase)
904 comedi_pci_disable(info->pci_dev_p);
905 pci_dev_put(info->pci_dev_p);
906 }
907 }
908
909 return 0;
910 }
911
912 /*=============================================================================
913 Analog input section
914 ===========================================================================*/
915
916 static int me4000_ai_insn_read(comedi_device *dev,
917 comedi_subdevice *subdevice, comedi_insn *insn, unsigned int *data)
918 {
919
920 int chan = CR_CHAN(insn->chanspec);
921 int rang = CR_RANGE(insn->chanspec);
922 int aref = CR_AREF(insn->chanspec);
923
924 unsigned long entry = 0;
925 unsigned long tmp;
926 long lval;
927
928 CALL_PDEBUG("In me4000_ai_insn_read()\n");
929
930 if (insn->n == 0) {
931 return 0;
932 } else if (insn->n > 1) {
933 printk(KERN_ERR
934 "comedi%d: me4000: me4000_ai_insn_read(): Invalid instruction length %d\n",
935 dev->minor, insn->n);
936 return -EINVAL;
937 }
938
939 switch (rang) {
940 case 0:
941 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
942 break;
943 case 1:
944 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
945 break;
946 case 2:
947 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
948 break;
949 case 3:
950 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
951 break;
952 default:
953 printk(KERN_ERR
954 "comedi%d: me4000: me4000_ai_insn_read(): Invalid range specified\n",
955 dev->minor);
956 return -EINVAL;
957 }
958
959 switch (aref) {
960 case AREF_GROUND:
961 case AREF_COMMON:
962 if (chan >= thisboard->ai.count) {
963 printk(KERN_ERR
964 "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
965 dev->minor);
966 return -EINVAL;
967 }
968 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
969 break;
970
971 case AREF_DIFF:
972 if (rang == 0 || rang == 1) {
973 printk(KERN_ERR
974 "comedi%d: me4000: me4000_ai_insn_read(): Range must be bipolar when aref = diff\n",
975 dev->minor);
976 return -EINVAL;
977 }
978
979 if (chan >= thisboard->ai.diff_count) {
980 printk(KERN_ERR
981 "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
982 dev->minor);
983 return -EINVAL;
984 }
985 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
986 break;
987 default:
988 printk(KERN_ERR
989 "comedi%d: me4000: me4000_ai_insn_read(): Invalid aref specified\n",
990 dev->minor);
991 return -EINVAL;
992 }
993
994 entry |= ME4000_AI_LIST_LAST_ENTRY;
995
996 /* Clear channel list, data fifo and both stop bits */
997 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
998 tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
999 ME4000_AI_CTRL_BIT_DATA_FIFO |
1000 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1001 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1002
1003 /* Set the acquisition mode to single */
1004 tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
1005 ME4000_AI_CTRL_BIT_MODE_2);
1006 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1007
1008 /* Enable channel list and data fifo */
1009 tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
1010 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1011
1012 /* Generate channel list entry */
1013 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1014
1015 /* Set the timer to maximum sample rate */
1016 me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg);
1017 me4000_outl(dev, ME4000_AI_MIN_TICKS,
1018 info->ai_context.chan_pre_timer_reg);
1019
1020 /* Start conversion by dummy read */
1021 me4000_inl(dev, info->ai_context.start_reg);
1022
1023 /* Wait until ready */
1024 udelay(10);
1025 if (!(me4000_inl(dev, info->ai_context.
1026 status_reg) & ME4000_AI_STATUS_BIT_EF_DATA)) {
1027 printk(KERN_ERR
1028 "comedi%d: me4000: me4000_ai_insn_read(): Value not available after wait\n",
1029 dev->minor);
1030 return -EIO;
1031 }
1032
1033 /* Read value from data fifo */
1034 lval = me4000_inl(dev, info->ai_context.data_reg) & 0xFFFF;
1035 data[0] = lval ^ 0x8000;
1036
1037 return 1;
1038 }
1039
1040 static int me4000_ai_cancel(comedi_device *dev, comedi_subdevice *s)
1041 {
1042 unsigned long tmp;
1043
1044 CALL_PDEBUG("In me4000_ai_cancel()\n");
1045
1046 /* Stop any running conversion */
1047 tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
1048 tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
1049 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1050
1051 /* Clear the control register */
1052 me4000_outl(dev, 0x0, info->ai_context.ctrl_reg);
1053
1054 return 0;
1055 }
1056
1057 static int ai_check_chanlist(comedi_device *dev,
1058 comedi_subdevice *s, comedi_cmd *cmd)
1059 {
1060 int aref;
1061 int i;
1062
1063 CALL_PDEBUG("In ai_check_chanlist()\n");
1064
1065 /* Check whether a channel list is available */
1066 if (!cmd->chanlist_len) {
1067 printk(KERN_ERR
1068 "comedi%d: me4000: ai_check_chanlist(): No channel list available\n",
1069 dev->minor);
1070 return -EINVAL;
1071 }
1072
1073 /* Check the channel list size */
1074 if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
1075 printk(KERN_ERR
1076 "comedi%d: me4000: ai_check_chanlist(): Channel list is to large\n",
1077 dev->minor);
1078 return -EINVAL;
1079 }
1080
1081 /* Check the pointer */
1082 if (!cmd->chanlist) {
1083 printk(KERN_ERR
1084 "comedi%d: me4000: ai_check_chanlist(): NULL pointer to channel list\n",
1085 dev->minor);
1086 return -EFAULT;
1087 }
1088
1089 /* Check whether aref is equal for all entries */
1090 aref = CR_AREF(cmd->chanlist[0]);
1091 for (i = 0; i < cmd->chanlist_len; i++) {
1092 if (CR_AREF(cmd->chanlist[i]) != aref) {
1093 printk(KERN_ERR
1094 "comedi%d: me4000: ai_check_chanlist(): Mode is not equal for all entries\n",
1095 dev->minor);
1096 return -EINVAL;
1097 }
1098 }
1099
1100 /* Check whether channels are available for this ending */
1101 if (aref == SDF_DIFF) {
1102 for (i = 0; i < cmd->chanlist_len; i++) {
1103 if (CR_CHAN(cmd->chanlist[i]) >=
1104 thisboard->ai.diff_count) {
1105 printk(KERN_ERR
1106 "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
1107 dev->minor);
1108 return -EINVAL;
1109 }
1110 }
1111 } else {
1112 for (i = 0; i < cmd->chanlist_len; i++) {
1113 if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) {
1114 printk(KERN_ERR
1115 "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
1116 dev->minor);
1117 return -EINVAL;
1118 }
1119 }
1120 }
1121
1122 /* Check if bipolar is set for all entries when in differential mode */
1123 if (aref == SDF_DIFF) {
1124 for (i = 0; i < cmd->chanlist_len; i++) {
1125 if (CR_RANGE(cmd->chanlist[i]) != 1 &&
1126 CR_RANGE(cmd->chanlist[i]) != 2) {
1127 printk(KERN_ERR
1128 "comedi%d: me4000: ai_check_chanlist(): Bipolar is not selected in differential mode\n",
1129 dev->minor);
1130 return -EINVAL;
1131 }
1132 }
1133 }
1134
1135 return 0;
1136 }
1137
1138 static int ai_round_cmd_args(comedi_device *dev,
1139 comedi_subdevice *s,
1140 comedi_cmd *cmd,
1141 unsigned int *init_ticks,
1142 unsigned int *scan_ticks, unsigned int *chan_ticks)
1143 {
1144
1145 int rest;
1146
1147 CALL_PDEBUG("In ai_round_cmd_args()\n");
1148
1149 *init_ticks = 0;
1150 *scan_ticks = 0;
1151 *chan_ticks = 0;
1152
1153 PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd->start_arg);
1154 PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n",
1155 cmd->scan_begin_arg);
1156 PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd->convert_arg);
1157
1158 if (cmd->start_arg) {
1159 *init_ticks = (cmd->start_arg * 33) / 1000;
1160 rest = (cmd->start_arg * 33) % 1000;
1161
1162 if (cmd->flags & TRIG_ROUND_NEAREST) {
1163 if (rest > 33)
1164 (*init_ticks)++;
1165 } else if (cmd->flags & TRIG_ROUND_UP) {
1166 if (rest)
1167 (*init_ticks)++;
1168 }
1169 }
1170
1171 if (cmd->scan_begin_arg) {
1172 *scan_ticks = (cmd->scan_begin_arg * 33) / 1000;
1173 rest = (cmd->scan_begin_arg * 33) % 1000;
1174
1175 if (cmd->flags & TRIG_ROUND_NEAREST) {
1176 if (rest > 33)
1177 (*scan_ticks)++;
1178 } else if (cmd->flags & TRIG_ROUND_UP) {
1179 if (rest)
1180 (*scan_ticks)++;
1181 }
1182 }
1183
1184 if (cmd->convert_arg) {
1185 *chan_ticks = (cmd->convert_arg * 33) / 1000;
1186 rest = (cmd->convert_arg * 33) % 1000;
1187
1188 if (cmd->flags & TRIG_ROUND_NEAREST) {
1189 if (rest > 33)
1190 (*chan_ticks)++;
1191 } else if (cmd->flags & TRIG_ROUND_UP) {
1192 if (rest)
1193 (*chan_ticks)++;
1194 }
1195 }
1196
1197 PDEBUG("ai_round_cmd_args(): init_ticks = %d\n", *init_ticks);
1198 PDEBUG("ai_round_cmd_args(): scan_ticks = %d\n", *scan_ticks);
1199 PDEBUG("ai_round_cmd_args(): chan_ticks = %d\n", *chan_ticks);
1200
1201 return 0;
1202 }
1203
1204 static void ai_write_timer(comedi_device *dev,
1205 unsigned int init_ticks,
1206 unsigned int scan_ticks, unsigned int chan_ticks)
1207 {
1208
1209 CALL_PDEBUG("In ai_write_timer()\n");
1210
1211 me4000_outl(dev, init_ticks - 1,
1212 info->ai_context.scan_pre_timer_low_reg);
1213 me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg);
1214
1215 if (scan_ticks) {
1216 me4000_outl(dev, scan_ticks - 1,
1217 info->ai_context.scan_timer_low_reg);
1218 me4000_outl(dev, 0x0, info->ai_context.scan_timer_high_reg);
1219 }
1220
1221 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_pre_timer_reg);
1222 me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg);
1223 }
1224
1225 static int ai_prepare(comedi_device *dev,
1226 comedi_subdevice *s,
1227 comedi_cmd *cmd,
1228 unsigned int init_ticks,
1229 unsigned int scan_ticks, unsigned int chan_ticks)
1230 {
1231
1232 unsigned long tmp = 0;
1233
1234 CALL_PDEBUG("In ai_prepare()\n");
1235
1236 /* Write timer arguments */
1237 ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
1238
1239 /* Reset control register */
1240 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1241
1242 /* Start sources */
1243 if ((cmd->start_src == TRIG_EXT &&
1244 cmd->scan_begin_src == TRIG_TIMER &&
1245 cmd->convert_src == TRIG_TIMER) ||
1246 (cmd->start_src == TRIG_EXT &&
1247 cmd->scan_begin_src == TRIG_FOLLOW &&
1248 cmd->convert_src == TRIG_TIMER)) {
1249 tmp = ME4000_AI_CTRL_BIT_MODE_1 |
1250 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1251 ME4000_AI_CTRL_BIT_DATA_FIFO;
1252 } else if (cmd->start_src == TRIG_EXT &&
1253 cmd->scan_begin_src == TRIG_EXT &&
1254 cmd->convert_src == TRIG_TIMER) {
1255 tmp = ME4000_AI_CTRL_BIT_MODE_2 |
1256 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1257 ME4000_AI_CTRL_BIT_DATA_FIFO;
1258 } else if (cmd->start_src == TRIG_EXT &&
1259 cmd->scan_begin_src == TRIG_EXT &&
1260 cmd->convert_src == TRIG_EXT) {
1261 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1262 ME4000_AI_CTRL_BIT_MODE_1 |
1263 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1264 ME4000_AI_CTRL_BIT_DATA_FIFO;
1265 } else {
1266 tmp = ME4000_AI_CTRL_BIT_MODE_0 |
1267 ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
1268 ME4000_AI_CTRL_BIT_DATA_FIFO;
1269 }
1270
1271 /* Stop triggers */
1272 if (cmd->stop_src == TRIG_COUNT) {
1273 me4000_outl(dev, cmd->chanlist_len * cmd->stop_arg,
1274 info->ai_context.sample_counter_reg);
1275 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1276 } else if (cmd->stop_src == TRIG_NONE &&
1277 cmd->scan_end_src == TRIG_COUNT) {
1278 me4000_outl(dev, cmd->scan_end_arg,
1279 info->ai_context.sample_counter_reg);
1280 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
1281 } else {
1282 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
1283 }
1284
1285 /* Write the setup to the control register */
1286 me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
1287
1288 /* Write the channel list */
1289 ai_write_chanlist(dev, s, cmd);
1290
1291 return 0;
1292 }
1293
1294 static int ai_write_chanlist(comedi_device *dev,
1295 comedi_subdevice *s, comedi_cmd *cmd)
1296 {
1297 unsigned int entry;
1298 unsigned int chan;
1299 unsigned int rang;
1300 unsigned int aref;
1301 int i;
1302
1303 CALL_PDEBUG("In ai_write_chanlist()\n");
1304
1305 for (i = 0; i < cmd->chanlist_len; i++) {
1306 chan = CR_CHAN(cmd->chanlist[i]);
1307 rang = CR_RANGE(cmd->chanlist[i]);
1308 aref = CR_AREF(cmd->chanlist[i]);
1309
1310 entry = chan;
1311
1312 if (rang == 0) {
1313 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_2_5;
1314 } else if (rang == 1) {
1315 entry |= ME4000_AI_LIST_RANGE_UNIPOLAR_10;
1316 } else if (rang == 2) {
1317 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_2_5;
1318 } else {
1319 entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10;
1320 }
1321
1322 if (aref == SDF_DIFF) {
1323 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL;
1324 } else {
1325 entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED;
1326 }
1327
1328 me4000_outl(dev, entry, info->ai_context.channel_list_reg);
1329 }
1330
1331 return 0;
1332 }
1333
1334 static int me4000_ai_do_cmd(comedi_device *dev, comedi_subdevice *s)
1335 {
1336 int err;
1337 unsigned int init_ticks = 0;
1338 unsigned int scan_ticks = 0;
1339 unsigned int chan_ticks = 0;
1340 comedi_cmd *cmd = &s->async->cmd;
1341
1342 CALL_PDEBUG("In me4000_ai_do_cmd()\n");
1343
1344 /* Reset the analog input */
1345 err = me4000_ai_cancel(dev, s);
1346 if (err)
1347 return err;
1348
1349 /* Round the timer arguments */
1350 err = ai_round_cmd_args(dev,
1351 s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1352 if (err)
1353 return err;
1354
1355 /* Prepare the AI for acquisition */
1356 err = ai_prepare(dev, s, cmd, init_ticks, scan_ticks, chan_ticks);
1357 if (err)
1358 return err;
1359
1360 /* Start acquistion by dummy read */
1361 me4000_inl(dev, info->ai_context.start_reg);
1362
1363 return 0;
1364 }
1365
1366 /*
1367 * me4000_ai_do_cmd_test():
1368 *
1369 * The demo cmd.c in ./comedilib/demo specifies 6 return values:
1370 * - success
1371 * - invalid source
1372 * - source conflict
1373 * - invalid argument
1374 * - argument conflict
1375 * - invalid chanlist
1376 * So I tried to adopt this scheme.
1377 */
1378 static int me4000_ai_do_cmd_test(comedi_device *dev,
1379 comedi_subdevice *s, comedi_cmd *cmd)
1380 {
1381
1382 unsigned int init_ticks;
1383 unsigned int chan_ticks;
1384 unsigned int scan_ticks;
1385 int err = 0;
1386
1387 CALL_PDEBUG("In me4000_ai_do_cmd_test()\n");
1388
1389 PDEBUG("me4000_ai_do_cmd_test(): subdev = %d\n", cmd->subdev);
1390 PDEBUG("me4000_ai_do_cmd_test(): flags = %08X\n", cmd->flags);
1391 PDEBUG("me4000_ai_do_cmd_test(): start_src = %08X\n",
1392 cmd->start_src);
1393 PDEBUG("me4000_ai_do_cmd_test(): start_arg = %d\n",
1394 cmd->start_arg);
1395 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n",
1396 cmd->scan_begin_src);
1397 PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n",
1398 cmd->scan_begin_arg);
1399 PDEBUG("me4000_ai_do_cmd_test(): convert_src = %08X\n",
1400 cmd->convert_src);
1401 PDEBUG("me4000_ai_do_cmd_test(): convert_arg = %d\n",
1402 cmd->convert_arg);
1403 PDEBUG("me4000_ai_do_cmd_test(): scan_end_src = %08X\n",
1404 cmd->scan_end_src);
1405 PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg = %d\n",
1406 cmd->scan_end_arg);
1407 PDEBUG("me4000_ai_do_cmd_test(): stop_src = %08X\n",
1408 cmd->stop_src);
1409 PDEBUG("me4000_ai_do_cmd_test(): stop_arg = %d\n", cmd->stop_arg);
1410 PDEBUG("me4000_ai_do_cmd_test(): chanlist = %d\n",
1411 (unsigned int)cmd->chanlist);
1412 PDEBUG("me4000_ai_do_cmd_test(): chanlist_len = %d\n",
1413 cmd->chanlist_len);
1414
1415 /* Only rounding flags are implemented */
1416 cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
1417
1418 /* Round the timer arguments */
1419 ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
1420
1421 /*
1422 * Stage 1. Check if the trigger sources are generally valid.
1423 */
1424 switch (cmd->start_src) {
1425 case TRIG_NOW:
1426 case TRIG_EXT:
1427 break;
1428 case TRIG_ANY:
1429 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1430 err++;
1431 break;
1432 default:
1433 printk(KERN_ERR
1434 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start source\n",
1435 dev->minor);
1436 cmd->start_src = TRIG_NOW;
1437 err++;
1438 }
1439 switch (cmd->scan_begin_src) {
1440 case TRIG_FOLLOW:
1441 case TRIG_TIMER:
1442 case TRIG_EXT:
1443 break;
1444 case TRIG_ANY:
1445 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1446 err++;
1447 break;
1448 default:
1449 printk(KERN_ERR
1450 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan begin source\n",
1451 dev->minor);
1452 cmd->scan_begin_src = TRIG_FOLLOW;
1453 err++;
1454 }
1455 switch (cmd->convert_src) {
1456 case TRIG_TIMER:
1457 case TRIG_EXT:
1458 break;
1459 case TRIG_ANY:
1460 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1461 err++;
1462 break;
1463 default:
1464 printk(KERN_ERR
1465 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert source\n",
1466 dev->minor);
1467 cmd->convert_src = TRIG_TIMER;
1468 err++;
1469 }
1470 switch (cmd->scan_end_src) {
1471 case TRIG_NONE:
1472 case TRIG_COUNT:
1473 break;
1474 case TRIG_ANY:
1475 cmd->scan_end_src &= TRIG_NONE | TRIG_COUNT;
1476 err++;
1477 break;
1478 default:
1479 printk(KERN_ERR
1480 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end source\n",
1481 dev->minor);
1482 cmd->scan_end_src = TRIG_NONE;
1483 err++;
1484 }
1485 switch (cmd->stop_src) {
1486 case TRIG_NONE:
1487 case TRIG_COUNT:
1488 break;
1489 case TRIG_ANY:
1490 cmd->stop_src &= TRIG_NONE | TRIG_COUNT;
1491 err++;
1492 break;
1493 default:
1494 printk(KERN_ERR
1495 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop source\n",
1496 dev->minor);
1497 cmd->stop_src = TRIG_NONE;
1498 err++;
1499 }
1500 if (err)
1501 return 1;
1502
1503 /*
1504 * Stage 2. Check for trigger source conflicts.
1505 */
1506 if (cmd->start_src == TRIG_NOW &&
1507 cmd->scan_begin_src == TRIG_TIMER &&
1508 cmd->convert_src == TRIG_TIMER) {
1509 } else if (cmd->start_src == TRIG_NOW &&
1510 cmd->scan_begin_src == TRIG_FOLLOW &&
1511 cmd->convert_src == TRIG_TIMER) {
1512 } else if (cmd->start_src == TRIG_EXT &&
1513 cmd->scan_begin_src == TRIG_TIMER &&
1514 cmd->convert_src == TRIG_TIMER) {
1515 } else if (cmd->start_src == TRIG_EXT &&
1516 cmd->scan_begin_src == TRIG_FOLLOW &&
1517 cmd->convert_src == TRIG_TIMER) {
1518 } else if (cmd->start_src == TRIG_EXT &&
1519 cmd->scan_begin_src == TRIG_EXT &&
1520 cmd->convert_src == TRIG_TIMER) {
1521 } else if (cmd->start_src == TRIG_EXT &&
1522 cmd->scan_begin_src == TRIG_EXT &&
1523 cmd->convert_src == TRIG_EXT) {
1524 } else {
1525 printk(KERN_ERR
1526 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start trigger combination\n",
1527 dev->minor);
1528 cmd->start_src = TRIG_NOW;
1529 cmd->scan_begin_src = TRIG_FOLLOW;
1530 cmd->convert_src = TRIG_TIMER;
1531 err++;
1532 }
1533
1534 if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
1535 } else if (cmd->stop_src == TRIG_COUNT &&
1536 cmd->scan_end_src == TRIG_NONE) {
1537 } else if (cmd->stop_src == TRIG_NONE &&
1538 cmd->scan_end_src == TRIG_COUNT) {
1539 } else if (cmd->stop_src == TRIG_COUNT &&
1540 cmd->scan_end_src == TRIG_COUNT) {
1541 } else {
1542 printk(KERN_ERR
1543 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop trigger combination\n",
1544 dev->minor);
1545 cmd->stop_src = TRIG_NONE;
1546 cmd->scan_end_src = TRIG_NONE;
1547 err++;
1548 }
1549 if (err)
1550 return 2;
1551
1552 /*
1553 * Stage 3. Check if arguments are generally valid.
1554 */
1555 if (cmd->chanlist_len < 1) {
1556 printk(KERN_ERR
1557 "comedi%d: me4000: me4000_ai_do_cmd_test(): No channel list\n",
1558 dev->minor);
1559 cmd->chanlist_len = 1;
1560 err++;
1561 }
1562 if (init_ticks < 66) {
1563 printk(KERN_ERR
1564 "comedi%d: me4000: me4000_ai_do_cmd_test(): Start arg to low\n",
1565 dev->minor);
1566 cmd->start_arg = 2000;
1567 err++;
1568 }
1569 if (scan_ticks && scan_ticks < 67) {
1570 printk(KERN_ERR
1571 "comedi%d: me4000: me4000_ai_do_cmd_test(): Scan begin arg to low\n",
1572 dev->minor);
1573 cmd->scan_begin_arg = 2031;
1574 err++;
1575 }
1576 if (chan_ticks < 66) {
1577 printk(KERN_ERR
1578 "comedi%d: me4000: me4000_ai_do_cmd_test(): Convert arg to low\n",
1579 dev->minor);
1580 cmd->convert_arg = 2000;
1581 err++;
1582 }
1583
1584 if (err)
1585 return 3;
1586
1587 /*
1588 * Stage 4. Check for argument conflicts.
1589 */
1590 if (cmd->start_src == TRIG_NOW &&
1591 cmd->scan_begin_src == TRIG_TIMER &&
1592 cmd->convert_src == TRIG_TIMER) {
1593
1594 /* Check timer arguments */
1595 if (init_ticks < ME4000_AI_MIN_TICKS) {
1596 printk(KERN_ERR
1597 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1598 dev->minor);
1599 cmd->start_arg = 2000; /* 66 ticks at least */
1600 err++;
1601 }
1602 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1603 printk(KERN_ERR
1604 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1605 dev->minor);
1606 cmd->convert_arg = 2000; /* 66 ticks at least */
1607 err++;
1608 }
1609 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1610 printk(KERN_ERR
1611 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1612 dev->minor);
1613 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; /* At least one tick more */
1614 err++;
1615 }
1616 } else if (cmd->start_src == TRIG_NOW &&
1617 cmd->scan_begin_src == TRIG_FOLLOW &&
1618 cmd->convert_src == TRIG_TIMER) {
1619
1620 /* Check timer arguments */
1621 if (init_ticks < ME4000_AI_MIN_TICKS) {
1622 printk(KERN_ERR
1623 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1624 dev->minor);
1625 cmd->start_arg = 2000; /* 66 ticks at least */
1626 err++;
1627 }
1628 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1629 printk(KERN_ERR
1630 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1631 dev->minor);
1632 cmd->convert_arg = 2000; /* 66 ticks at least */
1633 err++;
1634 }
1635 } else if (cmd->start_src == TRIG_EXT &&
1636 cmd->scan_begin_src == TRIG_TIMER &&
1637 cmd->convert_src == TRIG_TIMER) {
1638
1639 /* Check timer arguments */
1640 if (init_ticks < ME4000_AI_MIN_TICKS) {
1641 printk(KERN_ERR
1642 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1643 dev->minor);
1644 cmd->start_arg = 2000; /* 66 ticks at least */
1645 err++;
1646 }
1647 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1648 printk(KERN_ERR
1649 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1650 dev->minor);
1651 cmd->convert_arg = 2000; /* 66 ticks at least */
1652 err++;
1653 }
1654 if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
1655 printk(KERN_ERR
1656 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1657 dev->minor);
1658 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; /* At least one tick more */
1659 err++;
1660 }
1661 } else if (cmd->start_src == TRIG_EXT &&
1662 cmd->scan_begin_src == TRIG_FOLLOW &&
1663 cmd->convert_src == TRIG_TIMER) {
1664
1665 /* Check timer arguments */
1666 if (init_ticks < ME4000_AI_MIN_TICKS) {
1667 printk(KERN_ERR
1668 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1669 dev->minor);
1670 cmd->start_arg = 2000; /* 66 ticks at least */
1671 err++;
1672 }
1673 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1674 printk(KERN_ERR
1675 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1676 dev->minor);
1677 cmd->convert_arg = 2000; /* 66 ticks at least */
1678 err++;
1679 }
1680 } else if (cmd->start_src == TRIG_EXT &&
1681 cmd->scan_begin_src == TRIG_EXT &&
1682 cmd->convert_src == TRIG_TIMER) {
1683
1684 /* Check timer arguments */
1685 if (init_ticks < ME4000_AI_MIN_TICKS) {
1686 printk(KERN_ERR
1687 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1688 dev->minor);
1689 cmd->start_arg = 2000; /* 66 ticks at least */
1690 err++;
1691 }
1692 if (chan_ticks < ME4000_AI_MIN_TICKS) {
1693 printk(KERN_ERR
1694 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
1695 dev->minor);
1696 cmd->convert_arg = 2000; /* 66 ticks at least */
1697 err++;
1698 }
1699 } else if (cmd->start_src == TRIG_EXT &&
1700 cmd->scan_begin_src == TRIG_EXT &&
1701 cmd->convert_src == TRIG_EXT) {
1702
1703 /* Check timer arguments */
1704 if (init_ticks < ME4000_AI_MIN_TICKS) {
1705 printk(KERN_ERR
1706 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
1707 dev->minor);
1708 cmd->start_arg = 2000; /* 66 ticks at least */
1709 err++;
1710 }
1711 }
1712 if (cmd->stop_src == TRIG_COUNT) {
1713 if (cmd->stop_arg == 0) {
1714 printk(KERN_ERR
1715 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop arg\n",
1716 dev->minor);
1717 cmd->stop_arg = 1;
1718 err++;
1719 }
1720 }
1721 if (cmd->scan_end_src == TRIG_COUNT) {
1722 if (cmd->scan_end_arg == 0) {
1723 printk(KERN_ERR
1724 "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
1725 dev->minor);
1726 cmd->scan_end_arg = 1;
1727 err++;
1728 }
1729 }
1730
1731 if (err)
1732 return 4;
1733
1734 /*
1735 * Stage 5. Check the channel list.
1736 */
1737 if (ai_check_chanlist(dev, s, cmd))
1738 return 5;
1739
1740 return 0;
1741 }
1742
1743 static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG)
1744 {
1745 unsigned int tmp;
1746 comedi_device *dev = dev_id;
1747 comedi_subdevice *s = dev->subdevices;
1748 me4000_ai_context_t *ai_context = &info->ai_context;
1749 int i;
1750 int c = 0;
1751 long lval;
1752
1753 ISR_PDEBUG("me4000_ai_isr() is executed\n");
1754
1755 if (!dev->attached) {
1756 ISR_PDEBUG("me4000_ai_isr() premature interrupt\n");
1757 return IRQ_NONE;
1758 }
1759
1760 /* Reset all events */
1761 s->async->events = 0;
1762
1763 /* Check if irq number is right */
1764 if (irq != ai_context->irq) {
1765 printk(KERN_ERR
1766 "comedi%d: me4000: me4000_ai_isr(): Incorrect interrupt num: %d\n",
1767 dev->minor, irq);
1768 return IRQ_HANDLED;
1769 }
1770
1771 if (me4000_inl(dev,
1772 ai_context->
1773 irq_status_reg) & ME4000_IRQ_STATUS_BIT_AI_HF) {
1774 ISR_PDEBUG
1775 ("me4000_ai_isr(): Fifo half full interrupt occured\n");
1776
1777 /* Read status register to find out what happened */
1778 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1779
1780 if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
1781 !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
1782 (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1783 ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
1784 c = ME4000_AI_FIFO_COUNT;
1785
1786 /* FIFO overflow, so stop conversion and disable all interrupts */
1787 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1788 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1789 ME4000_AI_CTRL_BIT_SC_IRQ);
1790 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1791
1792 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1793
1794 printk(KERN_ERR
1795 "comedi%d: me4000: me4000_ai_isr(): FIFO overflow\n",
1796 dev->minor);
1797 } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
1798 && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
1799 && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
1800 ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n");
1801
1802 s->async->events |= COMEDI_CB_BLOCK;
1803
1804 c = ME4000_AI_FIFO_COUNT / 2;
1805 } else {
1806 printk(KERN_ERR
1807 "comedi%d: me4000: me4000_ai_isr(): Can't determine state of fifo\n",
1808 dev->minor);
1809 c = 0;
1810
1811 /* Undefined state, so stop conversion and disable all interrupts */
1812 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1813 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1814 ME4000_AI_CTRL_BIT_SC_IRQ);
1815 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1816
1817 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1818
1819 printk(KERN_ERR
1820 "comedi%d: me4000: me4000_ai_isr(): Undefined FIFO state\n",
1821 dev->minor);
1822 }
1823
1824 ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c);
1825
1826 for (i = 0; i < c; i++) {
1827 /* Read value from data fifo */
1828 lval = inl(ai_context->data_reg) & 0xFFFF;
1829 lval ^= 0x8000;
1830
1831 if (!comedi_buf_put(s->async, lval)) {
1832 /* Buffer overflow, so stop conversion and disable all interrupts */
1833 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1834 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
1835 ME4000_AI_CTRL_BIT_SC_IRQ);
1836 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1837
1838 s->async->events |= COMEDI_CB_OVERFLOW;
1839
1840 printk(KERN_ERR
1841 "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
1842 dev->minor);
1843
1844 break;
1845 }
1846 }
1847
1848 /* Work is done, so reset the interrupt */
1849 ISR_PDEBUG("me4000_ai_isr(): Reset fifo half full interrupt\n");
1850 tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1851 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1852 tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
1853 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1854 }
1855
1856 if (me4000_inl(dev,
1857 ai_context->
1858 irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
1859 ISR_PDEBUG
1860 ("me4000_ai_isr(): Sample counter interrupt occured\n");
1861
1862 s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
1863
1864 /* Acquisition is complete, so stop conversion and disable all interrupts */
1865 tmp = me4000_inl(dev, ai_context->ctrl_reg);
1866 tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
1867 tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ);
1868 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1869
1870 /* Poll data until fifo empty */
1871 while (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_EF_DATA) {
1872 /* Read value from data fifo */
1873 lval = inl(ai_context->data_reg) & 0xFFFF;
1874 lval ^= 0x8000;
1875
1876 if (!comedi_buf_put(s->async, lval)) {
1877 printk(KERN_ERR
1878 "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
1879 dev->minor);
1880 s->async->events |= COMEDI_CB_OVERFLOW;
1881 break;
1882 }
1883 }
1884
1885 /* Work is done, so reset the interrupt */
1886 ISR_PDEBUG
1887 ("me4000_ai_isr(): Reset interrupt from sample counter\n");
1888 tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1889 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1890 tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
1891 me4000_outl(dev, tmp, ai_context->ctrl_reg);
1892 }
1893
1894 ISR_PDEBUG("me4000_ai_isr(): Events = 0x%X\n", s->async->events);
1895
1896 if (s->async->events)
1897 comedi_event(dev, s);
1898
1899 return IRQ_HANDLED;
1900 }
1901
1902 /*=============================================================================
1903 Analog output section
1904 ===========================================================================*/
1905
1906 static int me4000_ao_insn_write(comedi_device *dev,
1907 comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
1908 {
1909
1910 int chan = CR_CHAN(insn->chanspec);
1911 int rang = CR_RANGE(insn->chanspec);
1912 int aref = CR_AREF(insn->chanspec);
1913 unsigned long tmp;
1914
1915 CALL_PDEBUG("In me4000_ao_insn_write()\n");
1916
1917 if (insn->n == 0) {
1918 return 0;
1919 } else if (insn->n > 1) {
1920 printk(KERN_ERR
1921 "comedi%d: me4000: me4000_ao_insn_write(): Invalid instruction length %d\n",
1922 dev->minor, insn->n);
1923 return -EINVAL;
1924 }
1925
1926 if (chan >= thisboard->ao.count) {
1927 printk(KERN_ERR
1928 "comedi%d: me4000: me4000_ao_insn_write(): Invalid channel %d\n",
1929 dev->minor, insn->n);
1930 return -EINVAL;
1931 }
1932
1933 if (rang != 0) {
1934 printk(KERN_ERR
1935 "comedi%d: me4000: me4000_ao_insn_write(): Invalid range %d\n",
1936 dev->minor, insn->n);
1937 return -EINVAL;
1938 }
1939
1940 if (aref != AREF_GROUND && aref != AREF_COMMON) {
1941 printk(KERN_ERR
1942 "comedi%d: me4000: me4000_ao_insn_write(): Invalid aref %d\n",
1943 dev->minor, insn->n);
1944 return -EINVAL;
1945 }
1946
1947 /* Stop any running conversion */
1948 tmp = me4000_inl(dev, info->ao_context[chan].ctrl_reg);
1949 tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
1950 me4000_outl(dev, tmp, info->ao_context[chan].ctrl_reg);
1951
1952 /* Clear control register and set to single mode */
1953 me4000_outl(dev, 0x0, info->ao_context[chan].ctrl_reg);
1954
1955 /* Write data value */
1956 me4000_outl(dev, data[0], info->ao_context[chan].single_reg);
1957
1958 /* Store in the mirror */
1959 info->ao_context[chan].mirror = data[0];
1960
1961 return 1;
1962 }
1963
1964 static int me4000_ao_insn_read(comedi_device *dev,
1965 comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
1966 {
1967 int chan = CR_CHAN(insn->chanspec);
1968
1969 if (insn->n == 0) {
1970 return 0;
1971 } else if (insn->n > 1) {
1972 printk("comedi%d: me4000: me4000_ao_insn_read(): Invalid instruction length\n", dev->minor);
1973 return -EINVAL;
1974 }
1975
1976 data[0] = info->ao_context[chan].mirror;
1977
1978 return 1;
1979 }
1980
1981 /*=============================================================================
1982 Digital I/O section
1983 ===========================================================================*/
1984
1985 static int me4000_dio_insn_bits(comedi_device *dev,
1986 comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
1987 {
1988
1989 CALL_PDEBUG("In me4000_dio_insn_bits()\n");
1990
1991 /* Length of data must be 2 (mask and new data, see below) */
1992 if (insn->n == 0)
1993 return 0;
1994
1995 if (insn->n != 2) {
1996 printk("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n", dev->minor);
1997 return -EINVAL;
1998 }
1999
2000 /*
2001 * The insn data consists of a mask in data[0] and the new data
2002 * in data[1]. The mask defines which bits we are concerning about.
2003 * The new data must be anded with the mask.
2004 * Each channel corresponds to a bit.
2005 */
2006 if (data[0]) {
2007 /* Check if requested ports are configured for output */
2008 if ((s->io_bits & data[0]) != data[0])
2009 return -EIO;
2010
2011 s->state &= ~data[0];
2012 s->state |= data[0] & data[1];
2013
2014 /* Write out the new digital output lines */
2015 me4000_outl(dev, (s->state >> 0) & 0xFF,
2016 info->dio_context.port_0_reg);
2017 me4000_outl(dev, (s->state >> 8) & 0xFF,
2018 info->dio_context.port_1_reg);
2019 me4000_outl(dev, (s->state >> 16) & 0xFF,
2020 info->dio_context.port_2_reg);
2021 me4000_outl(dev, (s->state >> 24) & 0xFF,
2022 info->dio_context.port_3_reg);
2023 }
2024
2025 /* On return, data[1] contains the value of
2026 the digital input and output lines. */
2027 data[1] =
2028 ((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) |
2029 ((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) |
2030 ((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) |
2031 ((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24);
2032
2033 return 2;
2034 }
2035
2036 static int me4000_dio_insn_config(comedi_device *dev,
2037 comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
2038 {
2039 unsigned long tmp;
2040 int chan = CR_CHAN(insn->chanspec);
2041
2042 CALL_PDEBUG("In me4000_dio_insn_config()\n");
2043
2044 if (data[0] == INSN_CONFIG_DIO_QUERY) {
2045 data[1] =
2046 (s->
2047 io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
2048 return insn->n;
2049 }
2050
2051 /*
2052 * The input or output configuration of each digital line is
2053 * configured by a special insn_config instruction. chanspec
2054 * contains the channel to be changed, and data[0] contains the
2055 * value COMEDI_INPUT or COMEDI_OUTPUT.
2056 * On the ME-4000 it is only possible to switch port wise (8 bit)
2057 */
2058
2059 tmp = me4000_inl(dev, info->dio_context.ctrl_reg);
2060
2061 if (data[0] == COMEDI_OUTPUT) {
2062 if (chan < 8) {
2063 s->io_bits |= 0xFF;
2064 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2065 ME4000_DIO_CTRL_BIT_MODE_1);
2066 tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
2067 } else if (chan < 16) {
2068 /*
2069 * Chech for optoisolated ME-4000 version. If one the first
2070 * port is a fixed output port and the second is a fixed input port.
2071 */
2072 if (!me4000_inl(dev, info->dio_context.dir_reg))
2073 return -ENODEV;
2074
2075 s->io_bits |= 0xFF00;
2076 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2077 ME4000_DIO_CTRL_BIT_MODE_3);
2078 tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
2079 } else if (chan < 24) {
2080 s->io_bits |= 0xFF0000;
2081 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2082 ME4000_DIO_CTRL_BIT_MODE_5);
2083 tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
2084 } else if (chan < 32) {
2085 s->io_bits |= 0xFF000000;
2086 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2087 ME4000_DIO_CTRL_BIT_MODE_7);
2088 tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
2089 } else {
2090 return -EINVAL;
2091 }
2092 } else {
2093 if (chan < 8) {
2094 /*
2095 * Chech for optoisolated ME-4000 version. If one the first
2096 * port is a fixed output port and the second is a fixed input port.
2097 */
2098 if (!me4000_inl(dev, info->dio_context.dir_reg))
2099 return -ENODEV;
2100
2101 s->io_bits &= ~0xFF;
2102 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
2103 ME4000_DIO_CTRL_BIT_MODE_1);
2104 } else if (chan < 16) {
2105 s->io_bits &= ~0xFF00;
2106 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
2107 ME4000_DIO_CTRL_BIT_MODE_3);
2108 } else if (chan < 24) {
2109 s->io_bits &= ~0xFF0000;
2110 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
2111 ME4000_DIO_CTRL_BIT_MODE_5);
2112 } else if (chan < 32) {
2113 s->io_bits &= ~0xFF000000;
2114 tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
2115 ME4000_DIO_CTRL_BIT_MODE_7);
2116 } else {
2117 return -EINVAL;
2118 }
2119 }
2120
2121 me4000_outl(dev, tmp, info->dio_context.ctrl_reg);
2122
2123 return 1;
2124 }
2125
2126 /*=============================================================================
2127 Counter section
2128 ===========================================================================*/
2129
2130 static int cnt_reset(comedi_device *dev, unsigned int channel)
2131 {
2132
2133 CALL_PDEBUG("In cnt_reset()\n");
2134
2135 switch (channel) {
2136 case 0:
2137 me4000_outb(dev, 0x30, info->cnt_context.ctrl_reg);
2138 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2139 me4000_outb(dev, 0x00, info->cnt_context.counter_0_reg);
2140 break;
2141 case 1:
2142 me4000_outb(dev, 0x70, info->cnt_context.ctrl_reg);
2143 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2144 me4000_outb(dev, 0x00, info->cnt_context.counter_1_reg);
2145 break;
2146 case 2:
2147 me4000_outb(dev, 0xB0, info->cnt_context.ctrl_reg);
2148 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2149 me4000_outb(dev, 0x00, info->cnt_context.counter_2_reg);
2150 break;
2151 default:
2152 printk(KERN_ERR
2153 "comedi%d: me4000: cnt_reset(): Invalid channel\n",
2154 dev->minor);
2155 return -EINVAL;
2156 }
2157
2158 return 0;
2159 }
2160
2161 static int cnt_config(comedi_device *dev, unsigned int channel,
2162 unsigned int mode)
2163 {
2164 int tmp = 0;
2165
2166 CALL_PDEBUG("In cnt_config()\n");
2167
2168 switch (channel) {
2169 case 0:
2170 tmp |= ME4000_CNT_COUNTER_0;
2171 break;
2172 case 1:
2173 tmp |= ME4000_CNT_COUNTER_1;
2174 break;
2175 case 2:
2176 tmp |= ME4000_CNT_COUNTER_2;
2177 break;
2178 default:
2179 printk(KERN_ERR
2180 "comedi%d: me4000: cnt_config(): Invalid channel\n",
2181 dev->minor);
2182 return -EINVAL;
2183 }
2184
2185 switch (mode) {
2186 case 0:
2187 tmp |= ME4000_CNT_MODE_0;
2188 break;
2189 case 1:
2190 tmp |= ME4000_CNT_MODE_1;
2191 break;
2192 case 2:
2193 tmp |= ME4000_CNT_MODE_2;
2194 break;
2195 case 3:
2196 tmp |= ME4000_CNT_MODE_3;
2197 break;
2198 case 4:
2199 tmp |= ME4000_CNT_MODE_4;
2200 break;
2201 case 5:
2202 tmp |= ME4000_CNT_MODE_5;
2203 break;
2204 default:
2205 printk(KERN_ERR
2206 "comedi%d: me4000: cnt_config(): Invalid counter mode\n",
2207 dev->minor);
2208 return -EINVAL;
2209 }
2210
2211 /* Write the control word */
2212 tmp |= 0x30;
2213 me4000_outb(dev, tmp, info->cnt_context.ctrl_reg);
2214
2215 return 0;
2216 }
2217
2218 static int me4000_cnt_insn_config(comedi_device *dev,
2219 comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
2220 {
2221
2222 int err;
2223
2224 CALL_PDEBUG("In me4000_cnt_insn_config()\n");
2225
2226 switch (data[0]) {
2227 case GPCT_RESET:
2228 if (insn->n != 1) {
2229 printk(KERN_ERR
2230 "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2231 dev->minor, insn->n);
2232 return -EINVAL;
2233 }
2234
2235 err = cnt_reset(dev, insn->chanspec);
2236 if (err)
2237 return err;
2238 break;
2239 case GPCT_SET_OPERATION:
2240 if (insn->n != 2) {
2241 printk(KERN_ERR
2242 "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
2243 dev->minor, insn->n);
2244 return -EINVAL;
2245 }
2246
2247 err = cnt_config(dev, insn->chanspec, data[1]);
2248 if (err)
2249 return err;
2250 break;
2251 default:
2252 printk(KERN_ERR
2253 "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction\n",
2254 dev->minor);
2255 return -EINVAL;
2256 }
2257
2258 return 2;
2259 }
2260
2261 static int me4000_cnt_insn_read(comedi_device *dev,
2262 comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
2263 {
2264
2265 unsigned short tmp;
2266
2267 CALL_PDEBUG("In me4000_cnt_insn_read()\n");
2268
2269 if (insn->n == 0)
2270 return 0;
2271
2272 if (insn->n > 1) {
2273 printk(KERN_ERR
2274 "comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
2275 dev->minor, insn->n);
2276 return -EINVAL;
2277 }
2278
2279 switch (insn->chanspec) {
2280 case 0:
2281 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2282 data[0] = tmp;
2283 tmp = me4000_inb(dev, info->cnt_context.counter_0_reg);
2284 data[0] |= tmp << 8;
2285 break;
2286 case 1:
2287 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2288 data[0] = tmp;
2289 tmp = me4000_inb(dev, info->cnt_context.counter_1_reg);
2290 data[0] |= tmp << 8;
2291 break;
2292 case 2:
2293 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2294 data[0] = tmp;
2295 tmp = me4000_inb(dev, info->cnt_context.counter_2_reg);
2296 data[0] |= tmp << 8;
2297 break;
2298 default:
2299 printk(KERN_ERR
2300 "comedi%d: me4000: me4000_cnt_insn_read(): Invalid channel %d\n",
2301 dev->minor, insn->chanspec);
2302 return -EINVAL;
2303 }
2304
2305 return 1;
2306 }
2307
2308 static int me4000_cnt_insn_write(comedi_device *dev,
2309 comedi_subdevice *s, comedi_insn *insn, unsigned int *data)
2310 {
2311
2312 unsigned short tmp;
2313
2314 CALL_PDEBUG("In me4000_cnt_insn_write()\n");
2315
2316 if (insn->n == 0) {
2317 return 0;
2318 } else if (insn->n > 1) {
2319 printk(KERN_ERR
2320 "comedi%d: me4000: me4000_cnt_insn_write(): Invalid instruction length %d\n",
2321 dev->minor, insn->n);
2322 return -EINVAL;
2323 }
2324
2325 switch (insn->chanspec) {
2326 case 0:
2327 tmp = data[0] & 0xFF;
2328 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2329 tmp = (data[0] >> 8) & 0xFF;
2330 me4000_outb(dev, tmp, info->cnt_context.counter_0_reg);
2331 break;
2332 case 1:
2333 tmp = data[0] & 0xFF;
2334 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2335 tmp = (data[0] >> 8) & 0xFF;
2336 me4000_outb(dev, tmp, info->cnt_context.counter_1_reg);
2337 break;
2338 case 2:
2339 tmp = data[0] & 0xFF;
2340 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2341 tmp = (data[0] >> 8) & 0xFF;
2342 me4000_outb(dev, tmp, info->cnt_context.counter_2_reg);
2343 break;
2344 default:
2345 printk(KERN_ERR
2346 "comedi%d: me4000: me4000_cnt_insn_write(): Invalid channel %d\n",
2347 dev->minor, insn->chanspec);
2348 return -EINVAL;
2349 }
2350
2351 return 1;
2352 }
2353
2354 COMEDI_PCI_INITCLEANUP(driver_me4000, me4000_pci_table);