root/drivers/staging/comedi/drivers/ni_labpc_common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. labpc_inb
  2. labpc_outb
  3. labpc_readb
  4. labpc_writeb
  5. labpc_cancel
  6. labpc_ai_set_chan_and_gain
  7. labpc_setup_cmd6_reg
  8. labpc_read_adc_fifo
  9. labpc_clear_adc_fifo
  10. labpc_ai_eoc
  11. labpc_ai_insn_read
  12. labpc_use_continuous_mode
  13. labpc_ai_convert_period
  14. labpc_set_ai_convert_period
  15. labpc_ai_scan_period
  16. labpc_set_ai_scan_period
  17. labpc_adc_timing
  18. labpc_ai_scan_mode
  19. labpc_ai_check_chanlist
  20. labpc_ai_cmdtest
  21. labpc_ai_cmd
  22. labpc_drain_fifo
  23. labpc_drain_dregs
  24. labpc_interrupt
  25. labpc_ao_write
  26. labpc_ao_insn_write
  27. labpc_serial_out
  28. labpc_serial_in
  29. labpc_eeprom_read
  30. labpc_eeprom_read_status
  31. labpc_eeprom_write
  32. write_caldac
  33. labpc_calib_insn_write
  34. labpc_eeprom_ready
  35. labpc_eeprom_insn_write
  36. labpc_common_attach
  37. labpc_common_detach
  38. labpc_common_init
  39. labpc_common_exit

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * comedi/drivers/ni_labpc_common.c
   4  *
   5  * Common support code for "ni_labpc", "ni_labpc_pci" and "ni_labpc_cs".
   6  *
   7  * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net>
   8  */
   9 
  10 #include <linux/module.h>
  11 #include <linux/interrupt.h>
  12 #include <linux/io.h>
  13 #include <linux/delay.h>
  14 #include <linux/slab.h>
  15 
  16 #include "../comedidev.h"
  17 
  18 #include "comedi_8254.h"
  19 #include "8255.h"
  20 #include "ni_labpc.h"
  21 #include "ni_labpc_regs.h"
  22 #include "ni_labpc_isadma.h"
  23 
  24 enum scan_mode {
  25         MODE_SINGLE_CHAN,
  26         MODE_SINGLE_CHAN_INTERVAL,
  27         MODE_MULT_CHAN_UP,
  28         MODE_MULT_CHAN_DOWN,
  29 };
  30 
  31 static const struct comedi_lrange range_labpc_plus_ai = {
  32         16, {
  33                 BIP_RANGE(5),
  34                 BIP_RANGE(4),
  35                 BIP_RANGE(2.5),
  36                 BIP_RANGE(1),
  37                 BIP_RANGE(0.5),
  38                 BIP_RANGE(0.25),
  39                 BIP_RANGE(0.1),
  40                 BIP_RANGE(0.05),
  41                 UNI_RANGE(10),
  42                 UNI_RANGE(8),
  43                 UNI_RANGE(5),
  44                 UNI_RANGE(2),
  45                 UNI_RANGE(1),
  46                 UNI_RANGE(0.5),
  47                 UNI_RANGE(0.2),
  48                 UNI_RANGE(0.1)
  49         }
  50 };
  51 
  52 static const struct comedi_lrange range_labpc_1200_ai = {
  53         14, {
  54                 BIP_RANGE(5),
  55                 BIP_RANGE(2.5),
  56                 BIP_RANGE(1),
  57                 BIP_RANGE(0.5),
  58                 BIP_RANGE(0.25),
  59                 BIP_RANGE(0.1),
  60                 BIP_RANGE(0.05),
  61                 UNI_RANGE(10),
  62                 UNI_RANGE(5),
  63                 UNI_RANGE(2),
  64                 UNI_RANGE(1),
  65                 UNI_RANGE(0.5),
  66                 UNI_RANGE(0.2),
  67                 UNI_RANGE(0.1)
  68         }
  69 };
  70 
  71 static const struct comedi_lrange range_labpc_ao = {
  72         2, {
  73                 BIP_RANGE(5),
  74                 UNI_RANGE(10)
  75         }
  76 };
  77 
  78 /*
  79  * functions that do inb/outb and readb/writeb so we can use
  80  * function pointers to decide which to use
  81  */
  82 static unsigned int labpc_inb(struct comedi_device *dev, unsigned long reg)
  83 {
  84         return inb(dev->iobase + reg);
  85 }
  86 
  87 static void labpc_outb(struct comedi_device *dev,
  88                        unsigned int byte, unsigned long reg)
  89 {
  90         outb(byte, dev->iobase + reg);
  91 }
  92 
  93 static unsigned int labpc_readb(struct comedi_device *dev, unsigned long reg)
  94 {
  95         return readb(dev->mmio + reg);
  96 }
  97 
  98 static void labpc_writeb(struct comedi_device *dev,
  99                          unsigned int byte, unsigned long reg)
 100 {
 101         writeb(byte, dev->mmio + reg);
 102 }
 103 
 104 static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 105 {
 106         struct labpc_private *devpriv = dev->private;
 107         unsigned long flags;
 108 
 109         spin_lock_irqsave(&dev->spinlock, flags);
 110         devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
 111         devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
 112         spin_unlock_irqrestore(&dev->spinlock, flags);
 113 
 114         devpriv->cmd3 = 0;
 115         devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
 116 
 117         return 0;
 118 }
 119 
 120 static void labpc_ai_set_chan_and_gain(struct comedi_device *dev,
 121                                        enum scan_mode mode,
 122                                        unsigned int chan,
 123                                        unsigned int range,
 124                                        unsigned int aref)
 125 {
 126         const struct labpc_boardinfo *board = dev->board_ptr;
 127         struct labpc_private *devpriv = dev->private;
 128 
 129         if (board->is_labpc1200) {
 130                 /*
 131                  * The LabPC-1200 boards do not have a gain
 132                  * of '0x10'. Skip the range values that would
 133                  * result in this gain.
 134                  */
 135                 range += (range > 0) + (range > 7);
 136         }
 137 
 138         /* munge channel bits for differential/scan disabled mode */
 139         if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) &&
 140             aref == AREF_DIFF)
 141                 chan *= 2;
 142         devpriv->cmd1 = CMD1_MA(chan);
 143         devpriv->cmd1 |= CMD1_GAIN(range);
 144 
 145         devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
 146 }
 147 
 148 static void labpc_setup_cmd6_reg(struct comedi_device *dev,
 149                                  struct comedi_subdevice *s,
 150                                  enum scan_mode mode,
 151                                  enum transfer_type xfer,
 152                                  unsigned int range,
 153                                  unsigned int aref,
 154                                  bool ena_intr)
 155 {
 156         const struct labpc_boardinfo *board = dev->board_ptr;
 157         struct labpc_private *devpriv = dev->private;
 158 
 159         if (!board->is_labpc1200)
 160                 return;
 161 
 162         /* reference inputs to ground or common? */
 163         if (aref != AREF_GROUND)
 164                 devpriv->cmd6 |= CMD6_NRSE;
 165         else
 166                 devpriv->cmd6 &= ~CMD6_NRSE;
 167 
 168         /* bipolar or unipolar range? */
 169         if (comedi_range_is_unipolar(s, range))
 170                 devpriv->cmd6 |= CMD6_ADCUNI;
 171         else
 172                 devpriv->cmd6 &= ~CMD6_ADCUNI;
 173 
 174         /*  interrupt on fifo half full? */
 175         if (xfer == fifo_half_full_transfer)
 176                 devpriv->cmd6 |= CMD6_HFINTEN;
 177         else
 178                 devpriv->cmd6 &= ~CMD6_HFINTEN;
 179 
 180         /* enable interrupt on counter a1 terminal count? */
 181         if (ena_intr)
 182                 devpriv->cmd6 |= CMD6_DQINTEN;
 183         else
 184                 devpriv->cmd6 &= ~CMD6_DQINTEN;
 185 
 186         /* are we scanning up or down through channels? */
 187         if (mode == MODE_MULT_CHAN_UP)
 188                 devpriv->cmd6 |= CMD6_SCANUP;
 189         else
 190                 devpriv->cmd6 &= ~CMD6_SCANUP;
 191 
 192         devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
 193 }
 194 
 195 static unsigned int labpc_read_adc_fifo(struct comedi_device *dev)
 196 {
 197         struct labpc_private *devpriv = dev->private;
 198         unsigned int lsb = devpriv->read_byte(dev, ADC_FIFO_REG);
 199         unsigned int msb = devpriv->read_byte(dev, ADC_FIFO_REG);
 200 
 201         return (msb << 8) | lsb;
 202 }
 203 
 204 static void labpc_clear_adc_fifo(struct comedi_device *dev)
 205 {
 206         struct labpc_private *devpriv = dev->private;
 207 
 208         devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
 209         labpc_read_adc_fifo(dev);
 210 }
 211 
 212 static int labpc_ai_eoc(struct comedi_device *dev,
 213                         struct comedi_subdevice *s,
 214                         struct comedi_insn *insn,
 215                         unsigned long context)
 216 {
 217         struct labpc_private *devpriv = dev->private;
 218 
 219         devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
 220         if (devpriv->stat1 & STAT1_DAVAIL)
 221                 return 0;
 222         return -EBUSY;
 223 }
 224 
 225 static int labpc_ai_insn_read(struct comedi_device *dev,
 226                               struct comedi_subdevice *s,
 227                               struct comedi_insn *insn,
 228                               unsigned int *data)
 229 {
 230         struct labpc_private *devpriv = dev->private;
 231         unsigned int chan = CR_CHAN(insn->chanspec);
 232         unsigned int range = CR_RANGE(insn->chanspec);
 233         unsigned int aref = CR_AREF(insn->chanspec);
 234         int ret;
 235         int i;
 236 
 237         /* disable timed conversions, interrupt generation and dma */
 238         labpc_cancel(dev, s);
 239 
 240         labpc_ai_set_chan_and_gain(dev, MODE_SINGLE_CHAN, chan, range, aref);
 241 
 242         labpc_setup_cmd6_reg(dev, s, MODE_SINGLE_CHAN, fifo_not_empty_transfer,
 243                              range, aref, false);
 244 
 245         /* setup cmd4 register */
 246         devpriv->cmd4 = 0;
 247         devpriv->cmd4 |= CMD4_ECLKRCV;
 248         /* single-ended/differential */
 249         if (aref == AREF_DIFF)
 250                 devpriv->cmd4 |= CMD4_SEDIFF;
 251         devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
 252 
 253         /* initialize pacer counter to prevent any problems */
 254         comedi_8254_set_mode(devpriv->counter, 0, I8254_MODE2 | I8254_BINARY);
 255 
 256         labpc_clear_adc_fifo(dev);
 257 
 258         for (i = 0; i < insn->n; i++) {
 259                 /* trigger conversion */
 260                 devpriv->write_byte(dev, 0x1, ADC_START_CONVERT_REG);
 261 
 262                 ret = comedi_timeout(dev, s, insn, labpc_ai_eoc, 0);
 263                 if (ret)
 264                         return ret;
 265 
 266                 data[i] = labpc_read_adc_fifo(dev);
 267         }
 268 
 269         return insn->n;
 270 }
 271 
 272 static bool labpc_use_continuous_mode(const struct comedi_cmd *cmd,
 273                                       enum scan_mode mode)
 274 {
 275         if (mode == MODE_SINGLE_CHAN || cmd->scan_begin_src == TRIG_FOLLOW)
 276                 return true;
 277 
 278         return false;
 279 }
 280 
 281 static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd,
 282                                             enum scan_mode mode)
 283 {
 284         if (cmd->convert_src != TRIG_TIMER)
 285                 return 0;
 286 
 287         if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER)
 288                 return cmd->scan_begin_arg;
 289 
 290         return cmd->convert_arg;
 291 }
 292 
 293 static void labpc_set_ai_convert_period(struct comedi_cmd *cmd,
 294                                         enum scan_mode mode, unsigned int ns)
 295 {
 296         if (cmd->convert_src != TRIG_TIMER)
 297                 return;
 298 
 299         if (mode == MODE_SINGLE_CHAN &&
 300             cmd->scan_begin_src == TRIG_TIMER) {
 301                 cmd->scan_begin_arg = ns;
 302                 if (cmd->convert_arg > cmd->scan_begin_arg)
 303                         cmd->convert_arg = cmd->scan_begin_arg;
 304         } else {
 305                 cmd->convert_arg = ns;
 306         }
 307 }
 308 
 309 static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd,
 310                                          enum scan_mode mode)
 311 {
 312         if (cmd->scan_begin_src != TRIG_TIMER)
 313                 return 0;
 314 
 315         if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
 316                 return 0;
 317 
 318         return cmd->scan_begin_arg;
 319 }
 320 
 321 static void labpc_set_ai_scan_period(struct comedi_cmd *cmd,
 322                                      enum scan_mode mode, unsigned int ns)
 323 {
 324         if (cmd->scan_begin_src != TRIG_TIMER)
 325                 return;
 326 
 327         if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
 328                 return;
 329 
 330         cmd->scan_begin_arg = ns;
 331 }
 332 
 333 /* figures out what counter values to use based on command */
 334 static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
 335                              enum scan_mode mode)
 336 {
 337         struct comedi_8254 *pacer = dev->pacer;
 338         unsigned int convert_period = labpc_ai_convert_period(cmd, mode);
 339         unsigned int scan_period = labpc_ai_scan_period(cmd, mode);
 340         unsigned int base_period;
 341 
 342         /*
 343          * If both convert and scan triggers are TRIG_TIMER, then they
 344          * both rely on counter b0. If only one TRIG_TIMER is used, we
 345          * can use the generic cascaded timing functions.
 346          */
 347         if (convert_period && scan_period) {
 348                 /*
 349                  * pick the lowest divisor value we can (for maximum input
 350                  * clock speed on convert and scan counters)
 351                  */
 352                 pacer->next_div1 = (scan_period - 1) /
 353                                    (pacer->osc_base * I8254_MAX_COUNT) + 1;
 354 
 355                 comedi_check_trigger_arg_min(&pacer->next_div1, 2);
 356                 comedi_check_trigger_arg_max(&pacer->next_div1,
 357                                              I8254_MAX_COUNT);
 358 
 359                 base_period = pacer->osc_base * pacer->next_div1;
 360 
 361                 /*  set a0 for conversion frequency and b1 for scan frequency */
 362                 switch (cmd->flags & CMDF_ROUND_MASK) {
 363                 default:
 364                 case CMDF_ROUND_NEAREST:
 365                         pacer->next_div = DIV_ROUND_CLOSEST(convert_period,
 366                                                             base_period);
 367                         pacer->next_div2 = DIV_ROUND_CLOSEST(scan_period,
 368                                                              base_period);
 369                         break;
 370                 case CMDF_ROUND_UP:
 371                         pacer->next_div = DIV_ROUND_UP(convert_period,
 372                                                        base_period);
 373                         pacer->next_div2 = DIV_ROUND_UP(scan_period,
 374                                                         base_period);
 375                         break;
 376                 case CMDF_ROUND_DOWN:
 377                         pacer->next_div = convert_period / base_period;
 378                         pacer->next_div2 = scan_period / base_period;
 379                         break;
 380                 }
 381                 /*  make sure a0 and b1 values are acceptable */
 382                 comedi_check_trigger_arg_min(&pacer->next_div, 2);
 383                 comedi_check_trigger_arg_max(&pacer->next_div, I8254_MAX_COUNT);
 384                 comedi_check_trigger_arg_min(&pacer->next_div2, 2);
 385                 comedi_check_trigger_arg_max(&pacer->next_div2,
 386                                              I8254_MAX_COUNT);
 387 
 388                 /*  write corrected timings to command */
 389                 labpc_set_ai_convert_period(cmd, mode,
 390                                             base_period * pacer->next_div);
 391                 labpc_set_ai_scan_period(cmd, mode,
 392                                          base_period * pacer->next_div2);
 393         } else if (scan_period) {
 394                 /*
 395                  * calculate cascaded counter values
 396                  * that give desired scan timing
 397                  * (pacer->next_div2 / pacer->next_div1)
 398                  */
 399                 comedi_8254_cascade_ns_to_timer(pacer, &scan_period,
 400                                                 cmd->flags);
 401                 labpc_set_ai_scan_period(cmd, mode, scan_period);
 402         } else if (convert_period) {
 403                 /*
 404                  * calculate cascaded counter values
 405                  * that give desired conversion timing
 406                  * (pacer->next_div / pacer->next_div1)
 407                  */
 408                 comedi_8254_cascade_ns_to_timer(pacer, &convert_period,
 409                                                 cmd->flags);
 410                 /* transfer div2 value so correct timer gets updated */
 411                 pacer->next_div = pacer->next_div2;
 412                 labpc_set_ai_convert_period(cmd, mode, convert_period);
 413         }
 414 }
 415 
 416 static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
 417 {
 418         unsigned int chan0;
 419         unsigned int chan1;
 420 
 421         if (cmd->chanlist_len == 1)
 422                 return MODE_SINGLE_CHAN;
 423 
 424         /* chanlist may be NULL during cmdtest */
 425         if (!cmd->chanlist)
 426                 return MODE_MULT_CHAN_UP;
 427 
 428         chan0 = CR_CHAN(cmd->chanlist[0]);
 429         chan1 = CR_CHAN(cmd->chanlist[1]);
 430 
 431         if (chan0 < chan1)
 432                 return MODE_MULT_CHAN_UP;
 433 
 434         if (chan0 > chan1)
 435                 return MODE_MULT_CHAN_DOWN;
 436 
 437         return MODE_SINGLE_CHAN_INTERVAL;
 438 }
 439 
 440 static int labpc_ai_check_chanlist(struct comedi_device *dev,
 441                                    struct comedi_subdevice *s,
 442                                    struct comedi_cmd *cmd)
 443 {
 444         enum scan_mode mode = labpc_ai_scan_mode(cmd);
 445         unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
 446         unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
 447         unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
 448         int i;
 449 
 450         for (i = 0; i < cmd->chanlist_len; i++) {
 451                 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
 452                 unsigned int range = CR_RANGE(cmd->chanlist[i]);
 453                 unsigned int aref = CR_AREF(cmd->chanlist[i]);
 454 
 455                 switch (mode) {
 456                 case MODE_SINGLE_CHAN:
 457                         break;
 458                 case MODE_SINGLE_CHAN_INTERVAL:
 459                         if (chan != chan0) {
 460                                 dev_dbg(dev->class_dev,
 461                                         "channel scanning order specified in chanlist is not supported by hardware\n");
 462                                 return -EINVAL;
 463                         }
 464                         break;
 465                 case MODE_MULT_CHAN_UP:
 466                         if (chan != i) {
 467                                 dev_dbg(dev->class_dev,
 468                                         "channel scanning order specified in chanlist is not supported by hardware\n");
 469                                 return -EINVAL;
 470                         }
 471                         break;
 472                 case MODE_MULT_CHAN_DOWN:
 473                         if (chan != (cmd->chanlist_len - i - 1)) {
 474                                 dev_dbg(dev->class_dev,
 475                                         "channel scanning order specified in chanlist is not supported by hardware\n");
 476                                 return -EINVAL;
 477                         }
 478                         break;
 479                 }
 480 
 481                 if (range != range0) {
 482                         dev_dbg(dev->class_dev,
 483                                 "entries in chanlist must all have the same range\n");
 484                         return -EINVAL;
 485                 }
 486 
 487                 if (aref != aref0) {
 488                         dev_dbg(dev->class_dev,
 489                                 "entries in chanlist must all have the same reference\n");
 490                         return -EINVAL;
 491                 }
 492         }
 493 
 494         return 0;
 495 }
 496 
 497 static int labpc_ai_cmdtest(struct comedi_device *dev,
 498                             struct comedi_subdevice *s, struct comedi_cmd *cmd)
 499 {
 500         const struct labpc_boardinfo *board = dev->board_ptr;
 501         int err = 0;
 502         int tmp, tmp2;
 503         unsigned int stop_mask;
 504         enum scan_mode mode;
 505 
 506         /* Step 1 : check if triggers are trivially valid */
 507 
 508         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
 509         err |= comedi_check_trigger_src(&cmd->scan_begin_src,
 510                                         TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
 511         err |= comedi_check_trigger_src(&cmd->convert_src,
 512                                         TRIG_TIMER | TRIG_EXT);
 513         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 514 
 515         stop_mask = TRIG_COUNT | TRIG_NONE;
 516         if (board->is_labpc1200)
 517                 stop_mask |= TRIG_EXT;
 518         err |= comedi_check_trigger_src(&cmd->stop_src, stop_mask);
 519 
 520         if (err)
 521                 return 1;
 522 
 523         /* Step 2a : make sure trigger sources are unique */
 524 
 525         err |= comedi_check_trigger_is_unique(cmd->start_src);
 526         err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
 527         err |= comedi_check_trigger_is_unique(cmd->convert_src);
 528         err |= comedi_check_trigger_is_unique(cmd->stop_src);
 529 
 530         /* Step 2b : and mutually compatible */
 531 
 532         /* can't have external stop and start triggers at once */
 533         if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
 534                 err++;
 535 
 536         if (err)
 537                 return 2;
 538 
 539         /* Step 3: check if arguments are trivially valid */
 540 
 541         switch (cmd->start_src) {
 542         case TRIG_NOW:
 543                 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
 544                 break;
 545         case TRIG_EXT:
 546                 /* start_arg value is ignored */
 547                 break;
 548         }
 549 
 550         if (!cmd->chanlist_len)
 551                 err |= -EINVAL;
 552         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
 553                                            cmd->chanlist_len);
 554 
 555         if (cmd->convert_src == TRIG_TIMER) {
 556                 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
 557                                                     board->ai_speed);
 558         }
 559 
 560         /* make sure scan timing is not too fast */
 561         if (cmd->scan_begin_src == TRIG_TIMER) {
 562                 if (cmd->convert_src == TRIG_TIMER) {
 563                         err |= comedi_check_trigger_arg_min(&cmd->
 564                                                             scan_begin_arg,
 565                                                             cmd->convert_arg *
 566                                                             cmd->chanlist_len);
 567                 }
 568                 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
 569                                                     board->ai_speed *
 570                                                     cmd->chanlist_len);
 571         }
 572 
 573         switch (cmd->stop_src) {
 574         case TRIG_COUNT:
 575                 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
 576                 break;
 577         case TRIG_NONE:
 578                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
 579                 break;
 580                 /*
 581                  * TRIG_EXT doesn't care since it doesn't
 582                  * trigger off a numbered channel
 583                  */
 584         default:
 585                 break;
 586         }
 587 
 588         if (err)
 589                 return 3;
 590 
 591         /* step 4: fix up any arguments */
 592 
 593         tmp = cmd->convert_arg;
 594         tmp2 = cmd->scan_begin_arg;
 595         mode = labpc_ai_scan_mode(cmd);
 596         labpc_adc_timing(dev, cmd, mode);
 597         if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
 598                 err++;
 599 
 600         if (err)
 601                 return 4;
 602 
 603         /* Step 5: check channel list if it exists */
 604         if (cmd->chanlist && cmd->chanlist_len > 0)
 605                 err |= labpc_ai_check_chanlist(dev, s, cmd);
 606 
 607         if (err)
 608                 return 5;
 609 
 610         return 0;
 611 }
 612 
 613 static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 614 {
 615         const struct labpc_boardinfo *board = dev->board_ptr;
 616         struct labpc_private *devpriv = dev->private;
 617         struct comedi_async *async = s->async;
 618         struct comedi_cmd *cmd = &async->cmd;
 619         enum scan_mode mode = labpc_ai_scan_mode(cmd);
 620         unsigned int chanspec = (mode == MODE_MULT_CHAN_UP) ?
 621                                 cmd->chanlist[cmd->chanlist_len - 1] :
 622                                 cmd->chanlist[0];
 623         unsigned int chan = CR_CHAN(chanspec);
 624         unsigned int range = CR_RANGE(chanspec);
 625         unsigned int aref = CR_AREF(chanspec);
 626         enum transfer_type xfer;
 627         unsigned long flags;
 628 
 629         /* make sure board is disabled before setting up acquisition */
 630         labpc_cancel(dev, s);
 631 
 632         /*  initialize software conversion count */
 633         if (cmd->stop_src == TRIG_COUNT)
 634                 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
 635 
 636         /*  setup hardware conversion counter */
 637         if (cmd->stop_src == TRIG_EXT) {
 638                 /*
 639                  * load counter a1 with count of 3
 640                  * (pc+ manual says this is minimum allowed) using mode 0
 641                  */
 642                 comedi_8254_load(devpriv->counter, 1,
 643                                  3, I8254_MODE0 | I8254_BINARY);
 644         } else  {
 645                 /* just put counter a1 in mode 0 to set its output low */
 646                 comedi_8254_set_mode(devpriv->counter, 1,
 647                                      I8254_MODE0 | I8254_BINARY);
 648         }
 649 
 650         /* figure out what method we will use to transfer data */
 651         if (devpriv->dma &&
 652             (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0) {
 653                 /*
 654                  * dma unsafe at RT priority,
 655                  * and too much setup time for CMDF_WAKE_EOS
 656                  */
 657                 xfer = isa_dma_transfer;
 658         } else if (board->is_labpc1200 &&
 659                    (cmd->flags & CMDF_WAKE_EOS) == 0 &&
 660                    (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) {
 661                 /*
 662                  * pc-plus has no fifo-half full interrupt
 663                  * wake-end-of-scan should interrupt on fifo not empty
 664                  * make sure we are taking more than just a few points
 665                  */
 666                 xfer = fifo_half_full_transfer;
 667         } else {
 668                 xfer = fifo_not_empty_transfer;
 669         }
 670         devpriv->current_transfer = xfer;
 671 
 672         labpc_ai_set_chan_and_gain(dev, mode, chan, range, aref);
 673 
 674         labpc_setup_cmd6_reg(dev, s, mode, xfer, range, aref,
 675                              (cmd->stop_src == TRIG_EXT));
 676 
 677         /* manual says to set scan enable bit on second pass */
 678         if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) {
 679                 devpriv->cmd1 |= CMD1_SCANEN;
 680                 /*
 681                  * Need a brief delay before enabling scan, or scan
 682                  * list will get screwed when you switch between
 683                  * scan up to scan down mode - dunno why.
 684                  */
 685                 udelay(1);
 686                 devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
 687         }
 688 
 689         devpriv->write_byte(dev, cmd->chanlist_len, INTERVAL_COUNT_REG);
 690         /*  load count */
 691         devpriv->write_byte(dev, 0x1, INTERVAL_STROBE_REG);
 692 
 693         if (cmd->convert_src == TRIG_TIMER ||
 694             cmd->scan_begin_src == TRIG_TIMER) {
 695                 struct comedi_8254 *pacer = dev->pacer;
 696                 struct comedi_8254 *counter = devpriv->counter;
 697 
 698                 comedi_8254_update_divisors(pacer);
 699 
 700                 /* set up pacing */
 701                 comedi_8254_load(pacer, 0, pacer->divisor1,
 702                                  I8254_MODE3 | I8254_BINARY);
 703 
 704                 /* set up conversion pacing */
 705                 comedi_8254_set_mode(counter, 0, I8254_MODE2 | I8254_BINARY);
 706                 if (labpc_ai_convert_period(cmd, mode))
 707                         comedi_8254_write(counter, 0, pacer->divisor);
 708 
 709                 /* set up scan pacing */
 710                 if (labpc_ai_scan_period(cmd, mode))
 711                         comedi_8254_load(pacer, 1, pacer->divisor2,
 712                                          I8254_MODE2 | I8254_BINARY);
 713         }
 714 
 715         labpc_clear_adc_fifo(dev);
 716 
 717         if (xfer == isa_dma_transfer)
 718                 labpc_setup_dma(dev, s);
 719 
 720         /*  enable error interrupts */
 721         devpriv->cmd3 |= CMD3_ERRINTEN;
 722         /*  enable fifo not empty interrupt? */
 723         if (xfer == fifo_not_empty_transfer)
 724                 devpriv->cmd3 |= CMD3_FIFOINTEN;
 725         devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
 726 
 727         /*  setup any external triggering/pacing (cmd4 register) */
 728         devpriv->cmd4 = 0;
 729         if (cmd->convert_src != TRIG_EXT)
 730                 devpriv->cmd4 |= CMD4_ECLKRCV;
 731         /*
 732          * XXX should discard first scan when using interval scanning
 733          * since manual says it is not synced with scan clock.
 734          */
 735         if (!labpc_use_continuous_mode(cmd, mode)) {
 736                 devpriv->cmd4 |= CMD4_INTSCAN;
 737                 if (cmd->scan_begin_src == TRIG_EXT)
 738                         devpriv->cmd4 |= CMD4_EOIRCV;
 739         }
 740         /*  single-ended/differential */
 741         if (aref == AREF_DIFF)
 742                 devpriv->cmd4 |= CMD4_SEDIFF;
 743         devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
 744 
 745         /*  startup acquisition */
 746 
 747         spin_lock_irqsave(&dev->spinlock, flags);
 748 
 749         /* use 2 cascaded counters for pacing */
 750         devpriv->cmd2 |= CMD2_TBSEL;
 751 
 752         devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
 753         if (cmd->start_src == TRIG_EXT)
 754                 devpriv->cmd2 |= CMD2_HWTRIG;
 755         else
 756                 devpriv->cmd2 |= CMD2_SWTRIG;
 757         if (cmd->stop_src == TRIG_EXT)
 758                 devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG);
 759 
 760         devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
 761 
 762         spin_unlock_irqrestore(&dev->spinlock, flags);
 763 
 764         return 0;
 765 }
 766 
 767 /* read all available samples from ai fifo */
 768 static int labpc_drain_fifo(struct comedi_device *dev)
 769 {
 770         struct labpc_private *devpriv = dev->private;
 771         struct comedi_async *async = dev->read_subdev->async;
 772         struct comedi_cmd *cmd = &async->cmd;
 773         unsigned short data;
 774         const int timeout = 10000;
 775         unsigned int i;
 776 
 777         devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
 778 
 779         for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout;
 780              i++) {
 781                 /*  quit if we have all the data we want */
 782                 if (cmd->stop_src == TRIG_COUNT) {
 783                         if (devpriv->count == 0)
 784                                 break;
 785                         devpriv->count--;
 786                 }
 787                 data = labpc_read_adc_fifo(dev);
 788                 comedi_buf_write_samples(dev->read_subdev, &data, 1);
 789                 devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
 790         }
 791         if (i == timeout) {
 792                 dev_err(dev->class_dev, "ai timeout, fifo never empties\n");
 793                 async->events |= COMEDI_CB_ERROR;
 794                 return -1;
 795         }
 796 
 797         return 0;
 798 }
 799 
 800 /*
 801  * Makes sure all data acquired by board is transferred to comedi (used
 802  * when acquisition is terminated by stop_src == TRIG_EXT).
 803  */
 804 static void labpc_drain_dregs(struct comedi_device *dev)
 805 {
 806         struct labpc_private *devpriv = dev->private;
 807 
 808         if (devpriv->current_transfer == isa_dma_transfer)
 809                 labpc_drain_dma(dev);
 810 
 811         labpc_drain_fifo(dev);
 812 }
 813 
 814 /* interrupt service routine */
 815 static irqreturn_t labpc_interrupt(int irq, void *d)
 816 {
 817         struct comedi_device *dev = d;
 818         const struct labpc_boardinfo *board = dev->board_ptr;
 819         struct labpc_private *devpriv = dev->private;
 820         struct comedi_subdevice *s = dev->read_subdev;
 821         struct comedi_async *async;
 822         struct comedi_cmd *cmd;
 823 
 824         if (!dev->attached) {
 825                 dev_err(dev->class_dev, "premature interrupt\n");
 826                 return IRQ_HANDLED;
 827         }
 828 
 829         async = s->async;
 830         cmd = &async->cmd;
 831 
 832         /* read board status */
 833         devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
 834         if (board->is_labpc1200)
 835                 devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
 836 
 837         if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
 838                                STAT1_OVERRUN | STAT1_DAVAIL)) == 0 &&
 839             (devpriv->stat2 & STAT2_OUTA1) == 0 &&
 840             (devpriv->stat2 & STAT2_FIFONHF)) {
 841                 return IRQ_NONE;
 842         }
 843 
 844         if (devpriv->stat1 & STAT1_OVERRUN) {
 845                 /* clear error interrupt */
 846                 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
 847                 async->events |= COMEDI_CB_ERROR;
 848                 comedi_handle_events(dev, s);
 849                 dev_err(dev->class_dev, "overrun\n");
 850                 return IRQ_HANDLED;
 851         }
 852 
 853         if (devpriv->current_transfer == isa_dma_transfer)
 854                 labpc_handle_dma_status(dev);
 855         else
 856                 labpc_drain_fifo(dev);
 857 
 858         if (devpriv->stat1 & STAT1_CNTINT) {
 859                 dev_err(dev->class_dev, "handled timer interrupt?\n");
 860                 /*  clear it */
 861                 devpriv->write_byte(dev, 0x1, TIMER_CLEAR_REG);
 862         }
 863 
 864         if (devpriv->stat1 & STAT1_OVERFLOW) {
 865                 /*  clear error interrupt */
 866                 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
 867                 async->events |= COMEDI_CB_ERROR;
 868                 comedi_handle_events(dev, s);
 869                 dev_err(dev->class_dev, "overflow\n");
 870                 return IRQ_HANDLED;
 871         }
 872         /*  handle external stop trigger */
 873         if (cmd->stop_src == TRIG_EXT) {
 874                 if (devpriv->stat2 & STAT2_OUTA1) {
 875                         labpc_drain_dregs(dev);
 876                         async->events |= COMEDI_CB_EOA;
 877                 }
 878         }
 879 
 880         /* TRIG_COUNT end of acquisition */
 881         if (cmd->stop_src == TRIG_COUNT) {
 882                 if (devpriv->count == 0)
 883                         async->events |= COMEDI_CB_EOA;
 884         }
 885 
 886         comedi_handle_events(dev, s);
 887         return IRQ_HANDLED;
 888 }
 889 
 890 static void labpc_ao_write(struct comedi_device *dev,
 891                            struct comedi_subdevice *s,
 892                            unsigned int chan, unsigned int val)
 893 {
 894         struct labpc_private *devpriv = dev->private;
 895 
 896         devpriv->write_byte(dev, val & 0xff, DAC_LSB_REG(chan));
 897         devpriv->write_byte(dev, (val >> 8) & 0xff, DAC_MSB_REG(chan));
 898 
 899         s->readback[chan] = val;
 900 }
 901 
 902 static int labpc_ao_insn_write(struct comedi_device *dev,
 903                                struct comedi_subdevice *s,
 904                                struct comedi_insn *insn,
 905                                unsigned int *data)
 906 {
 907         const struct labpc_boardinfo *board = dev->board_ptr;
 908         struct labpc_private *devpriv = dev->private;
 909         unsigned int channel;
 910         unsigned int range;
 911         unsigned int i;
 912         unsigned long flags;
 913 
 914         channel = CR_CHAN(insn->chanspec);
 915 
 916         /*
 917          * Turn off pacing of analog output channel.
 918          * NOTE: hardware bug in daqcard-1200 means pacing cannot
 919          * be independently enabled/disabled for its the two channels.
 920          */
 921         spin_lock_irqsave(&dev->spinlock, flags);
 922         devpriv->cmd2 &= ~CMD2_LDAC(channel);
 923         devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
 924         spin_unlock_irqrestore(&dev->spinlock, flags);
 925 
 926         /* set range */
 927         if (board->is_labpc1200) {
 928                 range = CR_RANGE(insn->chanspec);
 929                 if (comedi_range_is_unipolar(s, range))
 930                         devpriv->cmd6 |= CMD6_DACUNI(channel);
 931                 else
 932                         devpriv->cmd6 &= ~CMD6_DACUNI(channel);
 933                 /*  write to register */
 934                 devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
 935         }
 936         /* send data */
 937         for (i = 0; i < insn->n; i++)
 938                 labpc_ao_write(dev, s, channel, data[i]);
 939 
 940         return insn->n;
 941 }
 942 
 943 /* lowlevel write to eeprom/dac */
 944 static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
 945                              unsigned int value_width)
 946 {
 947         struct labpc_private *devpriv = dev->private;
 948         int i;
 949 
 950         for (i = 1; i <= value_width; i++) {
 951                 /*  clear serial clock */
 952                 devpriv->cmd5 &= ~CMD5_SCLK;
 953                 /*  send bits most significant bit first */
 954                 if (value & (1 << (value_width - i)))
 955                         devpriv->cmd5 |= CMD5_SDATA;
 956                 else
 957                         devpriv->cmd5 &= ~CMD5_SDATA;
 958                 udelay(1);
 959                 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
 960                 /*  set clock to load bit */
 961                 devpriv->cmd5 |= CMD5_SCLK;
 962                 udelay(1);
 963                 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
 964         }
 965 }
 966 
 967 /* lowlevel read from eeprom */
 968 static unsigned int labpc_serial_in(struct comedi_device *dev)
 969 {
 970         struct labpc_private *devpriv = dev->private;
 971         unsigned int value = 0;
 972         int i;
 973         const int value_width = 8;      /*  number of bits wide values are */
 974 
 975         for (i = 1; i <= value_width; i++) {
 976                 /*  set serial clock */
 977                 devpriv->cmd5 |= CMD5_SCLK;
 978                 udelay(1);
 979                 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
 980                 /*  clear clock bit */
 981                 devpriv->cmd5 &= ~CMD5_SCLK;
 982                 udelay(1);
 983                 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
 984                 /*  read bits most significant bit first */
 985                 udelay(1);
 986                 devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
 987                 if (devpriv->stat2 & STAT2_PROMOUT)
 988                         value |= 1 << (value_width - i);
 989         }
 990 
 991         return value;
 992 }
 993 
 994 static unsigned int labpc_eeprom_read(struct comedi_device *dev,
 995                                       unsigned int address)
 996 {
 997         struct labpc_private *devpriv = dev->private;
 998         unsigned int value;
 999         /*  bits to tell eeprom to expect a read */
1000         const int read_instruction = 0x3;
1001         /*  8 bit write lengths to eeprom */
1002         const int write_length = 8;
1003 
1004         /*  enable read/write to eeprom */
1005         devpriv->cmd5 &= ~CMD5_EEPROMCS;
1006         udelay(1);
1007         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1008         devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
1009         udelay(1);
1010         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1011 
1012         /*  send read instruction */
1013         labpc_serial_out(dev, read_instruction, write_length);
1014         /*  send 8 bit address to read from */
1015         labpc_serial_out(dev, address, write_length);
1016         /*  read result */
1017         value = labpc_serial_in(dev);
1018 
1019         /*  disable read/write to eeprom */
1020         devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
1021         udelay(1);
1022         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1023 
1024         return value;
1025 }
1026 
1027 static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
1028 {
1029         struct labpc_private *devpriv = dev->private;
1030         unsigned int value;
1031         const int read_status_instruction = 0x5;
1032         const int write_length = 8;     /*  8 bit write lengths to eeprom */
1033 
1034         /*  enable read/write to eeprom */
1035         devpriv->cmd5 &= ~CMD5_EEPROMCS;
1036         udelay(1);
1037         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1038         devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
1039         udelay(1);
1040         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1041 
1042         /*  send read status instruction */
1043         labpc_serial_out(dev, read_status_instruction, write_length);
1044         /*  read result */
1045         value = labpc_serial_in(dev);
1046 
1047         /*  disable read/write to eeprom */
1048         devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
1049         udelay(1);
1050         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1051 
1052         return value;
1053 }
1054 
1055 static void labpc_eeprom_write(struct comedi_device *dev,
1056                                unsigned int address, unsigned int value)
1057 {
1058         struct labpc_private *devpriv = dev->private;
1059         const int write_enable_instruction = 0x6;
1060         const int write_instruction = 0x2;
1061         const int write_length = 8;     /*  8 bit write lengths to eeprom */
1062 
1063         /*  enable read/write to eeprom */
1064         devpriv->cmd5 &= ~CMD5_EEPROMCS;
1065         udelay(1);
1066         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1067         devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
1068         udelay(1);
1069         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1070 
1071         /*  send write_enable instruction */
1072         labpc_serial_out(dev, write_enable_instruction, write_length);
1073         devpriv->cmd5 &= ~CMD5_EEPROMCS;
1074         udelay(1);
1075         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1076 
1077         /*  send write instruction */
1078         devpriv->cmd5 |= CMD5_EEPROMCS;
1079         udelay(1);
1080         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1081         labpc_serial_out(dev, write_instruction, write_length);
1082         /*  send 8 bit address to write to */
1083         labpc_serial_out(dev, address, write_length);
1084         /*  write value */
1085         labpc_serial_out(dev, value, write_length);
1086         devpriv->cmd5 &= ~CMD5_EEPROMCS;
1087         udelay(1);
1088         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1089 
1090         /*  disable read/write to eeprom */
1091         devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
1092         udelay(1);
1093         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1094 }
1095 
1096 /* writes to 8 bit calibration dacs */
1097 static void write_caldac(struct comedi_device *dev, unsigned int channel,
1098                          unsigned int value)
1099 {
1100         struct labpc_private *devpriv = dev->private;
1101 
1102         /*  clear caldac load bit and make sure we don't write to eeprom */
1103         devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT);
1104         udelay(1);
1105         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1106 
1107         /*  write 4 bit channel */
1108         labpc_serial_out(dev, channel, 4);
1109         /*  write 8 bit caldac value */
1110         labpc_serial_out(dev, value, 8);
1111 
1112         /*  set and clear caldac bit to load caldac value */
1113         devpriv->cmd5 |= CMD5_CALDACLD;
1114         udelay(1);
1115         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1116         devpriv->cmd5 &= ~CMD5_CALDACLD;
1117         udelay(1);
1118         devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1119 }
1120 
1121 static int labpc_calib_insn_write(struct comedi_device *dev,
1122                                   struct comedi_subdevice *s,
1123                                   struct comedi_insn *insn,
1124                                   unsigned int *data)
1125 {
1126         unsigned int chan = CR_CHAN(insn->chanspec);
1127 
1128         /*
1129          * Only write the last data value to the caldac. Preceding
1130          * data would be overwritten anyway.
1131          */
1132         if (insn->n > 0) {
1133                 unsigned int val = data[insn->n - 1];
1134 
1135                 if (s->readback[chan] != val) {
1136                         write_caldac(dev, chan, val);
1137                         s->readback[chan] = val;
1138                 }
1139         }
1140 
1141         return insn->n;
1142 }
1143 
1144 static int labpc_eeprom_ready(struct comedi_device *dev,
1145                               struct comedi_subdevice *s,
1146                               struct comedi_insn *insn,
1147                               unsigned long context)
1148 {
1149         unsigned int status;
1150 
1151         /* make sure there isn't already a write in progress */
1152         status = labpc_eeprom_read_status(dev);
1153         if ((status & 0x1) == 0)
1154                 return 0;
1155         return -EBUSY;
1156 }
1157 
1158 static int labpc_eeprom_insn_write(struct comedi_device *dev,
1159                                    struct comedi_subdevice *s,
1160                                    struct comedi_insn *insn,
1161                                    unsigned int *data)
1162 {
1163         unsigned int chan = CR_CHAN(insn->chanspec);
1164         int ret;
1165 
1166         /* only allow writes to user area of eeprom */
1167         if (chan < 16 || chan > 127)
1168                 return -EINVAL;
1169 
1170         /*
1171          * Only write the last data value to the eeprom. Preceding
1172          * data would be overwritten anyway.
1173          */
1174         if (insn->n > 0) {
1175                 unsigned int val = data[insn->n - 1];
1176 
1177                 ret = comedi_timeout(dev, s, insn, labpc_eeprom_ready, 0);
1178                 if (ret)
1179                         return ret;
1180 
1181                 labpc_eeprom_write(dev, chan, val);
1182                 s->readback[chan] = val;
1183         }
1184 
1185         return insn->n;
1186 }
1187 
1188 int labpc_common_attach(struct comedi_device *dev,
1189                         unsigned int irq, unsigned long isr_flags)
1190 {
1191         const struct labpc_boardinfo *board = dev->board_ptr;
1192         struct labpc_private *devpriv;
1193         struct comedi_subdevice *s;
1194         int ret;
1195         int i;
1196 
1197         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1198         if (!devpriv)
1199                 return -ENOMEM;
1200 
1201         if (dev->mmio) {
1202                 devpriv->read_byte = labpc_readb;
1203                 devpriv->write_byte = labpc_writeb;
1204         } else {
1205                 devpriv->read_byte = labpc_inb;
1206                 devpriv->write_byte = labpc_outb;
1207         }
1208 
1209         /* initialize board's command registers */
1210         devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
1211         devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
1212         devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
1213         devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
1214         if (board->is_labpc1200) {
1215                 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1216                 devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
1217         }
1218 
1219         if (irq) {
1220                 ret = request_irq(irq, labpc_interrupt, isr_flags,
1221                                   dev->board_name, dev);
1222                 if (ret == 0)
1223                         dev->irq = irq;
1224         }
1225 
1226         if (dev->mmio) {
1227                 dev->pacer = comedi_8254_mm_init(dev->mmio + COUNTER_B_BASE_REG,
1228                                                  I8254_OSC_BASE_2MHZ,
1229                                                  I8254_IO8, 0);
1230                 devpriv->counter = comedi_8254_mm_init(dev->mmio +
1231                                                        COUNTER_A_BASE_REG,
1232                                                        I8254_OSC_BASE_2MHZ,
1233                                                        I8254_IO8, 0);
1234         } else {
1235                 dev->pacer = comedi_8254_init(dev->iobase + COUNTER_B_BASE_REG,
1236                                               I8254_OSC_BASE_2MHZ,
1237                                               I8254_IO8, 0);
1238                 devpriv->counter = comedi_8254_init(dev->iobase +
1239                                                     COUNTER_A_BASE_REG,
1240                                                     I8254_OSC_BASE_2MHZ,
1241                                                     I8254_IO8, 0);
1242         }
1243         if (!dev->pacer || !devpriv->counter)
1244                 return -ENOMEM;
1245 
1246         ret = comedi_alloc_subdevices(dev, 5);
1247         if (ret)
1248                 return ret;
1249 
1250         /* analog input subdevice */
1251         s = &dev->subdevices[0];
1252         s->type         = COMEDI_SUBD_AI;
1253         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1254         s->n_chan       = 8;
1255         s->len_chanlist = 8;
1256         s->maxdata      = 0x0fff;
1257         s->range_table  = board->is_labpc1200 ?
1258                           &range_labpc_1200_ai : &range_labpc_plus_ai;
1259         s->insn_read    = labpc_ai_insn_read;
1260         if (dev->irq) {
1261                 dev->read_subdev = s;
1262                 s->subdev_flags |= SDF_CMD_READ;
1263                 s->do_cmd       = labpc_ai_cmd;
1264                 s->do_cmdtest   = labpc_ai_cmdtest;
1265                 s->cancel       = labpc_cancel;
1266         }
1267 
1268         /* analog output */
1269         s = &dev->subdevices[1];
1270         if (board->has_ao) {
1271                 s->type         = COMEDI_SUBD_AO;
1272                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1273                 s->n_chan       = 2;
1274                 s->maxdata      = 0x0fff;
1275                 s->range_table  = &range_labpc_ao;
1276                 s->insn_write   = labpc_ao_insn_write;
1277 
1278                 ret = comedi_alloc_subdev_readback(s);
1279                 if (ret)
1280                         return ret;
1281 
1282                 /* initialize analog outputs to a known value */
1283                 for (i = 0; i < s->n_chan; i++)
1284                         labpc_ao_write(dev, s, i, s->maxdata / 2);
1285         } else {
1286                 s->type         = COMEDI_SUBD_UNUSED;
1287         }
1288 
1289         /* 8255 dio */
1290         s = &dev->subdevices[2];
1291         if (dev->mmio)
1292                 ret = subdev_8255_mm_init(dev, s, NULL, DIO_BASE_REG);
1293         else
1294                 ret = subdev_8255_init(dev, s, NULL, DIO_BASE_REG);
1295         if (ret)
1296                 return ret;
1297 
1298         /*  calibration subdevices for boards that have one */
1299         s = &dev->subdevices[3];
1300         if (board->is_labpc1200) {
1301                 s->type         = COMEDI_SUBD_CALIB;
1302                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1303                 s->n_chan       = 16;
1304                 s->maxdata      = 0xff;
1305                 s->insn_write   = labpc_calib_insn_write;
1306 
1307                 ret = comedi_alloc_subdev_readback(s);
1308                 if (ret)
1309                         return ret;
1310 
1311                 for (i = 0; i < s->n_chan; i++) {
1312                         write_caldac(dev, i, s->maxdata / 2);
1313                         s->readback[i] = s->maxdata / 2;
1314                 }
1315         } else {
1316                 s->type         = COMEDI_SUBD_UNUSED;
1317         }
1318 
1319         /* EEPROM (256 bytes) */
1320         s = &dev->subdevices[4];
1321         if (board->is_labpc1200) {
1322                 s->type         = COMEDI_SUBD_MEMORY;
1323                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1324                 s->n_chan       = 256;
1325                 s->maxdata      = 0xff;
1326                 s->insn_write   = labpc_eeprom_insn_write;
1327 
1328                 ret = comedi_alloc_subdev_readback(s);
1329                 if (ret)
1330                         return ret;
1331 
1332                 for (i = 0; i < s->n_chan; i++)
1333                         s->readback[i] = labpc_eeprom_read(dev, i);
1334         } else {
1335                 s->type         = COMEDI_SUBD_UNUSED;
1336         }
1337 
1338         return 0;
1339 }
1340 EXPORT_SYMBOL_GPL(labpc_common_attach);
1341 
1342 void labpc_common_detach(struct comedi_device *dev)
1343 {
1344         struct labpc_private *devpriv = dev->private;
1345 
1346         if (devpriv)
1347                 kfree(devpriv->counter);
1348 }
1349 EXPORT_SYMBOL_GPL(labpc_common_detach);
1350 
1351 static int __init labpc_common_init(void)
1352 {
1353         return 0;
1354 }
1355 module_init(labpc_common_init);
1356 
1357 static void __exit labpc_common_exit(void)
1358 {
1359 }
1360 module_exit(labpc_common_exit);
1361 
1362 MODULE_AUTHOR("Comedi http://www.comedi.org");
1363 MODULE_DESCRIPTION("Comedi helper for ni_labpc, ni_labpc_pci, ni_labpc_cs");
1364 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */