3 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
8 * Tel: +19(0)7223/9493-0
9 * Fax: +49(0)7223/9493-92
10 * http://www.addi-data.com
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
18 * This program is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
24 #include <linux/module.h>
25 #include <linux/interrupt.h>
27 #include "../comedi_pci.h"
28 #include "amcc_s5933.h"
32 * PCI Bar 0 Register map (devpriv->amcc)
33 * see amcc_s5933.h for register and bit defines
37 * PCI Bar 1 Register map (dev->iobase)
38 * see z8536.h for Z8536 internal registers and bit defines
40 #define APCI1500_Z8536_PORTC_REG 0x00
41 #define APCI1500_Z8536_PORTB_REG 0x01
42 #define APCI1500_Z8536_PORTA_REG 0x02
43 #define APCI1500_Z8536_CTRL_REG 0x03
46 * PCI Bar 2 Register map (devpriv->addon)
48 #define APCI1500_CLK_SEL_REG 0x00
49 #define APCI1500_DI_REG 0x00
50 #define APCI1500_DO_REG 0x02
52 struct apci1500_private {
58 /* Digital trigger configuration [0]=AND [1]=OR */
59 unsigned int pm[2]; /* Pattern Mask */
60 unsigned int pt[2]; /* Pattern Transition */
61 unsigned int pp[2]; /* Pattern Polarity */
64 static unsigned int z8536_read(struct comedi_device *dev, unsigned int reg)
69 spin_lock_irqsave(&dev->spinlock, flags);
70 outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
71 val = inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
72 spin_unlock_irqrestore(&dev->spinlock, flags);
77 static void z8536_write(struct comedi_device *dev,
78 unsigned int val, unsigned int reg)
82 spin_lock_irqsave(&dev->spinlock, flags);
83 outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
84 outb(val, dev->iobase + APCI1500_Z8536_CTRL_REG);
85 spin_unlock_irqrestore(&dev->spinlock, flags);
88 static void z8536_reset(struct comedi_device *dev)
93 * Even if the state of the Z8536 is not known, the following
94 * sequence will reset it and put it in State 0.
96 spin_lock_irqsave(&dev->spinlock, flags);
97 inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
98 outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
99 inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
100 outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
101 outb(1, dev->iobase + APCI1500_Z8536_CTRL_REG);
102 outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
103 spin_unlock_irqrestore(&dev->spinlock, flags);
105 /* Disable all Ports and Counter/Timers */
106 z8536_write(dev, 0x00, Z8536_CFG_CTRL_REG);
109 * Port A is connected to Ditial Input channels 0-7.
110 * Configure the port to allow interrupt detection.
112 z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
114 Z8536_PAB_MODE_PMS_DISABLE,
116 z8536_write(dev, 0xff, Z8536_PB_DPP_REG);
117 z8536_write(dev, 0xff, Z8536_PA_DD_REG);
120 * Port B is connected to Ditial Input channels 8-13.
121 * Configure the port to allow interrupt detection.
123 * NOTE: Bits 7 and 6 of Port B are connected to internal
124 * diagnostic signals and bit 7 is inverted.
126 z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
128 Z8536_PAB_MODE_PMS_DISABLE,
130 z8536_write(dev, 0x7f, Z8536_PB_DPP_REG);
131 z8536_write(dev, 0xff, Z8536_PB_DD_REG);
134 * Not sure what Port C is connected to...
136 z8536_write(dev, 0x09, Z8536_PC_DPP_REG);
137 z8536_write(dev, 0x0e, Z8536_PC_DD_REG);
140 * Clear and disable all interrupt sources.
142 * Just in case, the reset of the Z8536 should have already
145 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PA_CMDSTAT_REG);
146 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
148 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PB_CMDSTAT_REG);
149 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
151 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(0));
152 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(0));
154 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(1));
155 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(1));
157 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(2));
158 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(2));
160 /* Disable all interrupts */
161 z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
164 static void apci1500_port_enable(struct comedi_device *dev, bool enable)
168 cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
170 cfg |= (Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
172 cfg &= ~(Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
173 z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
176 static void apci1500_timer_enable(struct comedi_device *dev,
177 unsigned int chan, bool enable)
183 bit = Z8536_CFG_CTRL_CT1E;
185 bit = Z8536_CFG_CTRL_CT2E;
187 bit = Z8536_CFG_CTRL_PCE_CT3E;
189 cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
194 z8536_write(dev, 0x00, Z8536_CT_CMDSTAT_REG(chan));
196 z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
199 static bool apci1500_ack_irq(struct comedi_device *dev,
204 val = z8536_read(dev, reg);
205 if ((val & Z8536_STAT_IE_IP) == Z8536_STAT_IE_IP) {
206 val &= 0x0f; /* preserve any write bits */
207 val |= Z8536_CMD_CLR_IP_IUS;
208 z8536_write(dev, val, reg);
215 static irqreturn_t apci1500_interrupt(int irq, void *d)
217 struct comedi_device *dev = d;
218 struct apci1500_private *devpriv = dev->private;
219 struct comedi_subdevice *s = dev->read_subdev;
220 unsigned int status = 0;
223 val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
224 if (!(val & INTCSR_INTR_ASSERTED))
227 if (apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG))
228 status |= 0x01; /* port a event (inputs 0-7) */
230 if (apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG)) {
231 /* Tests if this is an external error */
232 val = inb(dev->iobase + APCI1500_Z8536_PORTB_REG);
235 if (val & 0x80) /* voltage error */
237 if (val & 0x40) /* short circuit error */
240 status |= 0x02; /* port b event (inputs 8-13) */
245 * NOTE: The 'status' returned by the sample matches the
246 * interrupt mask information from the APCI-1500 Users Manual.
249 * ---------- ------------------------------------------
250 * 0x00000001 Event 1 has occurred
251 * 0x00000010 Event 2 has occurred
252 * 0x00000100 Counter/timer 1 has run down (not implemented)
253 * 0x00001000 Counter/timer 2 has run down (not implemented)
254 * 0x00010000 Counter 3 has run down (not implemented)
255 * 0x00100000 Watchdog has run down (not implemented)
256 * 0x01000000 Voltage error
257 * 0x10000000 Short-circuit error
259 comedi_buf_write_samples(s, &status, 1);
260 comedi_handle_events(dev, s);
265 static int apci1500_di_cancel(struct comedi_device *dev,
266 struct comedi_subdevice *s)
268 /* Disables the main interrupt on the board */
269 z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
271 /* Disable Ports A & B */
272 apci1500_port_enable(dev, false);
274 /* Ack any pending interrupts */
275 apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG);
276 apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG);
278 /* Disable pattern interrupts */
279 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
280 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
282 /* Enable Ports A & B */
283 apci1500_port_enable(dev, true);
288 static int apci1500_di_inttrig_start(struct comedi_device *dev,
289 struct comedi_subdevice *s,
290 unsigned int trig_num)
292 struct apci1500_private *devpriv = dev->private;
293 struct comedi_cmd *cmd = &s->async->cmd;
294 unsigned int pa_mode = Z8536_PAB_MODE_PMS_DISABLE;
295 unsigned int pb_mode = Z8536_PAB_MODE_PMS_DISABLE;
296 unsigned int pa_trig = trig_num & 0x01;
297 unsigned int pb_trig = (trig_num >> 1) & 0x01;
298 bool valid_trig = false;
301 if (trig_num != cmd->start_arg)
304 /* Disable Ports A & B */
305 apci1500_port_enable(dev, false);
307 /* Set Port A for selected trigger pattern */
308 z8536_write(dev, devpriv->pm[pa_trig] & 0xff, Z8536_PA_PM_REG);
309 z8536_write(dev, devpriv->pt[pa_trig] & 0xff, Z8536_PA_PT_REG);
310 z8536_write(dev, devpriv->pp[pa_trig] & 0xff, Z8536_PA_PP_REG);
312 /* Set Port B for selected trigger pattern */
313 z8536_write(dev, (devpriv->pm[pb_trig] >> 8) & 0xff, Z8536_PB_PM_REG);
314 z8536_write(dev, (devpriv->pt[pb_trig] >> 8) & 0xff, Z8536_PB_PT_REG);
315 z8536_write(dev, (devpriv->pp[pb_trig] >> 8) & 0xff, Z8536_PB_PP_REG);
317 /* Set Port A trigger mode (if enabled) and enable interrupt */
318 if (devpriv->pm[pa_trig] & 0xff) {
319 pa_mode = pa_trig ? Z8536_PAB_MODE_PMS_AND
320 : Z8536_PAB_MODE_PMS_OR;
322 val = z8536_read(dev, Z8536_PA_MODE_REG);
323 val &= ~Z8536_PAB_MODE_PMS_MASK;
324 val |= (pa_mode | Z8536_PAB_MODE_IMO);
325 z8536_write(dev, val, Z8536_PA_MODE_REG);
327 z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PA_CMDSTAT_REG);
331 dev_dbg(dev->class_dev,
332 "Port A configured for %s mode pattern detection\n",
333 pa_trig ? "AND" : "OR");
336 /* Set Port B trigger mode (if enabled) and enable interrupt */
337 if (devpriv->pm[pb_trig] & 0xff00) {
338 pb_mode = pb_trig ? Z8536_PAB_MODE_PMS_AND
339 : Z8536_PAB_MODE_PMS_OR;
341 val = z8536_read(dev, Z8536_PB_MODE_REG);
342 val &= ~Z8536_PAB_MODE_PMS_MASK;
343 val |= (pb_mode | Z8536_PAB_MODE_IMO);
344 z8536_write(dev, val, Z8536_PB_MODE_REG);
346 z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PB_CMDSTAT_REG);
350 dev_dbg(dev->class_dev,
351 "Port B configured for %s mode pattern detection\n",
352 pb_trig ? "AND" : "OR");
355 /* Enable Ports A & B */
356 apci1500_port_enable(dev, true);
359 dev_dbg(dev->class_dev,
360 "digital trigger %d is not configured\n", trig_num);
364 /* Authorizes the main interrupt on the board */
365 z8536_write(dev, Z8536_INT_CTRL_MIE | Z8536_INT_CTRL_DLC,
371 static int apci1500_di_cmd(struct comedi_device *dev,
372 struct comedi_subdevice *s)
374 s->async->inttrig = apci1500_di_inttrig_start;
379 static int apci1500_di_cmdtest(struct comedi_device *dev,
380 struct comedi_subdevice *s,
381 struct comedi_cmd *cmd)
385 /* Step 1 : check if triggers are trivially valid */
387 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
388 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
389 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
390 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
391 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
396 /* Step 2a : make sure trigger sources are unique */
397 /* Step 2b : and mutually compatible */
399 /* Step 3: check if arguments are trivially valid */
402 * Internal start source triggers:
404 * 0 AND mode for Port A (digital inputs 0-7)
405 * AND mode for Port B (digital inputs 8-13 and internal signals)
407 * 1 OR mode for Port A (digital inputs 0-7)
408 * AND mode for Port B (digital inputs 8-13 and internal signals)
410 * 2 AND mode for Port A (digital inputs 0-7)
411 * OR mode for Port B (digital inputs 8-13 and internal signals)
413 * 3 OR mode for Port A (digital inputs 0-7)
414 * OR mode for Port B (digital inputs 8-13 and internal signals)
416 err |= comedi_check_trigger_arg_max(&cmd->start_arg, 3);
418 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
419 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
420 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
422 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
427 /* Step 4: fix up any arguments */
429 /* Step 5: check channel list if it exists */
435 * The pattern-recognition logic must be configured before the digital
436 * input async command is started.
438 * Digital input channels 0 to 13 can generate interrupts. Channels 14
439 * and 15 are connected to internal board status/diagnostic signals.
441 * Channel 14 - Voltage error (the external supply is < 5V)
442 * Channel 15 - Short-circuit/overtemperature error
444 * data[0] : INSN_CONFIG_DIGITAL_TRIG
445 * data[1] : trigger number
448 * data[2] : configuration operation:
449 * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
450 * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = edge interrupts
451 * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = level interrupts
452 * data[3] : left-shift for data[4] and data[5]
453 * data[4] : rising-edge/high level channels
454 * data[5] : falling-edge/low level channels
456 static int apci1500_di_cfg_trig(struct comedi_device *dev,
457 struct comedi_subdevice *s,
458 struct comedi_insn *insn,
461 struct apci1500_private *devpriv = dev->private;
462 unsigned int trig = data[1];
463 unsigned int shift = data[3];
464 unsigned int hi_mask = data[4] << shift;
465 unsigned int lo_mask = data[5] << shift;
466 unsigned int chan_mask = hi_mask | lo_mask;
467 unsigned int old_mask = (1 << shift) - 1;
468 unsigned int pm = devpriv->pm[trig] & old_mask;
469 unsigned int pt = devpriv->pt[trig] & old_mask;
470 unsigned int pp = devpriv->pp[trig] & old_mask;
473 dev_dbg(dev->class_dev,
474 "invalid digital trigger number (0=AND, 1=OR)\n");
478 if (chan_mask > 0xffff) {
479 dev_dbg(dev->class_dev, "invalid digital trigger channel\n");
484 case COMEDI_DIGITAL_TRIG_DISABLE:
485 /* clear trigger configuration */
490 case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
491 pm |= chan_mask; /* enable channels */
492 pt |= chan_mask; /* enable edge detection */
493 pp |= hi_mask; /* rising-edge channels */
494 pp &= ~lo_mask; /* falling-edge channels */
496 case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
497 pm |= chan_mask; /* enable channels */
498 pt &= ~chan_mask; /* enable level detection */
499 pp |= hi_mask; /* high level channels */
500 pp &= ~lo_mask; /* low level channels */
507 * The AND mode trigger can only have one channel (max) enabled
508 * for edge detection.
516 ret |= comedi_check_trigger_is_unique(src);
518 src = (pt >> 8) & 0xff;
520 ret |= comedi_check_trigger_is_unique(src);
523 dev_dbg(dev->class_dev,
524 "invalid AND trigger configuration\n");
529 /* save the trigger configuration */
530 devpriv->pm[trig] = pm;
531 devpriv->pt[trig] = pt;
532 devpriv->pp[trig] = pp;
537 static int apci1500_di_insn_config(struct comedi_device *dev,
538 struct comedi_subdevice *s,
539 struct comedi_insn *insn,
543 case INSN_CONFIG_DIGITAL_TRIG:
544 return apci1500_di_cfg_trig(dev, s, insn, data);
550 static int apci1500_di_insn_bits(struct comedi_device *dev,
551 struct comedi_subdevice *s,
552 struct comedi_insn *insn,
555 struct apci1500_private *devpriv = dev->private;
557 data[1] = inw(devpriv->addon + APCI1500_DI_REG);
562 static int apci1500_do_insn_bits(struct comedi_device *dev,
563 struct comedi_subdevice *s,
564 struct comedi_insn *insn,
567 struct apci1500_private *devpriv = dev->private;
569 if (comedi_dio_update_state(s, data))
570 outw(s->state, devpriv->addon + APCI1500_DO_REG);
577 static int apci1500_timer_insn_config(struct comedi_device *dev,
578 struct comedi_subdevice *s,
579 struct comedi_insn *insn,
582 struct apci1500_private *devpriv = dev->private;
583 unsigned int chan = CR_CHAN(insn->chanspec);
587 case INSN_CONFIG_ARM:
588 val = data[1] & s->maxdata;
589 z8536_write(dev, val & 0xff, Z8536_CT_RELOAD_LSB_REG(chan));
590 z8536_write(dev, (val >> 8) & 0xff,
591 Z8536_CT_RELOAD_MSB_REG(chan));
593 apci1500_timer_enable(dev, chan, true);
594 z8536_write(dev, Z8536_CT_CMDSTAT_GCB,
595 Z8536_CT_CMDSTAT_REG(chan));
597 case INSN_CONFIG_DISARM:
598 apci1500_timer_enable(dev, chan, false);
601 case INSN_CONFIG_GET_COUNTER_STATUS:
603 val = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
604 if (val & Z8536_CT_STAT_CIP)
605 data[1] |= COMEDI_COUNTER_COUNTING;
606 if (val & Z8536_CT_CMDSTAT_GCB)
607 data[1] |= COMEDI_COUNTER_ARMED;
608 if (val & Z8536_STAT_IP) {
609 data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
610 apci1500_ack_irq(dev, Z8536_CT_CMDSTAT_REG(chan));
612 data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
613 COMEDI_COUNTER_TERMINAL_COUNT;
616 case INSN_CONFIG_SET_COUNTER_MODE:
617 /* Simulate the 8254 timer modes */
620 /* Interrupt on Terminal Count */
621 val = Z8536_CT_MODE_ECE |
622 Z8536_CT_MODE_DCS_ONESHOT;
625 /* Hardware Retriggerable One-Shot */
626 val = Z8536_CT_MODE_ETE |
627 Z8536_CT_MODE_DCS_ONESHOT;
631 val = Z8536_CT_MODE_CSC |
632 Z8536_CT_MODE_DCS_PULSE;
635 /* Square Wave Mode */
636 val = Z8536_CT_MODE_CSC |
637 Z8536_CT_MODE_DCS_SQRWAVE;
640 /* Software Triggered Strobe */
641 val = Z8536_CT_MODE_REB |
642 Z8536_CT_MODE_DCS_PULSE;
645 /* Hardware Triggered Strobe (watchdog) */
646 val = Z8536_CT_MODE_EOE |
649 Z8536_CT_MODE_DCS_PULSE;
654 apci1500_timer_enable(dev, chan, false);
655 z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
658 case INSN_CONFIG_SET_CLOCK_SRC:
661 devpriv->clk_src = data[1];
662 if (devpriv->clk_src == 2)
663 devpriv->clk_src = 3;
664 outw(devpriv->clk_src, devpriv->addon + APCI1500_CLK_SEL_REG);
666 case INSN_CONFIG_GET_CLOCK_SRC:
667 switch (devpriv->clk_src) {
669 data[1] = 0; /* 111.86 kHz / 2 */
670 data[2] = 17879; /* 17879 ns (approx) */
673 data[1] = 1; /* 3.49 kHz / 2 */
674 data[2] = 573066; /* 573066 ns (approx) */
677 data[1] = 2; /* 1.747 kHz / 2 */
678 data[2] = 1164822; /* 1164822 ns (approx) */
685 case INSN_CONFIG_SET_GATE_SRC:
689 val = z8536_read(dev, Z8536_CT_MODE_REG(chan));
690 val &= Z8536_CT_MODE_EGE;
692 val |= Z8536_CT_MODE_EGE;
693 else if (data[1] > 1)
695 z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
697 case INSN_CONFIG_GET_GATE_SRC:
708 static int apci1500_timer_insn_write(struct comedi_device *dev,
709 struct comedi_subdevice *s,
710 struct comedi_insn *insn,
713 unsigned int chan = CR_CHAN(insn->chanspec);
716 cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
717 cmd &= Z8536_CT_CMDSTAT_GCB; /* preserve gate */
718 cmd |= Z8536_CT_CMD_TCB; /* set trigger */
720 /* software trigger a timer, it only makes sense to do one write */
722 z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
727 static int apci1500_timer_insn_read(struct comedi_device *dev,
728 struct comedi_subdevice *s,
729 struct comedi_insn *insn,
732 unsigned int chan = CR_CHAN(insn->chanspec);
737 cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
738 cmd &= Z8536_CT_CMDSTAT_GCB; /* preserve gate */
739 cmd |= Z8536_CT_CMD_RCC; /* set RCC */
741 for (i = 0; i < insn->n; i++) {
742 z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
744 val = z8536_read(dev, Z8536_CT_VAL_MSB_REG(chan)) << 8;
745 val |= z8536_read(dev, Z8536_CT_VAL_LSB_REG(chan));
753 static int apci1500_auto_attach(struct comedi_device *dev,
754 unsigned long context)
756 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
757 struct apci1500_private *devpriv;
758 struct comedi_subdevice *s;
761 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
765 ret = comedi_pci_enable(dev);
769 dev->iobase = pci_resource_start(pcidev, 1);
770 devpriv->amcc = pci_resource_start(pcidev, 0);
771 devpriv->addon = pci_resource_start(pcidev, 2);
775 if (pcidev->irq > 0) {
776 ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED,
777 dev->board_name, dev);
779 dev->irq = pcidev->irq;
782 ret = comedi_alloc_subdevices(dev, 3);
786 /* Digital Input subdevice */
787 s = &dev->subdevices[0];
788 s->type = COMEDI_SUBD_DI;
789 s->subdev_flags = SDF_READABLE;
792 s->range_table = &range_digital;
793 s->insn_bits = apci1500_di_insn_bits;
795 dev->read_subdev = s;
796 s->subdev_flags |= SDF_CMD_READ;
798 s->insn_config = apci1500_di_insn_config;
799 s->do_cmdtest = apci1500_di_cmdtest;
800 s->do_cmd = apci1500_di_cmd;
801 s->cancel = apci1500_di_cancel;
804 /* Digital Output subdevice */
805 s = &dev->subdevices[1];
806 s->type = COMEDI_SUBD_DO;
807 s->subdev_flags = SDF_WRITABLE;
810 s->range_table = &range_digital;
811 s->insn_bits = apci1500_do_insn_bits;
813 /* reset all the digital outputs */
814 outw(0x0, devpriv->addon + APCI1500_DO_REG);
816 /* Counter/Timer(Watchdog) subdevice */
817 s = &dev->subdevices[2];
818 s->type = COMEDI_SUBD_TIMER;
819 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
822 s->range_table = &range_unknown;
823 s->insn_config = apci1500_timer_insn_config;
824 s->insn_write = apci1500_timer_insn_write;
825 s->insn_read = apci1500_timer_insn_read;
827 /* Enable the PCI interrupt */
829 outl(0x2000 | INTCSR_INBOX_FULL_INT,
830 devpriv->amcc + AMCC_OP_REG_INTCSR);
831 inl(devpriv->amcc + AMCC_OP_REG_IMB1);
832 inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
833 outl(INTCSR_INBOX_INTR_STATUS | 0x2000 | INTCSR_INBOX_FULL_INT,
834 devpriv->amcc + AMCC_OP_REG_INTCSR);
840 static void apci1500_detach(struct comedi_device *dev)
842 struct apci1500_private *devpriv = dev->private;
845 outl(0x0, devpriv->amcc + AMCC_OP_REG_INTCSR);
846 comedi_pci_detach(dev);
849 static struct comedi_driver apci1500_driver = {
850 .driver_name = "addi_apci_1500",
851 .module = THIS_MODULE,
852 .auto_attach = apci1500_auto_attach,
853 .detach = apci1500_detach,
856 static int apci1500_pci_probe(struct pci_dev *dev,
857 const struct pci_device_id *id)
859 return comedi_pci_auto_config(dev, &apci1500_driver, id->driver_data);
862 static const struct pci_device_id apci1500_pci_table[] = {
863 { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80fc) },
866 MODULE_DEVICE_TABLE(pci, apci1500_pci_table);
868 static struct pci_driver apci1500_pci_driver = {
869 .name = "addi_apci_1500",
870 .id_table = apci1500_pci_table,
871 .probe = apci1500_pci_probe,
872 .remove = comedi_pci_auto_unconfig,
874 module_comedi_pci_driver(apci1500_driver, apci1500_pci_driver);
876 MODULE_AUTHOR("Comedi http://www.comedi.org");
877 MODULE_DESCRIPTION("ADDI-DATA APCI-1500, 16 channel DI / 16 channel DO boards");
878 MODULE_LICENSE("GPL");