65 #include "../comedidev.h"
76 #define PCI_VENDOR_ID_AMCC 0x10e8
79 #undef PCI9118_PARANOIDCHECK
84 #define IORANGE_9118 64
85 #define PCI9118_CHANLEN 255
90 #define PCI9118_CNT0 0x00
91 #define PCI9118_CNT1 0x04
92 #define PCI9118_CNT2 0x08
93 #define PCI9118_CNTCTRL 0x0c
94 #define PCI9118_AD_DATA 0x10
95 #define PCI9118_DA1 0x10
96 #define PCI9118_DA2 0x14
97 #define PCI9118_ADSTAT 0x18
98 #define PCI9118_ADCNTRL 0x18
99 #define PCI9118_DI 0x1c
100 #define PCI9118_DO 0x1c
101 #define PCI9118_SOFTTRG 0x20
102 #define PCI9118_GAIN 0x24
103 #define PCI9118_BURST 0x28
104 #define PCI9118_SCANMOD 0x2c
105 #define PCI9118_ADFUNC 0x30
106 #define PCI9118_DELFIFO 0x34
107 #define PCI9118_INTSRC 0x38
108 #define PCI9118_INTCTRL 0x38
111 #define AdControl_UniP 0x80
112 #define AdControl_Diff 0x40
113 #define AdControl_SoftG 0x20
114 #define AdControl_ExtG 0x10
118 #define AdControl_ExtM 0x08
122 #define AdControl_TmrTr 0x04
127 #define AdControl_Int 0x02
128 #define AdControl_Dma 0x01
131 #define AdFunction_PDTrg 0x80
136 #define AdFunction_PETrg 0x40
141 #define AdFunction_BSSH 0x20
142 #define AdFunction_BM 0x10
143 #define AdFunction_BS 0x08
147 #define AdFunction_PM 0x04
151 #define AdFunction_AM 0x02
155 #define AdFunction_Start 0x01
158 #define AdStatus_nFull 0x100
159 #define AdStatus_nHfull 0x080
160 #define AdStatus_nEpty 0x040
161 #define AdStatus_Acmp 0x020
162 #define AdStatus_DTH 0x010
163 #define AdStatus_Bover 0x008
164 #define AdStatus_ADOS 0x004
165 #define AdStatus_ADOR 0x002
166 #define AdStatus_ADrdy 0x001
170 #define Int_Timer 0x08
171 #define Int_About 0x04
172 #define Int_Hfull 0x02
173 #define Int_DTrg 0x01
175 #define START_AI_EXT 0x01
176 #define STOP_AI_EXT 0x02
177 #define START_AI_INT 0x04
178 #define STOP_AI_INT 0x08
206 #define PCI9118_BIPOLAR_RANGES 4
242 #ifdef PCI9118_PARANOIDCHECK
247 unsigned char chanlistlen;
349 unsigned int *
chanlist,
int frontadd,
int backadd)
353 unsigned int i, differencial = 0, bipolar = 0;
362 (
"comedi%d: range/channel list is too long for "
363 "actual configuration (%d>%d)!",
373 for (i = 1; i < n_chan; i++) {
377 "Differencial and single ended "
378 "inputs can't be mixtured!");
384 "Bipolar and unipolar ranges "
385 "can't be mixtured!");
388 if (!devpriv->
usemux && differencial &&
391 "If AREF_DIFF is used then is "
392 "available only first 8 channels!");
402 unsigned int *chanlist,
int rot,
int frontadd,
403 int backadd,
int usedma,
char useeos)
406 unsigned int i, differencial = 0, bipolar = 0;
407 unsigned int scanquad,
gain, ssh = 0x00;
445 #ifdef PCI9118_PARANOIDCHECK
446 devpriv->chanlistlen = n_chan;
448 devpriv->chanlist[i] = 0x55aa;
453 for (i = 0; i < frontadd; i++) {
455 scanquad =
CR_CHAN(chanlist[0]);
459 scanquad |= ((gain & 0x03) << 8);
465 for (i = 0; i < n_chan; i++) {
466 scanquad =
CR_CHAN(chanlist[i]);
467 #ifdef PCI9118_PARANOIDCHECK
468 devpriv->chanlist[i ^
usedma] = (scanquad & 0xf) << rot;
471 scanquad |= ((gain & 0x03) << 8);
476 for (i = 0; i < backadd; i++) {
477 scanquad =
CR_CHAN(chanlist[0]);
480 scanquad |= ((gain & 0x03) << 8);
484 #ifdef PCI9118_PARANOIDCHECK
485 devpriv->chanlist[n_chan ^
usedma] = devpriv->chanlist[0 ^
usedma];
488 for (i = 1; i < n_chan; i++) {
489 devpriv->chanlist[(n_chan +
i) ^ usedma] =
490 (
CR_CHAN(chanlist[i]) & 0xf) << rot;
492 devpriv->chanlist[(2 * n_chan) ^ usedma] =
493 devpriv->chanlist[0 ^ usedma];
524 if (!setup_channel_list(dev, s, 1, &insn->
chanspec, 0, 0, 0, 0, 0))
529 for (n = 0; n < insn->
n; n++) {
574 for (n = 0; n < insn->
n; n++) {
590 for (n = 0; n < insn->
n; n++)
591 data[n] = devpriv->
ao_data[chan];
610 s->
state &= ~data[0];
611 s->
state |= (data[0] & data[1]);
619 static void interrupt_pci9118_ai_mode4_switch(
struct comedi_device *dev)
635 static unsigned int defragment_dma_buffer(
struct comedi_device *dev,
638 unsigned int num_samples)
641 unsigned int i = 0,
j = 0;
647 for (i = 0; i < num_samples; i++) {
650 dma_buffer[
j++] = dma_buffer[
i];
662 unsigned int num_samples)
667 num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
670 s->
async->cur_chan += num_samples;
674 num_samples *
sizeof(
short));
675 if (num_bytes < num_samples *
sizeof(
short))
695 static int pci9118_exttrg_del(
struct comedi_device *dev,
unsigned char source)
716 unsigned int *tim1,
unsigned int *tim2,
717 unsigned int flags,
int chans,
718 unsigned int *div1,
unsigned int *
div2,
719 char usessh,
unsigned int chnsshfront)
721 const struct boardtype *this_board = comedi_board(dev);
727 if (*tim2 < this_board->ai_ns_min)
733 if (*tim2 < this_board->ai_ns_min)
737 if (*div1 < this_board->ai_pacer_min)
740 *div2 = *div2 / *div1;
747 if (usessh & (chnsshfront == 0))
748 if (*div2 < (chans + 2))
757 unsigned int divisor1,
unsigned int divisor2)
764 if ((mode == 1) || (mode == 2) || (mode == 4)) {
782 start_pacer(dev, 0, 0, 0);
807 s->
async->cur_chan = 0;
821 static char pci9118_decode_error_status(
struct comedi_device *dev,
828 comedi_error(dev,
"A/D FIFO Full status (Fatal Error!)");
833 "A/D Burst Mode Overrun Status (Fatal Error!)");
846 pci9118_ai_cancel(dev, s);
856 unsigned int num_bytes,
857 unsigned int start_chan_index)
860 unsigned int i, num_samples = num_bytes /
sizeof(
short);
863 for (i = 0; i < num_samples; i++) {
869 array[
i] = (array[
i] >> 4) & 0x0fff;
874 static void interrupt_pci9118_ai_onesample(
struct comedi_device *dev,
876 unsigned short int_adstat,
877 unsigned int int_amcc,
878 unsigned short int_daq)
881 register short sampl;
883 s->
async->events = 0;
886 if (pci9118_decode_error_status(dev, s, int_adstat))
891 #ifdef PCI9118_PARANOIDCHECK
893 if ((sampl & 0x000f) != devpriv->chanlist[s->
async->cur_chan]) {
896 (
"comedi: A/D SAMPL - data dropout: "
897 "received channel %d, expected %d!\n",
899 devpriv->chanlist[s->
async->cur_chan]);
901 pci9118_ai_cancel(dev, s);
907 cfc_write_to_buffer(s, sampl);
908 s->
async->cur_chan++;
916 pci9118_ai_cancel(dev, s);
921 if (s->
async->events)
925 static void interrupt_pci9118_ai_dma(
struct comedi_device *dev,
927 unsigned short int_adstat,
928 unsigned int int_amcc,
929 unsigned short int_daq)
932 unsigned int next_dma_buf, samplesinbuf, sampls,
m;
937 pci9118_ai_cancel(dev, s);
945 pci9118_ai_cancel(dev, s);
951 if (pci9118_decode_error_status(dev, s, int_adstat))
968 if (devpriv->
ai_do == 4)
969 interrupt_pci9118_ai_mode4_switch(dev);
978 move_block_from_dma(dev, s,
987 pci9118_ai_cancel(dev, s);
998 if (devpriv->
ai_do == 4)
999 interrupt_pci9118_ai_mode4_switch(dev);
1009 unsigned int int_daq = 0, int_amcc, int_adstat;
1028 if (devpriv->
ai_do) {
1041 start_pacer(dev, devpriv->
ai_do,
1084 if (devpriv->
ai_do != 3) {
1098 const struct boardtype *this_board = comedi_board(dev);
1103 unsigned int divisor1 = 0, divisor2 = 0;
1107 err |= cfc_check_trigger_src(&cmd->
start_src,
1118 err |= cfc_check_trigger_src(&cmd->
convert_src, flags);
1121 err |= cfc_check_trigger_src(&cmd->
stop_src,
1129 err |= cfc_check_trigger_is_unique(cmd->
start_src);
1131 err |= cfc_check_trigger_is_unique(cmd->
convert_src);
1132 err |= cfc_check_trigger_is_unique(cmd->
stop_src);
1300 unsigned int dmalen0, dmalen1,
i;
1322 (
"comedi%d: WAR: DMA0 buf too short, can't "
1323 "support TRIG_WAKE_EOS (%d<%d)\n",
1324 dev->
minor, dmalen0,
1333 (
"comedi%d: ERR: DMA0 buf len bug? "
1335 dev->
minor, dmalen0);
1345 (
"comedi%d: WAR: DMA1 buf too short, "
1346 "can't support TRIG_WAKE_EOS (%d<%d)\n",
1347 dev->
minor, dmalen1,
1356 (
"comedi%d: ERR: DMA1 buf len bug? "
1358 dev->
minor, dmalen1);
1449 static int pci9118_ai_docmd_sampl(
struct comedi_device *dev,
1454 switch (devpriv->
ai_do) {
1459 comedi_error(dev,
"pci9118_ai_docmd_sampl() mode 2 bug!\n");
1465 comedi_error(dev,
"pci9118_ai_docmd_sampl() mode 4 bug!\n");
1469 "pci9118_ai_docmd_sampl() mode number bug!\n");
1473 devpriv->
int_ai_func = interrupt_pci9118_ai_onesample;
1480 if ((devpriv->
ai_do == 1) || (devpriv->
ai_do == 2))
1492 if (devpriv->
ai_do != 3) {
1508 Compute_and_setup_dma(dev);
1510 switch (devpriv->
ai_do) {
1544 comedi_error(dev,
"pci9118_ai_docmd_dma() mode number bug!\n");
1562 if (devpriv->
ai_do != 3) {
1575 const struct boardtype *this_board = comedi_board(dev);
1578 unsigned int addchans = 0;
1604 s->
async->inttrig = pci9118_ai_inttrig;
1692 if (devpriv->
usedma == 1)
1710 if (!check_channel_list(dev, s, devpriv->
ai_n_chan,
1714 if (!setup_channel_list(dev, s, devpriv->
ai_n_chan,
1734 pci9118_calc_divisors(devpriv->
ai_do, dev, s,
1750 "cmd->scan_begin_src=TRIG_TIMER works "
1751 "only with bus mastering!");
1756 pci9118_calc_divisors(devpriv->
ai_do, dev, s,
1772 start_pacer(dev, -1, 0, 0);
1797 s->
async->cur_chan = 0;
1801 ret = pci9118_ai_docmd_dma(dev, s);
1803 ret = pci9118_ai_docmd_sampl(dev, s);
1819 start_pacer(dev, 0, 0, 0);
1871 const struct boardtype *this_board = comedi_board(dev);
1883 if (pcidev->
bus->number != bus ||
1894 pcidev->
bus->number,
1902 "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
1903 dev->
minor, bus, slot);
1910 const struct boardtype *this_board = comedi_board(dev);
1915 unsigned short master;
1919 printk(
"comedi%d: adl_pci9118: board=%s", dev->
minor, this_board->
name);
1926 ret = alloc_private(dev,
sizeof(*devpriv));
1928 printk(
" - Allocation failed!\n");
1933 pcidev = pci9118_find_pci(dev, it);
1936 comedi_set_hw_dev(dev, &pcidev->
dev);
1953 "ADLink PCI-9118", dev)) {
1954 printk(
", unable to allocate IRQ %d, DISABLING IT",
1961 printk(
", IRQ disabled");
1968 for (i = 0; i < 2; i++) {
1969 for (pages = 4; pages >= 0; pages--) {
1987 printk(
", Can't allocate DMA buffer, DMA disabled!");
1996 devpriv->
master = master;
2000 printk(
", no bus master");
2005 if (devpriv->
usemux > 256)
2008 if (devpriv->
usemux > 128) {
2029 pci_write_config_word(pcidev,
PCI_COMMAND, u16w | 64);
2048 s->
cancel = pci9118_ai_cancel;
2053 s->
do_cmd = pci9118_ai_cmd;
2054 s->
munge = pci9118_ai_munge;
2107 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2130 static const struct boardtype boardtypes[] = {
2132 .name =
"pci9118dg",
2134 .device_id = 0x80d9,
2142 .ai_maxdata = 0x0fff,
2143 .ao_maxdata = 0x0fff,
2144 .rangelist_ai = &range_pci9118dg_hr,
2148 .half_fifo_size = 512,
2150 .name =
"pci9118hg",
2152 .device_id = 0x80d9,
2160 .ai_maxdata = 0x0fff,
2161 .ao_maxdata = 0x0fff,
2162 .rangelist_ai = &range_pci9118hg,
2166 .half_fifo_size = 512,
2168 .name =
"pci9118hr",
2170 .device_id = 0x80d9,
2178 .ai_maxdata = 0xffff,
2179 .ao_maxdata = 0x0fff,
2180 .rangelist_ai = &range_pci9118dg_hr,
2184 .half_fifo_size = 512,
2189 .driver_name =
"adl_pci9118",
2191 .attach = pci9118_attach,
2192 .detach = pci9118_detach,
2194 .board_name = &boardtypes[0].
name,
2215 static struct pci_driver adl_pci9118_pci_driver = {
2216 .name =
"adl_pci9118",
2217 .id_table = adl_pci9118_pci_table,
2218 .probe = adl_pci9118_pci_probe,