This source file includes following definitions.
- rtd_ns_to_timer_base
- rtd_ns_to_timer
- rtd_convert_chan_gain
- rtd_load_channelgain_list
- rtd520_probe_fifo_depth
- rtd_ai_eoc
- rtd_ai_rinsn
- ai_read_n
- rtd_interrupt
- rtd_ai_cmdtest
- rtd_ai_cmd
- rtd_ai_cancel
- rtd_ao_eoc
- rtd_ao_insn_write
- rtd_dio_insn_bits
- rtd_dio_insn_config
- rtd_counter_insn_config
- rtd_reset
- rtd_init_board
- rtd_pci_latency_quirk
- rtd_auto_attach
- rtd_detach
- rtd520_pci_probe
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 
  71 
  72 
  73 
  74 
  75 
  76 
  77 
  78 
  79 
  80 
  81 
  82 
  83 
  84 
  85 #include <linux/module.h>
  86 #include <linux/delay.h>
  87 #include <linux/interrupt.h>
  88 
  89 #include "../comedi_pci.h"
  90 
  91 #include "comedi_8254.h"
  92 #include "plx9080.h"
  93 
  94 
  95 
  96 
  97 #define LAS0_USER_IO            0x0008  
  98 #define LAS0_ADC                0x0010  
  99 #define FS_DAC1_NOT_EMPTY       BIT(0)  
 100 #define FS_DAC1_HEMPTY          BIT(1)  
 101 #define FS_DAC1_NOT_FULL        BIT(2)  
 102 #define FS_DAC2_NOT_EMPTY       BIT(4)  
 103 #define FS_DAC2_HEMPTY          BIT(5)  
 104 #define FS_DAC2_NOT_FULL        BIT(6)  
 105 #define FS_ADC_NOT_EMPTY        BIT(8)  
 106 #define FS_ADC_HEMPTY           BIT(9)  
 107 #define FS_ADC_NOT_FULL         BIT(10) 
 108 #define FS_DIN_NOT_EMPTY        BIT(12) 
 109 #define FS_DIN_HEMPTY           BIT(13) 
 110 #define FS_DIN_NOT_FULL         BIT(14) 
 111 #define LAS0_UPDATE_DAC(x)      (0x0014 + ((x) * 0x4))  
 112 #define LAS0_DAC                0x0024  
 113 #define LAS0_PACER              0x0028  
 114 #define LAS0_TIMER              0x002c  
 115 #define LAS0_IT                 0x0030  
 116 #define IRQM_ADC_FIFO_WRITE     BIT(0)  
 117 #define IRQM_CGT_RESET          BIT(1)  
 118 #define IRQM_CGT_PAUSE          BIT(3)  
 119 #define IRQM_ADC_ABOUT_CNT      BIT(4)  
 120 #define IRQM_ADC_DELAY_CNT      BIT(5)  
 121 #define IRQM_ADC_SAMPLE_CNT     BIT(6)  
 122 #define IRQM_DAC1_UCNT          BIT(7)  
 123 #define IRQM_DAC2_UCNT          BIT(8)  
 124 #define IRQM_UTC1               BIT(9)  
 125 #define IRQM_UTC1_INV           BIT(10) 
 126 #define IRQM_UTC2               BIT(11) 
 127 #define IRQM_DIGITAL_IT         BIT(12) 
 128 #define IRQM_EXTERNAL_IT        BIT(13) 
 129 #define IRQM_ETRIG_RISING       BIT(14) 
 130 #define IRQM_ETRIG_FALLING      BIT(15) 
 131 #define LAS0_CLEAR              0x0034  
 132 #define LAS0_OVERRUN            0x0038  
 133 #define LAS0_PCLK               0x0040  
 134 #define LAS0_BCLK               0x0044  
 135 #define LAS0_ADC_SCNT           0x0048  
 136 #define LAS0_DAC1_UCNT          0x004c  
 137 #define LAS0_DAC2_UCNT          0x0050  
 138 #define LAS0_DCNT               0x0054  
 139 #define LAS0_ACNT               0x0058  
 140 #define LAS0_DAC_CLK            0x005c  
 141 #define LAS0_8254_TIMER_BASE    0x0060  
 142 #define LAS0_DIO0               0x0070  
 143 #define LAS0_DIO1               0x0074  
 144 #define LAS0_DIO0_CTRL          0x0078  
 145 #define LAS0_DIO_STATUS         0x007c  
 146 #define LAS0_BOARD_RESET        0x0100  
 147 #define LAS0_DMA0_SRC           0x0104  
 148 #define LAS0_DMA1_SRC           0x0108  
 149 #define LAS0_ADC_CONVERSION     0x010c  
 150 #define LAS0_BURST_START        0x0110  
 151 #define LAS0_PACER_START        0x0114  
 152 #define LAS0_PACER_STOP         0x0118  
 153 #define LAS0_ACNT_STOP_ENABLE   0x011c  
 154 #define LAS0_PACER_REPEAT       0x0120  
 155 #define LAS0_DIN_START          0x0124  
 156 #define LAS0_DIN_FIFO_CLEAR     0x0128  
 157 #define LAS0_ADC_FIFO_CLEAR     0x012c  
 158 #define LAS0_CGT_WRITE          0x0130  
 159 #define LAS0_CGL_WRITE          0x0134  
 160 #define LAS0_CG_DATA            0x0138  
 161 #define LAS0_CGT_ENABLE         0x013c  
 162 #define LAS0_CG_ENABLE          0x0140  
 163 #define LAS0_CGT_PAUSE          0x0144  
 164 #define LAS0_CGT_RESET          0x0148  
 165 #define LAS0_CGT_CLEAR          0x014c  
 166 #define LAS0_DAC_CTRL(x)        (0x0150 + ((x) * 0x14)) 
 167 #define LAS0_DAC_SRC(x)         (0x0154 + ((x) * 0x14)) 
 168 #define LAS0_DAC_CYCLE(x)       (0x0158 + ((x) * 0x14)) 
 169 #define LAS0_DAC_RESET(x)       (0x015c + ((x) * 0x14)) 
 170 #define LAS0_DAC_FIFO_CLEAR(x)  (0x0160 + ((x) * 0x14)) 
 171 #define LAS0_ADC_SCNT_SRC       0x0178  
 172 #define LAS0_PACER_SELECT       0x0180  
 173 #define LAS0_SBUS0_SRC          0x0184  
 174 #define LAS0_SBUS0_ENABLE       0x0188  
 175 #define LAS0_SBUS1_SRC          0x018c  
 176 #define LAS0_SBUS1_ENABLE       0x0190  
 177 #define LAS0_SBUS2_SRC          0x0198  
 178 #define LAS0_SBUS2_ENABLE       0x019c  
 179 #define LAS0_ETRG_POLARITY      0x01a4  
 180 #define LAS0_EINT_POLARITY      0x01a8  
 181 #define LAS0_8254_CLK_SEL(x)    (0x01ac + ((x) * 0x8))  
 182 #define LAS0_8254_GATE_SEL(x)   (0x01b0 + ((x) * 0x8))  
 183 #define LAS0_UOUT0_SELECT       0x01c4  
 184 #define LAS0_UOUT1_SELECT       0x01c8  
 185 #define LAS0_DMA0_RESET         0x01cc  
 186 #define LAS0_DMA1_RESET         0x01d0  
 187 
 188 
 189 
 190 
 191 #define LAS1_ADC_FIFO           0x0000  
 192 #define LAS1_HDIO_FIFO          0x0004  
 193 #define LAS1_DAC_FIFO(x)        (0x0008 + ((x) * 0x4))  
 194 
 195 
 196 
 197 
 198 
 199 
 200 
 201 
 202 
 203 #define DMA_CHAIN_COUNT 2       
 204 
 205 
 206 
 207 
 208 #define TRANS_TARGET_PERIOD 10000000    
 209 
 210 
 211 
 212 #define RTD_MAX_CHANLIST        128     
 213 
 214 
 215 
 216 
 217 
 218 #define RTD_CLOCK_RATE  8000000 
 219 #define RTD_CLOCK_BASE  125     
 220 
 221 
 222 #define RTD_MAX_SPEED   1625    
 223 
 224 #define RTD_MAX_SPEED_1 875     
 225 
 226 #define RTD_MIN_SPEED   2097151875      
 227 
 228 #define RTD_MIN_SPEED_1 5000000 
 229 
 230 
 231 #define DMA_MODE_BITS (\
 232                        PLX_LOCAL_BUS_16_WIDE_BITS \
 233                        | PLX_DMA_EN_READYIN_BIT \
 234                        | PLX_DMA_LOCAL_BURST_EN_BIT \
 235                        | PLX_EN_CHAIN_BIT \
 236                        | PLX_DMA_INTR_PCI_BIT \
 237                        | PLX_LOCAL_ADDR_CONST_BIT \
 238                        | PLX_DEMAND_MODE_BIT)
 239 
 240 #define DMA_TRANSFER_BITS (\
 241   PLX_DESC_IN_PCI_BIT \
 242  | PLX_INTR_TERM_COUNT \
 243          | PLX_XFER_LOCAL_TO_PCI)
 244 
 245 
 246 
 247 
 248 
 249 
 250 
 251 
 252 static const struct comedi_lrange rtd_ai_7520_range = {
 253         18, {
 254                 
 255                 BIP_RANGE(5.0),
 256                 BIP_RANGE(5.0 / 2),
 257                 BIP_RANGE(5.0 / 4),
 258                 BIP_RANGE(5.0 / 8),
 259                 BIP_RANGE(5.0 / 16),
 260                 BIP_RANGE(5.0 / 32),
 261                 
 262                 BIP_RANGE(10.0),
 263                 BIP_RANGE(10.0 / 2),
 264                 BIP_RANGE(10.0 / 4),
 265                 BIP_RANGE(10.0 / 8),
 266                 BIP_RANGE(10.0 / 16),
 267                 BIP_RANGE(10.0 / 32),
 268                 
 269                 UNI_RANGE(10.0),
 270                 UNI_RANGE(10.0 / 2),
 271                 UNI_RANGE(10.0 / 4),
 272                 UNI_RANGE(10.0 / 8),
 273                 UNI_RANGE(10.0 / 16),
 274                 UNI_RANGE(10.0 / 32),
 275         }
 276 };
 277 
 278 
 279 static const struct comedi_lrange rtd_ai_4520_range = {
 280         24, {
 281                 
 282                 BIP_RANGE(5.0),
 283                 BIP_RANGE(5.0 / 2),
 284                 BIP_RANGE(5.0 / 4),
 285                 BIP_RANGE(5.0 / 8),
 286                 BIP_RANGE(5.0 / 16),
 287                 BIP_RANGE(5.0 / 32),
 288                 BIP_RANGE(5.0 / 64),
 289                 BIP_RANGE(5.0 / 128),
 290                 
 291                 BIP_RANGE(10.0),
 292                 BIP_RANGE(10.0 / 2),
 293                 BIP_RANGE(10.0 / 4),
 294                 BIP_RANGE(10.0 / 8),
 295                 BIP_RANGE(10.0 / 16),
 296                 BIP_RANGE(10.0 / 32),
 297                 BIP_RANGE(10.0 / 64),
 298                 BIP_RANGE(10.0 / 128),
 299                 
 300                 UNI_RANGE(10.0),
 301                 UNI_RANGE(10.0 / 2),
 302                 UNI_RANGE(10.0 / 4),
 303                 UNI_RANGE(10.0 / 8),
 304                 UNI_RANGE(10.0 / 16),
 305                 UNI_RANGE(10.0 / 32),
 306                 UNI_RANGE(10.0 / 64),
 307                 UNI_RANGE(10.0 / 128),
 308         }
 309 };
 310 
 311 
 312 static const struct comedi_lrange rtd_ao_range = {
 313         4, {
 314                 UNI_RANGE(5),
 315                 UNI_RANGE(10),
 316                 BIP_RANGE(5),
 317                 BIP_RANGE(10),
 318         }
 319 };
 320 
 321 enum rtd_boardid {
 322         BOARD_DM7520,
 323         BOARD_PCI4520,
 324 };
 325 
 326 struct rtd_boardinfo {
 327         const char *name;
 328         int range_bip10;        
 329         int range_uni10;        
 330         const struct comedi_lrange *ai_range;
 331 };
 332 
 333 static const struct rtd_boardinfo rtd520_boards[] = {
 334         [BOARD_DM7520] = {
 335                 .name           = "DM7520",
 336                 .range_bip10    = 6,
 337                 .range_uni10    = 12,
 338                 .ai_range       = &rtd_ai_7520_range,
 339         },
 340         [BOARD_PCI4520] = {
 341                 .name           = "PCI4520",
 342                 .range_bip10    = 8,
 343                 .range_uni10    = 16,
 344                 .ai_range       = &rtd_ai_4520_range,
 345         },
 346 };
 347 
 348 struct rtd_private {
 349         
 350         void __iomem *las1;
 351         void __iomem *lcfg;
 352 
 353         long ai_count;          
 354         int xfer_count;         
 355         int flags;              
 356         unsigned int fifosz;
 357 
 358         
 359         unsigned char timer_gate_src[3];
 360         unsigned char timer_clk_src[3];
 361 };
 362 
 363 
 364 #define SEND_EOS        0x01    
 365 #define DMA0_ACTIVE     0x02    
 366 #define DMA1_ACTIVE     0x04    
 367 
 368 
 369 
 370 
 371 
 372 
 373 
 374 static int rtd_ns_to_timer_base(unsigned int *nanosec,
 375                                 unsigned int flags, int base)
 376 {
 377         int divider;
 378 
 379         switch (flags & CMDF_ROUND_MASK) {
 380         case CMDF_ROUND_NEAREST:
 381         default:
 382                 divider = DIV_ROUND_CLOSEST(*nanosec, base);
 383                 break;
 384         case CMDF_ROUND_DOWN:
 385                 divider = (*nanosec) / base;
 386                 break;
 387         case CMDF_ROUND_UP:
 388                 divider = DIV_ROUND_UP(*nanosec, base);
 389                 break;
 390         }
 391         if (divider < 2)
 392                 divider = 2;    
 393 
 394         
 395 
 396 
 397 
 398 
 399         *nanosec = base * divider;
 400         return divider - 1;     
 401 }
 402 
 403 
 404 
 405 
 406 
 407 
 408 static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags)
 409 {
 410         return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE);
 411 }
 412 
 413 
 414 static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
 415                                             unsigned int chanspec, int index)
 416 {
 417         const struct rtd_boardinfo *board = dev->board_ptr;
 418         unsigned int chan = CR_CHAN(chanspec);
 419         unsigned int range = CR_RANGE(chanspec);
 420         unsigned int aref = CR_AREF(chanspec);
 421         unsigned short r = 0;
 422 
 423         r |= chan & 0xf;
 424 
 425         
 426         if (range < board->range_bip10) {
 427                 
 428                 r |= 0x000;
 429                 r |= (range & 0x7) << 4;
 430         } else if (range < board->range_uni10) {
 431                 
 432                 r |= 0x100;
 433                 r |= ((range - board->range_bip10) & 0x7) << 4;
 434         } else {
 435                 
 436                 r |= 0x200;
 437                 r |= ((range - board->range_uni10) & 0x7) << 4;
 438         }
 439 
 440         switch (aref) {
 441         case AREF_GROUND:       
 442                 break;
 443 
 444         case AREF_COMMON:
 445                 r |= 0x80;      
 446                 break;
 447 
 448         case AREF_DIFF:
 449                 r |= 0x400;     
 450                 break;
 451 
 452         case AREF_OTHER:        
 453                 break;
 454         }
 455         return r;
 456 }
 457 
 458 
 459 static void rtd_load_channelgain_list(struct comedi_device *dev,
 460                                       unsigned int n_chan, unsigned int *list)
 461 {
 462         if (n_chan > 1) {       
 463                 int ii;
 464 
 465                 writel(0, dev->mmio + LAS0_CGT_CLEAR);
 466                 writel(1, dev->mmio + LAS0_CGT_ENABLE);
 467                 for (ii = 0; ii < n_chan; ii++) {
 468                         writel(rtd_convert_chan_gain(dev, list[ii], ii),
 469                                dev->mmio + LAS0_CGT_WRITE);
 470                 }
 471         } else {                
 472                 writel(0, dev->mmio + LAS0_CGT_ENABLE);
 473                 writel(rtd_convert_chan_gain(dev, list[0], 0),
 474                        dev->mmio + LAS0_CGL_WRITE);
 475         }
 476 }
 477 
 478 
 479 
 480 
 481 
 482 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
 483 {
 484         unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
 485         unsigned int i;
 486         static const unsigned int limit = 0x2000;
 487         unsigned int fifo_size = 0;
 488 
 489         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
 490         rtd_load_channelgain_list(dev, 1, &chanspec);
 491         
 492         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
 493         
 494         for (i = 0; i < limit; ++i) {
 495                 unsigned int fifo_status;
 496                 
 497                 writew(0, dev->mmio + LAS0_ADC);
 498                 usleep_range(1, 1000);
 499                 fifo_status = readl(dev->mmio + LAS0_ADC);
 500                 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
 501                         fifo_size = 2 * i;
 502                         break;
 503                 }
 504         }
 505         if (i == limit) {
 506                 dev_info(dev->class_dev, "failed to probe fifo size.\n");
 507                 return -EIO;
 508         }
 509         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
 510         if (fifo_size != 0x400 && fifo_size != 0x2000) {
 511                 dev_info(dev->class_dev,
 512                          "unexpected fifo size of %i, expected 1024 or 8192.\n",
 513                          fifo_size);
 514                 return -EIO;
 515         }
 516         return fifo_size;
 517 }
 518 
 519 static int rtd_ai_eoc(struct comedi_device *dev,
 520                       struct comedi_subdevice *s,
 521                       struct comedi_insn *insn,
 522                       unsigned long context)
 523 {
 524         unsigned int status;
 525 
 526         status = readl(dev->mmio + LAS0_ADC);
 527         if (status & FS_ADC_NOT_EMPTY)
 528                 return 0;
 529         return -EBUSY;
 530 }
 531 
 532 static int rtd_ai_rinsn(struct comedi_device *dev,
 533                         struct comedi_subdevice *s, struct comedi_insn *insn,
 534                         unsigned int *data)
 535 {
 536         struct rtd_private *devpriv = dev->private;
 537         unsigned int range = CR_RANGE(insn->chanspec);
 538         int ret;
 539         int n;
 540 
 541         
 542         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
 543 
 544         
 545         rtd_load_channelgain_list(dev, 1, &insn->chanspec);
 546 
 547         
 548         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
 549 
 550         
 551         for (n = 0; n < insn->n; n++) {
 552                 unsigned short d;
 553                 
 554                 writew(0, dev->mmio + LAS0_ADC);
 555 
 556                 ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0);
 557                 if (ret)
 558                         return ret;
 559 
 560                 
 561                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
 562                 d >>= 3;        
 563 
 564                 
 565                 if (comedi_range_is_bipolar(s, range))
 566                         d = comedi_offset_munge(s, d);
 567 
 568                 data[n] = d & s->maxdata;
 569         }
 570 
 571         
 572         return n;
 573 }
 574 
 575 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
 576                      int count)
 577 {
 578         struct rtd_private *devpriv = dev->private;
 579         struct comedi_async *async = s->async;
 580         struct comedi_cmd *cmd = &async->cmd;
 581         int ii;
 582 
 583         for (ii = 0; ii < count; ii++) {
 584                 unsigned int range = CR_RANGE(cmd->chanlist[async->cur_chan]);
 585                 unsigned short d;
 586 
 587                 if (devpriv->ai_count == 0) {   
 588                         d = readw(devpriv->las1 + LAS1_ADC_FIFO);
 589                         continue;
 590                 }
 591 
 592                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
 593                 d >>= 3;        
 594 
 595                 
 596                 if (comedi_range_is_bipolar(s, range))
 597                         d = comedi_offset_munge(s, d);
 598                 d &= s->maxdata;
 599 
 600                 if (!comedi_buf_write_samples(s, &d, 1))
 601                         return -1;
 602 
 603                 if (devpriv->ai_count > 0)      
 604                         devpriv->ai_count--;
 605         }
 606         return 0;
 607 }
 608 
 609 static irqreturn_t rtd_interrupt(int irq, void *d)
 610 {
 611         struct comedi_device *dev = d;
 612         struct comedi_subdevice *s = dev->read_subdev;
 613         struct rtd_private *devpriv = dev->private;
 614         u32 overrun;
 615         u16 status;
 616         u16 fifo_status;
 617 
 618         if (!dev->attached)
 619                 return IRQ_NONE;
 620 
 621         fifo_status = readl(dev->mmio + LAS0_ADC);
 622         
 623         if (!(fifo_status & FS_ADC_NOT_FULL))   
 624                 goto xfer_abort;
 625 
 626         status = readw(dev->mmio + LAS0_IT);
 627         
 628         if (status == 0)
 629                 return IRQ_HANDLED;
 630 
 631         if (status & IRQM_ADC_ABOUT_CNT) {      
 632                 
 633 
 634 
 635 
 636 
 637 
 638                 if (!(fifo_status & FS_ADC_HEMPTY)) {
 639                         
 640                         if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0)
 641                                 goto xfer_abort;
 642 
 643                         if (devpriv->ai_count == 0)
 644                                 goto xfer_done;
 645                 } else if (devpriv->xfer_count > 0) {
 646                         if (fifo_status & FS_ADC_NOT_EMPTY) {
 647                                 
 648                                 if (ai_read_n(dev, s, devpriv->xfer_count) < 0)
 649                                         goto xfer_abort;
 650 
 651                                 if (devpriv->ai_count == 0)
 652                                         goto xfer_done;
 653                         }
 654                 }
 655         }
 656 
 657         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
 658         if (overrun)
 659                 goto xfer_abort;
 660 
 661         
 662         writew(status, dev->mmio + LAS0_CLEAR);
 663         readw(dev->mmio + LAS0_CLEAR);
 664 
 665         comedi_handle_events(dev, s);
 666 
 667         return IRQ_HANDLED;
 668 
 669 xfer_abort:
 670         s->async->events |= COMEDI_CB_ERROR;
 671 
 672 xfer_done:
 673         s->async->events |= COMEDI_CB_EOA;
 674 
 675         
 676         status = readw(dev->mmio + LAS0_IT);
 677         writew(status, dev->mmio + LAS0_CLEAR);
 678         readw(dev->mmio + LAS0_CLEAR);
 679 
 680         fifo_status = readl(dev->mmio + LAS0_ADC);
 681         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
 682 
 683         comedi_handle_events(dev, s);
 684 
 685         return IRQ_HANDLED;
 686 }
 687 
 688 static int rtd_ai_cmdtest(struct comedi_device *dev,
 689                           struct comedi_subdevice *s, struct comedi_cmd *cmd)
 690 {
 691         int err = 0;
 692         unsigned int arg;
 693 
 694         
 695 
 696         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
 697         err |= comedi_check_trigger_src(&cmd->scan_begin_src,
 698                                         TRIG_TIMER | TRIG_EXT);
 699         err |= comedi_check_trigger_src(&cmd->convert_src,
 700                                         TRIG_TIMER | TRIG_EXT);
 701         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 702         err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 703 
 704         if (err)
 705                 return 1;
 706 
 707         
 708 
 709         err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
 710         err |= comedi_check_trigger_is_unique(cmd->convert_src);
 711         err |= comedi_check_trigger_is_unique(cmd->stop_src);
 712 
 713         
 714 
 715         if (err)
 716                 return 2;
 717 
 718         
 719 
 720         err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
 721 
 722         if (cmd->scan_begin_src == TRIG_TIMER) {
 723                 
 724                 if (cmd->chanlist_len == 1) {   
 725                         if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
 726                                                          RTD_MAX_SPEED_1)) {
 727                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
 728                                                 CMDF_ROUND_UP);
 729                                 err |= -EINVAL;
 730                         }
 731                         if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
 732                                                          RTD_MIN_SPEED_1)) {
 733                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
 734                                                 CMDF_ROUND_DOWN);
 735                                 err |= -EINVAL;
 736                         }
 737                 } else {
 738                         if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
 739                                                          RTD_MAX_SPEED)) {
 740                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
 741                                                 CMDF_ROUND_UP);
 742                                 err |= -EINVAL;
 743                         }
 744                         if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
 745                                                          RTD_MIN_SPEED)) {
 746                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
 747                                                 CMDF_ROUND_DOWN);
 748                                 err |= -EINVAL;
 749                         }
 750                 }
 751         } else {
 752                 
 753                 
 754                 
 755                 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
 756         }
 757 
 758         if (cmd->convert_src == TRIG_TIMER) {
 759                 if (cmd->chanlist_len == 1) {   
 760                         if (comedi_check_trigger_arg_min(&cmd->convert_arg,
 761                                                          RTD_MAX_SPEED_1)) {
 762                                 rtd_ns_to_timer(&cmd->convert_arg,
 763                                                 CMDF_ROUND_UP);
 764                                 err |= -EINVAL;
 765                         }
 766                         if (comedi_check_trigger_arg_max(&cmd->convert_arg,
 767                                                          RTD_MIN_SPEED_1)) {
 768                                 rtd_ns_to_timer(&cmd->convert_arg,
 769                                                 CMDF_ROUND_DOWN);
 770                                 err |= -EINVAL;
 771                         }
 772                 } else {
 773                         if (comedi_check_trigger_arg_min(&cmd->convert_arg,
 774                                                          RTD_MAX_SPEED)) {
 775                                 rtd_ns_to_timer(&cmd->convert_arg,
 776                                                 CMDF_ROUND_UP);
 777                                 err |= -EINVAL;
 778                         }
 779                         if (comedi_check_trigger_arg_max(&cmd->convert_arg,
 780                                                          RTD_MIN_SPEED)) {
 781                                 rtd_ns_to_timer(&cmd->convert_arg,
 782                                                 CMDF_ROUND_DOWN);
 783                                 err |= -EINVAL;
 784                         }
 785                 }
 786         } else {
 787                 
 788                 
 789                 err |= comedi_check_trigger_arg_max(&cmd->convert_arg, 9);
 790         }
 791 
 792         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
 793                                            cmd->chanlist_len);
 794 
 795         if (cmd->stop_src == TRIG_COUNT)
 796                 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
 797         else    
 798                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
 799 
 800         if (err)
 801                 return 3;
 802 
 803         
 804 
 805         if (cmd->scan_begin_src == TRIG_TIMER) {
 806                 arg = cmd->scan_begin_arg;
 807                 rtd_ns_to_timer(&arg, cmd->flags);
 808                 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
 809         }
 810 
 811         if (cmd->convert_src == TRIG_TIMER) {
 812                 arg = cmd->convert_arg;
 813                 rtd_ns_to_timer(&arg, cmd->flags);
 814                 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
 815 
 816                 if (cmd->scan_begin_src == TRIG_TIMER) {
 817                         arg = cmd->convert_arg * cmd->scan_end_arg;
 818                         err |= comedi_check_trigger_arg_min(&cmd->
 819                                                             scan_begin_arg,
 820                                                             arg);
 821                 }
 822         }
 823 
 824         if (err)
 825                 return 4;
 826 
 827         return 0;
 828 }
 829 
 830 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 831 {
 832         struct rtd_private *devpriv = dev->private;
 833         struct comedi_cmd *cmd = &s->async->cmd;
 834         int timer;
 835 
 836         
 837         
 838         writel(0, dev->mmio + LAS0_PACER_STOP);
 839         writel(0, dev->mmio + LAS0_PACER);      
 840         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
 841         writew(0, dev->mmio + LAS0_IT);
 842         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
 843         writel(0, dev->mmio + LAS0_OVERRUN);
 844 
 845         
 846         
 847         rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
 848 
 849         
 850         if (cmd->chanlist_len > 1) {
 851                 
 852                 writel(0, dev->mmio + LAS0_PACER_START);
 853                 
 854                 writel(1, dev->mmio + LAS0_BURST_START);
 855                 
 856                 writel(2, dev->mmio + LAS0_ADC_CONVERSION);
 857         } else {                
 858                 
 859                 writel(0, dev->mmio + LAS0_PACER_START);
 860                 
 861                 writel(1, dev->mmio + LAS0_ADC_CONVERSION);
 862         }
 863         writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + LAS0_ACNT);
 864 
 865         if (cmd->scan_begin_src == TRIG_TIMER) {
 866                 
 867                 
 868                 if (cmd->flags & CMDF_WAKE_EOS) {
 869                         
 870 
 871 
 872 
 873 
 874                         devpriv->xfer_count = cmd->chanlist_len;
 875                         devpriv->flags |= SEND_EOS;
 876                 } else {
 877                         
 878                         devpriv->xfer_count =
 879                             (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
 880                             cmd->scan_begin_arg;
 881                         if (devpriv->xfer_count < cmd->chanlist_len) {
 882                                 
 883                                 devpriv->xfer_count = cmd->chanlist_len;
 884                         } else {        
 885                                 devpriv->xfer_count =
 886                                     DIV_ROUND_UP(devpriv->xfer_count,
 887                                                  cmd->chanlist_len);
 888                                 devpriv->xfer_count *= cmd->chanlist_len;
 889                         }
 890                         devpriv->flags |= SEND_EOS;
 891                 }
 892                 if (devpriv->xfer_count >= (devpriv->fifosz / 2)) {
 893                         
 894                         devpriv->xfer_count = 0;
 895                         devpriv->flags &= ~SEND_EOS;
 896                 } else {
 897                         
 898                         writel((devpriv->xfer_count - 1) & 0xffff,
 899                                dev->mmio + LAS0_ACNT);
 900                 }
 901         } else {                
 902                 devpriv->xfer_count = 0;
 903                 devpriv->flags &= ~SEND_EOS;
 904         }
 905         
 906         writel(1, dev->mmio + LAS0_PACER_SELECT);
 907         
 908         writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE);
 909 
 910         
 911 
 912         
 913         switch (cmd->stop_src) {
 914         case TRIG_COUNT:        
 915                 devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
 916                 if ((devpriv->xfer_count > 0) &&
 917                     (devpriv->xfer_count > devpriv->ai_count)) {
 918                         devpriv->xfer_count = devpriv->ai_count;
 919                 }
 920                 break;
 921 
 922         case TRIG_NONE: 
 923                 devpriv->ai_count = -1; 
 924                 break;
 925         }
 926 
 927         
 928         switch (cmd->scan_begin_src) {
 929         case TRIG_TIMER:        
 930                 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
 931                                         CMDF_ROUND_NEAREST);
 932                 
 933                 writel(timer & 0xffffff, dev->mmio + LAS0_PCLK);
 934 
 935                 break;
 936 
 937         case TRIG_EXT:
 938                 
 939                 writel(1, dev->mmio + LAS0_PACER_START);
 940                 break;
 941         }
 942 
 943         
 944         switch (cmd->convert_src) {
 945         case TRIG_TIMER:        
 946                 if (cmd->chanlist_len > 1) {
 947                         
 948                         timer = rtd_ns_to_timer(&cmd->convert_arg,
 949                                                 CMDF_ROUND_NEAREST);
 950                         
 951                         writel(timer & 0x3ff, dev->mmio + LAS0_BCLK);
 952                 }
 953 
 954                 break;
 955 
 956         case TRIG_EXT:          
 957                 
 958                 writel(2, dev->mmio + LAS0_BURST_START);
 959                 break;
 960         }
 961         
 962 
 963         
 964 
 965 
 966 
 967         writew(~0, dev->mmio + LAS0_CLEAR);
 968         readw(dev->mmio + LAS0_CLEAR);
 969 
 970         
 971         
 972         writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
 973 
 974         
 975         
 976         readl(dev->mmio + LAS0_PACER);  
 977         return 0;
 978 }
 979 
 980 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 981 {
 982         struct rtd_private *devpriv = dev->private;
 983 
 984         
 985         writel(0, dev->mmio + LAS0_PACER_STOP);
 986         writel(0, dev->mmio + LAS0_PACER);      
 987         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
 988         writew(0, dev->mmio + LAS0_IT);
 989         devpriv->ai_count = 0;  
 990         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
 991         return 0;
 992 }
 993 
 994 static int rtd_ao_eoc(struct comedi_device *dev,
 995                       struct comedi_subdevice *s,
 996                       struct comedi_insn *insn,
 997                       unsigned long context)
 998 {
 999         unsigned int chan = CR_CHAN(insn->chanspec);
1000         unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY;
1001         unsigned int status;
1002 
1003         status = readl(dev->mmio + LAS0_ADC);
1004         if (status & bit)
1005                 return 0;
1006         return -EBUSY;
1007 }
1008 
1009 static int rtd_ao_insn_write(struct comedi_device *dev,
1010                              struct comedi_subdevice *s,
1011                              struct comedi_insn *insn,
1012                              unsigned int *data)
1013 {
1014         struct rtd_private *devpriv = dev->private;
1015         unsigned int chan = CR_CHAN(insn->chanspec);
1016         unsigned int range = CR_RANGE(insn->chanspec);
1017         int ret;
1018         int i;
1019 
1020         
1021         writew(range & 7, dev->mmio + LAS0_DAC_CTRL(chan));
1022 
1023         for (i = 0; i < insn->n; ++i) {
1024                 unsigned int val = data[i];
1025 
1026                 
1027                 if (comedi_range_is_bipolar(s, range)) {
1028                         val = comedi_offset_munge(s, val);
1029                         val |= (val & ((s->maxdata + 1) >> 1)) << 1;
1030                 }
1031 
1032                 
1033                 val <<= 3;
1034 
1035                 writew(val, devpriv->las1 + LAS1_DAC_FIFO(chan));
1036                 writew(0, dev->mmio + LAS0_UPDATE_DAC(chan));
1037 
1038                 ret = comedi_timeout(dev, s, insn, rtd_ao_eoc, 0);
1039                 if (ret)
1040                         return ret;
1041 
1042                 s->readback[chan] = data[i];
1043         }
1044 
1045         return insn->n;
1046 }
1047 
1048 static int rtd_dio_insn_bits(struct comedi_device *dev,
1049                              struct comedi_subdevice *s,
1050                              struct comedi_insn *insn,
1051                              unsigned int *data)
1052 {
1053         if (comedi_dio_update_state(s, data))
1054                 writew(s->state & 0xff, dev->mmio + LAS0_DIO0);
1055 
1056         data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff;
1057 
1058         return insn->n;
1059 }
1060 
1061 static int rtd_dio_insn_config(struct comedi_device *dev,
1062                                struct comedi_subdevice *s,
1063                                struct comedi_insn *insn,
1064                                unsigned int *data)
1065 {
1066         int ret;
1067 
1068         ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1069         if (ret)
1070                 return ret;
1071 
1072         
1073 
1074         
1075         writew(0x01, dev->mmio + LAS0_DIO_STATUS);
1076         writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL);
1077 
1078         
1079         writew(0x00, dev->mmio + LAS0_DIO_STATUS);
1080 
1081         
1082 
1083         
1084 
1085         return insn->n;
1086 }
1087 
1088 static int rtd_counter_insn_config(struct comedi_device *dev,
1089                                    struct comedi_subdevice *s,
1090                                    struct comedi_insn *insn,
1091                                    unsigned int *data)
1092 {
1093         struct rtd_private *devpriv = dev->private;
1094         unsigned int chan = CR_CHAN(insn->chanspec);
1095         unsigned int max_src;
1096         unsigned int src;
1097 
1098         switch (data[0]) {
1099         case INSN_CONFIG_SET_GATE_SRC:
1100                 
1101 
1102 
1103 
1104 
1105 
1106 
1107 
1108 
1109                 src = data[2];
1110                 max_src = (chan == 0) ? 3 : 4;
1111                 if (src > max_src)
1112                         return -EINVAL;
1113 
1114                 devpriv->timer_gate_src[chan] = src;
1115                 writeb(src, dev->mmio + LAS0_8254_GATE_SEL(chan));
1116                 break;
1117         case INSN_CONFIG_GET_GATE_SRC:
1118                 data[2] = devpriv->timer_gate_src[chan];
1119                 break;
1120         case INSN_CONFIG_SET_CLOCK_SRC:
1121                 
1122 
1123 
1124 
1125 
1126 
1127 
1128 
1129 
1130 
1131                 src = data[1];
1132                 switch (chan) {
1133                 case 0:
1134                         max_src = 3;
1135                         break;
1136                 case 1:
1137                         max_src = 5;
1138                         break;
1139                 case 2:
1140                         max_src = 4;
1141                         break;
1142                 default:
1143                         return -EINVAL;
1144                 }
1145                 if (src > max_src)
1146                         return -EINVAL;
1147 
1148                 devpriv->timer_clk_src[chan] = src;
1149                 writeb(src, dev->mmio + LAS0_8254_CLK_SEL(chan));
1150                 break;
1151         case INSN_CONFIG_GET_CLOCK_SRC:
1152                 src = devpriv->timer_clk_src[chan];
1153                 data[1] = devpriv->timer_clk_src[chan];
1154                 data[2] = (src == 0) ? RTD_CLOCK_BASE : 0;
1155                 break;
1156         default:
1157                 return -EINVAL;
1158         }
1159 
1160         return insn->n;
1161 }
1162 
1163 static void rtd_reset(struct comedi_device *dev)
1164 {
1165         struct rtd_private *devpriv = dev->private;
1166 
1167         writel(0, dev->mmio + LAS0_BOARD_RESET);
1168         usleep_range(100, 1000);        
1169         writel(0, devpriv->lcfg + PLX_REG_INTCSR);
1170         writew(0, dev->mmio + LAS0_IT);
1171         writew(~0, dev->mmio + LAS0_CLEAR);
1172         readw(dev->mmio + LAS0_CLEAR);
1173 }
1174 
1175 
1176 
1177 
1178 
1179 static void rtd_init_board(struct comedi_device *dev)
1180 {
1181         rtd_reset(dev);
1182 
1183         writel(0, dev->mmio + LAS0_OVERRUN);
1184         writel(0, dev->mmio + LAS0_CGT_CLEAR);
1185         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
1186         writel(0, dev->mmio + LAS0_DAC_RESET(0));
1187         writel(0, dev->mmio + LAS0_DAC_RESET(1));
1188         
1189         writew(0, dev->mmio + LAS0_DIO_STATUS);
1190         
1191 }
1192 
1193 
1194 static void rtd_pci_latency_quirk(struct comedi_device *dev,
1195                                   struct pci_dev *pcidev)
1196 {
1197         unsigned char pci_latency;
1198 
1199         pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
1200         if (pci_latency < 32) {
1201                 dev_info(dev->class_dev,
1202                          "PCI latency changed from %d to %d\n",
1203                          pci_latency, 32);
1204                 pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
1205         }
1206 }
1207 
1208 static int rtd_auto_attach(struct comedi_device *dev,
1209                            unsigned long context)
1210 {
1211         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1212         const struct rtd_boardinfo *board = NULL;
1213         struct rtd_private *devpriv;
1214         struct comedi_subdevice *s;
1215         int ret;
1216 
1217         if (context < ARRAY_SIZE(rtd520_boards))
1218                 board = &rtd520_boards[context];
1219         if (!board)
1220                 return -ENODEV;
1221         dev->board_ptr = board;
1222         dev->board_name = board->name;
1223 
1224         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1225         if (!devpriv)
1226                 return -ENOMEM;
1227 
1228         ret = comedi_pci_enable(dev);
1229         if (ret)
1230                 return ret;
1231 
1232         dev->mmio = pci_ioremap_bar(pcidev, 2);
1233         devpriv->las1 = pci_ioremap_bar(pcidev, 3);
1234         devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
1235         if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg)
1236                 return -ENOMEM;
1237 
1238         rtd_pci_latency_quirk(dev, pcidev);
1239 
1240         if (pcidev->irq) {
1241                 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
1242                                   dev->board_name, dev);
1243                 if (ret == 0)
1244                         dev->irq = pcidev->irq;
1245         }
1246 
1247         ret = comedi_alloc_subdevices(dev, 4);
1248         if (ret)
1249                 return ret;
1250 
1251         s = &dev->subdevices[0];
1252         
1253         s->type         = COMEDI_SUBD_AI;
1254         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1255         s->n_chan       = 16;
1256         s->maxdata      = 0x0fff;
1257         s->range_table  = board->ai_range;
1258         s->len_chanlist = RTD_MAX_CHANLIST;
1259         s->insn_read    = rtd_ai_rinsn;
1260         if (dev->irq) {
1261                 dev->read_subdev = s;
1262                 s->subdev_flags |= SDF_CMD_READ;
1263                 s->do_cmd       = rtd_ai_cmd;
1264                 s->do_cmdtest   = rtd_ai_cmdtest;
1265                 s->cancel       = rtd_ai_cancel;
1266         }
1267 
1268         s = &dev->subdevices[1];
1269         
1270         s->type         = COMEDI_SUBD_AO;
1271         s->subdev_flags = SDF_WRITABLE;
1272         s->n_chan       = 2;
1273         s->maxdata      = 0x0fff;
1274         s->range_table  = &rtd_ao_range;
1275         s->insn_write   = rtd_ao_insn_write;
1276 
1277         ret = comedi_alloc_subdev_readback(s);
1278         if (ret)
1279                 return ret;
1280 
1281         s = &dev->subdevices[2];
1282         
1283         s->type         = COMEDI_SUBD_DIO;
1284         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1285         
1286         s->n_chan       = 8;
1287         s->maxdata      = 1;
1288         s->range_table  = &range_digital;
1289         s->insn_bits    = rtd_dio_insn_bits;
1290         s->insn_config  = rtd_dio_insn_config;
1291 
1292         
1293         s = &dev->subdevices[3];
1294         dev->pacer = comedi_8254_mm_init(dev->mmio + LAS0_8254_TIMER_BASE,
1295                                          RTD_CLOCK_BASE, I8254_IO8, 2);
1296         if (!dev->pacer)
1297                 return -ENOMEM;
1298 
1299         comedi_8254_subdevice_init(s, dev->pacer);
1300         dev->pacer->insn_config = rtd_counter_insn_config;
1301 
1302         rtd_init_board(dev);
1303 
1304         ret = rtd520_probe_fifo_depth(dev);
1305         if (ret < 0)
1306                 return ret;
1307         devpriv->fifosz = ret;
1308 
1309         if (dev->irq)
1310                 writel(PLX_INTCSR_PIEN | PLX_INTCSR_PLIEN,
1311                        devpriv->lcfg + PLX_REG_INTCSR);
1312 
1313         return 0;
1314 }
1315 
1316 static void rtd_detach(struct comedi_device *dev)
1317 {
1318         struct rtd_private *devpriv = dev->private;
1319 
1320         if (devpriv) {
1321                 
1322                 if (dev->mmio && devpriv->lcfg)
1323                         rtd_reset(dev);
1324                 if (dev->irq)
1325                         free_irq(dev->irq, dev);
1326                 if (dev->mmio)
1327                         iounmap(dev->mmio);
1328                 if (devpriv->las1)
1329                         iounmap(devpriv->las1);
1330                 if (devpriv->lcfg)
1331                         iounmap(devpriv->lcfg);
1332         }
1333         comedi_pci_disable(dev);
1334 }
1335 
1336 static struct comedi_driver rtd520_driver = {
1337         .driver_name    = "rtd520",
1338         .module         = THIS_MODULE,
1339         .auto_attach    = rtd_auto_attach,
1340         .detach         = rtd_detach,
1341 };
1342 
1343 static int rtd520_pci_probe(struct pci_dev *dev,
1344                             const struct pci_device_id *id)
1345 {
1346         return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
1347 }
1348 
1349 static const struct pci_device_id rtd520_pci_table[] = {
1350         { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
1351         { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
1352         { 0 }
1353 };
1354 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
1355 
1356 static struct pci_driver rtd520_pci_driver = {
1357         .name           = "rtd520",
1358         .id_table       = rtd520_pci_table,
1359         .probe          = rtd520_pci_probe,
1360         .remove         = comedi_pci_auto_unconfig,
1361 };
1362 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
1363 
1364 MODULE_AUTHOR("Comedi http://www.comedi.org");
1365 MODULE_DESCRIPTION("Comedi low-level driver");
1366 MODULE_LICENSE("GPL");