linux/drivers/staging/comedi/drivers/das16.c
<<
>>
Prefs
   1/*
   2    comedi/drivers/das16.c
   3    DAS16 driver
   4
   5    COMEDI - Linux Control and Measurement Device Interface
   6    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
   7    Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
   8    Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
   9
  10    This program is free software; you can redistribute it and/or modify
  11    it under the terms of the GNU General Public License as published by
  12    the Free Software Foundation; either version 2 of the License, or
  13    (at your option) any later version.
  14
  15    This program is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18    GNU General Public License for more details.
  19
  20    You should have received a copy of the GNU General Public License
  21    along with this program; if not, write to the Free Software
  22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23
  24************************************************************************
  25*/
  26/*
  27Driver: das16
  28Description: DAS16 compatible boards
  29Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
  30Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
  31  DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
  32  DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
  33  DAS-1602 (das-1602),
  34  [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
  35  PC104-DAS16JR/16 (pc104-das16jr/16),
  36  CIO-DAS16JR/16 (cio-das16jr/16),
  37  CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12),
  38  CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
  39  CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
  40  CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
  41Status: works
  42Updated: 2003-10-12
  43
  44A rewrite of the das16 and das1600 drivers.
  45Options:
  46        [0] - base io address
  47        [1] - irq (does nothing, irq is not used anymore)
  48        [2] - dma (optional, required for comedi_command support)
  49        [3] - master clock speed in MHz (optional, 1 or 10, ignored if
  50                board can probe clock, defaults to 1)
  51        [4] - analog input range lowest voltage in microvolts (optional,
  52                only useful if your board does not have software
  53                programmable gain)
  54        [5] - analog input range highest voltage in microvolts (optional,
  55                only useful if board does not have software programmable
  56                gain)
  57        [6] - analog output range lowest voltage in microvolts (optional)
  58        [7] - analog output range highest voltage in microvolts (optional)
  59        [8] - use timer mode for DMA.  Timer mode is needed e.g. for
  60                buggy DMA controllers in NS CS5530A (Geode Companion), and for
  61                'jr' cards that lack a hardware fifo.  This option is no
  62                longer needed, since timer mode is _always_ used.
  63
  64Passing a zero for an option is the same as leaving it unspecified.
  65
  66*/
  67/*
  68
  69Testing and debugging help provided by Daniel Koch.
  70
  71Keithley Manuals:
  72        2309.PDF (das16)
  73        4919.PDF (das1400, 1600)
  74        4922.PDF (das-1400)
  75        4923.PDF (das1200, 1400, 1600)
  76
  77Computer boards manuals also available from their website
  78www.measurementcomputing.com
  79
  80*/
  81
  82#include <linux/pci.h>
  83#include <linux/slab.h>
  84#include <linux/interrupt.h>
  85#include <asm/dma.h>
  86#include "../comedidev.h"
  87
  88#include "8253.h"
  89#include "8255.h"
  90#include "comedi_fc.h"
  91
  92#undef DEBUG
  93/* #define DEBUG */
  94
  95#ifdef DEBUG
  96#define DEBUG_PRINT(format, args...)    \
  97        printk(KERN_DEBUG "das16: " format, ## args)
  98#else
  99#define DEBUG_PRINT(format, args...)
 100#endif
 101
 102#define DAS16_SIZE 20           /*  number of ioports */
 103#define DAS16_DMA_SIZE 0xff00   /*  size in bytes of allocated dma buffer */
 104
 105/*
 106    cio-das16.pdf
 107
 108    "das16"
 109    "das16/f"
 110
 111  0     a/d bits 0-3            start 12 bit
 112  1     a/d bits 4-11           unused
 113  2     mux read                mux set
 114  3     di 4 bit                do 4 bit
 115  4     unused                  ao0_lsb
 116  5     unused                  ao0_msb
 117  6     unused                  ao1_lsb
 118  7     unused                  ao1_msb
 119  8     status eoc uni/bip      interrupt reset
 120  9     dma, int, trig ctrl     set dma, int
 121  a     pacer control           unused
 122  b     reserved                reserved
 123  cdef  8254
 124  0123  8255
 125
 126*/
 127
 128/*
 129    cio-das16jr.pdf
 130
 131    "das16jr"
 132
 133  0     a/d bits 0-3            start 12 bit
 134  1     a/d bits 4-11           unused
 135  2     mux read                mux set
 136  3     di 4 bit                do 4 bit
 137  4567  unused                  unused
 138  8     status eoc uni/bip      interrupt reset
 139  9     dma, int, trig ctrl     set dma, int
 140  a     pacer control           unused
 141  b     gain status             gain control
 142  cdef  8254
 143
 144*/
 145
 146/*
 147    cio-das16jr_16.pdf
 148
 149    "das16jr_16"
 150
 151  0     a/d bits 0-7            start 16 bit
 152  1     a/d bits 8-15           unused
 153  2     mux read                mux set
 154  3     di 4 bit                do 4 bit
 155  4567  unused                  unused
 156  8     status eoc uni/bip      interrupt reset
 157  9     dma, int, trig ctrl     set dma, int
 158  a     pacer control           unused
 159  b     gain status             gain control
 160  cdef  8254
 161
 162*/
 163/*
 164    cio-das160x-1x.pdf
 165
 166    "das1601/12"
 167    "das1602/12"
 168    "das1602/16"
 169
 170  0     a/d bits 0-3            start 12 bit
 171  1     a/d bits 4-11           unused
 172  2     mux read                mux set
 173  3     di 4 bit                do 4 bit
 174  4     unused                  ao0_lsb
 175  5     unused                  ao0_msb
 176  6     unused                  ao1_lsb
 177  7     unused                  ao1_msb
 178  8     status eoc uni/bip      interrupt reset
 179  9     dma, int, trig ctrl     set dma, int
 180  a     pacer control           unused
 181  b     gain status             gain control
 182  cdef  8254
 183  400   8255
 184  404   unused                  conversion enable
 185  405   unused                  burst enable
 186  406   unused                  das1600 enable
 187  407   status
 188
 189*/
 190
 191/*  size in bytes of a sample from board */
 192static const int sample_size = 2;
 193
 194#define DAS16_TRIG              0
 195#define DAS16_AI_LSB            0
 196#define DAS16_AI_MSB            1
 197#define DAS16_MUX               2
 198#define DAS16_DIO               3
 199#define DAS16_AO_LSB(x) ((x) ? 6 : 4)
 200#define DAS16_AO_MSB(x) ((x) ? 7 : 5)
 201#define DAS16_STATUS            8
 202#define   BUSY                  (1<<7)
 203#define   UNIPOLAR                      (1<<6)
 204#define   DAS16_MUXBIT                  (1<<5)
 205#define   DAS16_INT                     (1<<4)
 206#define DAS16_CONTROL           9
 207#define   DAS16_INTE                    (1<<7)
 208#define   DAS16_IRQ(x)                  (((x) & 0x7) << 4)
 209#define   DMA_ENABLE                    (1<<2)
 210#define   PACING_MASK   0x3
 211#define   INT_PACER             0x03
 212#define   EXT_PACER                     0x02
 213#define   DAS16_SOFT            0x00
 214#define DAS16_PACER             0x0A
 215#define   DAS16_CTR0                    (1<<1)
 216#define   DAS16_TRIG0                   (1<<0)
 217#define   BURST_LEN_BITS(x)                     (((x) & 0xf) << 4)
 218#define DAS16_GAIN              0x0B
 219#define DAS16_CNTR0_DATA                0x0C
 220#define DAS16_CNTR1_DATA                0x0D
 221#define DAS16_CNTR2_DATA                0x0E
 222#define DAS16_CNTR_CONTROL      0x0F
 223#define   DAS16_TERM_CNT        0x00
 224#define   DAS16_ONE_SHOT        0x02
 225#define   DAS16_RATE_GEN        0x04
 226#define   DAS16_CNTR_LSB_MSB    0x30
 227#define   DAS16_CNTR0           0x00
 228#define   DAS16_CNTR1           0x40
 229#define   DAS16_CNTR2           0x80
 230
 231#define DAS1600_CONV            0x404
 232#define   DAS1600_CONV_DISABLE          0x40
 233#define DAS1600_BURST           0x405
 234#define   DAS1600_BURST_VAL             0x40
 235#define DAS1600_ENABLE          0x406
 236#define   DAS1600_ENABLE_VAL            0x40
 237#define DAS1600_STATUS_B        0x407
 238#define   DAS1600_BME           0x40
 239#define   DAS1600_ME            0x20
 240#define   DAS1600_CD                    0x10
 241#define   DAS1600_WS                    0x02
 242#define   DAS1600_CLK_10MHZ             0x01
 243
 244static const struct comedi_lrange range_das1x01_bip = { 4, {
 245                                                            BIP_RANGE(10),
 246                                                            BIP_RANGE(1),
 247                                                            BIP_RANGE(0.1),
 248                                                            BIP_RANGE(0.01),
 249                                                            }
 250};
 251
 252static const struct comedi_lrange range_das1x01_unip = { 4, {
 253                                                             UNI_RANGE(10),
 254                                                             UNI_RANGE(1),
 255                                                             UNI_RANGE(0.1),
 256                                                             UNI_RANGE(0.01),
 257                                                             }
 258};
 259
 260static const struct comedi_lrange range_das1x02_bip = { 4, {
 261                                                            BIP_RANGE(10),
 262                                                            BIP_RANGE(5),
 263                                                            BIP_RANGE(2.5),
 264                                                            BIP_RANGE(1.25),
 265                                                            }
 266};
 267
 268static const struct comedi_lrange range_das1x02_unip = { 4, {
 269                                                             UNI_RANGE(10),
 270                                                             UNI_RANGE(5),
 271                                                             UNI_RANGE(2.5),
 272                                                             UNI_RANGE(1.25),
 273                                                             }
 274};
 275
 276static const struct comedi_lrange range_das16jr = { 9, {
 277                                                /*  also used by 16/330 */
 278                                                        BIP_RANGE(10),
 279                                                        BIP_RANGE(5),
 280                                                        BIP_RANGE(2.5),
 281                                                        BIP_RANGE(1.25),
 282                                                        BIP_RANGE(0.625),
 283                                                        UNI_RANGE(10),
 284                                                        UNI_RANGE(5),
 285                                                        UNI_RANGE(2.5),
 286                                                        UNI_RANGE(1.25),
 287                                                        }
 288};
 289
 290static const struct comedi_lrange range_das16jr_16 = { 8, {
 291                                                           BIP_RANGE(10),
 292                                                           BIP_RANGE(5),
 293                                                           BIP_RANGE(2.5),
 294                                                           BIP_RANGE(1.25),
 295                                                           UNI_RANGE(10),
 296                                                           UNI_RANGE(5),
 297                                                           UNI_RANGE(2.5),
 298                                                           UNI_RANGE(1.25),
 299                                                           }
 300};
 301
 302static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
 303static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
 304static const int das1600_gainlist[] = { 0, 1, 2, 3 };
 305
 306enum {
 307        das16_pg_none = 0,
 308        das16_pg_16jr,
 309        das16_pg_16jr_16,
 310        das16_pg_1601,
 311        das16_pg_1602,
 312};
 313static const int *const das16_gainlists[] = {
 314        NULL,
 315        das16jr_gainlist,
 316        das16jr_16_gainlist,
 317        das1600_gainlist,
 318        das1600_gainlist,
 319};
 320
 321static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
 322        &range_unknown,
 323        &range_das16jr,
 324        &range_das16jr_16,
 325        &range_das1x01_unip,
 326        &range_das1x02_unip,
 327};
 328
 329static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
 330        &range_unknown,
 331        &range_das16jr,
 332        &range_das16jr_16,
 333        &range_das1x01_bip,
 334        &range_das1x02_bip,
 335};
 336
 337struct munge_info {
 338        uint8_t byte;
 339        unsigned have_byte:1;
 340};
 341
 342static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 343                          struct comedi_insn *insn, unsigned int *data);
 344static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
 345                          struct comedi_insn *insn, unsigned int *data);
 346static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
 347                          struct comedi_insn *insn, unsigned int *data);
 348static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 349                          struct comedi_insn *insn, unsigned int *data);
 350
 351static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 352                          struct comedi_cmd *cmd);
 353static int das16_cmd_exec(struct comedi_device *dev,
 354                          struct comedi_subdevice *s);
 355static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
 356static void das16_ai_munge(struct comedi_device *dev,
 357                           struct comedi_subdevice *s, void *array,
 358                           unsigned int num_bytes,
 359                           unsigned int start_chan_index);
 360
 361static void das16_reset(struct comedi_device *dev);
 362static irqreturn_t das16_dma_interrupt(int irq, void *d);
 363static void das16_timer_interrupt(unsigned long arg);
 364static void das16_interrupt(struct comedi_device *dev);
 365
 366static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
 367                                    int flags);
 368static int das1600_mode_detect(struct comedi_device *dev);
 369static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
 370                                                struct comedi_cmd cmd);
 371
 372static void reg_dump(struct comedi_device *dev);
 373
 374struct das16_board {
 375        const char *name;
 376        void *ai;
 377        unsigned int ai_nbits;
 378        unsigned int ai_speed;  /*  max conversion speed in nanosec */
 379        unsigned int ai_pg;
 380        void *ao;
 381        unsigned int ao_nbits;
 382        void *di;
 383        void *do_;
 384
 385        unsigned int i8255_offset;
 386        unsigned int i8254_offset;
 387
 388        unsigned int size;
 389        unsigned int id;
 390};
 391
 392static const struct das16_board das16_boards[] = {
 393        {
 394         .name = "das-16",
 395         .ai = das16_ai_rinsn,
 396         .ai_nbits = 12,
 397         .ai_speed = 15000,
 398         .ai_pg = das16_pg_none,
 399         .ao = das16_ao_winsn,
 400         .ao_nbits = 12,
 401         .di = das16_di_rbits,
 402         .do_ = das16_do_wbits,
 403         .i8255_offset = 0x10,
 404         .i8254_offset = 0x0c,
 405         .size = 0x14,
 406         .id = 0x00,
 407         },
 408        {
 409         .name = "das-16g",
 410         .ai = das16_ai_rinsn,
 411         .ai_nbits = 12,
 412         .ai_speed = 15000,
 413         .ai_pg = das16_pg_none,
 414         .ao = das16_ao_winsn,
 415         .ao_nbits = 12,
 416         .di = das16_di_rbits,
 417         .do_ = das16_do_wbits,
 418         .i8255_offset = 0x10,
 419         .i8254_offset = 0x0c,
 420         .size = 0x14,
 421         .id = 0x00,
 422         },
 423        {
 424         .name = "das-16f",
 425         .ai = das16_ai_rinsn,
 426         .ai_nbits = 12,
 427         .ai_speed = 8500,
 428         .ai_pg = das16_pg_none,
 429         .ao = das16_ao_winsn,
 430         .ao_nbits = 12,
 431         .di = das16_di_rbits,
 432         .do_ = das16_do_wbits,
 433         .i8255_offset = 0x10,
 434         .i8254_offset = 0x0c,
 435         .size = 0x14,
 436         .id = 0x00,
 437         },
 438        {
 439         .name = "cio-das16",   /*  cio-das16.pdf */
 440         .ai = das16_ai_rinsn,
 441         .ai_nbits = 12,
 442         .ai_speed = 20000,
 443         .ai_pg = das16_pg_none,
 444         .ao = das16_ao_winsn,
 445         .ao_nbits = 12,
 446         .di = das16_di_rbits,
 447         .do_ = das16_do_wbits,
 448         .i8255_offset = 0x10,
 449         .i8254_offset = 0x0c,
 450         .size = 0x14,
 451         .id = 0x80,
 452         },
 453        {
 454         .name = "cio-das16/f", /*  das16.pdf */
 455         .ai = das16_ai_rinsn,
 456         .ai_nbits = 12,
 457         .ai_speed = 10000,
 458         .ai_pg = das16_pg_none,
 459         .ao = das16_ao_winsn,
 460         .ao_nbits = 12,
 461         .di = das16_di_rbits,
 462         .do_ = das16_do_wbits,
 463         .i8255_offset = 0x10,
 464         .i8254_offset = 0x0c,
 465         .size = 0x14,
 466         .id = 0x80,
 467         },
 468        {
 469         .name = "cio-das16/jr",        /*  cio-das16jr.pdf */
 470         .ai = das16_ai_rinsn,
 471         .ai_nbits = 12,
 472         .ai_speed = 7692,
 473         .ai_pg = das16_pg_16jr,
 474         .ao = NULL,
 475         .di = das16_di_rbits,
 476         .do_ = das16_do_wbits,
 477         .i8255_offset = 0,
 478         .i8254_offset = 0x0c,
 479         .size = 0x10,
 480         .id = 0x00,
 481         },
 482        {
 483         .name = "pc104-das16jr",       /*  pc104-das16jr_xx.pdf */
 484         .ai = das16_ai_rinsn,
 485         .ai_nbits = 12,
 486         .ai_speed = 3300,
 487         .ai_pg = das16_pg_16jr,
 488         .ao = NULL,
 489         .di = das16_di_rbits,
 490         .do_ = das16_do_wbits,
 491         .i8255_offset = 0,
 492         .i8254_offset = 0x0c,
 493         .size = 0x10,
 494         .id = 0x00,
 495         },
 496        {
 497         .name = "cio-das16jr/16",      /*  cio-das16jr_16.pdf */
 498         .ai = das16_ai_rinsn,
 499         .ai_nbits = 16,
 500         .ai_speed = 10000,
 501         .ai_pg = das16_pg_16jr_16,
 502         .ao = NULL,
 503         .di = das16_di_rbits,
 504         .do_ = das16_do_wbits,
 505         .i8255_offset = 0,
 506         .i8254_offset = 0x0c,
 507         .size = 0x10,
 508         .id = 0x00,
 509         },
 510        {
 511         .name = "pc104-das16jr/16",    /*  pc104-das16jr_xx.pdf */
 512         .ai = das16_ai_rinsn,
 513         .ai_nbits = 16,
 514         .ai_speed = 10000,
 515         .ai_pg = das16_pg_16jr_16,
 516         .ao = NULL,
 517         .di = das16_di_rbits,
 518         .do_ = das16_do_wbits,
 519         .i8255_offset = 0,
 520         .i8254_offset = 0x0c,
 521         .size = 0x10,
 522         .id = 0x00,
 523         },
 524        {
 525         .name = "das-1201",    /*  4924.pdf (keithley user's manual) */
 526         .ai = das16_ai_rinsn,
 527         .ai_nbits = 12,
 528         .ai_speed = 20000,
 529         .ai_pg = das16_pg_none,
 530         .ao = NULL,
 531         .di = das16_di_rbits,
 532         .do_ = das16_do_wbits,
 533         .i8255_offset = 0x400,
 534         .i8254_offset = 0x0c,
 535         .size = 0x408,
 536         .id = 0x20,
 537         },
 538        {
 539         .name = "das-1202",    /*  4924.pdf (keithley user's manual) */
 540         .ai = das16_ai_rinsn,
 541         .ai_nbits = 12,
 542         .ai_speed = 10000,
 543         .ai_pg = das16_pg_none,
 544         .ao = NULL,
 545         .di = das16_di_rbits,
 546         .do_ = das16_do_wbits,
 547         .i8255_offset = 0x400,
 548         .i8254_offset = 0x0c,
 549         .size = 0x408,
 550         .id = 0x20,
 551         },
 552        {
 553        /*  4919.pdf and 4922.pdf (keithley user's manual) */
 554         .name = "das-1401",
 555         .ai = das16_ai_rinsn,
 556         .ai_nbits = 12,
 557         .ai_speed = 10000,
 558         .ai_pg = das16_pg_1601,
 559         .ao = NULL,
 560         .di = das16_di_rbits,
 561         .do_ = das16_do_wbits,
 562         .i8255_offset = 0x0,
 563         .i8254_offset = 0x0c,
 564         .size = 0x408,
 565         .id = 0xc0   /*  4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
 566         },
 567        {
 568        /*  4919.pdf and 4922.pdf (keithley user's manual) */
 569         .name = "das-1402",
 570         .ai = das16_ai_rinsn,
 571         .ai_nbits = 12,
 572         .ai_speed = 10000,
 573         .ai_pg = das16_pg_1602,
 574         .ao = NULL,
 575         .di = das16_di_rbits,
 576         .do_ = das16_do_wbits,
 577         .i8255_offset = 0x0,
 578         .i8254_offset = 0x0c,
 579         .size = 0x408,
 580         .id = 0xc0   /*  4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
 581         },
 582        {
 583         .name = "das-1601",    /*  4919.pdf */
 584         .ai = das16_ai_rinsn,
 585         .ai_nbits = 12,
 586         .ai_speed = 10000,
 587         .ai_pg = das16_pg_1601,
 588         .ao = das16_ao_winsn,
 589         .ao_nbits = 12,
 590         .di = das16_di_rbits,
 591         .do_ = das16_do_wbits,
 592         .i8255_offset = 0x400,
 593         .i8254_offset = 0x0c,
 594         .size = 0x408,
 595         .id = 0xc0},
 596        {
 597         .name = "das-1602",    /*  4919.pdf */
 598         .ai = das16_ai_rinsn,
 599         .ai_nbits = 12,
 600         .ai_speed = 10000,
 601         .ai_pg = das16_pg_1602,
 602         .ao = das16_ao_winsn,
 603         .ao_nbits = 12,
 604         .di = das16_di_rbits,
 605         .do_ = das16_do_wbits,
 606         .i8255_offset = 0x400,
 607         .i8254_offset = 0x0c,
 608         .size = 0x408,
 609         .id = 0xc0},
 610        {
 611         .name = "cio-das1401/12",      /*  cio-das1400_series.pdf */
 612         .ai = das16_ai_rinsn,
 613         .ai_nbits = 12,
 614         .ai_speed = 6250,
 615         .ai_pg = das16_pg_1601,
 616         .ao = NULL,
 617         .di = das16_di_rbits,
 618         .do_ = das16_do_wbits,
 619         .i8255_offset = 0,
 620         .i8254_offset = 0x0c,
 621         .size = 0x408,
 622         .id = 0xc0},
 623        {
 624         .name = "cio-das1402/12",      /*  cio-das1400_series.pdf */
 625         .ai = das16_ai_rinsn,
 626         .ai_nbits = 12,
 627         .ai_speed = 6250,
 628         .ai_pg = das16_pg_1602,
 629         .ao = NULL,
 630         .di = das16_di_rbits,
 631         .do_ = das16_do_wbits,
 632         .i8255_offset = 0,
 633         .i8254_offset = 0x0c,
 634         .size = 0x408,
 635         .id = 0xc0},
 636        {
 637         .name = "cio-das1402/16",      /*  cio-das1400_series.pdf */
 638         .ai = das16_ai_rinsn,
 639         .ai_nbits = 16,
 640         .ai_speed = 10000,
 641         .ai_pg = das16_pg_1602,
 642         .ao = NULL,
 643         .di = das16_di_rbits,
 644         .do_ = das16_do_wbits,
 645         .i8255_offset = 0,
 646         .i8254_offset = 0x0c,
 647         .size = 0x408,
 648         .id = 0xc0},
 649        {
 650         .name = "cio-das1601/12",      /*  cio-das160x-1x.pdf */
 651         .ai = das16_ai_rinsn,
 652         .ai_nbits = 12,
 653         .ai_speed = 6250,
 654         .ai_pg = das16_pg_1601,
 655         .ao = das16_ao_winsn,
 656         .ao_nbits = 12,
 657         .di = das16_di_rbits,
 658         .do_ = das16_do_wbits,
 659         .i8255_offset = 0x400,
 660         .i8254_offset = 0x0c,
 661         .size = 0x408,
 662         .id = 0xc0},
 663        {
 664         .name = "cio-das1602/12",      /*  cio-das160x-1x.pdf */
 665         .ai = das16_ai_rinsn,
 666         .ai_nbits = 12,
 667         .ai_speed = 10000,
 668         .ai_pg = das16_pg_1602,
 669         .ao = das16_ao_winsn,
 670         .ao_nbits = 12,
 671         .di = das16_di_rbits,
 672         .do_ = das16_do_wbits,
 673         .i8255_offset = 0x400,
 674         .i8254_offset = 0x0c,
 675         .size = 0x408,
 676         .id = 0xc0},
 677        {
 678         .name = "cio-das1602/16",      /*  cio-das160x-1x.pdf */
 679         .ai = das16_ai_rinsn,
 680         .ai_nbits = 16,
 681         .ai_speed = 10000,
 682         .ai_pg = das16_pg_1602,
 683         .ao = das16_ao_winsn,
 684         .ao_nbits = 12,
 685         .di = das16_di_rbits,
 686         .do_ = das16_do_wbits,
 687         .i8255_offset = 0x400,
 688         .i8254_offset = 0x0c,
 689         .size = 0x408,
 690         .id = 0xc0},
 691        {
 692         .name = "cio-das16/330",       /*  ? */
 693         .ai = das16_ai_rinsn,
 694         .ai_nbits = 12,
 695         .ai_speed = 3030,
 696         .ai_pg = das16_pg_16jr,
 697         .ao = NULL,
 698         .di = das16_di_rbits,
 699         .do_ = das16_do_wbits,
 700         .i8255_offset = 0,
 701         .i8254_offset = 0x0c,
 702         .size = 0x14,
 703         .id = 0xf0},
 704#if 0
 705        {
 706         .name = "das16/330i",  /*  ? */
 707         },
 708        {
 709         .name = "das16/jr/ctr5",       /*  ? */
 710         },
 711        {
 712        /*  cio-das16_m1_16.pdf, this board is a bit quirky, no dma */
 713         .name = "cio-das16/m1/16",
 714         },
 715#endif
 716};
 717
 718static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it);
 719static int das16_detach(struct comedi_device *dev);
 720static struct comedi_driver driver_das16 = {
 721        .driver_name = "das16",
 722        .module = THIS_MODULE,
 723        .attach = das16_attach,
 724        .detach = das16_detach,
 725        .board_name = &das16_boards[0].name,
 726        .num_names = ARRAY_SIZE(das16_boards),
 727        .offset = sizeof(das16_boards[0]),
 728};
 729
 730#define DAS16_TIMEOUT 1000
 731
 732/* Period for timer interrupt in jiffies.  It's a function
 733 * to deal with possibility of dynamic HZ patches  */
 734static inline int timer_period(void)
 735{
 736        return HZ / 20;
 737}
 738
 739struct das16_private_struct {
 740        unsigned int ai_unipolar;       /*  unipolar flag */
 741        unsigned int ai_singleended;    /*  single ended flag */
 742        unsigned int clockbase; /*  master clock speed in ns */
 743        volatile unsigned int control_state;    /*  dma, interrupt and trigger control bits */
 744        volatile unsigned long adc_byte_count;  /*  number of bytes remaining */
 745        /*  divisor dividing master clock to get conversion frequency */
 746        unsigned int divisor1;
 747        /*  divisor dividing master clock to get conversion frequency */
 748        unsigned int divisor2;
 749        unsigned int dma_chan;  /*  dma channel */
 750        uint16_t *dma_buffer[2];
 751        dma_addr_t dma_buffer_addr[2];
 752        unsigned int current_buffer;
 753        volatile unsigned int dma_transfer_size;        /*  target number of bytes to transfer per dma shot */
 754        /**
 755         * user-defined analog input and output ranges
 756         * defined from config options
 757         */
 758        struct comedi_lrange *user_ai_range_table;
 759        struct comedi_lrange *user_ao_range_table;
 760
 761        struct timer_list timer;        /*  for timed interrupt */
 762        volatile short timer_running;
 763        volatile short timer_mode;      /*  true if using timer mode */
 764};
 765#define devpriv ((struct das16_private_struct *)(dev->private))
 766#define thisboard ((struct das16_board *)(dev->board_ptr))
 767
 768static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 769                          struct comedi_cmd *cmd)
 770{
 771        int err = 0, tmp;
 772        int gain, start_chan, i;
 773        int mask;
 774
 775        /* make sure triggers are valid */
 776        tmp = cmd->start_src;
 777        cmd->start_src &= TRIG_NOW;
 778        if (!cmd->start_src || tmp != cmd->start_src)
 779                err++;
 780
 781        tmp = cmd->scan_begin_src;
 782        mask = TRIG_FOLLOW;
 783        /*  if board supports burst mode */
 784        if (thisboard->size > 0x400)
 785                mask |= TRIG_TIMER | TRIG_EXT;
 786        cmd->scan_begin_src &= mask;
 787        if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
 788                err++;
 789
 790        tmp = cmd->convert_src;
 791        mask = TRIG_TIMER | TRIG_EXT;
 792        /*  if board supports burst mode */
 793        if (thisboard->size > 0x400)
 794                mask |= TRIG_NOW;
 795        cmd->convert_src &= mask;
 796        if (!cmd->convert_src || tmp != cmd->convert_src)
 797                err++;
 798
 799        tmp = cmd->scan_end_src;
 800        cmd->scan_end_src &= TRIG_COUNT;
 801        if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
 802                err++;
 803
 804        tmp = cmd->stop_src;
 805        cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
 806        if (!cmd->stop_src || tmp != cmd->stop_src)
 807                err++;
 808
 809        if (err)
 810                return 1;
 811
 812        /**
 813         * step 2: make sure trigger sources are unique and
 814         * mutually compatible
 815         */
 816        if (cmd->scan_begin_src != TRIG_TIMER &&
 817            cmd->scan_begin_src != TRIG_EXT &&
 818            cmd->scan_begin_src != TRIG_FOLLOW)
 819                err++;
 820        if (cmd->convert_src != TRIG_TIMER &&
 821            cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
 822                err++;
 823        if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
 824                err++;
 825
 826        /*  make sure scan_begin_src and convert_src dont conflict */
 827        if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
 828                err++;
 829        if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
 830                err++;
 831
 832        if (err)
 833                return 2;
 834
 835        /* step 3: make sure arguments are trivially compatible */
 836        if (cmd->start_arg != 0) {
 837                cmd->start_arg = 0;
 838                err++;
 839        }
 840
 841        if (cmd->scan_begin_src == TRIG_FOLLOW) {
 842                /* internal trigger */
 843                if (cmd->scan_begin_arg != 0) {
 844                        cmd->scan_begin_arg = 0;
 845                        err++;
 846                }
 847        }
 848
 849        if (cmd->scan_end_arg != cmd->chanlist_len) {
 850                cmd->scan_end_arg = cmd->chanlist_len;
 851                err++;
 852        }
 853        /*  check against maximum frequency */
 854        if (cmd->scan_begin_src == TRIG_TIMER) {
 855                if (cmd->scan_begin_arg <
 856                    thisboard->ai_speed * cmd->chanlist_len) {
 857                        cmd->scan_begin_arg =
 858                            thisboard->ai_speed * cmd->chanlist_len;
 859                        err++;
 860                }
 861        }
 862        if (cmd->convert_src == TRIG_TIMER) {
 863                if (cmd->convert_arg < thisboard->ai_speed) {
 864                        cmd->convert_arg = thisboard->ai_speed;
 865                        err++;
 866                }
 867        }
 868
 869        if (cmd->stop_src == TRIG_NONE) {
 870                if (cmd->stop_arg != 0) {
 871                        cmd->stop_arg = 0;
 872                        err++;
 873                }
 874        }
 875        if (err)
 876                return 3;
 877
 878        /*  step 4: fix up arguments */
 879        if (cmd->scan_begin_src == TRIG_TIMER) {
 880                unsigned int tmp = cmd->scan_begin_arg;
 881                /*  set divisors, correct timing arguments */
 882                i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
 883                                               &(devpriv->divisor1),
 884                                               &(devpriv->divisor2),
 885                                               &(cmd->scan_begin_arg),
 886                                               cmd->flags & TRIG_ROUND_MASK);
 887                err += (tmp != cmd->scan_begin_arg);
 888        }
 889        if (cmd->convert_src == TRIG_TIMER) {
 890                unsigned int tmp = cmd->convert_arg;
 891                /*  set divisors, correct timing arguments */
 892                i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
 893                                               &(devpriv->divisor1),
 894                                               &(devpriv->divisor2),
 895                                               &(cmd->convert_arg),
 896                                               cmd->flags & TRIG_ROUND_MASK);
 897                err += (tmp != cmd->convert_arg);
 898        }
 899        if (err)
 900                return 4;
 901
 902        /*  check channel/gain list against card's limitations */
 903        if (cmd->chanlist) {
 904                gain = CR_RANGE(cmd->chanlist[0]);
 905                start_chan = CR_CHAN(cmd->chanlist[0]);
 906                for (i = 1; i < cmd->chanlist_len; i++) {
 907                        if (CR_CHAN(cmd->chanlist[i]) !=
 908                            (start_chan + i) % s->n_chan) {
 909                                comedi_error(dev,
 910                                                "entries in chanlist must be "
 911                                                "consecutive channels, "
 912                                                "counting upwards\n");
 913                                err++;
 914                        }
 915                        if (CR_RANGE(cmd->chanlist[i]) != gain) {
 916                                comedi_error(dev,
 917                                                "entries in chanlist must all "
 918                                                "have the same gain\n");
 919                                err++;
 920                        }
 921                }
 922        }
 923        if (err)
 924                return 5;
 925
 926        return 0;
 927}
 928
 929static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 930{
 931        struct comedi_async *async = s->async;
 932        struct comedi_cmd *cmd = &async->cmd;
 933        unsigned int byte;
 934        unsigned long flags;
 935        int range;
 936
 937        if (devpriv->dma_chan == 0 || (dev->irq == 0
 938                                       && devpriv->timer_mode == 0)) {
 939                comedi_error(dev,
 940                                "irq (or use of 'timer mode') dma required to "
 941                                                        "execute comedi_cmd");
 942                return -1;
 943        }
 944        if (cmd->flags & TRIG_RT) {
 945                comedi_error(dev, "isa dma transfers cannot be performed with "
 946                                                        "TRIG_RT, aborting");
 947                return -1;
 948        }
 949
 950        devpriv->adc_byte_count =
 951            cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
 952
 953        /*  disable conversions for das1600 mode */
 954        if (thisboard->size > 0x400)
 955                outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
 956
 957        /*  set scan limits */
 958        byte = CR_CHAN(cmd->chanlist[0]);
 959        byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
 960        outb(byte, dev->iobase + DAS16_MUX);
 961
 962        /* set gain (this is also burst rate register but according to
 963         * computer boards manual, burst rate does nothing, even on
 964         * keithley cards) */
 965        if (thisboard->ai_pg != das16_pg_none) {
 966                range = CR_RANGE(cmd->chanlist[0]);
 967                outb((das16_gainlists[thisboard->ai_pg])[range],
 968                     dev->iobase + DAS16_GAIN);
 969        }
 970
 971        /* set counter mode and counts */
 972        cmd->convert_arg =
 973            das16_set_pacer(dev, cmd->convert_arg,
 974                            cmd->flags & TRIG_ROUND_MASK);
 975        DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
 976
 977        /* enable counters */
 978        byte = 0;
 979        /* Enable burst mode if appropriate. */
 980        if (thisboard->size > 0x400) {
 981                if (cmd->convert_src == TRIG_NOW) {
 982                        outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST);
 983                        /*  set burst length */
 984                        byte |= BURST_LEN_BITS(cmd->chanlist_len - 1);
 985                } else {
 986                        outb(0, dev->iobase + DAS1600_BURST);
 987                }
 988        }
 989        outb(byte, dev->iobase + DAS16_PACER);
 990
 991        /*  set up dma transfer */
 992        flags = claim_dma_lock();
 993        disable_dma(devpriv->dma_chan);
 994        /* clear flip-flop to make sure 2-byte registers for
 995         * count and address get set correctly */
 996        clear_dma_ff(devpriv->dma_chan);
 997        devpriv->current_buffer = 0;
 998        set_dma_addr(devpriv->dma_chan,
 999                     devpriv->dma_buffer_addr[devpriv->current_buffer]);
1000        /*  set appropriate size of transfer */
1001        devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd);
1002        set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
1003        enable_dma(devpriv->dma_chan);
1004        release_dma_lock(flags);
1005
1006        /*  set up interrupt */
1007        if (devpriv->timer_mode) {
1008                devpriv->timer_running = 1;
1009                devpriv->timer.expires = jiffies + timer_period();
1010                add_timer(&devpriv->timer);
1011                devpriv->control_state &= ~DAS16_INTE;
1012        } else {
1013                /* clear interrupt bit */
1014                outb(0x00, dev->iobase + DAS16_STATUS);
1015                /* enable interrupts */
1016                devpriv->control_state |= DAS16_INTE;
1017        }
1018        devpriv->control_state |= DMA_ENABLE;
1019        devpriv->control_state &= ~PACING_MASK;
1020        if (cmd->convert_src == TRIG_EXT)
1021                devpriv->control_state |= EXT_PACER;
1022        else
1023                devpriv->control_state |= INT_PACER;
1024        outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1025
1026        /* Enable conversions if using das1600 mode */
1027        if (thisboard->size > 0x400)
1028                outb(0, dev->iobase + DAS1600_CONV);
1029
1030
1031        return 0;
1032}
1033
1034static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1035{
1036        unsigned long flags;
1037
1038        spin_lock_irqsave(&dev->spinlock, flags);
1039        /* disable interrupts, dma and pacer clocked conversions */
1040        devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE;
1041        outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1042        if (devpriv->dma_chan)
1043                disable_dma(devpriv->dma_chan);
1044
1045        /*  disable SW timer */
1046        if (devpriv->timer_mode && devpriv->timer_running) {
1047                devpriv->timer_running = 0;
1048                del_timer(&devpriv->timer);
1049        }
1050
1051        /* disable burst mode */
1052        if (thisboard->size > 0x400)
1053                outb(0, dev->iobase + DAS1600_BURST);
1054
1055
1056        spin_unlock_irqrestore(&dev->spinlock, flags);
1057
1058        return 0;
1059}
1060
1061static void das16_reset(struct comedi_device *dev)
1062{
1063        outb(0, dev->iobase + DAS16_STATUS);
1064        outb(0, dev->iobase + DAS16_CONTROL);
1065        outb(0, dev->iobase + DAS16_PACER);
1066        outb(0, dev->iobase + DAS16_CNTR_CONTROL);
1067}
1068
1069static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
1070                          struct comedi_insn *insn, unsigned int *data)
1071{
1072        int i, n;
1073        int range;
1074        int chan;
1075        int msb, lsb;
1076
1077        /*  disable interrupts and pacing */
1078        devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK;
1079        outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1080
1081        /* set multiplexer */
1082        chan = CR_CHAN(insn->chanspec);
1083        chan |= CR_CHAN(insn->chanspec) << 4;
1084        outb(chan, dev->iobase + DAS16_MUX);
1085
1086        /* set gain */
1087        if (thisboard->ai_pg != das16_pg_none) {
1088                range = CR_RANGE(insn->chanspec);
1089                outb((das16_gainlists[thisboard->ai_pg])[range],
1090                     dev->iobase + DAS16_GAIN);
1091        }
1092
1093        for (n = 0; n < insn->n; n++) {
1094                /* trigger conversion */
1095                outb_p(0, dev->iobase + DAS16_TRIG);
1096
1097                for (i = 0; i < DAS16_TIMEOUT; i++) {
1098                        if (!(inb(dev->iobase + DAS16_STATUS) & BUSY))
1099                                break;
1100                }
1101                if (i == DAS16_TIMEOUT) {
1102                        printk("das16: timeout\n");
1103                        return -ETIME;
1104                }
1105                msb = inb(dev->iobase + DAS16_AI_MSB);
1106                lsb = inb(dev->iobase + DAS16_AI_LSB);
1107                if (thisboard->ai_nbits == 12)
1108                        data[n] = ((lsb >> 4) & 0xf) | (msb << 4);
1109                else
1110                        data[n] = lsb | (msb << 8);
1111
1112        }
1113
1114        return n;
1115}
1116
1117static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
1118                          struct comedi_insn *insn, unsigned int *data)
1119{
1120        unsigned int bits;
1121
1122        bits = inb(dev->iobase + DAS16_DIO) & 0xf;
1123        data[1] = bits;
1124        data[0] = 0;
1125
1126        return 2;
1127}
1128
1129static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
1130                          struct comedi_insn *insn, unsigned int *data)
1131{
1132        unsigned int wbits;
1133
1134        /*  only set bits that have been masked */
1135        data[0] &= 0xf;
1136        wbits = s->state;
1137        /*  zero bits that have been masked */
1138        wbits &= ~data[0];
1139        /*  set masked bits */
1140        wbits |= data[0] & data[1];
1141        s->state = wbits;
1142        data[1] = wbits;
1143
1144        outb(s->state, dev->iobase + DAS16_DIO);
1145
1146        return 2;
1147}
1148
1149static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
1150                          struct comedi_insn *insn, unsigned int *data)
1151{
1152        int i;
1153        int lsb, msb;
1154        int chan;
1155
1156        chan = CR_CHAN(insn->chanspec);
1157
1158        for (i = 0; i < insn->n; i++) {
1159                if (thisboard->ao_nbits == 12) {
1160                        lsb = (data[i] << 4) & 0xff;
1161                        msb = (data[i] >> 4) & 0xff;
1162                } else {
1163                        lsb = data[i] & 0xff;
1164                        msb = (data[i] >> 8) & 0xff;
1165                }
1166                outb(lsb, dev->iobase + DAS16_AO_LSB(chan));
1167                outb(msb, dev->iobase + DAS16_AO_MSB(chan));
1168        }
1169
1170        return i;
1171}
1172
1173static irqreturn_t das16_dma_interrupt(int irq, void *d)
1174{
1175        int status;
1176        struct comedi_device *dev = d;
1177
1178        status = inb(dev->iobase + DAS16_STATUS);
1179
1180        if ((status & DAS16_INT) == 0) {
1181                DEBUG_PRINT("spurious interrupt\n");
1182                return IRQ_NONE;
1183        }
1184
1185        /* clear interrupt */
1186        outb(0x00, dev->iobase + DAS16_STATUS);
1187        das16_interrupt(dev);
1188        return IRQ_HANDLED;
1189}
1190
1191static void das16_timer_interrupt(unsigned long arg)
1192{
1193        struct comedi_device *dev = (struct comedi_device *)arg;
1194
1195        das16_interrupt(dev);
1196
1197        if (devpriv->timer_running)
1198                mod_timer(&devpriv->timer, jiffies + timer_period());
1199}
1200
1201/* the pc104-das16jr (at least) has problems if the dma
1202        transfer is interrupted in the middle of transferring
1203        a 16 bit sample, so this function takes care to get
1204        an even transfer count after disabling dma
1205        channel.
1206*/
1207static int disable_dma_on_even(struct comedi_device *dev)
1208{
1209        int residue;
1210        int i;
1211        static const int disable_limit = 100;
1212        static const int enable_timeout = 100;
1213        disable_dma(devpriv->dma_chan);
1214        residue = get_dma_residue(devpriv->dma_chan);
1215        for (i = 0; i < disable_limit && (residue % 2); ++i) {
1216                int j;
1217                enable_dma(devpriv->dma_chan);
1218                for (j = 0; j < enable_timeout; ++j) {
1219                        int new_residue;
1220                        udelay(2);
1221                        new_residue = get_dma_residue(devpriv->dma_chan);
1222                        if (new_residue != residue)
1223                                break;
1224                }
1225                disable_dma(devpriv->dma_chan);
1226                residue = get_dma_residue(devpriv->dma_chan);
1227        }
1228        if (i == disable_limit) {
1229                comedi_error(dev, "failed to get an even dma transfer, "
1230                                                        "could be trouble.");
1231        }
1232        return residue;
1233}
1234
1235static void das16_interrupt(struct comedi_device *dev)
1236{
1237        unsigned long dma_flags, spin_flags;
1238        struct comedi_subdevice *s = dev->read_subdev;
1239        struct comedi_async *async;
1240        struct comedi_cmd *cmd;
1241        int num_bytes, residue;
1242        int buffer_index;
1243
1244        if (dev->attached == 0) {
1245                comedi_error(dev, "premature interrupt");
1246                return;
1247        }
1248        /*  initialize async here to make sure it is not NULL */
1249        async = s->async;
1250        cmd = &async->cmd;
1251
1252        if (devpriv->dma_chan == 0) {
1253                comedi_error(dev, "interrupt with no dma channel?");
1254                return;
1255        }
1256
1257        spin_lock_irqsave(&dev->spinlock, spin_flags);
1258        if ((devpriv->control_state & DMA_ENABLE) == 0) {
1259                spin_unlock_irqrestore(&dev->spinlock, spin_flags);
1260                DEBUG_PRINT("interrupt while dma disabled?\n");
1261                return;
1262        }
1263
1264        dma_flags = claim_dma_lock();
1265        clear_dma_ff(devpriv->dma_chan);
1266        residue = disable_dma_on_even(dev);
1267
1268        /*  figure out how many points to read */
1269        if (residue > devpriv->dma_transfer_size) {
1270                comedi_error(dev, "residue > transfer size!\n");
1271                async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1272                num_bytes = 0;
1273        } else
1274                num_bytes = devpriv->dma_transfer_size - residue;
1275
1276        if (cmd->stop_src == TRIG_COUNT &&
1277                                        num_bytes >= devpriv->adc_byte_count) {
1278                num_bytes = devpriv->adc_byte_count;
1279                async->events |= COMEDI_CB_EOA;
1280        }
1281
1282        buffer_index = devpriv->current_buffer;
1283        devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
1284        devpriv->adc_byte_count -= num_bytes;
1285
1286        /*  figure out how many bytes for next transfer */
1287        if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 &&
1288            devpriv->dma_transfer_size > devpriv->adc_byte_count)
1289                devpriv->dma_transfer_size = devpriv->adc_byte_count;
1290
1291        /*  re-enable  dma */
1292        if ((async->events & COMEDI_CB_EOA) == 0) {
1293                set_dma_addr(devpriv->dma_chan,
1294                             devpriv->dma_buffer_addr[devpriv->current_buffer]);
1295                set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
1296                enable_dma(devpriv->dma_chan);
1297                /* reenable conversions for das1600 mode, (stupid hardware) */
1298                if (thisboard->size > 0x400 && devpriv->timer_mode == 0)
1299                        outb(0x00, dev->iobase + DAS1600_CONV);
1300
1301        }
1302        release_dma_lock(dma_flags);
1303
1304        spin_unlock_irqrestore(&dev->spinlock, spin_flags);
1305
1306        cfc_write_array_to_buffer(s,
1307                                  devpriv->dma_buffer[buffer_index], num_bytes);
1308
1309        cfc_handle_events(dev, s);
1310}
1311
1312static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
1313                                    int rounding_flags)
1314{
1315        i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
1316                                       &(devpriv->divisor2), &ns,
1317                                       rounding_flags & TRIG_ROUND_MASK);
1318
1319        /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1320        i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2);
1321        i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2);
1322
1323        return ns;
1324}
1325
1326static void reg_dump(struct comedi_device *dev)
1327{
1328        DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
1329        DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX));
1330        DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO));
1331        DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS));
1332        DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL));
1333        DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER));
1334        DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN));
1335        DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
1336                    inb(dev->iobase + DAS16_CNTR_CONTROL));
1337        DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV));
1338        DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST));
1339        DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE));
1340        DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
1341                    inb(dev->iobase + DAS1600_STATUS_B));
1342}
1343
1344static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
1345{
1346        int status;
1347        int diobits;
1348
1349        /* status is available on all boards */
1350
1351        status = inb(dev->iobase + DAS16_STATUS);
1352
1353        if ((status & UNIPOLAR))
1354                devpriv->ai_unipolar = 1;
1355        else
1356                devpriv->ai_unipolar = 0;
1357
1358
1359        if ((status & DAS16_MUXBIT))
1360                devpriv->ai_singleended = 1;
1361        else
1362                devpriv->ai_singleended = 0;
1363
1364
1365        /* diobits indicates boards */
1366
1367        diobits = inb(dev->iobase + DAS16_DIO) & 0xf0;
1368
1369        printk(KERN_INFO " id bits are 0x%02x\n", diobits);
1370        if (thisboard->id != diobits) {
1371                printk(KERN_INFO " requested board's id bits are 0x%x (ignore)\n",
1372                       thisboard->id);
1373        }
1374
1375        return 0;
1376}
1377
1378static int das1600_mode_detect(struct comedi_device *dev)
1379{
1380        int status = 0;
1381
1382        status = inb(dev->iobase + DAS1600_STATUS_B);
1383
1384        if (status & DAS1600_CLK_10MHZ) {
1385                devpriv->clockbase = 100;
1386                printk(KERN_INFO " 10MHz pacer clock\n");
1387        } else {
1388                devpriv->clockbase = 1000;
1389                printk(KERN_INFO " 1MHz pacer clock\n");
1390        }
1391
1392        reg_dump(dev);
1393
1394        return 0;
1395}
1396
1397/*
1398 *
1399 * Options list:
1400 *   0  I/O base
1401 *   1  IRQ
1402 *   2  DMA
1403 *   3  Clock speed (in MHz)
1404 */
1405
1406static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1407{
1408        struct comedi_subdevice *s;
1409        int ret;
1410        unsigned int irq;
1411        unsigned long iobase;
1412        unsigned int dma_chan;
1413        int timer_mode;
1414        unsigned long flags;
1415        struct comedi_krange *user_ai_range, *user_ao_range;
1416
1417        iobase = it->options[0];
1418#if 0
1419        irq = it->options[1];
1420        timer_mode = it->options[8];
1421#endif
1422        /* always use time_mode since using irq can drop samples while
1423         * waiting for dma done interrupt (due to hardware limitations) */
1424        irq = 0;
1425        timer_mode = 1;
1426        if (timer_mode)
1427                irq = 0;
1428
1429        printk(KERN_INFO "comedi%d: das16:", dev->minor);
1430
1431        /*  check that clock setting is valid */
1432        if (it->options[3]) {
1433                if (it->options[3] != 0 &&
1434                    it->options[3] != 1 && it->options[3] != 10) {
1435                        printk
1436                            ("\n Invalid option.  Master clock must be set "
1437                                                        "to 1 or 10 (MHz)\n");
1438                        return -EINVAL;
1439                }
1440        }
1441
1442        ret = alloc_private(dev, sizeof(struct das16_private_struct));
1443        if (ret < 0)
1444                return ret;
1445
1446        if (thisboard->size < 0x400) {
1447                printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size);
1448                if (!request_region(iobase, thisboard->size, "das16")) {
1449                        printk(KERN_ERR " I/O port conflict\n");
1450                        return -EIO;
1451                }
1452        } else {
1453                printk(KERN_INFO " 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
1454                       iobase, iobase + 0x0f,
1455                       iobase + 0x400,
1456                       iobase + 0x400 + (thisboard->size & 0x3ff));
1457                if (!request_region(iobase, 0x10, "das16")) {
1458                        printk(KERN_ERR " I/O port conflict:  0x%04lx-0x%04lx\n",
1459                               iobase, iobase + 0x0f);
1460                        return -EIO;
1461                }
1462                if (!request_region(iobase + 0x400, thisboard->size & 0x3ff,
1463                                    "das16")) {
1464                        release_region(iobase, 0x10);
1465                        printk(KERN_ERR " I/O port conflict:  0x%04lx-0x%04lx\n",
1466                               iobase + 0x400,
1467                               iobase + 0x400 + (thisboard->size & 0x3ff));
1468                        return -EIO;
1469                }
1470        }
1471
1472        dev->iobase = iobase;
1473
1474        /*  probe id bits to make sure they are consistent */
1475        if (das16_probe(dev, it)) {
1476                printk(KERN_ERR " id bits do not match selected board, aborting\n");
1477                return -EINVAL;
1478        }
1479        dev->board_name = thisboard->name;
1480
1481        /*  get master clock speed */
1482        if (thisboard->size < 0x400) {
1483                if (it->options[3])
1484                        devpriv->clockbase = 1000 / it->options[3];
1485                else
1486                        devpriv->clockbase = 1000;      /*  1 MHz default */
1487        } else {
1488                das1600_mode_detect(dev);
1489        }
1490
1491        /* now for the irq */
1492        if (irq > 1 && irq < 8) {
1493                ret = request_irq(irq, das16_dma_interrupt, 0, "das16", dev);
1494
1495                if (ret < 0)
1496                        return ret;
1497                dev->irq = irq;
1498                printk(KERN_INFO " ( irq = %u )", irq);
1499        } else if (irq == 0) {
1500                printk(" ( no irq )");
1501        } else {
1502                printk(" invalid irq\n");
1503                return -EINVAL;
1504        }
1505
1506        /*  initialize dma */
1507        dma_chan = it->options[2];
1508        if (dma_chan == 1 || dma_chan == 3) {
1509                /*  allocate dma buffers */
1510                int i;
1511                for (i = 0; i < 2; i++) {
1512                        devpriv->dma_buffer[i] = pci_alloc_consistent(
1513                                                NULL, DAS16_DMA_SIZE,
1514                                                &devpriv->dma_buffer_addr[i]);
1515
1516                        if (devpriv->dma_buffer[i] == NULL)
1517                                return -ENOMEM;
1518                }
1519                if (request_dma(dma_chan, "das16")) {
1520                        printk(KERN_ERR " failed to allocate dma channel %i\n",
1521                               dma_chan);
1522                        return -EINVAL;
1523                }
1524                devpriv->dma_chan = dma_chan;
1525                flags = claim_dma_lock();
1526                disable_dma(devpriv->dma_chan);
1527                set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
1528                release_dma_lock(flags);
1529                printk(KERN_INFO " ( dma = %u)\n", dma_chan);
1530        } else if (dma_chan == 0) {
1531                printk(KERN_INFO " ( no dma )\n");
1532        } else {
1533                printk(KERN_ERR " invalid dma channel\n");
1534                return -EINVAL;
1535        }
1536
1537        /*  get any user-defined input range */
1538        if (thisboard->ai_pg == das16_pg_none &&
1539            (it->options[4] || it->options[5])) {
1540                /*  allocate single-range range table */
1541                devpriv->user_ai_range_table =
1542                    kmalloc(sizeof(struct comedi_lrange) +
1543                            sizeof(struct comedi_krange), GFP_KERNEL);
1544                /*  initialize ai range */
1545                devpriv->user_ai_range_table->length = 1;
1546                user_ai_range = devpriv->user_ai_range_table->range;
1547                user_ai_range->min = it->options[4];
1548                user_ai_range->max = it->options[5];
1549                user_ai_range->flags = UNIT_volt;
1550        }
1551        /*  get any user-defined output range */
1552        if (it->options[6] || it->options[7]) {
1553                /*  allocate single-range range table */
1554                devpriv->user_ao_range_table =
1555                    kmalloc(sizeof(struct comedi_lrange) +
1556                            sizeof(struct comedi_krange), GFP_KERNEL);
1557                /*  initialize ao range */
1558                devpriv->user_ao_range_table->length = 1;
1559                user_ao_range = devpriv->user_ao_range_table->range;
1560                user_ao_range->min = it->options[6];
1561                user_ao_range->max = it->options[7];
1562                user_ao_range->flags = UNIT_volt;
1563        }
1564
1565        if (timer_mode) {
1566                init_timer(&(devpriv->timer));
1567                devpriv->timer.function = das16_timer_interrupt;
1568                devpriv->timer.data = (unsigned long)dev;
1569        }
1570        devpriv->timer_mode = timer_mode ? 1 : 0;
1571
1572        ret = alloc_subdevices(dev, 5);
1573        if (ret < 0)
1574                return ret;
1575
1576        s = dev->subdevices + 0;
1577        dev->read_subdev = s;
1578        /* ai */
1579        if (thisboard->ai) {
1580                s->type = COMEDI_SUBD_AI;
1581                s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1582                if (devpriv->ai_singleended) {
1583                        s->n_chan = 16;
1584                        s->len_chanlist = 16;
1585                        s->subdev_flags |= SDF_GROUND;
1586                } else {
1587                        s->n_chan = 8;
1588                        s->len_chanlist = 8;
1589                        s->subdev_flags |= SDF_DIFF;
1590                }
1591                s->maxdata = (1 << thisboard->ai_nbits) - 1;
1592                if (devpriv->user_ai_range_table) { /*  user defined ai range */
1593                        s->range_table = devpriv->user_ai_range_table;
1594                } else if (devpriv->ai_unipolar) {
1595                        s->range_table = das16_ai_uni_lranges[thisboard->ai_pg];
1596                } else {
1597                        s->range_table = das16_ai_bip_lranges[thisboard->ai_pg];
1598                }
1599                s->insn_read = thisboard->ai;
1600                s->do_cmdtest = das16_cmd_test;
1601                s->do_cmd = das16_cmd_exec;
1602                s->cancel = das16_cancel;
1603                s->munge = das16_ai_munge;
1604        } else {
1605                s->type = COMEDI_SUBD_UNUSED;
1606        }
1607
1608        s = dev->subdevices + 1;
1609        /* ao */
1610        if (thisboard->ao) {
1611                s->type = COMEDI_SUBD_AO;
1612                s->subdev_flags = SDF_WRITABLE;
1613                s->n_chan = 2;
1614                s->maxdata = (1 << thisboard->ao_nbits) - 1;
1615                /*  user defined ao range */
1616                if (devpriv->user_ao_range_table)
1617                        s->range_table = devpriv->user_ao_range_table;
1618                else
1619                        s->range_table = &range_unknown;
1620
1621                s->insn_write = thisboard->ao;
1622        } else {
1623                s->type = COMEDI_SUBD_UNUSED;
1624        }
1625
1626        s = dev->subdevices + 2;
1627        /* di */
1628        if (thisboard->di) {
1629                s->type = COMEDI_SUBD_DI;
1630                s->subdev_flags = SDF_READABLE;
1631                s->n_chan = 4;
1632                s->maxdata = 1;
1633                s->range_table = &range_digital;
1634                s->insn_bits = thisboard->di;
1635        } else {
1636                s->type = COMEDI_SUBD_UNUSED;
1637        }
1638
1639        s = dev->subdevices + 3;
1640        /* do */
1641        if (thisboard->do_) {
1642                s->type = COMEDI_SUBD_DO;
1643                s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1644                s->n_chan = 4;
1645                s->maxdata = 1;
1646                s->range_table = &range_digital;
1647                s->insn_bits = thisboard->do_;
1648                /*  initialize digital output lines */
1649                outb(s->state, dev->iobase + DAS16_DIO);
1650        } else {
1651                s->type = COMEDI_SUBD_UNUSED;
1652        }
1653
1654        s = dev->subdevices + 4;
1655        /* 8255 */
1656        if (thisboard->i8255_offset != 0) {
1657                subdev_8255_init(dev, s, NULL, (dev->iobase +
1658                                                thisboard->i8255_offset));
1659        } else {
1660                s->type = COMEDI_SUBD_UNUSED;
1661        }
1662
1663        das16_reset(dev);
1664        /* set the interrupt level */
1665        devpriv->control_state = DAS16_IRQ(dev->irq);
1666        outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1667
1668        /*  turn on das1600 mode if available */
1669        if (thisboard->size > 0x400) {
1670                outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE);
1671                outb(0, dev->iobase + DAS1600_CONV);
1672                outb(0, dev->iobase + DAS1600_BURST);
1673        }
1674
1675        return 0;
1676}
1677
1678static int das16_detach(struct comedi_device *dev)
1679{
1680        printk(KERN_INFO "comedi%d: das16: remove\n", dev->minor);
1681
1682        das16_reset(dev);
1683
1684        if (dev->subdevices)
1685                subdev_8255_cleanup(dev, dev->subdevices + 4);
1686
1687        if (devpriv) {
1688                int i;
1689                for (i = 0; i < 2; i++) {
1690                        if (devpriv->dma_buffer[i])
1691                                pci_free_consistent(NULL, DAS16_DMA_SIZE,
1692                                                    devpriv->dma_buffer[i],
1693                                                    devpriv->
1694                                                    dma_buffer_addr[i]);
1695                }
1696                if (devpriv->dma_chan)
1697                        free_dma(devpriv->dma_chan);
1698                kfree(devpriv->user_ai_range_table);
1699                kfree(devpriv->user_ao_range_table);
1700        }
1701
1702        if (dev->irq)
1703                free_irq(dev->irq, dev);
1704
1705        if (dev->iobase) {
1706                if (thisboard->size < 0x400) {
1707                        release_region(dev->iobase, thisboard->size);
1708                } else {
1709                        release_region(dev->iobase, 0x10);
1710                        release_region(dev->iobase + 0x400,
1711                                       thisboard->size & 0x3ff);
1712                }
1713        }
1714
1715        return 0;
1716}
1717
1718static int __init driver_das16_init_module(void)
1719{
1720        return comedi_driver_register(&driver_das16);
1721}
1722
1723static void __exit driver_das16_cleanup_module(void)
1724{
1725        comedi_driver_unregister(&driver_das16);
1726}
1727
1728module_init(driver_das16_init_module);
1729module_exit(driver_das16_cleanup_module);
1730
1731/* utility function that suggests a dma transfer size in bytes */
1732static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
1733                                                struct comedi_cmd cmd)
1734{
1735        unsigned int size;
1736        unsigned int freq;
1737
1738        /* if we are using timer interrupt, we don't care how long it
1739         * will take to complete transfer since it will be interrupted
1740         * by timer interrupt */
1741        if (devpriv->timer_mode)
1742                return DAS16_DMA_SIZE;
1743
1744        /* otherwise, we are relying on dma terminal count interrupt,
1745         * so pick a reasonable size */
1746        if (cmd.convert_src == TRIG_TIMER)
1747                freq = 1000000000 / cmd.convert_arg;
1748        else if (cmd.scan_begin_src == TRIG_TIMER)
1749                freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len;
1750        /*  return some default value */
1751        else
1752                freq = 0xffffffff;
1753
1754        if (cmd.flags & TRIG_WAKE_EOS) {
1755                size = sample_size * cmd.chanlist_len;
1756        } else {
1757                /*  make buffer fill in no more than 1/3 second */
1758                size = (freq / 3) * sample_size;
1759        }
1760
1761        /*  set a minimum and maximum size allowed */
1762        if (size > DAS16_DMA_SIZE)
1763                size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size;
1764        else if (size < sample_size)
1765                size = sample_size;
1766
1767        if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
1768                size = devpriv->adc_byte_count;
1769
1770        return size;
1771}
1772
1773static void das16_ai_munge(struct comedi_device *dev,
1774                           struct comedi_subdevice *s, void *array,
1775                           unsigned int num_bytes,
1776                           unsigned int start_chan_index)
1777{
1778        unsigned int i, num_samples = num_bytes / sizeof(short);
1779        short *data = array;
1780
1781        for (i = 0; i < num_samples; i++) {
1782                data[i] = le16_to_cpu(data[i]);
1783                if (thisboard->ai_nbits == 12)
1784                        data[i] = (data[i] >> 4) & 0xfff;
1785
1786        }
1787}
1788
1789MODULE_AUTHOR("Comedi http://www.comedi.org");
1790MODULE_DESCRIPTION("Comedi low-level driver");
1791MODULE_LICENSE("GPL");
1792
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.