staging: comedi: ni_labpc: remove 'bustype' from boardinfo
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / comedi / drivers / ni_labpc.c
CommitLineData
124b13b2 1/*
31922394
HS
2 * comedi/drivers/ni_labpc.c
3 * Driver for National Instruments Lab-PC series boards and compatibles
4 * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
124b13b2
FMH
20
21/*
31922394
HS
22 * Driver: ni_labpc
23 * Description: National Instruments Lab-PC (& compatibles)
24 * Devices: (National Instruments) Lab-PC-1200 [lab-pc-1200]
25 * (National Instruments) Lab-PC-1200AI [lab-pc-1200ai]
26 * (National Instruments) Lab-PC+ [lab-pc+]
31922394
HS
27 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
28 * Status: works
29 *
30 * Configuration options - ISA boards:
31 * [0] - I/O port base address
32 * [1] - IRQ (optional, required for timed or externally triggered
33 * conversions)
34 * [2] - DMA channel (optional)
35 *
31922394
HS
36 * Tested with lab-pc-1200. For the older Lab-PC+, not all input
37 * ranges and analog references will work, the available ranges/arefs
38 * will depend on how you have configured the jumpers on your board
39 * (see your owner's manual).
40 *
41 * Kernel-level ISA plug-and-play support for the lab-pc-1200 boards
42 * has not yet been added to the driver, mainly due to the fact that
43 * I don't know the device id numbers. If you have one of these boards,
44 * please file a bug report at http://comedi.org/ so I can get the
45 * necessary information from you.
46 *
47 * The 1200 series boards have onboard calibration dacs for correcting
48 * analog input/output offsets and gains. The proper settings for these
49 * caldacs are stored on the board's eeprom. To read the caldac values
50 * from the eeprom and store them into a file that can be then be used
51 * by comedilib, use the comedi_calibrate program.
52 *
53 * The Lab-pc+ has quirky chanlist requirements when scanning multiple
54 * channels. Multiple channel scan sequence must start at highest channel,
55 * then decrement down to channel 0. The rest of the cards can scan down
56 * like lab-pc+ or scan up from channel zero. Chanlists consisting of all
57 * one channel are also legal, and allow you to pace conversions in bursts.
58 *
59 * NI manuals:
60 * 341309a (labpc-1200 register manual)
31922394
HS
61 * 320502b (lab-pc+)
62 */
124b13b2 63
25436dc9 64#include <linux/interrupt.h>
5a0e3ad6 65#include <linux/slab.h>
845d131e 66#include <linux/io.h>
33782dd5
HS
67#include <linux/delay.h>
68
124b13b2
FMH
69#include "../comedidev.h"
70
124b13b2
FMH
71#include <asm/dma.h>
72
73#include "8253.h"
74#include "8255.h"
124b13b2
FMH
75#include "comedi_fc.h"
76#include "ni_labpc.h"
77
42cb6a82
HS
78/*
79 * Register map (all registers are 8-bit)
80 */
81#define STAT1_REG 0x00 /* R: Status 1 reg */
82#define STAT1_DAVAIL (1 << 0)
83#define STAT1_OVERRUN (1 << 1)
84#define STAT1_OVERFLOW (1 << 2)
85#define STAT1_CNTINT (1 << 3)
86#define STAT1_GATA0 (1 << 5)
87#define STAT1_EXTGATA0 (1 << 6)
88#define CMD1_REG 0x00 /* W: Command 1 reg */
89#define CMD1_MA(x) (((x) & 0x7) << 0)
90#define CMD1_TWOSCMP (1 << 3)
91#define CMD1_GAIN_MASK (7 << 4)
92#define CMD1_SCANEN (1 << 7)
93#define CMD2_REG 0x01 /* W: Command 2 reg */
94#define CMD2_PRETRIG (1 << 0)
95#define CMD2_HWTRIG (1 << 1)
96#define CMD2_SWTRIG (1 << 2)
97#define CMD2_TBSEL (1 << 3)
98#define CMD2_2SDAC0 (1 << 4)
99#define CMD2_2SDAC1 (1 << 5)
100#define CMD2_LDAC(x) (1 << (6 + (x)))
101#define CMD3_REG 0x02 /* W: Command 3 reg */
102#define CMD3_DMAEN (1 << 0)
103#define CMD3_DIOINTEN (1 << 1)
104#define CMD3_DMATCINTEN (1 << 2)
105#define CMD3_CNTINTEN (1 << 3)
106#define CMD3_ERRINTEN (1 << 4)
107#define CMD3_FIFOINTEN (1 << 5)
108#define ADC_START_CONVERT_REG 0x03 /* W: Start Convert reg */
109#define DAC_LSB_REG(x) (0x04 + 2 * (x)) /* W: DAC0/1 LSB reg */
110#define DAC_MSB_REG(x) (0x05 + 2 * (x)) /* W: DAC0/1 MSB reg */
111#define ADC_FIFO_CLEAR_REG 0x08 /* W: A/D FIFO Clear reg */
112#define ADC_FIFO_REG 0x0a /* R: A/D FIFO reg */
113#define DMATC_CLEAR_REG 0x0a /* W: DMA Interrupt Clear reg */
114#define TIMER_CLEAR_REG 0x0c /* W: Timer Interrupt Clear reg */
115#define CMD6_REG 0x0e /* W: Command 6 reg */
116#define CMD6_NRSE (1 << 0)
117#define CMD6_ADCUNI (1 << 1)
118#define CMD6_DACUNI(x) (1 << (2 + (x)))
119#define CMD6_HFINTEN (1 << 5)
120#define CMD6_DQINTEN (1 << 6)
121#define CMD6_SCANUP (1 << 7)
122#define CMD4_REG 0x0f /* W: Command 3 reg */
123#define CMD4_INTSCAN (1 << 0)
124#define CMD4_EOIRCV (1 << 1)
125#define CMD4_ECLKDRV (1 << 2)
126#define CMD4_SEDIFF (1 << 3)
127#define CMD4_ECLKRCV (1 << 4)
128#define DIO_BASE_REG 0x10 /* R/W: 8255 DIO base reg */
129#define COUNTER_A_BASE_REG 0x14 /* R/W: 8253 Counter A base reg */
42cb6a82
HS
130#define COUNTER_B_BASE_REG 0x18 /* R/W: 8253 Counter B base reg */
131#define CMD5_REG 0x1c /* W: Command 5 reg */
132#define CMD5_WRTPRT (1 << 2)
133#define CMD5_DITHEREN (1 << 3)
134#define CMD5_CALDACLD (1 << 4)
135#define CMD5_SCLK (1 << 5)
136#define CMD5_SDATA (1 << 6)
137#define CMD5_EEPROMCS (1 << 7)
138#define STAT2_REG 0x1d /* R: Status 2 reg */
139#define STAT2_PROMOUT (1 << 0)
140#define STAT2_OUTA1 (1 << 1)
141#define STAT2_FIFONHF (1 << 2)
142#define INTERVAL_COUNT_REG 0x1e /* W: Interval Counter Data reg */
143#define INTERVAL_STROBE_REG 0x1f /* W: Interval Counter Strobe reg */
124b13b2 144
488ec9f1
HS
145#define LABPC_SIZE 0x20 /* size of ISA io region */
146#define LABPC_TIMER_BASE 500 /* 2 MHz master clock */
810c73c7
HS
147#define LABPC_ADC_TIMEOUT 1000
148
6f73fbce
IA
149enum scan_mode {
150 MODE_SINGLE_CHAN,
151 MODE_SINGLE_CHAN_INTERVAL,
152 MODE_MULT_CHAN_UP,
153 MODE_MULT_CHAN_DOWN,
154};
155
1b3e0c80
HS
156static const int labpc_plus_ai_gain_bits[] = {
157 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
158 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
124b13b2 159};
0a85b6f0 160
9ced1de6 161static const struct comedi_lrange range_labpc_plus_ai = {
1b3e0c80
HS
162 16, {
163 BIP_RANGE(5),
164 BIP_RANGE(4),
165 BIP_RANGE(2.5),
166 BIP_RANGE(1),
167 BIP_RANGE(0.5),
168 BIP_RANGE(0.25),
169 BIP_RANGE(0.1),
170 BIP_RANGE(0.05),
171 UNI_RANGE(10),
172 UNI_RANGE(8),
173 UNI_RANGE(5),
174 UNI_RANGE(2),
175 UNI_RANGE(1),
176 UNI_RANGE(0.5),
177 UNI_RANGE(0.2),
178 UNI_RANGE(0.1)
179 }
124b13b2
FMH
180};
181
1b3e0c80
HS
182const int labpc_1200_ai_gain_bits[] = {
183 0x00, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
184 0x00, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
124b13b2 185};
0656bb35 186EXPORT_SYMBOL_GPL(labpc_1200_ai_gain_bits);
0a85b6f0 187
9ced1de6 188const struct comedi_lrange range_labpc_1200_ai = {
1b3e0c80
HS
189 14, {
190 BIP_RANGE(5),
191 BIP_RANGE(2.5),
192 BIP_RANGE(1),
193 BIP_RANGE(0.5),
194 BIP_RANGE(0.25),
195 BIP_RANGE(0.1),
196 BIP_RANGE(0.05),
197 UNI_RANGE(10),
198 UNI_RANGE(5),
199 UNI_RANGE(2),
200 UNI_RANGE(1),
201 UNI_RANGE(0.5),
202 UNI_RANGE(0.2),
203 UNI_RANGE(0.1)
204 }
124b13b2 205};
0656bb35 206EXPORT_SYMBOL_GPL(range_labpc_1200_ai);
124b13b2 207
9ced1de6 208static const struct comedi_lrange range_labpc_ao = {
1b3e0c80
HS
209 2, {
210 BIP_RANGE(5),
211 UNI_RANGE(10)
212 }
124b13b2
FMH
213};
214
215/* functions that do inb/outb and readb/writeb so we can use
216 * function pointers to decide which to use */
217static inline unsigned int labpc_inb(unsigned long address)
218{
219 return inb(address);
220}
0a85b6f0 221
124b13b2
FMH
222static inline void labpc_outb(unsigned int byte, unsigned long address)
223{
224 outb(byte, address);
225}
0a85b6f0 226
124b13b2
FMH
227static inline unsigned int labpc_readb(unsigned long address)
228{
5743aaac 229 return readb((void __iomem *)address);
124b13b2 230}
0a85b6f0 231
124b13b2
FMH
232static inline void labpc_writeb(unsigned int byte, unsigned long address)
233{
5743aaac 234 writeb(byte, (void __iomem *)address);
124b13b2
FMH
235}
236
fa3cb219 237#ifdef CONFIG_COMEDI_NI_LABPC_ISA
f65d971d 238static const struct labpc_boardinfo labpc_boards[] = {
124b13b2 239 {
f2c447ca
HS
240 .name = "lab-pc-1200",
241 .ai_speed = 10000,
f2c447ca
HS
242 .register_layout = labpc_1200_layout,
243 .has_ao = 1,
244 .ai_range_table = &range_labpc_1200_ai,
245 .ai_range_code = labpc_1200_ai_gain_bits,
f2c447ca
HS
246 .ai_scan_up = 1,
247 }, {
248 .name = "lab-pc-1200ai",
249 .ai_speed = 10000,
f2c447ca
HS
250 .register_layout = labpc_1200_layout,
251 .ai_range_table = &range_labpc_1200_ai,
252 .ai_range_code = labpc_1200_ai_gain_bits,
f2c447ca
HS
253 .ai_scan_up = 1,
254 }, {
255 .name = "lab-pc+",
256 .ai_speed = 12000,
f2c447ca
HS
257 .register_layout = labpc_plus_layout,
258 .has_ao = 1,
259 .ai_range_table = &range_labpc_plus_ai,
260 .ai_range_code = labpc_plus_ai_gain_bits,
f2c447ca 261 },
124b13b2 262};
fa3cb219 263#endif
124b13b2 264
e41a6f6d
SR
265/* size in bytes of dma buffer */
266static const int dma_buffer_size = 0xff00;
267/* 2 bytes per sample */
268static const int sample_size = 2;
124b13b2 269
fbca05d6
HS
270static int labpc_counter_load(struct comedi_device *dev,
271 unsigned long base_address,
272 unsigned int counter_number,
273 unsigned int count, unsigned int mode)
274{
275 const struct labpc_boardinfo *board = comedi_board(dev);
276
277 if (board->has_mmio)
278 return i8254_mm_load((void __iomem *)base_address, 0,
279 counter_number, count, mode);
280 else
281 return i8254_load(base_address, 0, counter_number, count, mode);
282}
283
463f9304
HS
284static int labpc_counter_set_mode(struct comedi_device *dev,
285 unsigned long base_address,
286 unsigned int counter_number,
287 unsigned int mode)
288{
289 const struct labpc_boardinfo *board = comedi_board(dev);
290
291 if (board->has_mmio)
292 return i8254_mm_set_mode((void __iomem *)base_address, 0,
293 counter_number, mode);
294 else
295 return i8254_set_mode(base_address, 0, counter_number, mode);
296}
297
43a9411a
HS
298static bool labpc_range_is_unipolar(struct comedi_subdevice *s,
299 unsigned int range)
300{
43d092c6 301 return s->range_table->range[range].min >= 0;
43a9411a
HS
302}
303
8a498667
HS
304static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
305{
306 struct labpc_private *devpriv = dev->private;
307 unsigned long flags;
308
309 spin_lock_irqsave(&dev->spinlock, flags);
42cb6a82
HS
310 devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
311 devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
8a498667
HS
312 spin_unlock_irqrestore(&dev->spinlock, flags);
313
314 devpriv->cmd3 = 0;
42cb6a82 315 devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
8a498667
HS
316
317 return 0;
318}
319
8c2bc333
HS
320static void labpc_ai_set_chan_and_gain(struct comedi_device *dev,
321 enum scan_mode mode,
322 unsigned int chan,
323 unsigned int range,
324 unsigned int aref)
325{
326 const struct labpc_boardinfo *board = comedi_board(dev);
327 struct labpc_private *devpriv = dev->private;
328
329 /* munge channel bits for differential/scan disabled mode */
330 if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) &&
331 aref == AREF_DIFF)
332 chan *= 2;
42cb6a82 333 devpriv->cmd1 = CMD1_MA(chan);
8c2bc333
HS
334 devpriv->cmd1 |= board->ai_range_code[range];
335
42cb6a82 336 devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
8c2bc333
HS
337}
338
359553bb
HS
339static void labpc_setup_cmd6_reg(struct comedi_device *dev,
340 struct comedi_subdevice *s,
341 enum scan_mode mode,
342 enum transfer_type xfer,
343 unsigned int range,
344 unsigned int aref,
345 bool ena_intr)
346{
347 const struct labpc_boardinfo *board = comedi_board(dev);
348 struct labpc_private *devpriv = dev->private;
349
350 if (board->register_layout != labpc_1200_layout)
351 return;
352
353 /* reference inputs to ground or common? */
354 if (aref != AREF_GROUND)
42cb6a82 355 devpriv->cmd6 |= CMD6_NRSE;
359553bb 356 else
42cb6a82 357 devpriv->cmd6 &= ~CMD6_NRSE;
359553bb
HS
358
359 /* bipolar or unipolar range? */
360 if (labpc_range_is_unipolar(s, range))
42cb6a82 361 devpriv->cmd6 |= CMD6_ADCUNI;
359553bb 362 else
42cb6a82 363 devpriv->cmd6 &= ~CMD6_ADCUNI;
359553bb
HS
364
365 /* interrupt on fifo half full? */
366 if (xfer == fifo_half_full_transfer)
42cb6a82 367 devpriv->cmd6 |= CMD6_HFINTEN;
359553bb 368 else
42cb6a82 369 devpriv->cmd6 &= ~CMD6_HFINTEN;
359553bb
HS
370
371 /* enable interrupt on counter a1 terminal count? */
372 if (ena_intr)
42cb6a82 373 devpriv->cmd6 |= CMD6_DQINTEN;
359553bb 374 else
42cb6a82 375 devpriv->cmd6 &= ~CMD6_DQINTEN;
359553bb
HS
376
377 /* are we scanning up or down through channels? */
378 if (mode == MODE_MULT_CHAN_UP)
42cb6a82 379 devpriv->cmd6 |= CMD6_SCANUP;
359553bb 380 else
42cb6a82 381 devpriv->cmd6 &= ~CMD6_SCANUP;
359553bb 382
42cb6a82 383 devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
359553bb
HS
384}
385
3c4dfac8
HS
386static unsigned int labpc_read_adc_fifo(struct comedi_device *dev)
387{
388 struct labpc_private *devpriv = dev->private;
389 unsigned int lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
390 unsigned int msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
391
392 return (msb << 8) | lsb;
393}
394
395static void labpc_clear_adc_fifo(struct comedi_device *dev)
124b13b2 396{
9a1a6cf8 397 struct labpc_private *devpriv = dev->private;
78110bb8 398
42cb6a82 399 devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
3c4dfac8 400 labpc_read_adc_fifo(dev);
dd2aef64 401}
124b13b2 402
810c73c7
HS
403static int labpc_ai_wait_for_data(struct comedi_device *dev,
404 int timeout)
405{
406 struct labpc_private *devpriv = dev->private;
407 int i;
408
409 for (i = 0; i < timeout; i++) {
42cb6a82
HS
410 devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
411 if (devpriv->stat1 & STAT1_DAVAIL)
810c73c7
HS
412 return 0;
413 udelay(1);
414 }
415 return -ETIME;
416}
417
28a10930
HS
418static int labpc_ai_insn_read(struct comedi_device *dev,
419 struct comedi_subdevice *s,
420 struct comedi_insn *insn,
421 unsigned int *data)
dd2aef64
HS
422{
423 struct labpc_private *devpriv = dev->private;
73f2b1d2
HS
424 unsigned int chan = CR_CHAN(insn->chanspec);
425 unsigned int range = CR_RANGE(insn->chanspec);
426 unsigned int aref = CR_AREF(insn->chanspec);
810c73c7
HS
427 int ret;
428 int i;
124b13b2 429
8a498667
HS
430 /* disable timed conversions, interrupt generation and dma */
431 labpc_cancel(dev, s);
124b13b2 432
8c2bc333 433 labpc_ai_set_chan_and_gain(dev, MODE_SINGLE_CHAN, chan, range, aref);
124b13b2 434
359553bb
HS
435 labpc_setup_cmd6_reg(dev, s, MODE_SINGLE_CHAN, fifo_not_empty_transfer,
436 range, aref, false);
437
74df5760
HS
438 /* setup cmd4 register */
439 devpriv->cmd4 = 0;
42cb6a82 440 devpriv->cmd4 |= CMD4_ECLKRCV;
af81f093 441 /* single-ended/differential */
73f2b1d2 442 if (aref == AREF_DIFF)
42cb6a82
HS
443 devpriv->cmd4 |= CMD4_SEDIFF;
444 devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
124b13b2 445
463f9304 446 /* initialize pacer counter to prevent any problems */
f06563f0
HS
447 ret = labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
448 0, I8254_MODE2);
449 if (ret)
450 return ret;
7e2716cd 451
af81f093 452 labpc_clear_adc_fifo(dev);
7e2716cd 453
810c73c7 454 for (i = 0; i < insn->n; i++) {
af81f093 455 /* trigger conversion */
42cb6a82 456 devpriv->write_byte(0x1, dev->iobase + ADC_START_CONVERT_REG);
7e2716cd 457
810c73c7
HS
458 ret = labpc_ai_wait_for_data(dev, LABPC_ADC_TIMEOUT);
459 if (ret)
460 return ret;
461
462 data[i] = labpc_read_adc_fifo(dev);
dd2aef64 463 }
9a1a6cf8 464
810c73c7 465 return insn->n;
af81f093 466}
124b13b2 467
af81f093
HS
468#ifdef CONFIG_ISA_DMA_API
469/* utility function that suggests a dma transfer size in bytes */
470static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
471{
472 unsigned int size;
473 unsigned int freq;
124b13b2 474
af81f093
HS
475 if (cmd->convert_src == TRIG_TIMER)
476 freq = 1000000000 / cmd->convert_arg;
477 /* return some default value */
478 else
479 freq = 0xffffffff;
124b13b2 480
af81f093
HS
481 /* make buffer fill in no more than 1/3 second */
482 size = (freq / 3) * sample_size;
124b13b2 483
af81f093
HS
484 /* set a minimum and maximum size allowed */
485 if (size > dma_buffer_size)
486 size = dma_buffer_size - dma_buffer_size % sample_size;
487 else if (size < sample_size)
488 size = sample_size;
124b13b2 489
af81f093 490 return size;
124b13b2 491}
af81f093 492#endif
124b13b2 493
63a93381
HS
494static bool labpc_use_continuous_mode(const struct comedi_cmd *cmd,
495 enum scan_mode mode)
124b13b2 496{
63a93381
HS
497 if (mode == MODE_SINGLE_CHAN || cmd->scan_begin_src == TRIG_FOLLOW)
498 return true;
124b13b2 499
63a93381 500 return false;
124b13b2
FMH
501}
502
6f73fbce
IA
503static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd,
504 enum scan_mode mode)
124b13b2
FMH
505{
506 if (cmd->convert_src != TRIG_TIMER)
507 return 0;
508
6f73fbce 509 if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER)
124b13b2
FMH
510 return cmd->scan_begin_arg;
511
512 return cmd->convert_arg;
513}
514
6f73fbce
IA
515static void labpc_set_ai_convert_period(struct comedi_cmd *cmd,
516 enum scan_mode mode, unsigned int ns)
124b13b2
FMH
517{
518 if (cmd->convert_src != TRIG_TIMER)
519 return;
520
6f73fbce 521 if (mode == MODE_SINGLE_CHAN &&
0a85b6f0 522 cmd->scan_begin_src == TRIG_TIMER) {
124b13b2
FMH
523 cmd->scan_begin_arg = ns;
524 if (cmd->convert_arg > cmd->scan_begin_arg)
525 cmd->convert_arg = cmd->scan_begin_arg;
526 } else
527 cmd->convert_arg = ns;
528}
529
6f73fbce
IA
530static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd,
531 enum scan_mode mode)
124b13b2
FMH
532{
533 if (cmd->scan_begin_src != TRIG_TIMER)
534 return 0;
535
6f73fbce 536 if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
124b13b2
FMH
537 return 0;
538
539 return cmd->scan_begin_arg;
540}
541
af81f093
HS
542static void labpc_set_ai_scan_period(struct comedi_cmd *cmd,
543 enum scan_mode mode, unsigned int ns)
544{
545 if (cmd->scan_begin_src != TRIG_TIMER)
546 return;
547
548 if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
549 return;
550
551 cmd->scan_begin_arg = ns;
552}
553
554/* figures out what counter values to use based on command */
555static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
556 enum scan_mode mode)
557{
558 struct labpc_private *devpriv = dev->private;
559 /* max value for 16 bit counter in mode 2 */
560 const int max_counter_value = 0x10000;
561 /* min value for 16 bit counter in mode 2 */
562 const int min_counter_value = 2;
563 unsigned int base_period;
564 unsigned int scan_period;
565 unsigned int convert_period;
566
567 /*
568 * if both convert and scan triggers are TRIG_TIMER, then they
569 * both rely on counter b0
570 */
571 convert_period = labpc_ai_convert_period(cmd, mode);
572 scan_period = labpc_ai_scan_period(cmd, mode);
573 if (convert_period && scan_period) {
574 /*
575 * pick the lowest b0 divisor value we can (for maximum input
576 * clock speed on convert and scan counters)
577 */
578 devpriv->divisor_b0 = (scan_period - 1) /
579 (LABPC_TIMER_BASE * max_counter_value) + 1;
580 if (devpriv->divisor_b0 < min_counter_value)
581 devpriv->divisor_b0 = min_counter_value;
582 if (devpriv->divisor_b0 > max_counter_value)
583 devpriv->divisor_b0 = max_counter_value;
584
585 base_period = LABPC_TIMER_BASE * devpriv->divisor_b0;
586
587 /* set a0 for conversion frequency and b1 for scan frequency */
588 switch (cmd->flags & TRIG_ROUND_MASK) {
589 default:
590 case TRIG_ROUND_NEAREST:
591 devpriv->divisor_a0 =
592 (convert_period + (base_period / 2)) / base_period;
593 devpriv->divisor_b1 =
594 (scan_period + (base_period / 2)) / base_period;
595 break;
596 case TRIG_ROUND_UP:
597 devpriv->divisor_a0 =
598 (convert_period + (base_period - 1)) / base_period;
599 devpriv->divisor_b1 =
600 (scan_period + (base_period - 1)) / base_period;
601 break;
602 case TRIG_ROUND_DOWN:
603 devpriv->divisor_a0 = convert_period / base_period;
604 devpriv->divisor_b1 = scan_period / base_period;
605 break;
606 }
607 /* make sure a0 and b1 values are acceptable */
608 if (devpriv->divisor_a0 < min_counter_value)
609 devpriv->divisor_a0 = min_counter_value;
610 if (devpriv->divisor_a0 > max_counter_value)
611 devpriv->divisor_a0 = max_counter_value;
612 if (devpriv->divisor_b1 < min_counter_value)
613 devpriv->divisor_b1 = min_counter_value;
614 if (devpriv->divisor_b1 > max_counter_value)
615 devpriv->divisor_b1 = max_counter_value;
616 /* write corrected timings to command */
617 labpc_set_ai_convert_period(cmd, mode,
618 base_period * devpriv->divisor_a0);
619 labpc_set_ai_scan_period(cmd, mode,
620 base_period * devpriv->divisor_b1);
621 /*
622 * if only one TRIG_TIMER is used, we can employ the generic
623 * cascaded timing functions
624 */
625 } else if (scan_period) {
626 /*
627 * calculate cascaded counter values
628 * that give desired scan timing
629 */
630 i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
631 &(devpriv->divisor_b1),
632 &(devpriv->divisor_b0),
633 &scan_period,
634 cmd->flags & TRIG_ROUND_MASK);
635 labpc_set_ai_scan_period(cmd, mode, scan_period);
636 } else if (convert_period) {
637 /*
638 * calculate cascaded counter values
639 * that give desired conversion timing
640 */
641 i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
642 &(devpriv->divisor_a0),
643 &(devpriv->divisor_b0),
644 &convert_period,
645 cmd->flags & TRIG_ROUND_MASK);
646 labpc_set_ai_convert_period(cmd, mode, convert_period);
647 }
648}
649
650static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
651{
652 if (cmd->chanlist_len == 1)
653 return MODE_SINGLE_CHAN;
654
655 /* chanlist may be NULL during cmdtest. */
656 if (cmd->chanlist == NULL)
657 return MODE_MULT_CHAN_UP;
658
659 if (CR_CHAN(cmd->chanlist[0]) == CR_CHAN(cmd->chanlist[1]))
660 return MODE_SINGLE_CHAN_INTERVAL;
661
662 if (CR_CHAN(cmd->chanlist[0]) < CR_CHAN(cmd->chanlist[1]))
663 return MODE_MULT_CHAN_UP;
664
665 if (CR_CHAN(cmd->chanlist[0]) > CR_CHAN(cmd->chanlist[1]))
666 return MODE_MULT_CHAN_DOWN;
667
668 pr_err("ni_labpc: bug! cannot determine AI scan mode\n");
669 return 0;
670}
671
672static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
673 const struct comedi_cmd *cmd,
674 enum scan_mode mode)
675{
676 int channel, range, aref, i;
677
678 if (cmd->chanlist == NULL)
679 return 0;
680
681 if (mode == MODE_SINGLE_CHAN)
682 return 0;
683
684 if (mode == MODE_SINGLE_CHAN_INTERVAL) {
685 if (cmd->chanlist_len > 0xff) {
686 comedi_error(dev,
687 "ni_labpc: chanlist too long for single channel interval mode\n");
688 return 1;
689 }
690 }
691
692 channel = CR_CHAN(cmd->chanlist[0]);
693 range = CR_RANGE(cmd->chanlist[0]);
694 aref = CR_AREF(cmd->chanlist[0]);
695
696 for (i = 0; i < cmd->chanlist_len; i++) {
697
698 switch (mode) {
699 case MODE_SINGLE_CHAN_INTERVAL:
700 if (CR_CHAN(cmd->chanlist[i]) != channel) {
701 comedi_error(dev,
702 "channel scanning order specified in chanlist is not supported by hardware.\n");
703 return 1;
704 }
705 break;
706 case MODE_MULT_CHAN_UP:
707 if (CR_CHAN(cmd->chanlist[i]) != i) {
708 comedi_error(dev,
709 "channel scanning order specified in chanlist is not supported by hardware.\n");
710 return 1;
711 }
712 break;
713 case MODE_MULT_CHAN_DOWN:
714 if (CR_CHAN(cmd->chanlist[i]) !=
715 cmd->chanlist_len - i - 1) {
716 comedi_error(dev,
717 "channel scanning order specified in chanlist is not supported by hardware.\n");
718 return 1;
719 }
720 break;
721 default:
722 dev_err(dev->class_dev,
723 "ni_labpc: bug! in chanlist check\n");
724 return 1;
725 break;
726 }
727
728 if (CR_RANGE(cmd->chanlist[i]) != range) {
729 comedi_error(dev,
730 "entries in chanlist must all have the same range\n");
731 return 1;
732 }
124b13b2 733
af81f093
HS
734 if (CR_AREF(cmd->chanlist[i]) != aref) {
735 comedi_error(dev,
736 "entries in chanlist must all have the same reference\n");
737 return 1;
738 }
739 }
124b13b2 740
af81f093 741 return 0;
124b13b2
FMH
742}
743
0a85b6f0
MT
744static int labpc_ai_cmdtest(struct comedi_device *dev,
745 struct comedi_subdevice *s, struct comedi_cmd *cmd)
124b13b2 746{
d0baa0c1 747 const struct labpc_boardinfo *board = comedi_board(dev);
124b13b2
FMH
748 int err = 0;
749 int tmp, tmp2;
27020ffe 750 unsigned int stop_mask;
6f73fbce 751 enum scan_mode mode;
124b13b2 752
27020ffe 753 /* Step 1 : check if triggers are trivially valid */
124b13b2 754
27020ffe
HS
755 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
756 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
757 TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
758 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
759 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
124b13b2 760
124b13b2 761 stop_mask = TRIG_COUNT | TRIG_NONE;
d0baa0c1 762 if (board->register_layout == labpc_1200_layout)
124b13b2 763 stop_mask |= TRIG_EXT;
27020ffe 764 err |= cfc_check_trigger_src(&cmd->stop_src, stop_mask);
124b13b2
FMH
765
766 if (err)
767 return 1;
768
27020ffe 769 /* Step 2a : make sure trigger sources are unique */
124b13b2 770
27020ffe
HS
771 err |= cfc_check_trigger_is_unique(cmd->start_src);
772 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
773 err |= cfc_check_trigger_is_unique(cmd->convert_src);
774 err |= cfc_check_trigger_is_unique(cmd->stop_src);
775
776 /* Step 2b : and mutually compatible */
124b13b2 777
e41a6f6d 778 /* can't have external stop and start triggers at once */
124b13b2
FMH
779 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
780 err++;
781
782 if (err)
783 return 2;
784
88c79301 785 /* Step 3: check if arguments are trivially valid */
124b13b2 786
88c79301
HS
787 if (cmd->start_arg == TRIG_NOW)
788 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
124b13b2 789
412bd046 790 if (!cmd->chanlist_len)
88c79301
HS
791 err |= -EINVAL;
792 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
412bd046 793
88c79301
HS
794 if (cmd->convert_src == TRIG_TIMER)
795 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
d0baa0c1 796 board->ai_speed);
124b13b2 797
e41a6f6d 798 /* make sure scan timing is not too fast */
124b13b2 799 if (cmd->scan_begin_src == TRIG_TIMER) {
88c79301
HS
800 if (cmd->convert_src == TRIG_TIMER)
801 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
802 cmd->convert_arg * cmd->chanlist_len);
803 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
d0baa0c1 804 board->ai_speed * cmd->chanlist_len);
124b13b2 805 }
88c79301 806
124b13b2
FMH
807 switch (cmd->stop_src) {
808 case TRIG_COUNT:
88c79301 809 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
124b13b2
FMH
810 break;
811 case TRIG_NONE:
88c79301 812 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
124b13b2 813 break;
1309e617
MD
814 /*
815 * TRIG_EXT doesn't care since it doesn't
816 * trigger off a numbered channel
817 */
124b13b2
FMH
818 default:
819 break;
820 }
821
822 if (err)
823 return 3;
824
825 /* step 4: fix up any arguments */
826
827 tmp = cmd->convert_arg;
828 tmp2 = cmd->scan_begin_arg;
6f73fbce
IA
829 mode = labpc_ai_scan_mode(cmd);
830 labpc_adc_timing(dev, cmd, mode);
124b13b2
FMH
831 if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
832 err++;
833
834 if (err)
835 return 4;
836
6f73fbce 837 if (labpc_ai_chanlist_invalid(dev, cmd, mode))
124b13b2
FMH
838 return 5;
839
840 return 0;
841}
842
da91b269 843static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
124b13b2 844{
d0baa0c1 845 const struct labpc_boardinfo *board = comedi_board(dev);
9a1a6cf8 846 struct labpc_private *devpriv = dev->private;
d163679c 847 struct comedi_async *async = s->async;
ea6d0d4c 848 struct comedi_cmd *cmd = &async->cmd;
8a67a67f
HS
849 enum scan_mode mode = labpc_ai_scan_mode(cmd);
850 unsigned int chanspec = (mode == MODE_MULT_CHAN_UP)
851 ? cmd->chanlist[cmd->chanlist_len - 1]
852 : cmd->chanlist[0];
853 unsigned int chan = CR_CHAN(chanspec);
854 unsigned int range = CR_RANGE(chanspec);
855 unsigned int aref = CR_AREF(chanspec);
124b13b2
FMH
856 enum transfer_type xfer;
857 unsigned long flags;
8a67a67f 858 int ret;
124b13b2 859
25985edc 860 /* make sure board is disabled before setting up acquisition */
8a498667 861 labpc_cancel(dev, s);
124b13b2 862
f6b49620 863 /* initialize software conversion count */
412bd046 864 if (cmd->stop_src == TRIG_COUNT)
124b13b2 865 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
65d6d26c 866
f6b49620 867 /* setup hardware conversion counter */
124b13b2 868 if (cmd->stop_src == TRIG_EXT) {
1309e617
MD
869 /*
870 * load counter a1 with count of 3
871 * (pc+ manual says this is minimum allowed) using mode 0
872 */
124b13b2 873 ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
fbca05d6 874 1, 3, I8254_MODE0);
463f9304
HS
875 } else {
876 /* just put counter a1 in mode 0 to set its output low */
f06563f0
HS
877 ret = labpc_counter_set_mode(dev,
878 dev->iobase + COUNTER_A_BASE_REG,
879 1, I8254_MODE0);
880 }
881 if (ret) {
882 comedi_error(dev, "error loading counter a1");
883 return ret;
463f9304 884 }
124b13b2 885
3297d6c7 886#ifdef CONFIG_ISA_DMA_API
f6b49620
BP
887 /* figure out what method we will use to transfer data */
888 if (devpriv->dma_chan && /* need a dma channel allocated */
1309e617
MD
889 /*
890 * dma unsafe at RT priority,
891 * and too much setup time for TRIG_WAKE_EOS for
892 */
3a0a73b3 893 (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) == 0) {
124b13b2 894 xfer = isa_dma_transfer;
1309e617 895 /* pc-plus has no fifo-half full interrupt */
3297d6c7
RD
896 } else
897#endif
d0baa0c1 898 if (board->register_layout == labpc_1200_layout &&
0a85b6f0
MT
899 /* wake-end-of-scan should interrupt on fifo not empty */
900 (cmd->flags & TRIG_WAKE_EOS) == 0 &&
901 /* make sure we are taking more than just a few points */
902 (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) {
124b13b2
FMH
903 xfer = fifo_half_full_transfer;
904 } else
905 xfer = fifo_not_empty_transfer;
906 devpriv->current_transfer = xfer;
907
8c2bc333
HS
908 labpc_ai_set_chan_and_gain(dev, mode, chan, range, aref);
909
359553bb
HS
910 labpc_setup_cmd6_reg(dev, s, mode, xfer, range, aref,
911 (cmd->stop_src == TRIG_EXT));
912
e41a6f6d 913 /* manual says to set scan enable bit on second pass */
6f73fbce 914 if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) {
42cb6a82 915 devpriv->cmd1 |= CMD1_SCANEN;
e41a6f6d
SR
916 /* need a brief delay before enabling scan, or scan
917 * list will get screwed when you switch
124b13b2 918 * between scan up to scan down mode - dunno why */
5f74ea14 919 udelay(1);
42cb6a82 920 devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
124b13b2 921 }
124b13b2
FMH
922
923 devpriv->write_byte(cmd->chanlist_len,
0a85b6f0 924 dev->iobase + INTERVAL_COUNT_REG);
f6b49620 925 /* load count */
42cb6a82 926 devpriv->write_byte(0x1, dev->iobase + INTERVAL_STROBE_REG);
124b13b2 927
d5c8d9c4
HS
928 if (cmd->convert_src == TRIG_TIMER ||
929 cmd->scan_begin_src == TRIG_TIMER) {
f6b49620 930 /* set up pacing */
6f73fbce 931 labpc_adc_timing(dev, cmd, mode);
f6b49620 932 /* load counter b0 in mode 3 */
124b13b2 933 ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
fbca05d6 934 0, devpriv->divisor_b0, I8254_MODE3);
124b13b2
FMH
935 if (ret < 0) {
936 comedi_error(dev, "error loading counter b0");
937 return -1;
938 }
939 }
f6b49620 940 /* set up conversion pacing */
6f73fbce 941 if (labpc_ai_convert_period(cmd, mode)) {
f6b49620 942 /* load counter a0 in mode 2 */
124b13b2 943 ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
fbca05d6 944 0, devpriv->divisor_a0, I8254_MODE2);
463f9304
HS
945 } else {
946 /* initialize pacer counter to prevent any problems */
f06563f0
HS
947 ret = labpc_counter_set_mode(dev,
948 dev->iobase + COUNTER_A_BASE_REG,
949 0, I8254_MODE2);
950 }
951 if (ret) {
952 comedi_error(dev, "error loading counter a0");
953 return ret;
463f9304 954 }
124b13b2 955
f6b49620 956 /* set up scan pacing */
6f73fbce 957 if (labpc_ai_scan_period(cmd, mode)) {
f6b49620 958 /* load counter b1 in mode 2 */
124b13b2 959 ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
fbca05d6 960 1, devpriv->divisor_b1, I8254_MODE2);
124b13b2
FMH
961 if (ret < 0) {
962 comedi_error(dev, "error loading counter b1");
963 return -1;
964 }
965 }
966
967 labpc_clear_adc_fifo(dev);
968
3297d6c7 969#ifdef CONFIG_ISA_DMA_API
f6b49620 970 /* set up dma transfer */
124b13b2 971 if (xfer == isa_dma_transfer) {
fe7fc72a
HS
972 unsigned long irq_flags;
973
124b13b2
FMH
974 irq_flags = claim_dma_lock();
975 disable_dma(devpriv->dma_chan);
976 /* clear flip-flop to make sure 2-byte registers for
977 * count and address get set correctly */
978 clear_dma_ff(devpriv->dma_chan);
979 set_dma_addr(devpriv->dma_chan,
0a85b6f0 980 virt_to_bus(devpriv->dma_buffer));
f6b49620 981 /* set appropriate size of transfer */
62fea8c8 982 devpriv->dma_transfer_size = labpc_suggest_transfer_size(cmd);
124b13b2 983 if (cmd->stop_src == TRIG_COUNT &&
0a85b6f0 984 devpriv->count * sample_size < devpriv->dma_transfer_size) {
124b13b2 985 devpriv->dma_transfer_size =
0a85b6f0 986 devpriv->count * sample_size;
124b13b2
FMH
987 }
988 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
989 enable_dma(devpriv->dma_chan);
990 release_dma_lock(irq_flags);
f6b49620 991 /* enable board's dma */
42cb6a82 992 devpriv->cmd3 |= (CMD3_DMAEN | CMD3_DMATCINTEN);
124b13b2 993 } else
42cb6a82 994 devpriv->cmd3 &= ~(CMD3_DMAEN | CMD3_DMATCINTEN);
3297d6c7 995#endif
124b13b2 996
f6b49620 997 /* enable error interrupts */
42cb6a82 998 devpriv->cmd3 |= CMD3_ERRINTEN;
f6b49620 999 /* enable fifo not empty interrupt? */
124b13b2 1000 if (xfer == fifo_not_empty_transfer)
42cb6a82 1001 devpriv->cmd3 |= CMD3_FIFOINTEN;
124b13b2 1002 else
42cb6a82
HS
1003 devpriv->cmd3 &= ~CMD3_FIFOINTEN;
1004 devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
124b13b2 1005
74df5760
HS
1006 /* setup any external triggering/pacing (cmd4 register) */
1007 devpriv->cmd4 = 0;
22056e2b 1008 if (cmd->convert_src != TRIG_EXT)
42cb6a82 1009 devpriv->cmd4 |= CMD4_ECLKRCV;
22056e2b
IA
1010 /* XXX should discard first scan when using interval scanning
1011 * since manual says it is not synced with scan clock */
63a93381 1012 if (!labpc_use_continuous_mode(cmd, mode)) {
42cb6a82 1013 devpriv->cmd4 |= CMD4_INTSCAN;
22056e2b 1014 if (cmd->scan_begin_src == TRIG_EXT)
42cb6a82 1015 devpriv->cmd4 |= CMD4_EOIRCV;
22056e2b
IA
1016 }
1017 /* single-ended/differential */
1018 if (aref == AREF_DIFF)
42cb6a82
HS
1019 devpriv->cmd4 |= CMD4_SEDIFF;
1020 devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
22056e2b 1021
25985edc 1022 /* startup acquisition */
124b13b2 1023
5f74ea14 1024 spin_lock_irqsave(&dev->spinlock, flags);
58cd9b91
HS
1025
1026 /* use 2 cascaded counters for pacing */
42cb6a82 1027 devpriv->cmd2 |= CMD2_TBSEL;
58cd9b91
HS
1028
1029 devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
1030 if (cmd->start_src == TRIG_EXT)
42cb6a82 1031 devpriv->cmd2 |= CMD2_HWTRIG;
58cd9b91 1032 else
42cb6a82 1033 devpriv->cmd2 |= CMD2_SWTRIG;
58cd9b91 1034 if (cmd->stop_src == TRIG_EXT)
42cb6a82 1035 devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG);
58cd9b91 1036
42cb6a82 1037 devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
58cd9b91 1038
5f74ea14 1039 spin_unlock_irqrestore(&dev->spinlock, flags);
124b13b2
FMH
1040
1041 return 0;
1042}
1043
571e06c1
HS
1044#ifdef CONFIG_ISA_DMA_API
1045static void labpc_drain_dma(struct comedi_device *dev)
1046{
1047 struct labpc_private *devpriv = dev->private;
1048 struct comedi_subdevice *s = dev->read_subdev;
1049 struct comedi_async *async = s->async;
1050 int status;
1051 unsigned long flags;
1052 unsigned int max_points, num_points, residue, leftover;
1053 int i;
1054
74df5760 1055 status = devpriv->stat1;
571e06c1
HS
1056
1057 flags = claim_dma_lock();
1058 disable_dma(devpriv->dma_chan);
1059 /* clear flip-flop to make sure 2-byte registers for
1060 * count and address get set correctly */
1061 clear_dma_ff(devpriv->dma_chan);
1062
1063 /* figure out how many points to read */
1064 max_points = devpriv->dma_transfer_size / sample_size;
1065 /* residue is the number of points left to be done on the dma
1066 * transfer. It should always be zero at this point unless
1067 * the stop_src is set to external triggering.
1068 */
1069 residue = get_dma_residue(devpriv->dma_chan) / sample_size;
1070 num_points = max_points - residue;
1071 if (devpriv->count < num_points && async->cmd.stop_src == TRIG_COUNT)
1072 num_points = devpriv->count;
1073
1074 /* figure out how many points will be stored next time */
1075 leftover = 0;
1076 if (async->cmd.stop_src != TRIG_COUNT) {
1077 leftover = devpriv->dma_transfer_size / sample_size;
1078 } else if (devpriv->count > num_points) {
1079 leftover = devpriv->count - num_points;
1080 if (leftover > max_points)
1081 leftover = max_points;
1082 }
1083
1084 /* write data to comedi buffer */
1085 for (i = 0; i < num_points; i++)
1086 cfc_write_to_buffer(s, devpriv->dma_buffer[i]);
1087
1088 if (async->cmd.stop_src == TRIG_COUNT)
1089 devpriv->count -= num_points;
1090
1091 /* set address and count for next transfer */
1092 set_dma_addr(devpriv->dma_chan, virt_to_bus(devpriv->dma_buffer));
1093 set_dma_count(devpriv->dma_chan, leftover * sample_size);
1094 release_dma_lock(flags);
1095
1096 async->events |= COMEDI_CB_BLOCK;
1097}
1098
1099static void handle_isa_dma(struct comedi_device *dev)
1100{
1101 struct labpc_private *devpriv = dev->private;
1102
1103 labpc_drain_dma(dev);
1104
1105 enable_dma(devpriv->dma_chan);
1106
1107 /* clear dma tc interrupt */
1108 devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG);
1109}
1110#endif
1111
1112/* read all available samples from ai fifo */
1113static int labpc_drain_fifo(struct comedi_device *dev)
1114{
1115 struct labpc_private *devpriv = dev->private;
571e06c1
HS
1116 short data;
1117 struct comedi_async *async = dev->read_subdev->async;
1118 const int timeout = 10000;
1119 unsigned int i;
1120
42cb6a82 1121 devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
571e06c1 1122
42cb6a82 1123 for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout;
571e06c1
HS
1124 i++) {
1125 /* quit if we have all the data we want */
1126 if (async->cmd.stop_src == TRIG_COUNT) {
1127 if (devpriv->count == 0)
1128 break;
1129 devpriv->count--;
1130 }
3c4dfac8 1131 data = labpc_read_adc_fifo(dev);
571e06c1 1132 cfc_write_to_buffer(dev->read_subdev, data);
42cb6a82 1133 devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
571e06c1
HS
1134 }
1135 if (i == timeout) {
1136 comedi_error(dev, "ai timeout, fifo never empties");
1137 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1138 return -1;
1139 }
1140
1141 return 0;
1142}
1143
1144/* makes sure all data acquired by board is transferred to comedi (used
1145 * when acquisition is terminated by stop_src == TRIG_EXT). */
1146static void labpc_drain_dregs(struct comedi_device *dev)
1147{
1148#ifdef CONFIG_ISA_DMA_API
1149 struct labpc_private *devpriv = dev->private;
1150
1151 if (devpriv->current_transfer == isa_dma_transfer)
1152 labpc_drain_dma(dev);
1153#endif
1154
1155 labpc_drain_fifo(dev);
1156}
1157
1158/* interrupt service routine */
1159static irqreturn_t labpc_interrupt(int irq, void *d)
1160{
1161 struct comedi_device *dev = d;
d0baa0c1 1162 const struct labpc_boardinfo *board = comedi_board(dev);
571e06c1
HS
1163 struct labpc_private *devpriv = dev->private;
1164 struct comedi_subdevice *s = dev->read_subdev;
1165 struct comedi_async *async;
1166 struct comedi_cmd *cmd;
1167
1168 if (!dev->attached) {
1169 comedi_error(dev, "premature interrupt");
1170 return IRQ_HANDLED;
1171 }
1172
1173 async = s->async;
1174 cmd = &async->cmd;
1175 async->events = 0;
1176
1177 /* read board status */
42cb6a82 1178 devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
d0baa0c1 1179 if (board->register_layout == labpc_1200_layout)
42cb6a82 1180 devpriv->stat2 = devpriv->read_byte(dev->iobase + STAT2_REG);
571e06c1 1181
42cb6a82
HS
1182 if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
1183 STAT1_OVERRUN | STAT1_DAVAIL)) == 0
1184 && (devpriv->stat2 & STAT2_OUTA1) == 0
1185 && (devpriv->stat2 & STAT2_FIFONHF)) {
571e06c1
HS
1186 return IRQ_NONE;
1187 }
1188
42cb6a82 1189 if (devpriv->stat1 & STAT1_OVERRUN) {
571e06c1 1190 /* clear error interrupt */
42cb6a82 1191 devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
571e06c1
HS
1192 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1193 comedi_event(dev, s);
1194 comedi_error(dev, "overrun");
1195 return IRQ_HANDLED;
1196 }
1197
1198#ifdef CONFIG_ISA_DMA_API
1199 if (devpriv->current_transfer == isa_dma_transfer) {
1200 /*
1201 * if a dma terminal count of external stop trigger
1202 * has occurred
1203 */
42cb6a82 1204 if (devpriv->stat1 & STAT1_GATA0 ||
d0baa0c1 1205 (board->register_layout == labpc_1200_layout
42cb6a82 1206 && devpriv->stat2 & STAT2_OUTA1)) {
571e06c1
HS
1207 handle_isa_dma(dev);
1208 }
1209 } else
1210#endif
1211 labpc_drain_fifo(dev);
1212
42cb6a82 1213 if (devpriv->stat1 & STAT1_CNTINT) {
571e06c1
HS
1214 comedi_error(dev, "handled timer interrupt?");
1215 /* clear it */
1216 devpriv->write_byte(0x1, dev->iobase + TIMER_CLEAR_REG);
1217 }
1218
42cb6a82 1219 if (devpriv->stat1 & STAT1_OVERFLOW) {
571e06c1 1220 /* clear error interrupt */
42cb6a82 1221 devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
571e06c1
HS
1222 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1223 comedi_event(dev, s);
1224 comedi_error(dev, "overflow");
1225 return IRQ_HANDLED;
1226 }
1227 /* handle external stop trigger */
1228 if (cmd->stop_src == TRIG_EXT) {
42cb6a82 1229 if (devpriv->stat2 & STAT2_OUTA1) {
571e06c1
HS
1230 labpc_drain_dregs(dev);
1231 labpc_cancel(dev, s);
1232 async->events |= COMEDI_CB_EOA;
1233 }
1234 }
1235
1236 /* TRIG_COUNT end of acquisition */
1237 if (cmd->stop_src == TRIG_COUNT) {
1238 if (devpriv->count == 0) {
1239 labpc_cancel(dev, s);
1240 async->events |= COMEDI_CB_EOA;
1241 }
1242 }
1243
1244 comedi_event(dev, s);
1245 return IRQ_HANDLED;
1246}
1247
28a10930
HS
1248static int labpc_ao_insn_write(struct comedi_device *dev,
1249 struct comedi_subdevice *s,
1250 struct comedi_insn *insn,
1251 unsigned int *data)
8913491d 1252{
d0baa0c1 1253 const struct labpc_boardinfo *board = comedi_board(dev);
8913491d
HS
1254 struct labpc_private *devpriv = dev->private;
1255 int channel, range;
1256 unsigned long flags;
1257 int lsb, msb;
1258
1259 channel = CR_CHAN(insn->chanspec);
1260
1261 /* turn off pacing of analog output channel */
1262 /* note: hardware bug in daqcard-1200 means pacing cannot
1263 * be independently enabled/disabled for its the two channels */
1264 spin_lock_irqsave(&dev->spinlock, flags);
42cb6a82
HS
1265 devpriv->cmd2 &= ~CMD2_LDAC(channel);
1266 devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
8913491d
HS
1267 spin_unlock_irqrestore(&dev->spinlock, flags);
1268
1269 /* set range */
d0baa0c1 1270 if (board->register_layout == labpc_1200_layout) {
8913491d 1271 range = CR_RANGE(insn->chanspec);
43a9411a 1272 if (labpc_range_is_unipolar(s, range))
42cb6a82 1273 devpriv->cmd6 |= CMD6_DACUNI(channel);
8913491d 1274 else
42cb6a82 1275 devpriv->cmd6 &= ~CMD6_DACUNI(channel);
8913491d 1276 /* write to register */
42cb6a82 1277 devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
8913491d
HS
1278 }
1279 /* send data */
1280 lsb = data[0] & 0xff;
1281 msb = (data[0] >> 8) & 0xff;
1282 devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel));
1283 devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel));
1284
1285 /* remember value for readback */
1286 devpriv->ao_value[channel] = data[0];
1287
1288 return 1;
1289}
1290
28a10930
HS
1291static int labpc_ao_insn_read(struct comedi_device *dev,
1292 struct comedi_subdevice *s,
1293 struct comedi_insn *insn,
1294 unsigned int *data)
8913491d
HS
1295{
1296 struct labpc_private *devpriv = dev->private;
1297
1298 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
1299
1300 return 1;
1301}
1302
370c8e1f 1303static int labpc_8255_mmio(int dir, int port, int data, unsigned long iobase)
124b13b2
FMH
1304{
1305 if (dir) {
5743aaac 1306 writeb(data, (void __iomem *)(iobase + port));
124b13b2
FMH
1307 return 0;
1308 } else {
5743aaac 1309 return readb((void __iomem *)(iobase + port));
124b13b2
FMH
1310 }
1311}
1312
f6b49620 1313/* lowlevel write to eeprom/dac */
da91b269 1314static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
0a85b6f0 1315 unsigned int value_width)
124b13b2 1316{
9a1a6cf8 1317 struct labpc_private *devpriv = dev->private;
124b13b2
FMH
1318 int i;
1319
1320 for (i = 1; i <= value_width; i++) {
f6b49620 1321 /* clear serial clock */
42cb6a82 1322 devpriv->cmd5 &= ~CMD5_SCLK;
f6b49620 1323 /* send bits most significant bit first */
124b13b2 1324 if (value & (1 << (value_width - i)))
42cb6a82 1325 devpriv->cmd5 |= CMD5_SDATA;
124b13b2 1326 else
42cb6a82 1327 devpriv->cmd5 &= ~CMD5_SDATA;
5f74ea14 1328 udelay(1);
42cb6a82 1329 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
f6b49620 1330 /* set clock to load bit */
42cb6a82 1331 devpriv->cmd5 |= CMD5_SCLK;
5f74ea14 1332 udelay(1);
42cb6a82 1333 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2
FMH
1334 }
1335}
1336
f6b49620 1337/* lowlevel read from eeprom */
da91b269 1338static unsigned int labpc_serial_in(struct comedi_device *dev)
124b13b2 1339{
9a1a6cf8 1340 struct labpc_private *devpriv = dev->private;
124b13b2
FMH
1341 unsigned int value = 0;
1342 int i;
f6b49620 1343 const int value_width = 8; /* number of bits wide values are */
124b13b2
FMH
1344
1345 for (i = 1; i <= value_width; i++) {
f6b49620 1346 /* set serial clock */
42cb6a82 1347 devpriv->cmd5 |= CMD5_SCLK;
5f74ea14 1348 udelay(1);
42cb6a82 1349 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
f6b49620 1350 /* clear clock bit */
42cb6a82 1351 devpriv->cmd5 &= ~CMD5_SCLK;
5f74ea14 1352 udelay(1);
42cb6a82 1353 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
f6b49620 1354 /* read bits most significant bit first */
5f74ea14 1355 udelay(1);
42cb6a82
HS
1356 devpriv->stat2 = devpriv->read_byte(dev->iobase + STAT2_REG);
1357 if (devpriv->stat2 & STAT2_PROMOUT)
124b13b2 1358 value |= 1 << (value_width - i);
124b13b2
FMH
1359 }
1360
1361 return value;
1362}
1363
0a85b6f0
MT
1364static unsigned int labpc_eeprom_read(struct comedi_device *dev,
1365 unsigned int address)
124b13b2 1366{
9a1a6cf8 1367 struct labpc_private *devpriv = dev->private;
124b13b2 1368 unsigned int value;
e41a6f6d
SR
1369 /* bits to tell eeprom to expect a read */
1370 const int read_instruction = 0x3;
1371 /* 8 bit write lengths to eeprom */
1372 const int write_length = 8;
124b13b2 1373
f6b49620 1374 /* enable read/write to eeprom */
42cb6a82 1375 devpriv->cmd5 &= ~CMD5_EEPROMCS;
5f74ea14 1376 udelay(1);
42cb6a82
HS
1377 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
1378 devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
5f74ea14 1379 udelay(1);
42cb6a82 1380 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2 1381
f6b49620 1382 /* send read instruction */
124b13b2 1383 labpc_serial_out(dev, read_instruction, write_length);
f6b49620 1384 /* send 8 bit address to read from */
124b13b2 1385 labpc_serial_out(dev, address, write_length);
f6b49620 1386 /* read result */
124b13b2
FMH
1387 value = labpc_serial_in(dev);
1388
f6b49620 1389 /* disable read/write to eeprom */
42cb6a82 1390 devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
5f74ea14 1391 udelay(1);
42cb6a82 1392 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2
FMH
1393
1394 return value;
1395}
1396
bc3fc446
HS
1397static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
1398{
1399 struct labpc_private *devpriv = dev->private;
1400 unsigned int value;
1401 const int read_status_instruction = 0x5;
1402 const int write_length = 8; /* 8 bit write lengths to eeprom */
1403
1404 /* enable read/write to eeprom */
42cb6a82 1405 devpriv->cmd5 &= ~CMD5_EEPROMCS;
bc3fc446 1406 udelay(1);
42cb6a82
HS
1407 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
1408 devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
bc3fc446 1409 udelay(1);
42cb6a82 1410 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
bc3fc446
HS
1411
1412 /* send read status instruction */
1413 labpc_serial_out(dev, read_status_instruction, write_length);
1414 /* read result */
1415 value = labpc_serial_in(dev);
1416
1417 /* disable read/write to eeprom */
42cb6a82 1418 devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
bc3fc446 1419 udelay(1);
42cb6a82 1420 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
bc3fc446
HS
1421
1422 return value;
1423}
1424
d6269644
JL
1425static int labpc_eeprom_write(struct comedi_device *dev,
1426 unsigned int address, unsigned int value)
124b13b2 1427{
9a1a6cf8 1428 struct labpc_private *devpriv = dev->private;
124b13b2
FMH
1429 const int write_enable_instruction = 0x6;
1430 const int write_instruction = 0x2;
f6b49620 1431 const int write_length = 8; /* 8 bit write lengths to eeprom */
124b13b2
FMH
1432 const int write_in_progress_bit = 0x1;
1433 const int timeout = 10000;
1434 int i;
1435
f6b49620 1436 /* make sure there isn't already a write in progress */
124b13b2
FMH
1437 for (i = 0; i < timeout; i++) {
1438 if ((labpc_eeprom_read_status(dev) & write_in_progress_bit) ==
0a85b6f0 1439 0)
124b13b2
FMH
1440 break;
1441 }
1442 if (i == timeout) {
1443 comedi_error(dev, "eeprom write timed out");
1444 return -ETIME;
1445 }
f6b49620 1446 /* update software copy of eeprom */
124b13b2
FMH
1447 devpriv->eeprom_data[address] = value;
1448
f6b49620 1449 /* enable read/write to eeprom */
42cb6a82 1450 devpriv->cmd5 &= ~CMD5_EEPROMCS;
5f74ea14 1451 udelay(1);
42cb6a82
HS
1452 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
1453 devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
5f74ea14 1454 udelay(1);
42cb6a82 1455 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2 1456
f6b49620 1457 /* send write_enable instruction */
124b13b2 1458 labpc_serial_out(dev, write_enable_instruction, write_length);
42cb6a82 1459 devpriv->cmd5 &= ~CMD5_EEPROMCS;
5f74ea14 1460 udelay(1);
42cb6a82 1461 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2 1462
f6b49620 1463 /* send write instruction */
42cb6a82 1464 devpriv->cmd5 |= CMD5_EEPROMCS;
5f74ea14 1465 udelay(1);
42cb6a82 1466 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2 1467 labpc_serial_out(dev, write_instruction, write_length);
f6b49620 1468 /* send 8 bit address to write to */
124b13b2 1469 labpc_serial_out(dev, address, write_length);
f6b49620 1470 /* write value */
124b13b2 1471 labpc_serial_out(dev, value, write_length);
42cb6a82 1472 devpriv->cmd5 &= ~CMD5_EEPROMCS;
5f74ea14 1473 udelay(1);
42cb6a82 1474 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2 1475
f6b49620 1476 /* disable read/write to eeprom */
42cb6a82 1477 devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
5f74ea14 1478 udelay(1);
42cb6a82 1479 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2
FMH
1480
1481 return 0;
1482}
1483
f6b49620 1484/* writes to 8 bit calibration dacs */
da91b269 1485static void write_caldac(struct comedi_device *dev, unsigned int channel,
0a85b6f0 1486 unsigned int value)
124b13b2 1487{
9a1a6cf8
HS
1488 struct labpc_private *devpriv = dev->private;
1489
124b13b2
FMH
1490 if (value == devpriv->caldac[channel])
1491 return;
1492 devpriv->caldac[channel] = value;
1493
f6b49620 1494 /* clear caldac load bit and make sure we don't write to eeprom */
42cb6a82 1495 devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT);
5f74ea14 1496 udelay(1);
42cb6a82 1497 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2 1498
f6b49620 1499 /* write 4 bit channel */
124b13b2 1500 labpc_serial_out(dev, channel, 4);
f6b49620 1501 /* write 8 bit caldac value */
124b13b2
FMH
1502 labpc_serial_out(dev, value, 8);
1503
f6b49620 1504 /* set and clear caldac bit to load caldac value */
42cb6a82 1505 devpriv->cmd5 |= CMD5_CALDACLD;
5f74ea14 1506 udelay(1);
42cb6a82
HS
1507 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
1508 devpriv->cmd5 &= ~CMD5_CALDACLD;
5f74ea14 1509 udelay(1);
42cb6a82 1510 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
124b13b2
FMH
1511}
1512
28a10930 1513static int labpc_calib_insn_write(struct comedi_device *dev,
bc3fc446 1514 struct comedi_subdevice *s,
28a10930
HS
1515 struct comedi_insn *insn,
1516 unsigned int *data)
bc3fc446 1517{
7c00782b 1518 unsigned int chan = CR_CHAN(insn->chanspec);
bc3fc446 1519
7c00782b
HS
1520 /*
1521 * Only write the last data value to the caldac. Preceding
1522 * data would be overwritten anyway.
1523 */
1524 if (insn->n > 0)
1525 write_caldac(dev, chan, data[insn->n - 1]);
1526
1527 return insn->n;
bc3fc446
HS
1528}
1529
28a10930 1530static int labpc_calib_insn_read(struct comedi_device *dev,
bc3fc446 1531 struct comedi_subdevice *s,
28a10930
HS
1532 struct comedi_insn *insn,
1533 unsigned int *data)
bc3fc446
HS
1534{
1535 struct labpc_private *devpriv = dev->private;
198ac9dc
HS
1536 unsigned int chan = CR_CHAN(insn->chanspec);
1537 int i;
bc3fc446 1538
198ac9dc
HS
1539 for (i = 0; i < insn->n; i++)
1540 data[i] = devpriv->caldac[chan];
bc3fc446 1541
198ac9dc 1542 return insn->n;
bc3fc446
HS
1543}
1544
28a10930 1545static int labpc_eeprom_insn_write(struct comedi_device *dev,
bc3fc446 1546 struct comedi_subdevice *s,
28a10930
HS
1547 struct comedi_insn *insn,
1548 unsigned int *data)
bc3fc446 1549{
e7a1aa62 1550 unsigned int chan = CR_CHAN(insn->chanspec);
bc3fc446
HS
1551 int ret;
1552
e7a1aa62
HS
1553 /* only allow writes to user area of eeprom */
1554 if (chan < 16 || chan > 127)
bc3fc446 1555 return -EINVAL;
bc3fc446 1556
e7a1aa62
HS
1557 /*
1558 * Only write the last data value to the eeprom. Preceding
1559 * data would be overwritten anyway.
1560 */
1561 if (insn->n > 0) {
1562 ret = labpc_eeprom_write(dev, chan, data[insn->n - 1]);
1563 if (ret)
1564 return ret;
1565 }
bc3fc446 1566
e7a1aa62 1567 return insn->n;
bc3fc446
HS
1568}
1569
28a10930 1570static int labpc_eeprom_insn_read(struct comedi_device *dev,
bc3fc446 1571 struct comedi_subdevice *s,
28a10930
HS
1572 struct comedi_insn *insn,
1573 unsigned int *data)
bc3fc446
HS
1574{
1575 struct labpc_private *devpriv = dev->private;
1330af4c
HS
1576 unsigned int chan = CR_CHAN(insn->chanspec);
1577 int i;
bc3fc446 1578
1330af4c
HS
1579 for (i = 0; i < insn->n; i++)
1580 data[i] = devpriv->eeprom_data[chan];
bc3fc446 1581
1330af4c 1582 return insn->n;
bc3fc446
HS
1583}
1584
de024b3d 1585int labpc_common_attach(struct comedi_device *dev,
3e034797 1586 unsigned int irq, unsigned long isr_flags)
dd2aef64 1587{
d0baa0c1 1588 const struct labpc_boardinfo *board = comedi_board(dev);
dd2aef64
HS
1589 struct labpc_private *devpriv = dev->private;
1590 struct comedi_subdevice *s;
dd2aef64 1591 int ret;
cacedd0c 1592 int i;
dd2aef64 1593
4d3cc8ab 1594 if (board->has_mmio) {
dd2aef64
HS
1595 devpriv->read_byte = labpc_readb;
1596 devpriv->write_byte = labpc_writeb;
1597 } else {
1598 devpriv->read_byte = labpc_inb;
1599 devpriv->write_byte = labpc_outb;
1600 }
83d75eff 1601
dd2aef64 1602 /* initialize board's command registers */
42cb6a82
HS
1603 devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
1604 devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
1605 devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
1606 devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
d0baa0c1 1607 if (board->register_layout == labpc_1200_layout) {
42cb6a82
HS
1608 devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
1609 devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
dd2aef64
HS
1610 }
1611
dd2aef64 1612 if (irq) {
0229979a
HS
1613 ret = request_irq(irq, labpc_interrupt, isr_flags,
1614 dev->board_name, dev);
1615 if (ret == 0)
1616 dev->irq = irq;
dd2aef64 1617 }
dd2aef64 1618
dd2aef64
HS
1619 ret = comedi_alloc_subdevices(dev, 5);
1620 if (ret)
1621 return ret;
1622
1623 /* analog input subdevice */
1624 s = &dev->subdevices[0];
9bffb75d
HS
1625 s->type = COMEDI_SUBD_AI;
1626 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1627 s->n_chan = 8;
1628 s->len_chanlist = 8;
1629 s->maxdata = 0x0fff;
1630 s->range_table = board->ai_range_table;
1631 s->insn_read = labpc_ai_insn_read;
1632 if (dev->irq) {
1633 dev->read_subdev = s;
1634 s->subdev_flags |= SDF_CMD_READ;
1635 s->do_cmd = labpc_ai_cmd;
1636 s->do_cmdtest = labpc_ai_cmdtest;
1637 s->cancel = labpc_cancel;
1638 }
dd2aef64
HS
1639
1640 /* analog output */
1641 s = &dev->subdevices[1];
d0baa0c1 1642 if (board->has_ao) {
7d47f0f4
HS
1643 s->type = COMEDI_SUBD_AO;
1644 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1645 s->n_chan = NUM_AO_CHAN;
1646 s->maxdata = 0x0fff;
1647 s->range_table = &range_labpc_ao;
1648 s->insn_read = labpc_ao_insn_read;
1649 s->insn_write = labpc_ao_insn_write;
1650
dd2aef64
HS
1651 /* initialize analog outputs to a known value */
1652 for (i = 0; i < s->n_chan; i++) {
7d47f0f4
HS
1653 short lsb, msb;
1654
dd2aef64
HS
1655 devpriv->ao_value[i] = s->maxdata / 2;
1656 lsb = devpriv->ao_value[i] & 0xff;
1657 msb = (devpriv->ao_value[i] >> 8) & 0xff;
1658 devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(i));
1659 devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(i));
1660 }
1661 } else {
7d47f0f4 1662 s->type = COMEDI_SUBD_UNUSED;
dd2aef64
HS
1663 }
1664
1665 /* 8255 dio */
1666 s = &dev->subdevices[2];
370c8e1f
HS
1667 ret = subdev_8255_init(dev, s,
1668 (board->has_mmio) ? labpc_8255_mmio : NULL,
1669 dev->iobase + DIO_BASE_REG);
1670 if (ret)
1671 return ret;
dd2aef64
HS
1672
1673 /* calibration subdevices for boards that have one */
1674 s = &dev->subdevices[3];
d0baa0c1 1675 if (board->register_layout == labpc_1200_layout) {
7d47f0f4
HS
1676 s->type = COMEDI_SUBD_CALIB;
1677 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1678 s->n_chan = 16;
1679 s->maxdata = 0xff;
1680 s->insn_read = labpc_calib_insn_read;
1681 s->insn_write = labpc_calib_insn_write;
dd2aef64
HS
1682
1683 for (i = 0; i < s->n_chan; i++)
1684 write_caldac(dev, i, s->maxdata / 2);
1685 } else
7d47f0f4 1686 s->type = COMEDI_SUBD_UNUSED;
dd2aef64
HS
1687
1688 /* EEPROM */
1689 s = &dev->subdevices[4];
d0baa0c1 1690 if (board->register_layout == labpc_1200_layout) {
7d47f0f4
HS
1691 s->type = COMEDI_SUBD_MEMORY;
1692 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1693 s->n_chan = EEPROM_SIZE;
1694 s->maxdata = 0xff;
1695 s->insn_read = labpc_eeprom_insn_read;
1696 s->insn_write = labpc_eeprom_insn_write;
1697
1698 for (i = 0; i < s->n_chan; i++)
dd2aef64
HS
1699 devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
1700 } else
7d47f0f4 1701 s->type = COMEDI_SUBD_UNUSED;
dd2aef64
HS
1702
1703 return 0;
1704}
1705EXPORT_SYMBOL_GPL(labpc_common_attach);
1706
fa3cb219
HS
1707void labpc_common_detach(struct comedi_device *dev)
1708{
1709 comedi_spriv_free(dev, 2);
1710}
1711EXPORT_SYMBOL_GPL(labpc_common_detach);
1712
1713#ifdef CONFIG_COMEDI_NI_LABPC_ISA
dd2aef64
HS
1714static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1715{
d0baa0c1 1716 const struct labpc_boardinfo *board = comedi_board(dev);
dd2aef64 1717 struct labpc_private *devpriv;
fa3cb219
HS
1718 unsigned int irq = it->options[1];
1719 unsigned int dma_chan = it->options[2];
5b365a8a 1720 int ret;
dd2aef64
HS
1721
1722 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1723 if (!devpriv)
1724 return -ENOMEM;
1725 dev->private = devpriv;
1726
fa3cb219 1727 ret = comedi_request_region(dev, it->options[0], LABPC_SIZE);
dd2aef64
HS
1728 if (ret)
1729 return ret;
1730
3e034797 1731 ret = labpc_common_attach(dev, irq, 0);
76730884
HS
1732 if (ret)
1733 return ret;
1734
1735#ifdef CONFIG_ISA_DMA_API
1736 if (dev->irq && (dma_chan == 1 || dma_chan == 3)) {
1737 devpriv->dma_buffer = kmalloc(dma_buffer_size,
1738 GFP_KERNEL | GFP_DMA);
1739 if (devpriv->dma_buffer) {
1740 ret = request_dma(dma_chan, dev->board_name);
1741 if (ret == 0) {
1742 unsigned long dma_flags;
1743
1744 devpriv->dma_chan = dma_chan;
1745 dma_flags = claim_dma_lock();
1746 disable_dma(devpriv->dma_chan);
1747 set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
1748 release_dma_lock(dma_flags);
1749 } else {
1750 kfree(devpriv->dma_buffer);
1751 }
1752 }
1753 }
1754#endif
1755
1756 return 0;
dd2aef64
HS
1757}
1758
fa3cb219 1759void labpc_detach(struct comedi_device *dev)
dd2aef64 1760{
dd2aef64 1761 struct labpc_private *devpriv = dev->private;
dd2aef64 1762
fa3cb219
HS
1763 labpc_common_detach(dev);
1764
1765 if (devpriv) {
1766 kfree(devpriv->dma_buffer);
1767 if (devpriv->dma_chan)
1768 free_dma(devpriv->dma_chan);
3d1fe3f7 1769 }
fa3cb219 1770 comedi_legacy_detach(dev);
dd2aef64 1771}
dd2aef64 1772
5e51f0db 1773static struct comedi_driver labpc_driver = {
147a85d7 1774 .driver_name = "ni_labpc",
6e8bddf2
HS
1775 .module = THIS_MODULE,
1776 .attach = labpc_attach,
fa3cb219 1777 .detach = labpc_detach,
6e8bddf2
HS
1778 .num_names = ARRAY_SIZE(labpc_boards),
1779 .board_name = &labpc_boards[0].name,
1780 .offset = sizeof(struct labpc_boardinfo),
5e51f0db 1781};
fa3cb219
HS
1782module_comedi_driver(labpc_driver);
1783#else
1784static int __init labpc_common_init(void)
727b286b 1785{
fa3cb219 1786 return 0;
727b286b 1787}
fa3cb219 1788module_init(labpc_common_init);
727b286b 1789
fa3cb219
HS
1790static void __exit labpc_common_exit(void)
1791{
1792}
1793module_exit(labpc_common_exit);
124b13b2
FMH
1794#endif
1795
90f703d3
AT
1796MODULE_AUTHOR("Comedi http://www.comedi.org");
1797MODULE_DESCRIPTION("Comedi low-level driver");
1798MODULE_LICENSE("GPL");