10e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
20e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes * comedi/drivers/adv_pci1710.c
30e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *
40e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes * Author: Michal Dobes <dobes@tesnet.cz>
50e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *
60e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes * Thanks to ZhenGang Shang <ZhenGang.Shang@Advantech.com.cn>
70e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes * for testing and informations.
80e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *
90e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *  hardware driver for Advantech cards:
100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *   card:   PCI-1710, PCI-1710HG, PCI-1711, PCI-1713, PCI-1720, PCI-1731
110e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *   driver: pci1710,  pci1710hg,  pci1711,  pci1713,  pci1720,  pci1731
120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *
130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes * Options:
140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *  [0] - PCI bus number - if bus number and slot number are 0,
150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *                         then driver search for first unused card
160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *  [1] - PCI slot number
170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes *
180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
200e8db97a04b37960828b273d166e35eac9a1888bMichal DobesDriver: adv_pci1710
210e8db97a04b37960828b273d166e35eac9a1888bMichal DobesDescription: Advantech PCI-1710, PCI-1710HG, PCI-1711, PCI-1713,
2297feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark	     Advantech PCI-1720, PCI-1731
230e8db97a04b37960828b273d166e35eac9a1888bMichal DobesAuthor: Michal Dobes <dobes@tesnet.cz>
240e8db97a04b37960828b273d166e35eac9a1888bMichal DobesDevices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG (pci1710hg),
250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes  PCI-1711 (adv_pci1710), PCI-1713, PCI-1720,
260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes  PCI-1731
270e8db97a04b37960828b273d166e35eac9a1888bMichal DobesStatus: works
280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
290e8db97a04b37960828b273d166e35eac9a1888bMichal DobesThis driver supports AI, AO, DI and DO subdevices.
300e8db97a04b37960828b273d166e35eac9a1888bMichal DobesAI subdevice supports cmd and insn interface,
310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobesother subdevices support only insn interface.
320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
330e8db97a04b37960828b273d166e35eac9a1888bMichal DobesThe PCI-1710 and PCI-1710HG have the same PCI device ID, so the
340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobesdriver cannot distinguish between them, as would be normal for a
350e8db97a04b37960828b273d166e35eac9a1888bMichal DobesPCI driver.
360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
370e8db97a04b37960828b273d166e35eac9a1888bMichal DobesConfiguration options:
380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes  [0] - PCI bus of device (optional)
390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes  [1] - PCI slot of device (optional)
4097feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark	If bus/slot is not specified, the first available PCI
4197feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark	device will be used.
420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4470265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slaby#include <linux/interrupt.h>
4570265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slaby
460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#include "../comedidev.h"
470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#include "comedi_pci.h"
490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#include "8253.h"
510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#include "amcc_s5933.h"
520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5397feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark#define PCI171x_PARANOIDCHECK	/* if defined, then is used code which control
5497feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark				 * correct channel number on every 12 bit
5597feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark				 * sample */
560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#undef PCI171X_EXTDEBUG
580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define DRV_NAME "adv_pci1710"
600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#undef DPRINTK
620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171X_EXTDEBUG
635f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman#define DPRINTK(fmt, args...) printk(fmt, ## args)
640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#else
650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define DPRINTK(fmt, args...)
660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6859af888d6af8e3d2c91b32e00e43f2ce750589b8Greg Kroah-Hartman#define PCI_VENDOR_ID_ADVANTECH		0x13fe
6959af888d6af8e3d2c91b32e00e43f2ce750589b8Greg Kroah-Hartman
702696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* hardware types of the cards */
710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define TYPE_PCI171X	0
720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define TYPE_PCI1713	2
730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define TYPE_PCI1720	3
740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
7597feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark#define IORANGE_171x	32
7697feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark#define IORANGE_1720	16
770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_AD_DATA	 0	/* R:   A/D data */
790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_SOFTTRG	 0	/* W:   soft trigger for A/D */
800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_RANGE	 2	/* W:   A/D gain/range register */
810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_MUX	 4	/* W:   A/D multiplexor control */
820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_STATUS	 6	/* R:   status register */
830e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_CONTROL	 6	/* W:   control register */
840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_CLRINT	 8	/* W:   clear interrupts request */
850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_CLRFIFO	 9	/* W:   clear FIFO */
860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_DA1	10	/* W:   D/A register */
870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_DA2	12	/* W:   D/A register */
880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_DAREF	14	/* W:   D/A reference control */
890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_DI	16	/* R:   digi inputs */
900e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_DO	16	/* R:   digi inputs */
91d5a2ffd8e8d602293339f69180aff8914c454d83Uwe Kleine-König#define PCI171x_CNT0	24	/* R/W: 8254 counter 0 */
92d5a2ffd8e8d602293339f69180aff8914c454d83Uwe Kleine-König#define PCI171x_CNT1	26	/* R/W: 8254 counter 1 */
93d5a2ffd8e8d602293339f69180aff8914c454d83Uwe Kleine-König#define PCI171x_CNT2	28	/* R/W: 8254 counter 2 */
940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI171x_CNTCTRL	30	/* W:   8254 counter control */
950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9697feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark/* upper bits from status register (PCI171x_STATUS) (lower is same with control
9797feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark * reg) */
980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define	Status_FE	0x0100	/* 1=FIFO is empty */
990e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Status_FH	0x0200	/* 1=FIFO is half full */
1000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Status_FF	0x0400	/* 1=FIFO is full, fatal error */
10125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi#define Status_IRQ	0x0800	/* 1=IRQ occurred */
1022696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* bits from control register (PCI171x_CONTROL) */
10397feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark#define Control_CNT0	0x0040	/* 1=CNT0 have external source,
10497feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark				 * 0=have internal 100kHz source */
1050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Control_ONEFH	0x0020	/* 1=IRQ on FIFO is half full, 0=every sample */
1060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Control_IRQEN	0x0010	/* 1=enable IRQ */
1070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Control_GATE	0x0008	/* 1=enable external trigger GATE (8254?) */
1080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Control_EXT	0x0004	/* 1=external trigger source */
1090e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Control_PACER	0x0002	/* 1=enable internal 8254 trigger source */
1100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Control_SW	0x0001	/* 1=enable software trigger source */
1112696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* bits from counter control register (PCI171x_CNTCTRL) */
1120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Counter_BCD     0x0001	/* 0 = binary counter, 1 = BCD counter */
1130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Counter_M0      0x0002	/* M0-M2 select modes 0-5 */
1140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Counter_M1      0x0004	/* 000 = mode 0, 010 = mode 2 ... */
1150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Counter_M2      0x0008
1160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Counter_RW0     0x0010	/* RW0/RW1 select read/write mode */
1170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Counter_RW1     0x0020
1180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Counter_SC0     0x0040	/* Select Counter. Only 00 or 11 may */
11997feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark#define Counter_SC1     0x0080	/* be used, 00 for CNT0,
12097feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark				 * 11 for read-back command */
1210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI1720_DA0	 0	/* W:   D/A register 0 */
1230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI1720_DA1	 2	/* W:   D/A register 1 */
1240e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI1720_DA2	 4	/* W:   D/A register 2 */
1250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI1720_DA3	 6	/* W:   D/A register 3 */
1260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI1720_RANGE	 8	/* R/W: D/A range register */
1270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI1720_SYNCOUT	 9	/* W:   D/A synchronized output register */
1280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define PCI1720_SYNCONT	15	/* R/W: D/A synchronized control */
1290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1302696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton/* D/A synchronized control (PCI1720_SYNCONT) */
1310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#define Syncont_SC0	 1	/* set synchronous output mode */
1320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1339ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_pci1710_3 = { 9, {
1340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  BIP_RANGE(5),
1350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  BIP_RANGE(2.5),
1360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  BIP_RANGE(1.25),
1370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  BIP_RANGE(0.625),
1380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  BIP_RANGE(10),
1390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  UNI_RANGE(10),
1400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  UNI_RANGE(5),
1410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  UNI_RANGE(2.5),
1420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  UNI_RANGE(1.25)
1430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  }
1440e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes};
1450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14697feeef5c55fe783e6f01d4dec3fd0926e60b0d8Markstatic const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
14797feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark					      0x10, 0x11, 0x12, 0x13 };
1480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1499ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_pci1710hg = { 12, {
1500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   BIP_RANGE(5),
1510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   BIP_RANGE(0.5),
1520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   BIP_RANGE(0.05),
1530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   BIP_RANGE(0.005),
1540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   BIP_RANGE(10),
1550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   BIP_RANGE(1),
1560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   BIP_RANGE(0.1),
1570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   BIP_RANGE(0.01),
1580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   UNI_RANGE(10),
1590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   UNI_RANGE(1),
1600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   UNI_RANGE(0.1),
1610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   UNI_RANGE(0.01)
1620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   }
1630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes};
1640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
16597feeef5c55fe783e6f01d4dec3fd0926e60b0d8Markstatic const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
16697feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark					      0x05, 0x06, 0x07, 0x10, 0x11,
16797feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark					      0x12, 0x13 };
1680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1699ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_pci17x1 = { 5, {
1700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							BIP_RANGE(10),
1710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							BIP_RANGE(5),
1720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							BIP_RANGE(2.5),
1730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							BIP_RANGE(1.25),
1740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							BIP_RANGE(0.625)
1750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							}
1760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes};
1770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobesstatic const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
1790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1809ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_pci1720 = { 4, {
1810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							UNI_RANGE(5),
1820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							UNI_RANGE(10),
1830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							BIP_RANGE(5),
1840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							BIP_RANGE(10)
1850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							}
1860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes};
1870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1889ced1de69125b60f40127eddaa3be2a92bb0a1dfBill Pembertonstatic const struct comedi_lrange range_pci171x_da = { 2, {
1890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   UNI_RANGE(5),
1900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   UNI_RANGE(10),
1910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							   }
1920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes};
1930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci1710_attach(struct comedi_device *dev,
1950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			  struct comedi_devconfig *it);
196da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci1710_detach(struct comedi_device *dev);
1970e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1987875a00b702e62ebafe68cd2abf96570e2d747e5Bill Pembertonstruct boardtype {
1992696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	const char *name;	/*  board name */
2000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int device_id;
2012696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int iorange;		/*  I/O range len */
2022696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	char have_irq;		/*  1=card support IRQ */
2032696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	char cardtype;		/*  0=1710& co. 2=1713, ... */
2042696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int n_aichan;		/*  num of A/D chans */
2052696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int n_aichand;		/*  num of A/D chans in diff mode */
2062696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int n_aochan;		/*  num of D/A chans */
2072696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int n_dichan;		/*  num of DI chans */
2082696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int n_dochan;		/*  num of DO chans */
2092696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int n_counter;		/*  num of counters */
2102696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int ai_maxdata;		/*  resolution of A/D */
2112696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	int ao_maxdata;		/*  resolution of D/A */
2122696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	const struct comedi_lrange *rangelist_ai;	/*  rangelist for A/D */
2132696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	const char *rangecode_ai;	/*  range codes for programming */
2142696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	const struct comedi_lrange *rangelist_ao;	/*  rangelist for D/A */
2152696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_ns_min;	/*  max sample speed of card v ns */
2162696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int fifo_half_size;	/*  size of FIFO/2 */
2177875a00b702e62ebafe68cd2abf96570e2d747e5Bill Pemberton};
2180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
2190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobesstatic DEFINE_PCI_DEVICE_TABLE(pci1710_pci_table) = {
220d991058efbc140957af0f3338ad6f52448c2890eJavier Martinez Canillas	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1710) },
221d991058efbc140957af0f3338ad6f52448c2890eJavier Martinez Canillas	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1711) },
222d991058efbc140957af0f3338ad6f52448c2890eJavier Martinez Canillas	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1713) },
223d991058efbc140957af0f3338ad6f52448c2890eJavier Martinez Canillas	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1720) },
224d991058efbc140957af0f3338ad6f52448c2890eJavier Martinez Canillas	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1731) },
225d991058efbc140957af0f3338ad6f52448c2890eJavier Martinez Canillas	{ 0 }
2260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes};
2270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
2280e8db97a04b37960828b273d166e35eac9a1888bMichal DobesMODULE_DEVICE_TABLE(pci, pci1710_pci_table);
2290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
2307875a00b702e62ebafe68cd2abf96570e2d747e5Bill Pembertonstatic const struct boardtype boardtypes[] = {
2310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	{"pci1710", 0x1710,
2320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 IORANGE_171x, 1, TYPE_PCI171X,
2330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
2340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 &range_pci1710_3, range_codes_pci1710_3,
2350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 &range_pci171x_da,
2360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 10000, 2048},
2370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	{"pci1710hg", 0x1710,
2380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 IORANGE_171x, 1, TYPE_PCI171X,
2390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
2400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 &range_pci1710hg, range_codes_pci1710hg,
2410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 &range_pci171x_da,
2420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 10000, 2048},
2430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	{"pci1711", 0x1711,
2440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 IORANGE_171x, 1, TYPE_PCI171X,
2450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 16, 0, 2, 16, 16, 1, 0x0fff, 0x0fff,
2460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 &range_pci17x1, range_codes_pci17x1, &range_pci171x_da,
2470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 10000, 512},
2480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	{"pci1713", 0x1713,
2490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 IORANGE_171x, 1, TYPE_PCI1713,
2500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 32, 16, 0, 0, 0, 0, 0x0fff, 0x0000,
2510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 &range_pci1710_3, range_codes_pci1710_3, NULL,
2520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 10000, 2048},
2530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	{"pci1720", 0x1720,
2540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 IORANGE_1720, 0, TYPE_PCI1720,
2550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 0, 0, 4, 0, 0, 0, 0x0000, 0x0fff,
2560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 NULL, NULL, &range_pci1720,
2570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 0, 0},
2580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	{"pci1731", 0x1731,
2590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 IORANGE_171x, 1, TYPE_PCI171X,
2600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 16, 0, 0, 16, 16, 0, 0x0fff, 0x0000,
2610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 &range_pci17x1, range_codes_pci17x1, NULL,
2620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 10000, 512},
2632696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	/*  dummy entry corresponding to driver name */
2640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	{.name = DRV_NAME},
2650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes};
2660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
2677875a00b702e62ebafe68cd2abf96570e2d747e5Bill Pemberton#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
2680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
269139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_pci1710 = {
2700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	.driver_name = DRV_NAME,
2710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	.module = THIS_MODULE,
2720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	.attach = pci1710_attach,
2730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	.detach = pci1710_detach,
2740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	.num_names = n_boardtypes,
2750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	.board_name = &boardtypes[0].name,
2767875a00b702e62ebafe68cd2abf96570e2d747e5Bill Pemberton	.offset = sizeof(struct boardtype),
2770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes};
2780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
2796e8131a86d6c1a9896282f572d17c447a85262adBill Pembertonstruct pci1710_private {
2802696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	struct pci_dev *pcidev;	/*  ptr to PCI device */
2812696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	char valid;		/*  card is usable */
2822696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	char neverending_ai;	/*  we do unlimited AI */
2832696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int CntrlReg;	/*  Control register */
2842696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int i8254_osc_base;	/*  frequence of onboard oscilator */
2852696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_do;	/*  what do AI? 0=nothing, 1 to 4 mode */
2862696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_act_scan;	/*  how many scans we finished */
2872696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_act_chan;	/*  actual position in actual scan */
2882696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_buf_ptr;	/*  data buffer ptr in samples */
2892696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned char ai_eos;	/*  1=EOS wake up */
2900e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned char ai_et;
2910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int ai_et_CntrlReg;
2920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int ai_et_MuxVal;
2930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int ai_et_div1, ai_et_div2;
2942696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int act_chanlist[32];	/*  list of scaned channel */
2952696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned char act_chanlist_len;	/*  len of scanlist */
2962696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned char act_chanlist_pos;	/*  actual position in MUX list */
2972696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned char da_ranges;	/*  copy of D/A outpit range register */
2982696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_scans;	/*  len of scanlist */
2992696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_n_chan;	/*  how many channels is measured */
3002696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int *ai_chanlist;	/*  actaul chanlist */
3012696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_flags;	/*  flaglist */
3022696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_data_len;	/*  len of data buffer */
3030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	short *ai_data;		/*  data buffer */
3042696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	unsigned int ai_timer1;	/*  timers */
3050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int ai_timer2;
3062696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	short ao_data[4];	/*  data output buffer */
30797feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark	unsigned int cnt0_write_wait;	/* after a write, wait for update of the
30897feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark					 * internal state */
3096e8131a86d6c1a9896282f572d17c447a85262adBill Pemberton};
3100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
3116e8131a86d6c1a9896282f572d17c447a85262adBill Pemberton#define devpriv ((struct pci1710_private *)dev->private)
3127875a00b702e62ebafe68cd2abf96570e2d747e5Bill Pemberton#define this_board ((const struct boardtype *)dev->board_ptr)
3130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
3140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
3150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
3160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
3170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
3180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int check_channel_list(struct comedi_device *dev,
3190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			      struct comedi_subdevice *s,
3200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			      unsigned int *chanlist, unsigned int n_chan);
3210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void setup_channel_list(struct comedi_device *dev,
3220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       struct comedi_subdevice *s,
3230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       unsigned int *chanlist, unsigned int n_chan,
3240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       unsigned int seglen);
3250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void start_pacer(struct comedi_device *dev, int mode,
3260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			unsigned int divisor1, unsigned int divisor2);
327da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci1710_reset(struct comedi_device *dev);
3280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_ai_cancel(struct comedi_device *dev,
3290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			     struct comedi_subdevice *s);
3300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
33197feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark/*  used for gain list programming */
33297feeef5c55fe783e6f01d4dec3fd0926e60b0d8Markstatic const unsigned int muxonechan[] = {
33397feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark	0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,
3340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
3350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
3360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
3370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes};
3380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
3390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
3400e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
3410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
3420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_insn_read_ai(struct comedi_device *dev,
3430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				struct comedi_subdevice *s,
3440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				struct comedi_insn *insn, unsigned int *data)
3450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
3460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int n, timeout;
3470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171x_PARANOIDCHECK
3480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int idata;
3490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
3500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
3510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_insn_read_ai(...)\n");
3520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->CntrlReg &= Control_CNT0;
3532696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	devpriv->CntrlReg |= Control_SW;	/*  set software trigger */
3540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
3550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outb(0, dev->iobase + PCI171x_CLRFIFO);
3560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outb(0, dev->iobase + PCI171x_CLRINT);
3570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
3580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	setup_channel_list(dev, s, &insn->chanspec, 1, 1);
3590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
3600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 A ST=%4x IO=%x\n",
3610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		inw(dev->iobase + PCI171x_STATUS),
3620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		dev->iobase + PCI171x_STATUS);
3630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	for (n = 0; n < insn->n; n++) {
3640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(0, dev->iobase + PCI171x_SOFTTRG);	/* start conversion */
3650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		DPRINTK("adv_pci1710 B n=%d ST=%4x\n", n,
3660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			inw(dev->iobase + PCI171x_STATUS));
3675f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		/* udelay(1); */
3680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		DPRINTK("adv_pci1710 C n=%d ST=%4x\n", n,
3690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			inw(dev->iobase + PCI171x_STATUS));
3700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		timeout = 100;
3710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		while (timeout--) {
3720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			if (!(inw(dev->iobase + PCI171x_STATUS) & Status_FE))
3730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				goto conv_finish;
3740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			if (!(timeout % 10))
3750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				DPRINTK("adv_pci1710 D n=%d tm=%d ST=%4x\n", n,
3760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes					timeout,
3770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes					inw(dev->iobase + PCI171x_STATUS));
3780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
3790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_error(dev, "A/D insn timeout");
3800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outb(0, dev->iobase + PCI171x_CLRFIFO);
3810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outb(0, dev->iobase + PCI171x_CLRINT);
3820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		data[n] = 0;
3830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		DPRINTK
3840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    ("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n",
3850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     n);
3860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return -ETIME;
3870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
3880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralconv_finish:
3890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171x_PARANOIDCHECK
3900e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		idata = inw(dev->iobase + PCI171x_AD_DATA);
3910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (this_board->cardtype != TYPE_PCI1713)
3920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			if ((idata & 0xf000) != devpriv->act_chanlist[0]) {
3930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				comedi_error(dev, "A/D insn data droput!");
3940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				return -ETIME;
3950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			}
3960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		data[n] = idata & 0x0fff;
3970e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#else
3980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		data[n] = inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff;
3990e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
4000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4010e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
4020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outb(0, dev->iobase + PCI171x_CLRFIFO);
4040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outb(0, dev->iobase + PCI171x_CLRINT);
4050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n);
4070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return n;
4080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
4090e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
4110e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
4120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
4130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_insn_write_ao(struct comedi_device *dev,
4140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				 struct comedi_subdevice *s,
4150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				 struct comedi_insn *insn, unsigned int *data)
4160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
4170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int n, chan, range, ofs;
4180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	chan = CR_CHAN(insn->chanspec);
4200e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	range = CR_RANGE(insn->chanspec);
4210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (chan) {
4220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->da_ranges &= 0xfb;
4230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->da_ranges |= (range << 2);
4240e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
4250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		ofs = PCI171x_DA2;
4260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	} else {
4270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->da_ranges &= 0xfe;
4280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->da_ranges |= range;
4290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
4300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		ofs = PCI171x_DA1;
4310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
4320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	for (n = 0; n < insn->n; n++)
4340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(data[n], dev->iobase + ofs);
4350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ao_data[chan] = data[n];
4370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return n;
4390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4400e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
4410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
4430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
4440e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
4450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_insn_read_ao(struct comedi_device *dev,
4460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				struct comedi_subdevice *s,
4470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				struct comedi_insn *insn, unsigned int *data)
4480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
4490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int n, chan;
4500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	chan = CR_CHAN(insn->chanspec);
4520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	for (n = 0; n < insn->n; n++)
4530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		data[n] = devpriv->ao_data[chan];
4540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return n;
4560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
4570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
4590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
4600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
4610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_insn_bits_di(struct comedi_device *dev,
4620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				struct comedi_subdevice *s,
4630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				struct comedi_insn *insn, unsigned int *data)
4640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
4650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	data[1] = inw(dev->iobase + PCI171x_DI);
4660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 2;
4680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
4690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
4710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
4720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
4730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_insn_bits_do(struct comedi_device *dev,
4740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				struct comedi_subdevice *s,
4750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				struct comedi_insn *insn, unsigned int *data)
4760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
4770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (data[0]) {
4780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->state &= ~data[0];
4790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->state |= (data[0] & data[1]);
4800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(s->state, dev->iobase + PCI171x_DO);
4810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
4820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	data[1] = s->state;
4830e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 2;
4850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
4860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
4880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
4890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
4900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_insn_counter_read(struct comedi_device *dev,
4910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     struct comedi_subdevice *s,
4920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     struct comedi_insn *insn,
4930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     unsigned int *data)
4940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
4950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int msb, lsb, ccntrl;
4960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int i;
4970e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
4980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	ccntrl = 0xD2;		/* count only */
4990e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	for (i = 0; i < insn->n; i++) {
5000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
5010e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		lsb = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
5030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		msb = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
5040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		data[0] = lsb | (msb << 8);
5060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
5070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return insn->n;
5090e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
5100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5110e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
5120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
5130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
5140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_insn_counter_write(struct comedi_device *dev,
5150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				      struct comedi_subdevice *s,
5160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				      struct comedi_insn *insn,
5170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				      unsigned int *data)
5180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
5190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	uint msb, lsb, ccntrl, status;
5200e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	lsb = data[0] & 0x00FF;
5220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	msb = (data[0] & 0xFF00) >> 8;
5230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5240e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* write lsb, then msb */
5250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(lsb, dev->iobase + PCI171x_CNT0);
5260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(msb, dev->iobase + PCI171x_CNT0);
5270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (devpriv->cnt0_write_wait) {
5290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		/* wait for the new count to be loaded */
5300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		ccntrl = 0xE2;
5310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		do {
5320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
5330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			status = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
5340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		} while (status & 0x40);
5350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
5360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return insn->n;
5380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
5390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5400e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
5410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
5420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
543da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci171x_insn_counter_config(struct comedi_device *dev,
5440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				       struct comedi_subdevice *s,
5450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				       struct comedi_insn *insn,
5460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				       unsigned int *data)
5470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
5480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef unused
5490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* This doesn't work like a normal Comedi counter config */
5500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	uint ccntrl = 0;
5510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->cnt0_write_wait = data[0] & 0x20;
5530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* internal or external clock? */
5550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (!(data[0] & 0x10)) {	/* internal */
5560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->CntrlReg &= ~Control_CNT0;
5570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	} else {
5580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->CntrlReg |= Control_CNT0;
5590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
5600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
5610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (data[0] & 0x01)
5630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		ccntrl |= Counter_M0;
5640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (data[0] & 0x02)
5650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		ccntrl |= Counter_M1;
5660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (data[0] & 0x04)
5670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		ccntrl |= Counter_M2;
5680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (data[0] & 0x08)
5690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		ccntrl |= Counter_BCD;
5700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	ccntrl |= Counter_RW0;	/* set read/write mode */
5710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	ccntrl |= Counter_RW1;
5720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
5730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
5740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 1;
5760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
5770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
5790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
5800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
5810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci1720_insn_write_ao(struct comedi_device *dev,
5820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				 struct comedi_subdevice *s,
5830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				 struct comedi_insn *insn, unsigned int *data)
5840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
5850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int n, rangereg, chan;
5860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	chan = CR_CHAN(insn->chanspec);
5880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	rangereg = devpriv->da_ranges & (~(0x03 << (chan << 1)));
5890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	rangereg |= (CR_RANGE(insn->chanspec) << (chan << 1));
5900e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (rangereg != devpriv->da_ranges) {
5910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outb(rangereg, dev->iobase + PCI1720_RANGE);
5920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->da_ranges = rangereg;
5930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
5940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
5950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	for (n = 0; n < insn->n; n++) {
5960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(data[n], dev->iobase + PCI1720_DA0 + (chan << 1));
5972696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		outb(0, dev->iobase + PCI1720_SYNCOUT);	/*  update outputs */
5980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
5990e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ao_data[chan] = data[n];
6010e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return n;
6030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
6040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
6060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
6070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
6080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobesstatic void interrupt_pci1710_every_sample(void *d)
6090e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
61071b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton	struct comedi_device *dev = d;
61134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s = dev->subdevices + 0;
6120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int m;
6130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171x_PARANOIDCHECK
614790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	short sampl;
6150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
6160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_every_sample(...)\n");
6180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	m = inw(dev->iobase + PCI171x_STATUS);
6190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (m & Status_FE) {
6205f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m);
6210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		pci171x_ai_cancel(dev, s);
6220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
6230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_event(dev, s);
6240e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return;
6250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
6260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (m & Status_FF) {
6275f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		printk
6280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
6290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     dev->minor, m);
6300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		pci171x_ai_cancel(dev, s);
6310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
6320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_event(dev, s);
6330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return;
6340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
6350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6362696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear our INT request */
6370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("FOR ");
6390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) {
6400e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171x_PARANOIDCHECK
6410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		sampl = inw(dev->iobase + PCI171x_AD_DATA);
6420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		DPRINTK("%04x:", sampl);
6430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (this_board->cardtype != TYPE_PCI1713)
6440e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			if ((sampl & 0xf000) !=
6450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    devpriv->act_chanlist[s->async->cur_chan]) {
6465f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				printk
6470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				    ("comedi: A/D data dropout: received data from channel %d, expected %d!\n",
6480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     (sampl & 0xf000) >> 12,
6490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     (devpriv->
6500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				      act_chanlist[s->
6510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral						   async->cur_chan] & 0xf000) >>
6520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     12);
6530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				pci171x_ai_cancel(dev, s);
6540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				s->async->events |=
6550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				    COMEDI_CB_EOA | COMEDI_CB_ERROR;
6560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				comedi_event(dev, s);
6570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				return;
6580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			}
6590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		DPRINTK("%8d %2d %8d~", s->async->buf_int_ptr,
6600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			s->async->cur_chan, s->async->buf_int_count);
6610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_buf_put(s->async, sampl & 0x0fff);
6620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#else
6630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_buf_put(s->async,
6640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
6650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
6660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		++s->async->cur_chan;
6670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
668ec14016e751106499ef237efc1000a424f53e372Jason Wong		if (s->async->cur_chan >= devpriv->ai_n_chan)
6690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			s->async->cur_chan = 0;
670ec14016e751106499ef237efc1000a424f53e372Jason Wong
6710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6722696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		if (s->async->cur_chan == 0) {	/*  one scan done */
6730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ai_act_scan++;
6740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			DPRINTK
6750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    ("adv_pci1710 EDBG: EOS1 bic %d bip %d buc %d bup %d\n",
6760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			     s->async->buf_int_count, s->async->buf_int_ptr,
6770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			     s->async->buf_user_count, s->async->buf_user_ptr);
6780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			DPRINTK("adv_pci1710 EDBG: EOS2\n");
6792696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton			if ((!devpriv->neverending_ai) && (devpriv->ai_act_scan >= devpriv->ai_scans)) {	/*  all data sampled */
6800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				pci171x_ai_cancel(dev, s);
6810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				s->async->events |= COMEDI_CB_EOA;
6820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				comedi_event(dev, s);
6830e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				return;
6840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			}
6850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
6860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
6870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6882696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear our INT request */
6890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_every_sample(...)\n");
6900e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	comedi_event(dev, s);
6920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
6930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
6940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
6950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
6960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
6970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int move_block_from_fifo(struct comedi_device *dev,
6980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				struct comedi_subdevice *s, int n, int turn)
6990e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
7000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int i, j;
7010e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171x_PARANOIDCHECK
7020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int sampl;
7030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
7040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: move_block_from_fifo(...,%d,%d)\n", n,
7050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		turn);
7060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	j = s->async->cur_chan;
7070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	for (i = 0; i < n; i++) {
7080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171x_PARANOIDCHECK
7090e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		sampl = inw(dev->iobase + PCI171x_AD_DATA);
7100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (this_board->cardtype != TYPE_PCI1713)
7110e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			if ((sampl & 0xf000) != devpriv->act_chanlist[j]) {
7125f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				printk
7130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				    ("comedi%d: A/D  FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n",
7140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     dev->minor, (sampl & 0xf000) >> 12,
7150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     (devpriv->act_chanlist[j] & 0xf000) >> 12,
7160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     i, j, devpriv->ai_act_scan, n, turn,
7170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     sampl);
7180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				pci171x_ai_cancel(dev, s);
7190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				s->async->events |=
7200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				    COMEDI_CB_EOA | COMEDI_CB_ERROR;
7210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				comedi_event(dev, s);
7220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				return 1;
7230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			}
7240e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_buf_put(s->async, sampl & 0x0fff);
7250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#else
7260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_buf_put(s->async,
7270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
7280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
7290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		j++;
7300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (j >= devpriv->ai_n_chan) {
7310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			j = 0;
7320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ai_act_scan++;
7330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
7340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
73561283d227c6b39e30afc6346db099521b0b64fa1Ian Abbott	s->async->cur_chan = j;
7360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
7370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 0;
7380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
7390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
7400e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
7410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
7420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
7430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobesstatic void interrupt_pci1710_half_fifo(void *d)
7440e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
74571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton	struct comedi_device *dev = d;
74634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s = dev->subdevices + 0;
7470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int m, samplesinbuf;
7480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
7490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_half_fifo(...)\n");
7500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	m = inw(dev->iobase + PCI171x_STATUS);
7510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (!(m & Status_FH)) {
7525f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		printk("comedi%d: A/D FIFO not half full! (%4x)\n",
7530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       dev->minor, m);
7540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		pci171x_ai_cancel(dev, s);
7550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
7560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_event(dev, s);
7570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return;
7580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
7590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (m & Status_FF) {
7605f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		printk
7610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
7620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     dev->minor, m);
7630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		pci171x_ai_cancel(dev, s);
7640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
7650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_event(dev, s);
7660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return;
7670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
7680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
7690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	samplesinbuf = this_board->fifo_half_size;
770790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	if (samplesinbuf * sizeof(short) >= devpriv->ai_data_len) {
771790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton		m = devpriv->ai_data_len / sizeof(short);
7720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (move_block_from_fifo(dev, s, m, 0))
7730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			return;
7740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		samplesinbuf -= m;
7750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
7760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
7770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (samplesinbuf) {
7780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (move_block_from_fifo(dev, s, samplesinbuf, 1))
7790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			return;
7800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
7810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
7820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (!devpriv->neverending_ai)
78397feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark		if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data
78497feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark								    sampled */
7850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			pci171x_ai_cancel(dev, s);
7860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			s->async->events |= COMEDI_CB_EOA;
7870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			comedi_event(dev, s);
7880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			return;
7890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
7902696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear our INT request */
7910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_half_fifo(...)\n");
7920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
7930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	comedi_event(dev, s);
7940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
7950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
7960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
7970e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
7980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
79970265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t interrupt_service_pci1710(int irq, void *d)
8000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
80171b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton	struct comedi_device *dev = d;
8020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: interrupt_service_pci1710(%d,...)\n",
8040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		irq);
8052696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	if (!dev->attached)	/*  is device attached? */
8062696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		return IRQ_NONE;	/*  no, exit */
8070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8082696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ))	/*  is this interrupt from our board? */
8092696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		return IRQ_NONE;	/*  no, exit */
8100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8110e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: interrupt_service_pci1710() ST: %4x\n",
8120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		inw(dev->iobase + PCI171x_STATUS));
8130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8142696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	if (devpriv->ai_et) {	/*  Switch from initial TRIG_EXT to TRIG_xxx. */
8150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->ai_et = 0;
8160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->CntrlReg &= Control_CNT0;
8172696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		devpriv->CntrlReg |= Control_SW;	/*  set software trigger */
8180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
8190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->CntrlReg = devpriv->ai_et_CntrlReg;
8200e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outb(0, dev->iobase + PCI171x_CLRFIFO);
8210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outb(0, dev->iobase + PCI171x_CLRINT);
8220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);
8230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
8242696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		/*  start pacer */
8250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		start_pacer(dev, 1, devpriv->ai_et_div1, devpriv->ai_et_div2);
8260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return IRQ_HANDLED;
8270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
8282696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	if (devpriv->ai_eos) {	/*  We use FIFO half full INT or not? */
8290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		interrupt_pci1710_every_sample(d);
8300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	} else {
8310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		interrupt_pci1710_half_fifo(d);
8320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
8330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: interrupt_service_pci1710(...)\n");
8340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return IRQ_HANDLED;
8350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
8360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
8380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
8390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
840da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
8410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     struct comedi_subdevice *s)
8420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
84348b1aff5b93521c5ad90842bef52b218ac50a4abIan Abbott	unsigned int divisor1 = 0, divisor2 = 0;
8440e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int seglen;
8450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_docmd_and_mode(%d,...)\n",
8470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		mode);
8482696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
8490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
8510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				    devpriv->ai_n_chan);
8520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (seglen < 1)
8530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return -EINVAL;
8540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	setup_channel_list(dev, s, devpriv->ai_chanlist,
8550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   devpriv->ai_n_chan, seglen);
8560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outb(0, dev->iobase + PCI171x_CLRFIFO);
8580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outb(0, dev->iobase + PCI171x_CLRINT);
8590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_do = mode;
8610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_act_scan = 0;
8630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	s->async->cur_chan = 0;
8640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_buf_ptr = 0;
8650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->neverending_ai = 0;
8660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
8670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->CntrlReg &= Control_CNT0;
8682696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	if ((devpriv->ai_flags & TRIG_WAKE_EOS)) {	/*  don't we want wake up every scan?            devpriv->ai_eos=1; */
8690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->ai_eos = 1;
8700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	} else {
8710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->CntrlReg |= Control_ONEFH;
8720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->ai_eos = 0;
8730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
8740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
875ec14016e751106499ef237efc1000a424f53e372Jason Wong	if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1))
8760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->neverending_ai = 1;
877ec14016e751106499ef237efc1000a424f53e372Jason Wong	/* well, user want neverending */
878ec14016e751106499ef237efc1000a424f53e372Jason Wong	else
8790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->neverending_ai = 0;
880ec14016e751106499ef237efc1000a424f53e372Jason Wong
8810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	switch (mode) {
8820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	case 1:
8830e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	case 2:
8840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (devpriv->ai_timer1 < this_board->ai_ns_min)
8850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ai_timer1 = this_board->ai_ns_min;
8860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->CntrlReg |= Control_PACER | Control_IRQEN;
8870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (mode == 2) {
8880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ai_et_CntrlReg = devpriv->CntrlReg;
8890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->CntrlReg &=
8900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    ~(Control_PACER | Control_ONEFH | Control_GATE);
8910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->CntrlReg |= Control_EXT;
8920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ai_et = 1;
8930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		} else {
8940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ai_et = 0;
8950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
8960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
8970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  &divisor2, &devpriv->ai_timer1,
8980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  devpriv->ai_flags & TRIG_ROUND_MASK);
8990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		DPRINTK
9000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    ("adv_pci1710 EDBG: OSC base=%u div1=%u div2=%u timer=%u\n",
9010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     devpriv->i8254_osc_base, divisor1, divisor2,
9020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     devpriv->ai_timer1);
9030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
9040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (mode != 2) {
9052696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton			/*  start pacer */
9060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			start_pacer(dev, mode, divisor1, divisor2);
9070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		} else {
9080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ai_et_div1 = divisor1;
9090e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ai_et_div2 = divisor2;
9100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
9110e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		break;
9120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	case 3:
9130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->CntrlReg |= Control_EXT | Control_IRQEN;
9140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
9150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		break;
9160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
9170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_docmd_and_mode(...)\n");
9190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 0;
9200e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
9210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171X_EXTDEBUG
9230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
9240e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
9250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
926da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void pci171x_cmdtest_out(int e, struct comedi_cmd *cmd)
9270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
9285f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	printk("adv_pci1710 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
9290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
9305f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	printk("adv_pci1710 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
9310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
9325f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	printk("adv_pci1710 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
9330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       cmd->scan_end_src);
9345f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	printk("adv_pci1710 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",
9350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
9360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
9370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
9380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
9400e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
9410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
9420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_ai_cmdtest(struct comedi_device *dev,
9430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			      struct comedi_subdevice *s,
9440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			      struct comedi_cmd *cmd)
9450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
9460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int err = 0;
947a8cb9ad9ad872dc600314c1c8d07c420b3cdefbbGreg Kroah-Hartman	int tmp;
948a8cb9ad9ad872dc600314c1c8d07c420b3cdefbbGreg Kroah-Hartman	unsigned int divisor1 = 0, divisor2 = 0;
9490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...)\n");
9510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171X_EXTDEBUG
9520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	pci171x_cmdtest_out(-1, cmd);
9530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
9540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* step 1: make sure trigger sources are trivially valid */
9550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	tmp = cmd->start_src;
9570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	cmd->start_src &= TRIG_NOW | TRIG_EXT;
9580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (!cmd->start_src || tmp != cmd->start_src)
9590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
9600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	tmp = cmd->scan_begin_src;
9620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	cmd->scan_begin_src &= TRIG_FOLLOW;
9630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
9640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
9650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	tmp = cmd->convert_src;
9670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
9680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (!cmd->convert_src || tmp != cmd->convert_src)
9690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
9700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	tmp = cmd->scan_end_src;
9720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	cmd->scan_end_src &= TRIG_COUNT;
9730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
9740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
9750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	tmp = cmd->stop_src;
9770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
9780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (!cmd->stop_src || tmp != cmd->stop_src)
9790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
9800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (err) {
9820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171X_EXTDEBUG
9830e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		pci171x_cmdtest_out(1, cmd);
9840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
9850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		DPRINTK
9860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n",
9870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     err);
9880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return 1;
9890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
9900e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* step 2: make sure trigger sources are unique and mutually compatible */
9920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
9940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		cmd->start_src = TRIG_NOW;
9950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
9960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
9970e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
9980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->scan_begin_src != TRIG_FOLLOW) {
9990e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		cmd->scan_begin_src = TRIG_FOLLOW;
10000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
10010e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
10040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
10050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->scan_end_src != TRIG_COUNT) {
10070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		cmd->scan_end_src = TRIG_COUNT;
10080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
10090e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10110e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
10120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
10130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (err) {
10150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171X_EXTDEBUG
10160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		pci171x_cmdtest_out(2, cmd);
10170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
10180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		DPRINTK
10190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n",
10200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     err);
10210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return 2;
10220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10240e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* step 3: make sure arguments are trivially compatible */
10250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->start_arg != 0) {
10270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		cmd->start_arg = 0;
10280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
10290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->scan_begin_arg != 0) {
10320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		cmd->scan_begin_arg = 0;
10330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
10340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->convert_src == TRIG_TIMER) {
10370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (cmd->convert_arg < this_board->ai_ns_min) {
10380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			cmd->convert_arg = this_board->ai_ns_min;
10390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			err++;
10400e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
10410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	} else {		/* TRIG_FOLLOW */
10420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (cmd->convert_arg != 0) {
10430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			cmd->convert_arg = 0;
10440e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			err++;
10450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
10460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->scan_end_arg != cmd->chanlist_len) {
10490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		cmd->scan_end_arg = cmd->chanlist_len;
10500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		err++;
10510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->stop_src == TRIG_COUNT) {
10530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (!cmd->stop_arg) {
10540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			cmd->stop_arg = 1;
10550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			err++;
10560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
10570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	} else {		/* TRIG_NONE */
10580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (cmd->stop_arg != 0) {
10590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			cmd->stop_arg = 0;
10600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			err++;
10610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
10620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (err) {
10650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171X_EXTDEBUG
10660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		pci171x_cmdtest_out(3, cmd);
10670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
10680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		DPRINTK
10690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n",
10700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     err);
10710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return 3;
10720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* step 4: fix up any arguments */
10750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->convert_src == TRIG_TIMER) {
10770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		tmp = cmd->convert_arg;
10780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
10790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  &divisor2, &cmd->convert_arg,
10800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  cmd->flags & TRIG_ROUND_MASK);
10810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (cmd->convert_arg < this_board->ai_ns_min)
10820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			cmd->convert_arg = this_board->ai_ns_min;
10830e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (tmp != cmd->convert_arg)
10840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			err++;
10850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (err) {
10880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		DPRINTK
10890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n",
10900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		     err);
10910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return 4;
10920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
10930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* step 5: complain about special chanlist considerations */
10950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
10960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (cmd->chanlist) {
10970e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (!check_channel_list(dev, s, cmd->chanlist,
10980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					cmd->chanlist_len))
10992696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton			return 5;	/*  incorrect channels list */
11000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
11010e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
11020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) ret=0\n");
11030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 0;
11040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
11050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
11060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
11070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
11080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
1109da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
11100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
1111ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton	struct comedi_cmd *cmd = &s->async->cmd;
11120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
11130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmd(...)\n");
11140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_n_chan = cmd->chanlist_len;
11150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_chanlist = cmd->chanlist;
11160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_flags = cmd->flags;
11170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_data_len = s->async->prealloc_bufsz;
11180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_data = s->async->prealloc_buf;
11190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_timer1 = 0;
11200e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_timer2 = 0;
11210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1122ec14016e751106499ef237efc1000a424f53e372Jason Wong	if (cmd->stop_src == TRIG_COUNT)
11230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->ai_scans = cmd->stop_arg;
1124ec14016e751106499ef237efc1000a424f53e372Jason Wong	else
11250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->ai_scans = 0;
1126ec14016e751106499ef237efc1000a424f53e372Jason Wong
11270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
11282696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	if (cmd->scan_begin_src == TRIG_FOLLOW) {	/*  mode 1, 2, 3 */
11292696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		if (cmd->convert_src == TRIG_TIMER) {	/*  mode 1 and 2 */
11300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ai_timer1 = cmd->convert_arg;
11310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			return pci171x_ai_docmd_and_mode(cmd->start_src ==
11320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							 TRIG_EXT ? 2 : 1, dev,
11330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							 s);
11340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
11352696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		if (cmd->convert_src == TRIG_EXT) {	/*  mode 3 */
11360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			return pci171x_ai_docmd_and_mode(3, dev, s);
11370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
11380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
11390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
11400e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return -1;
11410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
11420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
11430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
11440e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
11450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes Check if channel list from user is builded correctly
11460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes If it's ok, then program scan/gain logic.
11470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes This works for all cards.
11480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
11490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int check_channel_list(struct comedi_device *dev,
11500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			      struct comedi_subdevice *s,
11510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			      unsigned int *chanlist, unsigned int n_chan)
11520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
11530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int chansegment[32];
11540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int i, nowmustbechan, seglen, segpos;
11550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
11560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG:  check_channel_list(...,%d)\n", n_chan);
11570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* correct channel and range number check itself comedi/range.c */
11580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (n_chan < 1) {
11590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		comedi_error(dev, "range/channel list is empty!");
11600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return 0;
11610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
11620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
11630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (n_chan > 1) {
116425985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		chansegment[0] = chanlist[0];	/*  first channel is every time ok */
11652696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {	/*  build part of chanlist */
11665f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			/*  printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */
11670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			if (chanlist[0] == chanlist[i])
11682696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton				break;	/*  we detect loop, this must by finish */
11692696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton			if (CR_CHAN(chanlist[i]) & 1)	/*  odd channel cann't by differencial */
11700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				if (CR_AREF(chanlist[i]) == AREF_DIFF) {
11710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes					comedi_error(dev,
11720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral						     "Odd channel can't be differential input!\n");
11730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes					return 0;
11740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				}
11750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			nowmustbechan =
11760a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
11770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			if (CR_AREF(chansegment[i - 1]) == AREF_DIFF)
11780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				nowmustbechan = (nowmustbechan + 1) % s->n_chan;
117925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi			if (nowmustbechan != CR_CHAN(chanlist[i])) {	/*  channel list isn't continuous :-( */
11805f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				printk
118125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi				    ("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
11820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     i, CR_CHAN(chanlist[i]), nowmustbechan,
11830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     CR_CHAN(chanlist[0]));
11840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				return 0;
11850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			}
11862696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton			chansegment[i] = chanlist[i];	/*  well, this is next correct channel in list */
11870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
11880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
11892696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		for (i = 0, segpos = 0; i < n_chan; i++) {	/*  check whole chanlist */
11905f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			/* printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */
11910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			if (chanlist[i] != chansegment[i % seglen]) {
11925f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				printk
11930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				    ("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
11940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     i, CR_CHAN(chansegment[i]),
11950a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     CR_RANGE(chansegment[i]),
11960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     CR_AREF(chansegment[i]),
11970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     CR_CHAN(chanlist[i % seglen]),
11980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     CR_RANGE(chanlist[i % seglen]),
11990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				     CR_AREF(chansegment[i % seglen]));
12002696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton				return 0;	/*  chan/gain list is strange */
12010e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			}
12020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
12030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	} else {
12040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		seglen = 1;
12050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
12060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return seglen;
12070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
12080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void setup_channel_list(struct comedi_device *dev,
12100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       struct comedi_subdevice *s,
12110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       unsigned int *chanlist, unsigned int n_chan,
12120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       unsigned int seglen)
12130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
12140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int i, range, chanprog;
12150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG:  setup_channel_list(...,%d,%d)\n", n_chan,
12170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		seglen);
12180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->act_chanlist_len = seglen;
12190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->act_chanlist_pos = 0;
12200e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("SegLen: %d\n", seglen);
12222696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	for (i = 0; i < seglen; i++) {	/*  store range list to card */
12230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		chanprog = muxonechan[CR_CHAN(chanlist[i])];
12240e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(chanprog, dev->iobase + PCI171x_MUX);	/* select channel */
12250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		range = this_board->rangecode_ai[CR_RANGE(chanlist[i])];
12260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (CR_AREF(chanlist[i]) == AREF_DIFF)
12270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			range |= 0x0020;
12280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(range, dev->iobase + PCI171x_RANGE);	/* select gain */
12290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#ifdef PCI171x_PARANOIDCHECK
12300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->act_chanlist[i] =
12310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    (CR_CHAN(chanlist[i]) << 12) & 0xf000;
12320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes#endif
12330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
12340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->act_chanlist[i]);
12350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
123661283d227c6b39e30afc6346db099521b0b64fa1Ian Abbott#ifdef PCI171x_PARANOIDCHECK
123761283d227c6b39e30afc6346db099521b0b64fa1Ian Abbott	for ( ; i < n_chan; i++) { /* store remainder of channel list */
123861283d227c6b39e30afc6346db099521b0b64fa1Ian Abbott		devpriv->act_chanlist[i] =
123961283d227c6b39e30afc6346db099521b0b64fa1Ian Abbott		    (CR_CHAN(chanlist[i]) << 12) & 0xf000;
124061283d227c6b39e30afc6346db099521b0b64fa1Ian Abbott	}
124161283d227c6b39e30afc6346db099521b0b64fa1Ian Abbott#endif
12420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_et_MuxVal =
12440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	    CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
12450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);	/* select channel interval to scan */
12460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("MUX: %4x L%4x.H%4x\n",
12470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8),
12480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		CR_CHAN(chanlist[0]), CR_CHAN(chanlist[seglen - 1]));
12490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
12500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
12520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
12530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
12540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic void start_pacer(struct comedi_device *dev, int mode,
12550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			unsigned int divisor1, unsigned int divisor2)
12560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
12570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode,
12580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		divisor1, divisor2);
12590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(0xb4, dev->iobase + PCI171x_CNTCTRL);
12600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(0x74, dev->iobase + PCI171x_CNTCTRL);
12610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (mode == 1) {
12630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2);
12640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2);
12650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1);
12660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1);
12670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
12680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: start_pacer(...)\n");
12690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
12700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
12720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
12730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
12740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci171x_ai_cancel(struct comedi_device *dev,
12750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			     struct comedi_subdevice *s)
12760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
12770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cancel(...)\n");
12780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	switch (this_board->cardtype) {
12800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	default:
12810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->CntrlReg &= Control_CNT0;
12820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->CntrlReg |= Control_SW;
12830e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12842696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);	/*  reset any operations */
12850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		start_pacer(dev, -1, 0, 0);
12860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outb(0, dev->iobase + PCI171x_CLRFIFO);
12870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		outb(0, dev->iobase + PCI171x_CLRINT);
12880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		break;
12890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
12900e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_do = 0;
12920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_act_scan = 0;
12930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	s->async->cur_chan = 0;
12940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ai_buf_ptr = 0;
12950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->neverending_ai = 0;
12960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
12970e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_cancel(...)\n");
12980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 0;
12990e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
13000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
13010e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
13020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
13030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
1304da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci171x_reset(struct comedi_device *dev)
13050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
13060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_reset(...)\n");
13070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(0x30, dev->iobase + PCI171x_CNTCTRL);
13082696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	devpriv->CntrlReg = Control_SW | Control_CNT0;	/*  Software trigger, CNT0=external */
13092696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);	/*  reset any operations */
13102696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(0, dev->iobase + PCI171x_CLRFIFO);	/*  clear FIFO */
13112696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear INT request */
13122696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	start_pacer(dev, -1, 0, 0);	/*  stop 8254 */
13130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->da_ranges = 0;
13140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_aochan) {
13152696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);	/*  set DACs to 0..5V */
13162696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		outw(0, dev->iobase + PCI171x_DA1);	/*  set DA outputs to 0V */
13170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		devpriv->ao_data[0] = 0x0000;
13180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (this_board->n_aochan > 1) {
13190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			outw(0, dev->iobase + PCI171x_DA2);
13200e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			devpriv->ao_data[1] = 0x0000;
13210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
13220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
13232696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outw(0, dev->iobase + PCI171x_DO);	/*  digital outputs to 0 */
13242696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(0, dev->iobase + PCI171x_CLRFIFO);	/*  clear FIFO */
13252696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear INT request */
13260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
13270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: pci171x_reset(...)\n");
13280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 0;
13290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
13300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
13310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
13320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
13330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
1334da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci1720_reset(struct comedi_device *dev)
13350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
13360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: pci1720_reset(...)\n");
13372696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT);	/*  set synchronous output mode */
13380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->da_ranges = 0xAA;
13392696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE);	/*  set all ranges to +/-5V */
13402696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outw(0x0800, dev->iobase + PCI1720_DA0);	/*  set outputs to 0V */
13410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(0x0800, dev->iobase + PCI1720_DA1);
13420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(0x0800, dev->iobase + PCI1720_DA2);
13430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	outw(0x0800, dev->iobase + PCI1720_DA3);
13442696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	outb(0, dev->iobase + PCI1720_SYNCOUT);	/*  update outputs */
13450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ao_data[0] = 0x0800;
13460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ao_data[1] = 0x0800;
13470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ao_data[2] = 0x0800;
13480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->ao_data[3] = 0x0800;
13490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: pci1720_reset(...)\n");
13500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 0;
13510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
13520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
13530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
13540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
13550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
1356da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci1710_reset(struct comedi_device *dev)
13570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
13580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: BGN: pci1710_reset(...)\n");
13590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	switch (this_board->cardtype) {
13600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	case TYPE_PCI1720:
13610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return pci1720_reset(dev);
13620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	default:
13630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return pci171x_reset(dev);
13640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
13650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	DPRINTK("adv_pci1710 EDBG: END: pci1710_reset(...)\n");
13660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
13670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
13680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
13690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
13700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
13710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int pci1710_attach(struct comedi_device *dev,
13720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			  struct comedi_devconfig *it)
13730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
137434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
13750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int ret, subdev, n_subdevices;
13760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned int irq;
13770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned long iobase;
13780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	struct pci_dev *pcidev;
13790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int opt_bus, opt_slot;
13800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	const char *errstr;
13810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	unsigned char pci_bus, pci_slot, pci_func;
13820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int i;
13830e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	int board_index;
13840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1385be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya	dev_info(dev->hw_dev, "comedi%d: adv_pci1710:\n", dev->minor);
13860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
13870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	opt_bus = it->options[0];
13880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	opt_slot = it->options[1];
13890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1390c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = alloc_private(dev, sizeof(struct pci1710_private));
1391be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya	if (ret < 0)
13920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return -ENOMEM;
13930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
13940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	/* Look for matching PCI device */
13950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	errstr = "not found!";
13960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	pcidev = NULL;
13970e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	board_index = this_board - boardtypes;
13980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_ADVANTECH,
13990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral						PCI_ANY_ID, pcidev))) {
14000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		if (strcmp(this_board->name, DRV_NAME) == 0) {
14010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			for (i = 0; i < n_boardtypes; ++i) {
14020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				if (pcidev->device == boardtypes[i].device_id) {
14030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes					board_index = i;
14040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes					break;
14050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				}
14060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			}
14070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			if (i == n_boardtypes)
14080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				continue;
14090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		} else {
14100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			if (pcidev->device != boardtypes[board_index].device_id)
14110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				continue;
14120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
14130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		/* Found matching vendor/device. */
14150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (opt_bus || opt_slot) {
14160e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			/* Check bus/slot. */
14170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			if (opt_bus != pcidev->bus->number
14180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    || opt_slot != PCI_SLOT(pcidev->devfn))
14190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				continue;	/* no match */
14200e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
14210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		/*
14220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		 * Look for device that isn't in use.
14230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		 * Enable PCI device and request regions.
14240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		 */
14250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (comedi_pci_enable(pcidev, DRV_NAME)) {
14260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			errstr =
14270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    "failed to enable PCI device and request regions!";
14280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			continue;
14290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
14302696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		/*  fixup board_ptr in case we were using the dummy entry with the driver name */
14310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		dev->board_ptr = &boardtypes[board_index];
14320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		break;
14330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
14340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (!pcidev) {
14360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (opt_bus || opt_slot) {
1437be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya			dev_err(dev->hw_dev, "- Card at b:s %d:%d %s\n",
1438be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya				opt_bus, opt_slot, errstr);
14390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		} else {
1440be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya			dev_err(dev->hw_dev, "- Card %s\n", errstr);
14410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
14420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return -EIO;
14430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
14440e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	pci_bus = pcidev->bus->number;
14460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	pci_slot = PCI_SLOT(pcidev->devfn);
14470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	pci_func = PCI_FUNC(pcidev->devfn);
14480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	irq = pcidev->irq;
14490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	iobase = pci_resource_start(pcidev, 2);
14500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1451be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya	dev_dbg(dev->hw_dev, "b:s:f=%d:%d:%d, io=0x%4lx\n", pci_bus, pci_slot,
1452be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya		pci_func, iobase);
14530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	dev->iobase = iobase;
14550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	dev->board_name = this_board->name;
14570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->pcidev = pcidev;
14580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	n_subdevices = 0;
14600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_aichan)
14610e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		n_subdevices++;
14620e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_aochan)
14630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		n_subdevices++;
14640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_dichan)
14650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		n_subdevices++;
14660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_dochan)
14670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		n_subdevices++;
14680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_counter)
14690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		n_subdevices++;
14700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
1471c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = alloc_subdevices(dev, n_subdevices);
1472be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya	if (ret < 0)
14730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		return ret;
14740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	pci1710_reset(dev);
14760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->have_irq) {
14780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (irq) {
14795f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			if (request_irq(irq, interrupt_service_pci1710,
14800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes					IRQF_SHARED, "Advantech PCI-1710",
14810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes					dev)) {
1482be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya				dev_dbg(dev->hw_dev, "unable to allocate IRQ %d, DISABLING IT",
1483be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya					irq);
14840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				irq = 0;	/* Can't use IRQ */
14850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			} else {
1486be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya				dev_dbg(dev->hw_dev, "irq=%u", irq);
14870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			}
14880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		} else {
1489be545c6251875797fdd9add35a48a1111e896d1eRavishankar karkala Mallikarjunayya			dev_dbg(dev->hw_dev, "IRQ disabled");
14900e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
14910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	} else {
14920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		irq = 0;
14930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
14940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	dev->irq = irq;
14960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	subdev = 0;
14970e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
14980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_aichan) {
14990e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s = dev->subdevices + subdev;
15000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		dev->read_subdev = s;
15010e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->type = COMEDI_SUBD_AI;
15020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
15030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (this_board->n_aichand)
15040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			s->subdev_flags |= SDF_DIFF;
15050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->n_chan = this_board->n_aichan;
15060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->maxdata = this_board->ai_maxdata;
15070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->len_chanlist = this_board->n_aichan;
15080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->range_table = this_board->rangelist_ai;
15090e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->cancel = pci171x_ai_cancel;
15100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->insn_read = pci171x_insn_read_ai;
15110e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (irq) {
15120e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			s->subdev_flags |= SDF_CMD_READ;
15130e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			s->do_cmdtest = pci171x_ai_cmdtest;
15140e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			s->do_cmd = pci171x_ai_cmd;
15150e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
15162696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton		devpriv->i8254_osc_base = 100;	/*  100ns=10MHz */
15170e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		subdev++;
15180e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
15190e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
15200e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_aochan) {
15210e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s = dev->subdevices + subdev;
15220e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->type = COMEDI_SUBD_AO;
15230e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
15240e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->n_chan = this_board->n_aochan;
15250e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->maxdata = this_board->ao_maxdata;
15260e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->len_chanlist = this_board->n_aochan;
15270e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->range_table = this_board->rangelist_ao;
15280e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		switch (this_board->cardtype) {
15290e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		case TYPE_PCI1720:
15300e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			s->insn_write = pci1720_insn_write_ao;
15310e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			break;
15320e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		default:
15330e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			s->insn_write = pci171x_insn_write_ao;
15340e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			break;
15350e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
15360e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->insn_read = pci171x_insn_read_ao;
15370e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		subdev++;
15380e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
15390e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
15400e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_dichan) {
15410e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s = dev->subdevices + subdev;
15420e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->type = COMEDI_SUBD_DI;
15430e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
15440e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->n_chan = this_board->n_dichan;
15450e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->maxdata = 1;
15460e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->len_chanlist = this_board->n_dichan;
15470e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->range_table = &range_digital;
15480e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->io_bits = 0;	/* all bits input */
15490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->insn_bits = pci171x_insn_bits_di;
15500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		subdev++;
15510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
15520e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
15530e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_dochan) {
15540e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s = dev->subdevices + subdev;
15550e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->type = COMEDI_SUBD_DO;
15560e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
15570e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->n_chan = this_board->n_dochan;
15580e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->maxdata = 1;
15590e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->len_chanlist = this_board->n_dochan;
15600e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->range_table = &range_digital;
156197feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark		/* all bits output */
156297feeef5c55fe783e6f01d4dec3fd0926e60b0d8Mark		s->io_bits = (1 << this_board->n_dochan) - 1;
15630e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->state = 0;
15640e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->insn_bits = pci171x_insn_bits_do;
15650e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		subdev++;
15660e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
15670e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
15680e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (this_board->n_counter) {
15690e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s = dev->subdevices + subdev;
15700e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->type = COMEDI_SUBD_COUNTER;
15710e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
15720e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->n_chan = this_board->n_counter;
15730e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->len_chanlist = this_board->n_counter;
15740e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->maxdata = 0xffff;
15750e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->range_table = &range_unknown;
15760e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->insn_read = pci171x_insn_counter_read;
15770e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->insn_write = pci171x_insn_counter_write;
15780e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		s->insn_config = pci171x_insn_counter_config;
15790e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		subdev++;
15800e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
15810e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
15820e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	devpriv->valid = 1;
15830e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
15840e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 0;
15850e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
15860e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
15870e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
15880e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
15890e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
1590da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int pci1710_detach(struct comedi_device *dev)
15910e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes{
15920e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
15930e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	if (dev->private) {
15940e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (devpriv->valid)
15950e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			pci1710_reset(dev);
15960e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (dev->irq)
15975f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			free_irq(dev->irq, dev);
15980e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		if (devpriv->pcidev) {
1599ec14016e751106499ef237efc1000a424f53e372Jason Wong			if (dev->iobase)
16000e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes				comedi_pci_disable(devpriv->pcidev);
1601ec14016e751106499ef237efc1000a424f53e372Jason Wong
16020e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes			pci_dev_put(devpriv->pcidev);
16030e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes		}
16040e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	}
16050e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
16060e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes	return 0;
16070e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes}
16080e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes
16090e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
16100e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
16110e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
1612727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit driver_pci1710_pci_probe(struct pci_dev *dev,
1613727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas					      const struct pci_device_id *ent)
1614727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{
1615727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	return comedi_pci_auto_config(dev, driver_pci1710.driver_name);
1616727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}
1617727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
1618727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit driver_pci1710_pci_remove(struct pci_dev *dev)
1619727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{
1620727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	comedi_pci_auto_unconfig(dev);
1621727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}
1622727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
1623727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver driver_pci1710_pci_driver = {
1624727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	.id_table = pci1710_pci_table,
1625727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	.probe = &driver_pci1710_pci_probe,
1626727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	.remove = __devexit_p(&driver_pci1710_pci_remove)
1627727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas};
1628727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
1629727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init driver_pci1710_init_module(void)
1630727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{
1631727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	int retval;
1632727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
1633727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	retval = comedi_driver_register(&driver_pci1710);
1634727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	if (retval < 0)
1635727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas		return retval;
1636727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
1637727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	driver_pci1710_pci_driver.name = (char *)driver_pci1710.driver_name;
1638727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	return pci_register_driver(&driver_pci1710_pci_driver);
1639727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}
1640727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
1641727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit driver_pci1710_cleanup_module(void)
1642727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{
1643727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	pci_unregister_driver(&driver_pci1710_pci_driver);
1644727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	comedi_driver_unregister(&driver_pci1710);
1645727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}
1646727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
1647727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(driver_pci1710_init_module);
1648727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(driver_pci1710_cleanup_module);
16490e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes/*
16500e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes==============================================================================
16510e8db97a04b37960828b273d166e35eac9a1888bMichal Dobes*/
165290f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
165390f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
165490f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
165590f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
1656