46 #include "../comedidev.h"
52 #define PCI171x_PARANOIDCHECK
56 #define PCI_VENDOR_ID_ADVANTECH 0x13fe
59 #define TYPE_PCI171X 0
60 #define TYPE_PCI1713 2
61 #define TYPE_PCI1720 3
63 #define IORANGE_171x 32
64 #define IORANGE_1720 16
66 #define PCI171x_AD_DATA 0
67 #define PCI171x_SOFTTRG 0
68 #define PCI171x_RANGE 2
70 #define PCI171x_STATUS 6
71 #define PCI171x_CONTROL 6
72 #define PCI171x_CLRINT 8
73 #define PCI171x_CLRFIFO 9
74 #define PCI171x_DA1 10
75 #define PCI171x_DA2 12
76 #define PCI171x_DAREF 14
79 #define PCI171x_CNT0 24
80 #define PCI171x_CNT1 26
81 #define PCI171x_CNT2 28
82 #define PCI171x_CNTCTRL 30
86 #define Status_FE 0x0100
87 #define Status_FH 0x0200
88 #define Status_FF 0x0400
89 #define Status_IRQ 0x0800
91 #define Control_CNT0 0x0040
93 #define Control_ONEFH 0x0020
94 #define Control_IRQEN 0x0010
95 #define Control_GATE 0x0008
96 #define Control_EXT 0x0004
97 #define Control_PACER 0x0002
98 #define Control_SW 0x0001
100 #define Counter_BCD 0x0001
101 #define Counter_M0 0x0002
102 #define Counter_M1 0x0004
103 #define Counter_M2 0x0008
104 #define Counter_RW0 0x0010
105 #define Counter_RW1 0x0020
106 #define Counter_SC0 0x0040
107 #define Counter_SC1 0x0080
110 #define PCI1720_DA0 0
111 #define PCI1720_DA1 2
112 #define PCI1720_DA2 4
113 #define PCI1720_DA3 6
114 #define PCI1720_RANGE 8
115 #define PCI1720_SYNCOUT 9
116 #define PCI1720_SYNCONT 15
119 #define Syncont_SC0 1
134 static const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
135 0x10, 0x11, 0x12, 0x13 };
153 static const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04,
154 0x05, 0x06, 0x07, 0x10, 0x11,
166 static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
203 static const struct boardtype boardtypes[] = {
216 .ai_maxdata = 0x0fff,
217 .ao_maxdata = 0x0fff,
218 .rangelist_ai = &range_pci1710_3,
219 .rangecode_ai = range_codes_pci1710_3,
220 .rangelist_ao = &range_pci171x_da,
222 .fifo_half_size = 2048,
235 .ai_maxdata = 0x0fff,
236 .ao_maxdata = 0x0fff,
237 .rangelist_ai = &range_pci1710hg,
238 .rangecode_ai = range_codes_pci1710hg,
239 .rangelist_ao = &range_pci171x_da,
241 .fifo_half_size = 2048,
253 .ai_maxdata = 0x0fff,
254 .ao_maxdata = 0x0fff,
255 .rangelist_ai = &range_pci17x1,
256 .rangecode_ai = range_codes_pci17x1,
257 .rangelist_ao = &range_pci171x_da,
259 .fifo_half_size = 512,
268 .ai_maxdata = 0x0fff,
269 .rangelist_ai = &range_pci1710_3,
270 .rangecode_ai = range_codes_pci1710_3,
272 .fifo_half_size = 2048,
279 .ao_maxdata = 0x0fff,
280 .rangelist_ao = &range_pci1720,
290 .ai_maxdata = 0x0fff,
291 .rangelist_ai = &range_pci17x1,
292 .rangecode_ai = range_codes_pci17x1,
294 .fifo_half_size = 512,
329 static const unsigned int muxonechan[] = {
330 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,
331 0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
332 0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
333 0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
344 unsigned int *chanlist,
unsigned int n_chan)
346 unsigned int chansegment[32];
347 unsigned int i, nowmustbechan, seglen, segpos;
358 chansegment[0] = chanlist[0];
359 for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {
360 if (chanlist[0] == chanlist[i])
362 if ((
CR_CHAN(chanlist[i]) & 1) &&
364 comedi_error(dev,
"Odd channel cannot be differential input!\n");
367 nowmustbechan = (
CR_CHAN(chansegment[i - 1]) + 1) % s->
n_chan;
369 nowmustbechan = (nowmustbechan + 1) % s->
n_chan;
370 if (nowmustbechan !=
CR_CHAN(chanlist[i])) {
371 printk(
"channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
372 i,
CR_CHAN(chanlist[i]), nowmustbechan,
376 chansegment[
i] = chanlist[
i];
379 for (i = 0, segpos = 0; i < n_chan; i++) {
380 if (chanlist[i] != chansegment[i % seglen]) {
381 printk(
"bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
387 CR_AREF(chansegment[i % seglen]));
396 unsigned int *chanlist,
unsigned int n_chan,
401 unsigned int i,
range, chanprog;
406 for (i = 0; i < seglen; i++) {
407 chanprog = muxonechan[
CR_CHAN(chanlist[i])];
413 #ifdef PCI171x_PARANOIDCHECK
415 (
CR_CHAN(chanlist[i]) << 12) & 0xf000;
418 #ifdef PCI171x_PARANOIDCHECK
419 for ( ; i < n_chan; i++) {
421 (
CR_CHAN(chanlist[i]) << 12) & 0xf000;
440 #ifdef PCI171x_PARANOIDCHECK
441 const struct boardtype *this_board = comedi_board(dev);
451 setup_channel_list(dev, s, &insn->
chanspec, 1, 1);
453 for (n = 0; n < insn->
n; n++) {
468 #ifdef PCI171x_PARANOIDCHECK
475 data[
n] = idata & 0x0fff;
512 for (n = 0; n < insn->
n; n++)
532 for (n = 0; n < insn->
n; n++)
533 data[n] = devpriv->
ao_data[chan];
558 s->
state &= ~data[0];
559 s->
state |= (data[0] & data[1]);
571 unsigned int divisor1,
unsigned int divisor2)
587 static int pci171x_insn_counter_read(
struct comedi_device *dev,
592 unsigned int msb,
lsb, ccntrl;
596 for (i = 0; i < insn->
n; i++) {
602 data[0] = lsb | (msb << 8);
611 static int pci171x_insn_counter_write(
struct comedi_device *dev,
619 lsb = data[0] & 0x00FF;
620 msb = (data[0] & 0xFF00) >> 8;
632 }
while (status & 0x40);
641 static int pci171x_insn_counter_config(
struct comedi_device *dev,
654 if (!(data[0] & 0x10)) {
685 int n, rangereg, chan;
688 rangereg = devpriv->
da_ranges & (~(0x03 << (chan << 1)));
695 for (n = 0; n < insn->
n; n++) {
711 const struct boardtype *this_board = comedi_board(dev);
720 start_pacer(dev, -1, 0, 0);
728 s->
async->cur_chan = 0;
738 static void interrupt_pci1710_every_sample(
void *
d)
744 #ifdef PCI171x_PARANOIDCHECK
745 const struct boardtype *this_board = comedi_board(dev);
751 printk(
"comedi%d: A/D FIFO empty (%4x)\n", dev->
minor, m);
752 pci171x_ai_cancel(dev, s);
759 (
"comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
761 pci171x_ai_cancel(dev, s);
770 #ifdef PCI171x_PARANOIDCHECK
773 if ((sampl & 0xf000) !=
776 (
"comedi: A/D data dropout: received data from channel %d, expected %d!\n",
777 (sampl & 0xf000) >> 12,
780 async->cur_chan] & 0xf000) >>
782 pci171x_ai_cancel(dev, s);
793 ++s->
async->cur_chan;
796 s->
async->cur_chan = 0;
799 if (s->
async->cur_chan == 0) {
804 pci171x_ai_cancel(dev, s);
825 #ifdef PCI171x_PARANOIDCHECK
826 const struct boardtype *this_board = comedi_board(dev);
830 j = s->
async->cur_chan;
831 for (i = 0; i <
n; i++) {
832 #ifdef PCI171x_PARANOIDCHECK
837 (
"comedi%d: A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n",
838 dev->
minor, (sampl & 0xf000) >> 12,
842 pci171x_ai_cancel(dev, s);
866 static void interrupt_pci1710_half_fifo(
void *d)
869 const struct boardtype *this_board = comedi_board(dev);
876 printk(
"comedi%d: A/D FIFO not half full! (%4x)\n",
878 pci171x_ai_cancel(dev, s);
885 (
"comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
887 pci171x_ai_cancel(dev, s);
894 if (samplesinbuf *
sizeof(
short) >= devpriv->
ai_data_len) {
896 if (move_block_from_fifo(dev, s, m, 0))
902 if (move_block_from_fifo(dev, s, samplesinbuf, 1))
909 pci171x_ai_cancel(dev, s);
922 static irqreturn_t interrupt_service_pci1710(
int irq,
void *d)
933 if (devpriv->
ai_et) {
948 interrupt_pci1710_every_sample(d);
950 interrupt_pci1710_half_fifo(d);
958 static int pci171x_ai_docmd_and_mode(
int mode,
struct comedi_device *dev,
961 const struct boardtype *this_board = comedi_board(dev);
963 unsigned int divisor1 = 0, divisor2 = 0;
966 start_pacer(dev, -1, 0, 0);
968 seglen = check_channel_list(dev, s, devpriv->
ai_chanlist,
981 s->
async->cur_chan = 0;
1021 start_pacer(dev, mode, divisor1, divisor2);
1043 const struct boardtype *this_board = comedi_board(dev);
1047 unsigned int divisor1 = 0, divisor2 = 0;
1062 err |= cfc_check_trigger_is_unique(cmd->
start_src);
1063 err |= cfc_check_trigger_is_unique(cmd->
convert_src);
1064 err |= cfc_check_trigger_is_unique(cmd->
stop_src);
1133 if (!check_channel_list(dev, s, cmd->
chanlist,
1166 return pci171x_ai_docmd_and_mode(cmd->
start_src ==
1171 return pci171x_ai_docmd_and_mode(3, dev, s);
1183 const struct boardtype *this_board = comedi_board(dev);
1191 start_pacer(dev, -1, 0, 0);
1236 const struct boardtype *this_board = comedi_board(dev);
1240 return pci1720_reset(dev);
1242 return pci171x_reset(dev);
1246 static const void *pci1710_find_boardinfo(
struct comedi_device *dev,
1252 for (i = 0; i <
ARRAY_SIZE(boardtypes); i++) {
1253 this_board = &boardtypes[
i];
1268 comedi_set_hw_dev(dev, &pcidev->
dev);
1270 this_board = pci1710_find_boardinfo(dev, pcidev);
1276 ret = alloc_private(dev,
sizeof(*devpriv));
1324 s->
cancel = pci171x_ai_cancel;
1329 s->
do_cmd = pci171x_ai_cmd;
1391 s->
insn_read = pci171x_insn_counter_read;
1405 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1418 .driver_name =
"adv_pci1710",
1420 .attach_pci = pci1710_attach_pci,
1421 .detach = pci1710_detach,
1445 static struct pci_driver adv_pci1710_pci_driver = {
1446 .name =
"adv_pci1710",
1447 .id_table = adv_pci1710_pci_table,
1448 .probe = adv_pci1710_pci_probe,