]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/s626.c
d6dc3381205a6f48797edc72c0a3dc9f00743324
[~andy/linux] / drivers / staging / comedi / drivers / s626.c
1 /*
2   comedi/drivers/s626.c
3   Sensoray s626 Comedi driver
4
5   COMEDI - Linux Control and Measurement Device Interface
6   Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7
8   Based on Sensoray Model 626 Linux driver Version 0.2
9   Copyright (C) 2002-2004 Sensoray Co., Inc.
10
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 2 of the License, or
14   (at your option) any later version.
15
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25 */
26
27 /*
28 Driver: s626
29 Description: Sensoray 626 driver
30 Devices: [Sensoray] 626 (s626)
31 Authors: Gianluca Palli <gpalli@deis.unibo.it>,
32 Updated: Fri, 15 Feb 2008 10:28:42 +0000
33 Status: experimental
34
35 Configuration options:
36   [0] - PCI bus of device (optional)
37   [1] - PCI slot of device (optional)
38   If bus/slot is not specified, the first supported
39   PCI device found will be used.
40
41 INSN_CONFIG instructions:
42   analog input:
43    none
44
45   analog output:
46    none
47
48   digital channel:
49    s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels
50    supported configuration options:
51    INSN_CONFIG_DIO_QUERY
52    COMEDI_INPUT
53    COMEDI_OUTPUT
54
55   encoder:
56    Every channel must be configured before reading.
57
58    Example code
59
60    insn.insn=INSN_CONFIG;   //configuration instruction
61    insn.n=1;                //number of operation (must be 1)
62    insn.data=&initialvalue; //initial value loaded into encoder
63                                 //during configuration
64    insn.subdev=5;           //encoder subdevice
65    insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
66                                                         //to configure
67
68    comedi_do_insn(cf,&insn); //executing configuration
69 */
70
71 #include <linux/interrupt.h>
72 #include <linux/kernel.h>
73 #include <linux/types.h>
74
75 #include "../comedidev.h"
76
77 #include "comedi_fc.h"
78 #include "s626.h"
79
80 #define PCI_VENDOR_ID_S626 0x1131
81 #define PCI_DEVICE_ID_S626 0x7146
82 #define PCI_SUBVENDOR_ID_S626 0x6000
83 #define PCI_SUBDEVICE_ID_S626 0x0272
84
85 struct s626_board {
86         const char *name;
87         int vendor_id;
88         int device_id;
89         int subvendor_id;
90         int subdevice_id;
91         int ai_chans;
92         int ai_bits;
93         int ao_chans;
94         int ao_bits;
95         int dio_chans;
96         int dio_banks;
97         int enc_chans;
98 };
99
100 static const struct s626_board s626_boards[] = {
101         {
102          .name = "s626",
103          .vendor_id = PCI_VENDOR_ID_S626,
104          .device_id = PCI_DEVICE_ID_S626,
105          .subvendor_id = PCI_SUBVENDOR_ID_S626,
106          .subdevice_id = PCI_SUBDEVICE_ID_S626,
107          .ai_chans = S626_ADC_CHANNELS,
108          .ai_bits = 14,
109          .ao_chans = S626_DAC_CHANNELS,
110          .ao_bits = 13,
111          .dio_chans = S626_DIO_CHANNELS,
112          .dio_banks = S626_DIO_BANKS,
113          .enc_chans = S626_ENCODER_CHANNELS,
114          }
115 };
116
117 #define thisboard ((const struct s626_board *)dev->board_ptr)
118
119 struct s626_private {
120         struct pci_dev *pdev;
121         void __iomem *base_addr;
122         int got_regions;
123         short allocatedBuf;
124         uint8_t ai_cmd_running; /*  ai_cmd is running */
125         uint8_t ai_continous;   /*  continous acquisition */
126         int ai_sample_count;    /*  number of samples to acquire */
127         unsigned int ai_sample_timer;
128         /*  time between samples in  units of the timer */
129         int ai_convert_count;   /*  conversion counter */
130         unsigned int ai_convert_timer;
131         /*  time between conversion in  units of the timer */
132         uint16_t CounterIntEnabs;
133         /* Counter interrupt enable  mask for MISC2 register. */
134         uint8_t AdcItems;       /* Number of items in ADC poll  list. */
135         struct bufferDMA RPSBuf;        /* DMA buffer used to hold ADC (RPS1) program. */
136         struct bufferDMA ANABuf;
137         /* DMA buffer used to receive ADC data and hold DAC data. */
138         uint32_t *pDacWBuf;
139         /* Pointer to logical adrs of DMA buffer used to hold DAC  data. */
140         uint16_t Dacpol;        /* Image of DAC polarity register. */
141         uint8_t TrimSetpoint[12];       /* Images of TrimDAC setpoints */
142         uint16_t ChargeEnabled; /* Image of MISC2 Battery */
143         /* Charge Enabled (0 or WRMISC2_CHARGE_ENABLE). */
144         uint16_t WDInterval;    /* Image of MISC2 watchdog interval control bits. */
145         uint32_t I2CAdrs;
146         /* I2C device address for onboard EEPROM (board rev dependent). */
147         /*   short         I2Cards; */
148         unsigned int ao_readback[S626_DAC_CHANNELS];
149 };
150
151 struct dio_private {
152         uint16_t RDDIn;
153         uint16_t WRDOut;
154         uint16_t RDEdgSel;
155         uint16_t WREdgSel;
156         uint16_t RDCapSel;
157         uint16_t WRCapSel;
158         uint16_t RDCapFlg;
159         uint16_t RDIntSel;
160         uint16_t WRIntSel;
161 };
162
163 static struct dio_private dio_private_A = {
164         .RDDIn = LP_RDDINA,
165         .WRDOut = LP_WRDOUTA,
166         .RDEdgSel = LP_RDEDGSELA,
167         .WREdgSel = LP_WREDGSELA,
168         .RDCapSel = LP_RDCAPSELA,
169         .WRCapSel = LP_WRCAPSELA,
170         .RDCapFlg = LP_RDCAPFLGA,
171         .RDIntSel = LP_RDINTSELA,
172         .WRIntSel = LP_WRINTSELA,
173 };
174
175 static struct dio_private dio_private_B = {
176         .RDDIn = LP_RDDINB,
177         .WRDOut = LP_WRDOUTB,
178         .RDEdgSel = LP_RDEDGSELB,
179         .WREdgSel = LP_WREDGSELB,
180         .RDCapSel = LP_RDCAPSELB,
181         .WRCapSel = LP_WRCAPSELB,
182         .RDCapFlg = LP_RDCAPFLGB,
183         .RDIntSel = LP_RDINTSELB,
184         .WRIntSel = LP_WRINTSELB,
185 };
186
187 static struct dio_private dio_private_C = {
188         .RDDIn = LP_RDDINC,
189         .WRDOut = LP_WRDOUTC,
190         .RDEdgSel = LP_RDEDGSELC,
191         .WREdgSel = LP_WREDGSELC,
192         .RDCapSel = LP_RDCAPSELC,
193         .WRCapSel = LP_WRCAPSELC,
194         .RDCapFlg = LP_RDCAPFLGC,
195         .RDIntSel = LP_RDINTSELC,
196         .WRIntSel = LP_WRINTSELC,
197 };
198
199 /* to group dio devices (48 bits mask and data are not allowed ???)
200 static struct dio_private *dio_private_word[]={
201   &dio_private_A,
202   &dio_private_B,
203   &dio_private_C,
204 };
205 */
206
207 #define devpriv ((struct s626_private *)dev->private)
208 #define diopriv ((struct dio_private *)s->private)
209
210 /* ioctl routines */
211 static int s626_ai_insn_config(struct comedi_device *dev,
212                                struct comedi_subdevice *s,
213                                struct comedi_insn *insn, unsigned int *data);
214 /* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */
215 static int s626_ai_insn_read(struct comedi_device *dev,
216                              struct comedi_subdevice *s,
217                              struct comedi_insn *insn, unsigned int *data);
218 static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
219 static int s626_ai_cmdtest(struct comedi_device *dev,
220                            struct comedi_subdevice *s, struct comedi_cmd *cmd);
221 static int s626_ai_cancel(struct comedi_device *dev,
222                           struct comedi_subdevice *s);
223 static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
224                          struct comedi_insn *insn, unsigned int *data);
225 static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
226                          struct comedi_insn *insn, unsigned int *data);
227 static int s626_dio_insn_bits(struct comedi_device *dev,
228                               struct comedi_subdevice *s,
229                               struct comedi_insn *insn, unsigned int *data);
230 static int s626_dio_insn_config(struct comedi_device *dev,
231                                 struct comedi_subdevice *s,
232                                 struct comedi_insn *insn, unsigned int *data);
233 static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan);
234 static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int gruop,
235                               unsigned int mask);
236 static int s626_dio_clear_irq(struct comedi_device *dev);
237 static int s626_enc_insn_config(struct comedi_device *dev,
238                                 struct comedi_subdevice *s,
239                                 struct comedi_insn *insn, unsigned int *data);
240 static int s626_enc_insn_read(struct comedi_device *dev,
241                               struct comedi_subdevice *s,
242                               struct comedi_insn *insn, unsigned int *data);
243 static int s626_enc_insn_write(struct comedi_device *dev,
244                                struct comedi_subdevice *s,
245                                struct comedi_insn *insn, unsigned int *data);
246 static int s626_ns_to_timer(int *nanosec, int round_mode);
247 static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd);
248 static int s626_ai_inttrig(struct comedi_device *dev,
249                            struct comedi_subdevice *s, unsigned int trignum);
250 static irqreturn_t s626_irq_handler(int irq, void *d);
251 static unsigned int s626_ai_reg_to_uint(int data);
252 /* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data); */
253
254 /* end ioctl routines */
255
256 /* internal routines */
257 static void s626_dio_init(struct comedi_device *dev);
258 static void ResetADC(struct comedi_device *dev, uint8_t * ppl);
259 static void LoadTrimDACs(struct comedi_device *dev);
260 static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
261                          uint8_t DacData);
262 static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr);
263 static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val);
264 static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata);
265 static void SendDAC(struct comedi_device *dev, uint32_t val);
266 static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage);
267 static void DEBItransfer(struct comedi_device *dev);
268 static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr);
269 static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata);
270 static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
271                         uint16_t wdata);
272 static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
273                       size_t bsize);
274
275 /*  COUNTER OBJECT ------------------------------------------------ */
276 struct enc_private {
277         /*  Pointers to functions that differ for A and B counters: */
278         uint16_t(*GetEnable) (struct comedi_device *dev, struct enc_private *); /* Return clock enable. */
279         uint16_t(*GetIntSrc) (struct comedi_device *dev, struct enc_private *); /* Return interrupt source. */
280         uint16_t(*GetLoadTrig) (struct comedi_device *dev, struct enc_private *);       /* Return preload trigger source. */
281         uint16_t(*GetMode) (struct comedi_device *dev, struct enc_private *);   /* Return standardized operating mode. */
282         void (*PulseIndex) (struct comedi_device *dev, struct enc_private *);   /* Generate soft index strobe. */
283         void (*SetEnable) (struct comedi_device *dev, struct enc_private *, uint16_t enab);     /* Program clock enable. */
284         void (*SetIntSrc) (struct comedi_device *dev, struct enc_private *, uint16_t IntSource);        /* Program interrupt source. */
285         void (*SetLoadTrig) (struct comedi_device *dev, struct enc_private *, uint16_t Trig);   /* Program preload trigger source. */
286         void (*SetMode) (struct comedi_device *dev, struct enc_private *, uint16_t Setup, uint16_t DisableIntSrc);      /* Program standardized operating mode. */
287         void (*ResetCapFlags) (struct comedi_device *dev, struct enc_private *);        /* Reset event capture flags. */
288
289         uint16_t MyCRA;         /*    Address of CRA register. */
290         uint16_t MyCRB;         /*    Address of CRB register. */
291         uint16_t MyLatchLsw;    /*    Address of Latch least-significant-word */
292         /*    register. */
293         uint16_t MyEventBits[4];        /*    Bit translations for IntSrc -->RDMISC2. */
294 };
295
296 #define encpriv ((struct enc_private *)(dev->subdevices+5)->private)
297
298 /* counters routines */
299 static void s626_timer_load(struct comedi_device *dev, struct enc_private *k,
300                             int tick);
301 static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k);
302 static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k);
303 static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k);
304 static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k);
305 static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k);
306 static void SetMode_A(struct comedi_device *dev, struct enc_private *k,
307                       uint16_t Setup, uint16_t DisableIntSrc);
308 static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
309                       uint16_t Setup, uint16_t DisableIntSrc);
310 static void SetEnable_A(struct comedi_device *dev, struct enc_private *k,
311                         uint16_t enab);
312 static void SetEnable_B(struct comedi_device *dev, struct enc_private *k,
313                         uint16_t enab);
314 static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k);
315 static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k);
316 static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
317                            uint16_t value);
318 /* static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k ); */
319 static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k,
320                           uint16_t Trig);
321 static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k,
322                           uint16_t Trig);
323 static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k);
324 static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k);
325 static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
326                         uint16_t IntSource);
327 static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
328                         uint16_t IntSource);
329 static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k);
330 static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k);
331 /* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value ) ; */
332 /* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k ) ; */
333 /* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value ); */
334 /* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k ) ; */
335 /* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value );  */
336 /* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k );  */
337 /* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value );  */
338 /* static uint16_t GetIndexSrc( struct comedi_device *dev,struct enc_private *k );  */
339 static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k);
340 static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k);
341 static void Preload(struct comedi_device *dev, struct enc_private *k,
342                     uint32_t value);
343 static void CountersInit(struct comedi_device *dev);
344 /* end internal routines */
345
346 /*  Counter objects constructor. */
347
348 /*  Counter overflow/index event flag masks for RDMISC2. */
349 #define INDXMASK(C)             (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 +  4)))
350 #define OVERMASK(C)             (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
351 #define EVBITS(C)               { 0, OVERMASK(C), INDXMASK(C), OVERMASK(C) | INDXMASK(C) }
352
353 /*  Translation table to map IntSrc into equivalent RDMISC2 event flag  bits. */
354 /* static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; */
355
356 /* struct enc_private; */
357 static struct enc_private enc_private_data[] = {
358         {
359          .GetEnable = GetEnable_A,
360          .GetIntSrc = GetIntSrc_A,
361          .GetLoadTrig = GetLoadTrig_A,
362          .GetMode = GetMode_A,
363          .PulseIndex = PulseIndex_A,
364          .SetEnable = SetEnable_A,
365          .SetIntSrc = SetIntSrc_A,
366          .SetLoadTrig = SetLoadTrig_A,
367          .SetMode = SetMode_A,
368          .ResetCapFlags = ResetCapFlags_A,
369          .MyCRA = LP_CR0A,
370          .MyCRB = LP_CR0B,
371          .MyLatchLsw = LP_CNTR0ALSW,
372          .MyEventBits = EVBITS(0),
373          },
374         {
375          .GetEnable = GetEnable_A,
376          .GetIntSrc = GetIntSrc_A,
377          .GetLoadTrig = GetLoadTrig_A,
378          .GetMode = GetMode_A,
379          .PulseIndex = PulseIndex_A,
380          .SetEnable = SetEnable_A,
381          .SetIntSrc = SetIntSrc_A,
382          .SetLoadTrig = SetLoadTrig_A,
383          .SetMode = SetMode_A,
384          .ResetCapFlags = ResetCapFlags_A,
385          .MyCRA = LP_CR1A,
386          .MyCRB = LP_CR1B,
387          .MyLatchLsw = LP_CNTR1ALSW,
388          .MyEventBits = EVBITS(1),
389          },
390         {
391          .GetEnable = GetEnable_A,
392          .GetIntSrc = GetIntSrc_A,
393          .GetLoadTrig = GetLoadTrig_A,
394          .GetMode = GetMode_A,
395          .PulseIndex = PulseIndex_A,
396          .SetEnable = SetEnable_A,
397          .SetIntSrc = SetIntSrc_A,
398          .SetLoadTrig = SetLoadTrig_A,
399          .SetMode = SetMode_A,
400          .ResetCapFlags = ResetCapFlags_A,
401          .MyCRA = LP_CR2A,
402          .MyCRB = LP_CR2B,
403          .MyLatchLsw = LP_CNTR2ALSW,
404          .MyEventBits = EVBITS(2),
405          },
406         {
407          .GetEnable = GetEnable_B,
408          .GetIntSrc = GetIntSrc_B,
409          .GetLoadTrig = GetLoadTrig_B,
410          .GetMode = GetMode_B,
411          .PulseIndex = PulseIndex_B,
412          .SetEnable = SetEnable_B,
413          .SetIntSrc = SetIntSrc_B,
414          .SetLoadTrig = SetLoadTrig_B,
415          .SetMode = SetMode_B,
416          .ResetCapFlags = ResetCapFlags_B,
417          .MyCRA = LP_CR0A,
418          .MyCRB = LP_CR0B,
419          .MyLatchLsw = LP_CNTR0BLSW,
420          .MyEventBits = EVBITS(3),
421          },
422         {
423          .GetEnable = GetEnable_B,
424          .GetIntSrc = GetIntSrc_B,
425          .GetLoadTrig = GetLoadTrig_B,
426          .GetMode = GetMode_B,
427          .PulseIndex = PulseIndex_B,
428          .SetEnable = SetEnable_B,
429          .SetIntSrc = SetIntSrc_B,
430          .SetLoadTrig = SetLoadTrig_B,
431          .SetMode = SetMode_B,
432          .ResetCapFlags = ResetCapFlags_B,
433          .MyCRA = LP_CR1A,
434          .MyCRB = LP_CR1B,
435          .MyLatchLsw = LP_CNTR1BLSW,
436          .MyEventBits = EVBITS(4),
437          },
438         {
439          .GetEnable = GetEnable_B,
440          .GetIntSrc = GetIntSrc_B,
441          .GetLoadTrig = GetLoadTrig_B,
442          .GetMode = GetMode_B,
443          .PulseIndex = PulseIndex_B,
444          .SetEnable = SetEnable_B,
445          .SetIntSrc = SetIntSrc_B,
446          .SetLoadTrig = SetLoadTrig_B,
447          .SetMode = SetMode_B,
448          .ResetCapFlags = ResetCapFlags_B,
449          .MyCRA = LP_CR2A,
450          .MyCRB = LP_CR2B,
451          .MyLatchLsw = LP_CNTR2BLSW,
452          .MyEventBits = EVBITS(5),
453          },
454 };
455
456 /*  enab/disable a function or test status bit(s) that are accessed */
457 /*  through Main Control Registers 1 or 2. */
458 #define MC_ENABLE(REGADRS, CTRLWORD)    writel(((uint32_t)(CTRLWORD) << 16) | (uint32_t)(CTRLWORD), devpriv->base_addr+(REGADRS))
459
460 #define MC_DISABLE(REGADRS, CTRLWORD)   writel((uint32_t)(CTRLWORD) << 16 , devpriv->base_addr+(REGADRS))
461
462 #define MC_TEST(REGADRS, CTRLWORD)      ((readl(devpriv->base_addr+(REGADRS)) & CTRLWORD) != 0)
463
464 /* #define WR7146(REGARDS,CTRLWORD)
465     writel(CTRLWORD,(uint32_t)(devpriv->base_addr+(REGARDS))) */
466 #define WR7146(REGARDS, CTRLWORD) writel(CTRLWORD, devpriv->base_addr+(REGARDS))
467
468 /* #define RR7146(REGARDS)
469     readl((uint32_t)(devpriv->base_addr+(REGARDS))) */
470 #define RR7146(REGARDS)         readl(devpriv->base_addr+(REGARDS))
471
472 #define BUGFIX_STREG(REGADRS)   (REGADRS - 4)
473
474 /*  Write a time slot control record to TSL2. */
475 #define VECTPORT(VECTNUM)               (P_TSL2 + ((VECTNUM) << 2))
476 #define SETVECT(VECTNUM, VECTVAL)       WR7146(VECTPORT(VECTNUM), (VECTVAL))
477
478 /*  Code macros used for constructing I2C command bytes. */
479 #define I2C_B2(ATTR, VAL)       (((ATTR) << 6) | ((VAL) << 24))
480 #define I2C_B1(ATTR, VAL)       (((ATTR) << 4) | ((VAL) << 16))
481 #define I2C_B0(ATTR, VAL)       (((ATTR) << 2) | ((VAL) <<  8))
482
483 static const struct comedi_lrange s626_range_table = { 2, {
484                                                            RANGE(-5, 5),
485                                                            RANGE(-10, 10),
486                                                            }
487 };
488
489 static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
490 {
491 /*   uint8_t    PollList; */
492 /*   uint16_t   AdcData; */
493 /*   uint16_t   StartVal; */
494 /*   uint16_t   index; */
495 /*   unsigned int data[16]; */
496         int result;
497         int i;
498         int ret;
499         resource_size_t resourceStart;
500         dma_addr_t appdma;
501         struct comedi_subdevice *s;
502         struct pci_dev *pdev = NULL;
503
504         if (alloc_private(dev, sizeof(struct s626_private)) < 0)
505                 return -ENOMEM;
506
507         for (i = 0; i < ARRAY_SIZE(s626_boards) && !pdev; i++) {
508                 do {
509                         pdev = pci_get_subsys(s626_boards[i].vendor_id,
510                                               s626_boards[i].device_id,
511                                               s626_boards[i].subvendor_id,
512                                               s626_boards[i].subdevice_id,
513                                               pdev);
514
515                         if ((it->options[0] || it->options[1]) && pdev) {
516                                 /* matches requested bus/slot */
517                                 if (pdev->bus->number == it->options[0] &&
518                                     PCI_SLOT(pdev->devfn) == it->options[1])
519                                         break;
520                         } else
521                                 break;
522                 } while (1);
523         }
524         devpriv->pdev = pdev;
525
526         if (pdev == NULL) {
527                 printk(KERN_ERR "s626_attach: Board not present!!!\n");
528                 return -ENODEV;
529         }
530
531         result = comedi_pci_enable(pdev, "s626");
532         if (result < 0) {
533                 printk(KERN_ERR "s626_attach: comedi_pci_enable fails\n");
534                 return -ENODEV;
535         }
536         devpriv->got_regions = 1;
537
538         resourceStart = pci_resource_start(devpriv->pdev, 0);
539
540         devpriv->base_addr = ioremap(resourceStart, SIZEOF_ADDRESS_SPACE);
541         if (devpriv->base_addr == NULL) {
542                 printk(KERN_ERR "s626_attach: IOREMAP failed\n");
543                 return -ENODEV;
544         }
545
546         if (devpriv->base_addr) {
547                 /* disable master interrupt */
548                 writel(0, devpriv->base_addr + P_IER);
549
550                 /* soft reset */
551                 writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1);
552
553                 /* DMA FIXME DMA// */
554                 DEBUG("s626_attach: DMA ALLOCATION\n");
555
556                 /* adc buffer allocation */
557                 devpriv->allocatedBuf = 0;
558
559                 devpriv->ANABuf.LogicalBase =
560                     pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
561
562                 if (devpriv->ANABuf.LogicalBase == NULL) {
563                         printk(KERN_ERR "s626_attach: DMA Memory mapping error\n");
564                         return -ENOMEM;
565                 }
566
567                 devpriv->ANABuf.PhysicalBase = appdma;
568
569                 DEBUG
570                     ("s626_attach: AllocDMAB ADC Logical=%p, bsize=%d, Physical=0x%x\n",
571                      devpriv->ANABuf.LogicalBase, DMABUF_SIZE,
572                      (uint32_t) devpriv->ANABuf.PhysicalBase);
573
574                 devpriv->allocatedBuf++;
575
576                 devpriv->RPSBuf.LogicalBase =
577                     pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
578
579                 if (devpriv->RPSBuf.LogicalBase == NULL) {
580                         printk(KERN_ERR "s626_attach: DMA Memory mapping error\n");
581                         return -ENOMEM;
582                 }
583
584                 devpriv->RPSBuf.PhysicalBase = appdma;
585
586                 DEBUG
587                     ("s626_attach: AllocDMAB RPS Logical=%p, bsize=%d, Physical=0x%x\n",
588                      devpriv->RPSBuf.LogicalBase, DMABUF_SIZE,
589                      (uint32_t) devpriv->RPSBuf.PhysicalBase);
590
591                 devpriv->allocatedBuf++;
592
593         }
594
595         dev->board_ptr = s626_boards;
596         dev->board_name = thisboard->name;
597
598         if (alloc_subdevices(dev, 6) < 0)
599                 return -ENOMEM;
600
601         dev->iobase = (unsigned long)devpriv->base_addr;
602         dev->irq = devpriv->pdev->irq;
603
604         /* set up interrupt handler */
605         if (dev->irq == 0) {
606                 printk(KERN_ERR " unknown irq (bad)\n");
607         } else {
608                 ret = request_irq(dev->irq, s626_irq_handler, IRQF_SHARED,
609                                   "s626", dev);
610
611                 if (ret < 0) {
612                         printk(KERN_ERR " irq not available\n");
613                         dev->irq = 0;
614                 }
615         }
616
617         DEBUG("s626_attach: -- it opts  %d,%d --\n",
618               it->options[0], it->options[1]);
619
620         s = dev->subdevices + 0;
621         /* analog input subdevice */
622         dev->read_subdev = s;
623         /* we support single-ended (ground) and differential */
624         s->type = COMEDI_SUBD_AI;
625         s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ;
626         s->n_chan = thisboard->ai_chans;
627         s->maxdata = (0xffff >> 2);
628         s->range_table = &s626_range_table;
629         s->len_chanlist = thisboard->ai_chans;  /* This is the maximum chanlist
630                                                    length that the board can
631                                                    handle */
632         s->insn_config = s626_ai_insn_config;
633         s->insn_read = s626_ai_insn_read;
634         s->do_cmd = s626_ai_cmd;
635         s->do_cmdtest = s626_ai_cmdtest;
636         s->cancel = s626_ai_cancel;
637
638         s = dev->subdevices + 1;
639         /* analog output subdevice */
640         s->type = COMEDI_SUBD_AO;
641         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
642         s->n_chan = thisboard->ao_chans;
643         s->maxdata = (0x3fff);
644         s->range_table = &range_bipolar10;
645         s->insn_write = s626_ao_winsn;
646         s->insn_read = s626_ao_rinsn;
647
648         s = dev->subdevices + 2;
649         /* digital I/O subdevice */
650         s->type = COMEDI_SUBD_DIO;
651         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
652         s->n_chan = S626_DIO_CHANNELS;
653         s->maxdata = 1;
654         s->io_bits = 0xffff;
655         s->private = &dio_private_A;
656         s->range_table = &range_digital;
657         s->insn_config = s626_dio_insn_config;
658         s->insn_bits = s626_dio_insn_bits;
659
660         s = dev->subdevices + 3;
661         /* digital I/O subdevice */
662         s->type = COMEDI_SUBD_DIO;
663         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
664         s->n_chan = 16;
665         s->maxdata = 1;
666         s->io_bits = 0xffff;
667         s->private = &dio_private_B;
668         s->range_table = &range_digital;
669         s->insn_config = s626_dio_insn_config;
670         s->insn_bits = s626_dio_insn_bits;
671
672         s = dev->subdevices + 4;
673         /* digital I/O subdevice */
674         s->type = COMEDI_SUBD_DIO;
675         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
676         s->n_chan = 16;
677         s->maxdata = 1;
678         s->io_bits = 0xffff;
679         s->private = &dio_private_C;
680         s->range_table = &range_digital;
681         s->insn_config = s626_dio_insn_config;
682         s->insn_bits = s626_dio_insn_bits;
683
684         s = dev->subdevices + 5;
685         /* encoder (counter) subdevice */
686         s->type = COMEDI_SUBD_COUNTER;
687         s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL;
688         s->n_chan = thisboard->enc_chans;
689         s->private = enc_private_data;
690         s->insn_config = s626_enc_insn_config;
691         s->insn_read = s626_enc_insn_read;
692         s->insn_write = s626_enc_insn_write;
693         s->maxdata = 0xffffff;
694         s->range_table = &range_unknown;
695
696         /* stop ai_command */
697         devpriv->ai_cmd_running = 0;
698
699         if (devpriv->base_addr && (devpriv->allocatedBuf == 2)) {
700                 dma_addr_t pPhysBuf;
701                 uint16_t chan;
702
703                 /*  enab DEBI and audio pins, enable I2C interface. */
704                 MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C);
705                 /*  Configure DEBI operating mode. */
706                 WR7146(P_DEBICFG, DEBI_CFG_SLAVE16      /*  Local bus is 16 */
707                        /*  bits wide. */
708                        | (DEBI_TOUT << DEBI_CFG_TOUT_BIT)
709
710                        /*  Declare DEBI */
711                        /*  transfer timeout */
712                        /*  interval. */
713                        |DEBI_SWAP       /*  Set up byte lane */
714                        /*  steering. */
715                        | DEBI_CFG_INTEL);       /*  Intel-compatible */
716                 /*  local bus (DEBI */
717                 /*  never times out). */
718                 DEBUG("s626_attach: %d debi init -- %d\n",
719                       DEBI_CFG_SLAVE16 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) |
720                       DEBI_SWAP | DEBI_CFG_INTEL,
721                       DEBI_CFG_INTEL | DEBI_CFG_TOQ | DEBI_CFG_INCQ |
722                       DEBI_CFG_16Q);
723
724                 /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */
725                 /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */
726
727                 /*  Paging is disabled. */
728                 WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE);  /*  Disable MMU paging. */
729
730                 /*  Init GPIO so that ADC Start* is negated. */
731                 WR7146(P_GPIO, GPIO_BASE | GPIO1_HI);
732
733                 /* IsBoardRevA is a boolean that indicates whether the board is RevA.
734                  *
735                  * VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC
736                  * EEPROM ADDRESS SELECTION.  Initialize the I2C interface, which
737                  * is used to access the onboard serial EEPROM.  The EEPROM's I2C
738                  * DeviceAddress is hardwired to a value that is dependent on the
739                  * 626 board revision.  On all board revisions, the EEPROM stores
740                  * TrimDAC calibration constants for analog I/O.  On RevB and
741                  * higher boards, the DeviceAddress is hardwired to 0 to enable
742                  * the EEPROM to also store the PCI SubVendorID and SubDeviceID;
743                  * this is the address at which the SAA7146 expects a
744                  * configuration EEPROM to reside.  On RevA boards, the EEPROM
745                  * device address, which is hardwired to 4, prevents the SAA7146
746                  * from retrieving PCI sub-IDs, so the SAA7146 uses its built-in
747                  * default values, instead.
748                  */
749
750                 /*     devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */
751                 /*  DeviceType (0xA0) */
752                 /*  and DeviceAddress<<1. */
753
754                 devpriv->I2CAdrs = 0xA0;        /*  I2C device address for onboard */
755                 /*  eeprom(revb) */
756
757                 /*  Issue an I2C ABORT command to halt any I2C operation in */
758                 /* progress and reset BUSY flag. */
759                 WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT);
760                 /*  Write I2C control: abort any I2C activity. */
761                 MC_ENABLE(P_MC2, MC2_UPLD_IIC);
762                 /*  Invoke command  upload */
763                 while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0)
764                         ;
765                 /*  and wait for upload to complete. */
766
767                 /* Per SAA7146 data sheet, write to STATUS reg twice to
768                  * reset all  I2C error flags. */
769                 for (i = 0; i < 2; i++) {
770                         WR7146(P_I2CSTAT, I2C_CLKSEL);
771                         /*  Write I2C control: reset  error flags. */
772                         MC_ENABLE(P_MC2, MC2_UPLD_IIC); /*  Invoke command upload */
773                         while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
774                                 ;
775                         /* and wait for upload to complete. */
776                 }
777
778                 /* Init audio interface functional attributes: set DAC/ADC
779                  * serial clock rates, invert DAC serial clock so that
780                  * DAC data setup times are satisfied, enable DAC serial
781                  * clock out.
782                  */
783
784                 WR7146(P_ACON2, ACON2_INIT);
785
786                 /* Set up TSL1 slot list, which is used to control the
787                  * accumulation of ADC data: RSD1 = shift data in on SD1.
788                  * SIB_A1  = store data uint8_t at next available location in
789                  * FB BUFFER1  register. */
790                 WR7146(P_TSL1, RSD1 | SIB_A1);
791                 /*  Fetch ADC high data uint8_t. */
792                 WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS);
793                 /*  Fetch ADC low data uint8_t; end of TSL1. */
794
795                 /*  enab TSL1 slot list so that it executes all the time. */
796                 WR7146(P_ACON1, ACON1_ADCSTART);
797
798                 /*  Initialize RPS registers used for ADC. */
799
800                 /* Physical start of RPS program. */
801                 WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
802
803                 WR7146(P_RPSPAGE1, 0);
804                 /*  RPS program performs no explicit mem writes. */
805                 WR7146(P_RPS1_TOUT, 0); /*  Disable RPS timeouts. */
806
807                 /* SAA7146 BUG WORKAROUND.  Initialize SAA7146 ADC interface
808                  * to a known state by invoking ADCs until FB BUFFER 1
809                  * register shows that it is correctly receiving ADC data.
810                  * This is necessary because the SAA7146 ADC interface does
811                  * not start up in a defined state after a PCI reset.
812                  */
813
814 /*     PollList = EOPL;         // Create a simple polling */
815 /*                              // list for analog input */
816 /*                              // channel 0. */
817 /*     ResetADC( dev, &PollList ); */
818
819 /*     s626_ai_rinsn(dev,dev->subdevices,NULL,data); //( &AdcData ); // */
820 /*                                                      //Get initial ADC */
821 /*                                                      //value. */
822
823 /*     StartVal = data[0]; */
824
825 /*     // VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED EXECUTION. */
826 /*     // Invoke ADCs until the new ADC value differs from the initial */
827 /*     // value or a timeout occurs.  The timeout protects against the */
828 /*     // possibility that the driver is restarting and the ADC data is a */
829 /*     // fixed value resulting from the applied ADC analog input being */
830 /*     // unusually quiet or at the rail. */
831
832 /*     for ( index = 0; index < 500; index++ ) */
833 /*       { */
834 /*      s626_ai_rinsn(dev,dev->subdevices,NULL,data); */
835 /*      AdcData = data[0];      //ReadADC(  &AdcData ); */
836 /*      if ( AdcData != StartVal ) */
837 /*              break; */
838 /*       } */
839
840                 /*  end initADC */
841
842                 /*  init the DAC interface */
843
844                 /* Init Audio2's output DMAC attributes: burst length = 1
845                  * DWORD,  threshold = 1 DWORD.
846                  */
847                 WR7146(P_PCI_BT_A, 0);
848
849                 /* Init Audio2's output DMA physical addresses.  The protection
850                  * address is set to 1 DWORD past the base address so that a
851                  * single DWORD will be transferred each time a DMA transfer is
852                  * enabled. */
853
854                 pPhysBuf =
855                     devpriv->ANABuf.PhysicalBase +
856                     (DAC_WDMABUF_OS * sizeof(uint32_t));
857
858                 WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf);      /*  Buffer base adrs. */
859                 WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); /*  Protection address. */
860
861                 /* Cache Audio2's output DMA buffer logical address.  This is
862                  * where DAC data is buffered for A2 output DMA transfers. */
863                 devpriv->pDacWBuf =
864                     (uint32_t *) devpriv->ANABuf.LogicalBase + DAC_WDMABUF_OS;
865
866                 /* Audio2's output channels does not use paging.  The protection
867                  * violation handling bit is set so that the DMAC will
868                  * automatically halt and its PCI address pointer will be reset
869                  * when the protection address is reached. */
870
871                 WR7146(P_PAGEA2_OUT, 8);
872
873                 /* Initialize time slot list 2 (TSL2), which is used to control
874                  * the clock generation for and serialization of data to be sent
875                  * to the DAC devices.  Slot 0 is a NOP that is used to trap TSL
876                  * execution; this permits other slots to be safely modified
877                  * without first turning off the TSL sequencer (which is
878                  * apparently impossible to do).  Also, SD3 (which is driven by a
879                  * pull-up resistor) is shifted in and stored to the MSB of
880                  * FB_BUFFER2 to be used as evidence that the slot sequence has
881                  * not yet finished executing.
882                  */
883
884                 SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS);
885                 /*  Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */
886
887                 /* Initialize slot 1, which is constant.  Slot 1 causes a
888                  * DWORD to be transferred from audio channel 2's output FIFO
889                  * to the FIFO's output buffer so that it can be serialized
890                  * and sent to the DAC during subsequent slots.  All remaining
891                  * slots are dynamically populated as required by the target
892                  * DAC device.
893                  */
894                 SETVECT(1, LF_A2);
895                 /*  Slot 1: Fetch DWORD from Audio2's output FIFO. */
896
897                 /*  Start DAC's audio interface (TSL2) running. */
898                 WR7146(P_ACON1, ACON1_DACSTART);
899
900                 /* end init DAC interface */
901
902                 /* Init Trim DACs to calibrated values.  Do it twice because the
903                  * SAA7146 audio channel does not always reset properly and
904                  * sometimes causes the first few TrimDAC writes to malfunction.
905                  */
906
907                 LoadTrimDACs(dev);
908                 LoadTrimDACs(dev);      /*  Insurance. */
909
910                 /* Manually init all gate array hardware in case this is a soft
911                  * reset (we have no way of determining whether this is a warm
912                  * or cold start).  This is necessary because the gate array will
913                  * reset only in response to a PCI hard reset; there is no soft
914                  * reset function. */
915
916                 /* Init all DAC outputs to 0V and init all DAC setpoint and
917                  * polarity images.
918                  */
919                 for (chan = 0; chan < S626_DAC_CHANNELS; chan++)
920                         SetDAC(dev, chan, 0);
921
922                 /* Init image of WRMISC2 Battery Charger Enabled control bit.
923                  * This image is used when the state of the charger control bit,
924                  * which has no direct hardware readback mechanism, is queried.
925                  */
926                 devpriv->ChargeEnabled = 0;
927
928                 /* Init image of watchdog timer interval in WRMISC2.  This image
929                  * maintains the value of the control bits of MISC2 are
930                  * continuously reset to zero as long as the WD timer is disabled.
931                  */
932                 devpriv->WDInterval = 0;
933
934                 /* Init Counter Interrupt enab mask for RDMISC2.  This mask is
935                  * applied against MISC2 when testing to determine which timer
936                  * events are requesting interrupt service.
937                  */
938                 devpriv->CounterIntEnabs = 0;
939
940                 /*  Init counters. */
941                 CountersInit(dev);
942
943                 /* Without modifying the state of the Battery Backup enab, disable
944                  * the watchdog timer, set DIO channels 0-5 to operate in the
945                  * standard DIO (vs. counter overflow) mode, disable the battery
946                  * charger, and reset the watchdog interval selector to zero.
947                  */
948                 WriteMISC2(dev, (uint16_t) (DEBIread(dev,
949                                                      LP_RDMISC2) &
950                                             MISC2_BATT_ENABLE));
951
952                 /*  Initialize the digital I/O subsystem. */
953                 s626_dio_init(dev);
954
955                 /* enable interrupt test */
956                 /*  writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */
957         }
958
959         DEBUG("s626_attach: comedi%d s626 attached %04x\n", dev->minor,
960               (uint32_t) devpriv->base_addr);
961
962         return 1;
963 }
964
965 static unsigned int s626_ai_reg_to_uint(int data)
966 {
967         unsigned int tempdata;
968
969         tempdata = (data >> 18);
970         if (tempdata & 0x2000)
971                 tempdata &= 0x1fff;
972         else
973                 tempdata += (1 << 13);
974
975         return tempdata;
976 }
977
978 /* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data){ */
979 /*   return 0; */
980 /* } */
981
982 static irqreturn_t s626_irq_handler(int irq, void *d)
983 {
984         struct comedi_device *dev = d;
985         struct comedi_subdevice *s;
986         struct comedi_cmd *cmd;
987         struct enc_private *k;
988         unsigned long flags;
989         int32_t *readaddr;
990         uint32_t irqtype, irqstatus;
991         int i = 0;
992         short tempdata;
993         uint8_t group;
994         uint16_t irqbit;
995
996         DEBUG("s626_irq_handler: interrupt request received!!!\n");
997
998         if (dev->attached == 0)
999                 return IRQ_NONE;
1000         /*  lock to avoid race with comedi_poll */
1001         spin_lock_irqsave(&dev->spinlock, flags);
1002
1003         /* save interrupt enable register state */
1004         irqstatus = readl(devpriv->base_addr + P_IER);
1005
1006         /* read interrupt type */
1007         irqtype = readl(devpriv->base_addr + P_ISR);
1008
1009         /* disable master interrupt */
1010         writel(0, devpriv->base_addr + P_IER);
1011
1012         /* clear interrupt */
1013         writel(irqtype, devpriv->base_addr + P_ISR);
1014
1015         /* do somethings */
1016         DEBUG("s626_irq_handler: interrupt type %d\n", irqtype);
1017
1018         switch (irqtype) {
1019         case IRQ_RPS1:          /*  end_of_scan occurs */
1020
1021                 DEBUG("s626_irq_handler: RPS1 irq detected\n");
1022
1023                 /*  manage ai subdevice */
1024                 s = dev->subdevices;
1025                 cmd = &(s->async->cmd);
1026
1027                 /* Init ptr to DMA buffer that holds new ADC data.  We skip the
1028                  * first uint16_t in the buffer because it contains junk data from
1029                  * the final ADC of the previous poll list scan.
1030                  */
1031                 readaddr = (int32_t *) devpriv->ANABuf.LogicalBase + 1;
1032
1033                 /*  get the data and hand it over to comedi */
1034                 for (i = 0; i < (s->async->cmd.chanlist_len); i++) {
1035                         /*  Convert ADC data to 16-bit integer values and copy to application */
1036                         /*  buffer. */
1037                         tempdata = s626_ai_reg_to_uint((int)*readaddr);
1038                         readaddr++;
1039
1040                         /* put data into read buffer */
1041                         /*  comedi_buf_put(s->async, tempdata); */
1042                         if (cfc_write_to_buffer(s, tempdata) == 0)
1043                                 printk
1044                                     ("s626_irq_handler: cfc_write_to_buffer error!\n");
1045
1046                         DEBUG("s626_irq_handler: ai channel %d acquired: %d\n",
1047                               i, tempdata);
1048                 }
1049
1050                 /* end of scan occurs */
1051                 s->async->events |= COMEDI_CB_EOS;
1052
1053                 if (!(devpriv->ai_continous))
1054                         devpriv->ai_sample_count--;
1055                 if (devpriv->ai_sample_count <= 0) {
1056                         devpriv->ai_cmd_running = 0;
1057
1058                         /*  Stop RPS program. */
1059                         MC_DISABLE(P_MC1, MC1_ERPS1);
1060
1061                         /* send end of acquisition */
1062                         s->async->events |= COMEDI_CB_EOA;
1063
1064                         /* disable master interrupt */
1065                         irqstatus = 0;
1066                 }
1067
1068                 if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) {
1069                         DEBUG
1070                             ("s626_irq_handler: enable interrupt on dio channel %d\n",
1071                              cmd->scan_begin_arg);
1072
1073                         s626_dio_set_irq(dev, cmd->scan_begin_arg);
1074
1075                         DEBUG("s626_irq_handler: External trigger is set!!!\n");
1076                 }
1077                 /*  tell comedi that data is there */
1078                 DEBUG("s626_irq_handler: events %d\n", s->async->events);
1079                 comedi_event(dev, s);
1080                 break;
1081         case IRQ_GPIO3: /* check dio and conter interrupt */
1082
1083                 DEBUG("s626_irq_handler: GPIO3 irq detected\n");
1084
1085                 /*  manage ai subdevice */
1086                 s = dev->subdevices;
1087                 cmd = &(s->async->cmd);
1088
1089                 /* s626_dio_clear_irq(dev); */
1090
1091                 for (group = 0; group < S626_DIO_BANKS; group++) {
1092                         irqbit = 0;
1093                         /* read interrupt type */
1094                         irqbit = DEBIread(dev,
1095                                           ((struct dio_private *)(dev->
1096                                                                   subdevices +
1097                                                                   2 +
1098                                                                   group)->
1099                                            private)->RDCapFlg);
1100
1101                         /* check if interrupt is generated from dio channels */
1102                         if (irqbit) {
1103                                 s626_dio_reset_irq(dev, group, irqbit);
1104                                 DEBUG
1105                                     ("s626_irq_handler: check interrupt on dio group %d %d\n",
1106                                      group, i);
1107                                 if (devpriv->ai_cmd_running) {
1108                                         /* check if interrupt is an ai acquisition start trigger */
1109                                         if ((irqbit >> (cmd->start_arg -
1110                                                         (16 * group)))
1111                                             == 1 && cmd->start_src == TRIG_EXT) {
1112                                                 DEBUG
1113                                                     ("s626_irq_handler: Edge capture interrupt received from channel %d\n",
1114                                                      cmd->start_arg);
1115
1116                                                 /*  Start executing the RPS program. */
1117                                                 MC_ENABLE(P_MC1, MC1_ERPS1);
1118
1119                                                 DEBUG
1120                                                     ("s626_irq_handler: acquisition start triggered!!!\n");
1121
1122                                                 if (cmd->scan_begin_src ==
1123                                                     TRIG_EXT) {
1124                                                         DEBUG
1125                                                             ("s626_ai_cmd: enable interrupt on dio channel %d\n",
1126                                                              cmd->
1127                                                              scan_begin_arg);
1128
1129                                                         s626_dio_set_irq(dev,
1130                                                                          cmd->scan_begin_arg);
1131
1132                                                         DEBUG
1133                                                             ("s626_irq_handler: External scan trigger is set!!!\n");
1134                                                 }
1135                                         }
1136                                         if ((irqbit >> (cmd->scan_begin_arg -
1137                                                         (16 * group)))
1138                                             == 1
1139                                             && cmd->scan_begin_src ==
1140                                             TRIG_EXT) {
1141                                                 DEBUG
1142                                                     ("s626_irq_handler: Edge capture interrupt received from channel %d\n",
1143                                                      cmd->scan_begin_arg);
1144
1145                                                 /*  Trigger ADC scan loop start by setting RPS Signal 0. */
1146                                                 MC_ENABLE(P_MC2, MC2_ADC_RPS);
1147
1148                                                 DEBUG
1149                                                     ("s626_irq_handler: scan triggered!!! %d\n",
1150                                                      devpriv->ai_sample_count);
1151                                                 if (cmd->convert_src ==
1152                                                     TRIG_EXT) {
1153
1154                                                         DEBUG
1155                                                             ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",
1156                                                              cmd->convert_arg -
1157                                                              (16 * group),
1158                                                              group);
1159
1160                                                         devpriv->ai_convert_count
1161                                                             = cmd->chanlist_len;
1162
1163                                                         s626_dio_set_irq(dev,
1164                                                                          cmd->convert_arg);
1165
1166                                                         DEBUG
1167                                                             ("s626_irq_handler: External convert trigger is set!!!\n");
1168                                                 }
1169
1170                                                 if (cmd->convert_src ==
1171                                                     TRIG_TIMER) {
1172                                                         k = &encpriv[5];
1173                                                         devpriv->ai_convert_count
1174                                                             = cmd->chanlist_len;
1175                                                         k->SetEnable(dev, k,
1176                                                                      CLKENAB_ALWAYS);
1177                                                 }
1178                                         }
1179                                         if ((irqbit >> (cmd->convert_arg -
1180                                                         (16 * group)))
1181                                             == 1
1182                                             && cmd->convert_src == TRIG_EXT) {
1183                                                 DEBUG
1184                                                     ("s626_irq_handler: Edge capture interrupt received from channel %d\n",
1185                                                      cmd->convert_arg);
1186
1187                                                 /*  Trigger ADC scan loop start by setting RPS Signal 0. */
1188                                                 MC_ENABLE(P_MC2, MC2_ADC_RPS);
1189
1190                                                 DEBUG
1191                                                     ("s626_irq_handler: adc convert triggered!!!\n");
1192
1193                                                 devpriv->ai_convert_count--;
1194
1195                                                 if (devpriv->ai_convert_count >
1196                                                     0) {
1197
1198                                                         DEBUG
1199                                                             ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",
1200                                                              cmd->convert_arg -
1201                                                              (16 * group),
1202                                                              group);
1203
1204                                                         s626_dio_set_irq(dev,
1205                                                                          cmd->convert_arg);
1206
1207                                                         DEBUG
1208                                                             ("s626_irq_handler: External trigger is set!!!\n");
1209                                                 }
1210                                         }
1211                                 }
1212                                 break;
1213                         }
1214                 }
1215
1216                 /* read interrupt type */
1217                 irqbit = DEBIread(dev, LP_RDMISC2);
1218
1219                 /* check interrupt on counters */
1220                 DEBUG("s626_irq_handler: check counters interrupt %d\n",
1221                       irqbit);
1222
1223                 if (irqbit & IRQ_COINT1A) {
1224                         DEBUG
1225                             ("s626_irq_handler: interrupt on counter 1A overflow\n");
1226                         k = &encpriv[0];
1227
1228                         /* clear interrupt capture flag */
1229                         k->ResetCapFlags(dev, k);
1230                 }
1231                 if (irqbit & IRQ_COINT2A) {
1232                         DEBUG
1233                             ("s626_irq_handler: interrupt on counter 2A overflow\n");
1234                         k = &encpriv[1];
1235
1236                         /* clear interrupt capture flag */
1237                         k->ResetCapFlags(dev, k);
1238                 }
1239                 if (irqbit & IRQ_COINT3A) {
1240                         DEBUG
1241                             ("s626_irq_handler: interrupt on counter 3A overflow\n");
1242                         k = &encpriv[2];
1243
1244                         /* clear interrupt capture flag */
1245                         k->ResetCapFlags(dev, k);
1246                 }
1247                 if (irqbit & IRQ_COINT1B) {
1248                         DEBUG
1249                             ("s626_irq_handler: interrupt on counter 1B overflow\n");
1250                         k = &encpriv[3];
1251
1252                         /* clear interrupt capture flag */
1253                         k->ResetCapFlags(dev, k);
1254                 }
1255                 if (irqbit & IRQ_COINT2B) {
1256                         DEBUG
1257                             ("s626_irq_handler: interrupt on counter 2B overflow\n");
1258                         k = &encpriv[4];
1259
1260                         /* clear interrupt capture flag */
1261                         k->ResetCapFlags(dev, k);
1262
1263                         if (devpriv->ai_convert_count > 0) {
1264                                 devpriv->ai_convert_count--;
1265                                 if (devpriv->ai_convert_count == 0)
1266                                         k->SetEnable(dev, k, CLKENAB_INDEX);
1267
1268                                 if (cmd->convert_src == TRIG_TIMER) {
1269                                         DEBUG
1270                                             ("s626_irq_handler: conver timer trigger!!! %d\n",
1271                                              devpriv->ai_convert_count);
1272
1273                                         /*  Trigger ADC scan loop start by setting RPS Signal 0. */
1274                                         MC_ENABLE(P_MC2, MC2_ADC_RPS);
1275                                 }
1276                         }
1277                 }
1278                 if (irqbit & IRQ_COINT3B) {
1279                         DEBUG
1280                             ("s626_irq_handler: interrupt on counter 3B overflow\n");
1281                         k = &encpriv[5];
1282
1283                         /* clear interrupt capture flag */
1284                         k->ResetCapFlags(dev, k);
1285
1286                         if (cmd->scan_begin_src == TRIG_TIMER) {
1287                                 DEBUG
1288                                     ("s626_irq_handler: scan timer trigger!!!\n");
1289
1290                                 /*  Trigger ADC scan loop start by setting RPS Signal 0. */
1291                                 MC_ENABLE(P_MC2, MC2_ADC_RPS);
1292                         }
1293
1294                         if (cmd->convert_src == TRIG_TIMER) {
1295                                 DEBUG
1296                                     ("s626_irq_handler: convert timer trigger is set\n");
1297                                 k = &encpriv[4];
1298                                 devpriv->ai_convert_count = cmd->chanlist_len;
1299                                 k->SetEnable(dev, k, CLKENAB_ALWAYS);
1300                         }
1301                 }
1302         }
1303
1304         /* enable interrupt */
1305         writel(irqstatus, devpriv->base_addr + P_IER);
1306
1307         DEBUG("s626_irq_handler: exit interrupt service routine.\n");
1308
1309         spin_unlock_irqrestore(&dev->spinlock, flags);
1310         return IRQ_HANDLED;
1311 }
1312
1313 static void s626_detach(struct comedi_device *dev)
1314 {
1315         if (devpriv) {
1316                 /* stop ai_command */
1317                 devpriv->ai_cmd_running = 0;
1318
1319                 if (devpriv->base_addr) {
1320                         /* interrupt mask */
1321                         WR7146(P_IER, 0);       /*  Disable master interrupt. */
1322                         WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1);    /*  Clear board's IRQ status flag. */
1323
1324                         /*  Disable the watchdog timer and battery charger. */
1325                         WriteMISC2(dev, 0);
1326
1327                         /*  Close all interfaces on 7146 device. */
1328                         WR7146(P_MC1, MC1_SHUTDOWN);
1329                         WR7146(P_ACON1, ACON1_BASE);
1330
1331                         CloseDMAB(dev, &devpriv->RPSBuf, DMABUF_SIZE);
1332                         CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE);
1333                 }
1334
1335                 if (dev->irq)
1336                         free_irq(dev->irq, dev);
1337                 if (devpriv->base_addr)
1338                         iounmap(devpriv->base_addr);
1339                 if (devpriv->pdev) {
1340                         if (devpriv->got_regions)
1341                                 comedi_pci_disable(devpriv->pdev);
1342                         pci_dev_put(devpriv->pdev);
1343                 }
1344         }
1345 }
1346
1347 /*
1348  * this functions build the RPS program for hardware driven acquistion
1349  */
1350 void ResetADC(struct comedi_device *dev, uint8_t * ppl)
1351 {
1352         register uint32_t *pRPS;
1353         uint32_t JmpAdrs;
1354         uint16_t i;
1355         uint16_t n;
1356         uint32_t LocalPPL;
1357         struct comedi_cmd *cmd = &(dev->subdevices->async->cmd);
1358
1359         /*  Stop RPS program in case it is currently running. */
1360         MC_DISABLE(P_MC1, MC1_ERPS1);
1361
1362         /*  Set starting logical address to write RPS commands. */
1363         pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase;
1364
1365         /*  Initialize RPS instruction pointer. */
1366         WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
1367
1368         /*  Construct RPS program in RPSBuf DMA buffer */
1369
1370         if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) {
1371                 DEBUG("ResetADC: scan_begin pause inserted\n");
1372                 /*  Wait for Start trigger. */
1373                 *pRPS++ = RPS_PAUSE | RPS_SIGADC;
1374                 *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
1375         }
1376
1377         /* SAA7146 BUG WORKAROUND Do a dummy DEBI Write.  This is necessary
1378          * because the first RPS DEBI Write following a non-RPS DEBI write
1379          * seems to always fail.  If we don't do this dummy write, the ADC
1380          * gain might not be set to the value required for the first slot in
1381          * the poll list; the ADC gain would instead remain unchanged from
1382          * the previously programmed value.
1383          */
1384         *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
1385         /* Write DEBI Write command and address to shadow RAM. */
1386
1387         *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
1388         *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
1389         /*  Write DEBI immediate data  to shadow RAM: */
1390
1391         *pRPS++ = GSEL_BIPOLAR5V;
1392         /*  arbitrary immediate data  value. */
1393
1394         *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
1395         /*  Reset "shadow RAM  uploaded" flag. */
1396         *pRPS++ = RPS_UPLOAD | RPS_DEBI;        /*  Invoke shadow RAM upload. */
1397         *pRPS++ = RPS_PAUSE | RPS_DEBI; /*  Wait for shadow upload to finish. */
1398
1399         /* Digitize all slots in the poll list. This is implemented as a
1400          * for loop to limit the slot count to 16 in case the application
1401          * forgot to set the EOPL flag in the final slot.
1402          */
1403         for (devpriv->AdcItems = 0; devpriv->AdcItems < 16; devpriv->AdcItems++) {
1404                 /* Convert application's poll list item to private board class
1405                  * format.  Each app poll list item is an uint8_t with form
1406                  * (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
1407                  * +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
1408                  */
1409                 LocalPPL =
1410                     (*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V :
1411                                    GSEL_BIPOLAR10V);
1412
1413                 /*  Switch ADC analog gain. */
1414                 *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); /*  Write DEBI command */
1415                 /*  and address to */
1416                 /*  shadow RAM. */
1417                 *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
1418                 *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);  /*  Write DEBI */
1419                 /*  immediate data to */
1420                 /*  shadow RAM. */
1421                 *pRPS++ = LocalPPL;
1422                 *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;     /*  Reset "shadow RAM uploaded" */
1423                 /*  flag. */
1424                 *pRPS++ = RPS_UPLOAD | RPS_DEBI;        /*  Invoke shadow RAM upload. */
1425                 *pRPS++ = RPS_PAUSE | RPS_DEBI; /*  Wait for shadow upload to */
1426                 /*  finish. */
1427
1428                 /*  Select ADC analog input channel. */
1429                 *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
1430                 /*  Write DEBI command and address to  shadow RAM. */
1431                 *pRPS++ = DEBI_CMD_WRWORD | LP_ISEL;
1432                 *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
1433                 /*  Write DEBI immediate data to shadow RAM. */
1434                 *pRPS++ = LocalPPL;
1435                 *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
1436                 /*  Reset "shadow RAM uploaded"  flag. */
1437
1438                 *pRPS++ = RPS_UPLOAD | RPS_DEBI;
1439                 /*  Invoke shadow RAM upload. */
1440
1441                 *pRPS++ = RPS_PAUSE | RPS_DEBI;
1442                 /*  Wait for shadow upload to finish. */
1443
1444                 /* Delay at least 10 microseconds for analog input settling.
1445                  * Instead of padding with NOPs, we use RPS_JUMP instructions
1446                  * here; this allows us to produce a longer delay than is
1447                  * possible with NOPs because each RPS_JUMP flushes the RPS'
1448                  * instruction prefetch pipeline.
1449                  */
1450                 JmpAdrs =
1451                     (uint32_t) devpriv->RPSBuf.PhysicalBase +
1452                     (uint32_t) ((unsigned long)pRPS -
1453                                 (unsigned long)devpriv->RPSBuf.LogicalBase);
1454                 for (i = 0; i < (10 * RPSCLK_PER_US / 2); i++) {
1455                         JmpAdrs += 8;   /*  Repeat to implement time delay: */
1456                         *pRPS++ = RPS_JUMP;     /*  Jump to next RPS instruction. */
1457                         *pRPS++ = JmpAdrs;
1458                 }
1459
1460                 if (cmd != NULL && cmd->convert_src != TRIG_NOW) {
1461                         DEBUG("ResetADC: convert pause inserted\n");
1462                         /*  Wait for Start trigger. */
1463                         *pRPS++ = RPS_PAUSE | RPS_SIGADC;
1464                         *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
1465                 }
1466                 /*  Start ADC by pulsing GPIO1. */
1467                 *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  Begin ADC Start pulse. */
1468                 *pRPS++ = GPIO_BASE | GPIO1_LO;
1469                 *pRPS++ = RPS_NOP;
1470                 /*  VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
1471                 *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  End ADC Start pulse. */
1472                 *pRPS++ = GPIO_BASE | GPIO1_HI;
1473
1474                 /* Wait for ADC to complete (GPIO2 is asserted high when ADC not
1475                  * busy) and for data from previous conversion to shift into FB
1476                  * BUFFER 1 register.
1477                  */
1478                 *pRPS++ = RPS_PAUSE | RPS_GPIO2;        /*  Wait for ADC done. */
1479
1480                 /*  Transfer ADC data from FB BUFFER 1 register to DMA buffer. */
1481                 *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);
1482                 *pRPS++ =
1483                     (uint32_t) devpriv->ANABuf.PhysicalBase +
1484                     (devpriv->AdcItems << 2);
1485
1486                 /*  If this slot's EndOfPollList flag is set, all channels have */
1487                 /*  now been processed. */
1488                 if (*ppl++ & EOPL) {
1489                         devpriv->AdcItems++;    /*  Adjust poll list item count. */
1490                         break;  /*  Exit poll list processing loop. */
1491                 }
1492         }
1493         DEBUG("ResetADC: ADC items %d\n", devpriv->AdcItems);
1494
1495         /* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US.  Allow the
1496          * ADC to stabilize for 2 microseconds before starting the final
1497          * (dummy) conversion.  This delay is necessary to allow sufficient
1498          * time between last conversion finished and the start of the dummy
1499          * conversion.  Without this delay, the last conversion's data value
1500          * is sometimes set to the previous conversion's data value.
1501          */
1502         for (n = 0; n < (2 * RPSCLK_PER_US); n++)
1503                 *pRPS++ = RPS_NOP;
1504
1505         /* Start a dummy conversion to cause the data from the last
1506          * conversion of interest to be shifted in.
1507          */
1508         *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  Begin ADC Start pulse. */
1509         *pRPS++ = GPIO_BASE | GPIO1_LO;
1510         *pRPS++ = RPS_NOP;
1511         /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
1512         *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  End ADC Start pulse. */
1513         *pRPS++ = GPIO_BASE | GPIO1_HI;
1514
1515         /* Wait for the data from the last conversion of interest to arrive
1516          * in FB BUFFER 1 register.
1517          */
1518         *pRPS++ = RPS_PAUSE | RPS_GPIO2;        /*  Wait for ADC done. */
1519
1520         /*  Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */
1521         *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);        /*  */
1522         *pRPS++ =
1523             (uint32_t) devpriv->ANABuf.PhysicalBase + (devpriv->AdcItems << 2);
1524
1525         /*  Indicate ADC scan loop is finished. */
1526         /*  *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ;  // Signal ReadADC() that scan is done. */
1527
1528         /* invoke interrupt */
1529         if (devpriv->ai_cmd_running == 1) {
1530                 DEBUG("ResetADC: insert irq in ADC RPS task\n");
1531                 *pRPS++ = RPS_IRQ;
1532         }
1533         /*  Restart RPS program at its beginning. */
1534         *pRPS++ = RPS_JUMP;     /*  Branch to start of RPS program. */
1535         *pRPS++ = (uint32_t) devpriv->RPSBuf.PhysicalBase;
1536
1537         /*  End of RPS program build */
1538 }
1539
1540 /* TO COMPLETE, IF NECESSARY */
1541 static int s626_ai_insn_config(struct comedi_device *dev,
1542                                struct comedi_subdevice *s,
1543                                struct comedi_insn *insn, unsigned int *data)
1544 {
1545
1546         return -EINVAL;
1547 }
1548
1549 /* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */
1550 /* { */
1551 /*   register uint8_t   i; */
1552 /*   register int32_t   *readaddr; */
1553
1554 /*   DEBUG("as626_ai_rinsn: ai_rinsn enter\n");  */
1555
1556 /*   Trigger ADC scan loop start by setting RPS Signal 0. */
1557 /*   MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
1558
1559 /*   Wait until ADC scan loop is finished (RPS Signal 0 reset). */
1560 /*   while ( MC_TEST( P_MC2, MC2_ADC_RPS ) ); */
1561
1562 /* Init ptr to DMA buffer that holds new ADC data.  We skip the
1563  * first uint16_t in the buffer because it contains junk data from
1564  * the final ADC of the previous poll list scan.
1565  */
1566 /*   readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; */
1567
1568 /*  Convert ADC data to 16-bit integer values and copy to application buffer. */
1569 /*   for ( i = 0; i < devpriv->AdcItems; i++ ) { */
1570 /*     *data = s626_ai_reg_to_uint( *readaddr++ ); */
1571 /*     DEBUG("s626_ai_rinsn: data %d\n",*data); */
1572 /*     data++; */
1573 /*   } */
1574
1575 /*   DEBUG("s626_ai_rinsn: ai_rinsn escape\n"); */
1576 /*   return i; */
1577 /* } */
1578
1579 static int s626_ai_insn_read(struct comedi_device *dev,
1580                              struct comedi_subdevice *s,
1581                              struct comedi_insn *insn, unsigned int *data)
1582 {
1583         uint16_t chan = CR_CHAN(insn->chanspec);
1584         uint16_t range = CR_RANGE(insn->chanspec);
1585         uint16_t AdcSpec = 0;
1586         uint32_t GpioImage;
1587         int n;
1588
1589         /* interrupt call test  */
1590 /*   writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); */
1591         /* Writing a logical 1 into any of the RPS_PSR bits causes the
1592          * corresponding interrupt to be generated if enabled
1593          */
1594
1595         DEBUG("s626_ai_insn_read: entering\n");
1596
1597         /* Convert application's ADC specification into form
1598          *  appropriate for register programming.
1599          */
1600         if (range == 0)
1601                 AdcSpec = (chan << 8) | (GSEL_BIPOLAR5V);
1602         else
1603                 AdcSpec = (chan << 8) | (GSEL_BIPOLAR10V);
1604
1605         /*  Switch ADC analog gain. */
1606         DEBIwrite(dev, LP_GSEL, AdcSpec);       /*  Set gain. */
1607
1608         /*  Select ADC analog input channel. */
1609         DEBIwrite(dev, LP_ISEL, AdcSpec);       /*  Select channel. */
1610
1611         for (n = 0; n < insn->n; n++) {
1612
1613                 /*  Delay 10 microseconds for analog input settling. */
1614                 udelay(10);
1615
1616                 /*  Start ADC by pulsing GPIO1 low. */
1617                 GpioImage = RR7146(P_GPIO);
1618                 /*  Assert ADC Start command */
1619                 WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1620                 /*    and stretch it out. */
1621                 WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1622                 WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1623                 /*  Negate ADC Start command. */
1624                 WR7146(P_GPIO, GpioImage | GPIO1_HI);
1625
1626                 /*  Wait for ADC to complete (GPIO2 is asserted high when */
1627                 /*  ADC not busy) and for data from previous conversion to */
1628                 /*  shift into FB BUFFER 1 register. */
1629
1630                 /*  Wait for ADC done. */
1631                 while (!(RR7146(P_PSR) & PSR_GPIO2))
1632                         ;
1633
1634                 /*  Fetch ADC data. */
1635                 if (n != 0)
1636                         data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
1637
1638                 /* Allow the ADC to stabilize for 4 microseconds before
1639                  * starting the next (final) conversion.  This delay is
1640                  * necessary to allow sufficient time between last
1641                  * conversion finished and the start of the next
1642                  * conversion.  Without this delay, the last conversion's
1643                  * data value is sometimes set to the previous
1644                  * conversion's data value.
1645                  */
1646                 udelay(4);
1647         }
1648
1649         /* Start a dummy conversion to cause the data from the
1650          * previous conversion to be shifted in. */
1651         GpioImage = RR7146(P_GPIO);
1652
1653         /* Assert ADC Start command */
1654         WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1655         /*    and stretch it out. */
1656         WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1657         WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
1658         /*  Negate ADC Start command. */
1659         WR7146(P_GPIO, GpioImage | GPIO1_HI);
1660
1661         /*  Wait for the data to arrive in FB BUFFER 1 register. */
1662
1663         /*  Wait for ADC done. */
1664         while (!(RR7146(P_PSR) & PSR_GPIO2))
1665                 ;
1666
1667         /*  Fetch ADC data from audio interface's input shift register. */
1668
1669         /*  Fetch ADC data. */
1670         if (n != 0)
1671                 data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
1672
1673         DEBUG("s626_ai_insn_read: samples %d, data %d\n", n, data[n - 1]);
1674
1675         return n;
1676 }
1677
1678 static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
1679 {
1680
1681         int n;
1682
1683         for (n = 0; n < cmd->chanlist_len; n++) {
1684                 if (CR_RANGE((cmd->chanlist)[n]) == 0)
1685                         ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_5V);
1686                 else
1687                         ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_10V);
1688         }
1689         if (n != 0)
1690                 ppl[n - 1] |= EOPL;
1691
1692         return n;
1693 }
1694
1695 static int s626_ai_inttrig(struct comedi_device *dev,
1696                            struct comedi_subdevice *s, unsigned int trignum)
1697 {
1698         if (trignum != 0)
1699                 return -EINVAL;
1700
1701         DEBUG("s626_ai_inttrig: trigger adc start...");
1702
1703         /*  Start executing the RPS program. */
1704         MC_ENABLE(P_MC1, MC1_ERPS1);
1705
1706         s->async->inttrig = NULL;
1707
1708         DEBUG(" done\n");
1709
1710         return 1;
1711 }
1712
1713 /*  TO COMPLETE  */
1714 static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1715 {
1716
1717         uint8_t ppl[16];
1718         struct comedi_cmd *cmd = &s->async->cmd;
1719         struct enc_private *k;
1720         int tick;
1721
1722         DEBUG("s626_ai_cmd: entering command function\n");
1723
1724         if (devpriv->ai_cmd_running) {
1725                 printk(KERN_ERR "s626_ai_cmd: Another ai_cmd is running %d\n",
1726                        dev->minor);
1727                 return -EBUSY;
1728         }
1729         /* disable interrupt */
1730         writel(0, devpriv->base_addr + P_IER);
1731
1732         /* clear interrupt request */
1733         writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->base_addr + P_ISR);
1734
1735         /* clear any pending interrupt */
1736         s626_dio_clear_irq(dev);
1737         /*   s626_enc_clear_irq(dev); */
1738
1739         /* reset ai_cmd_running flag */
1740         devpriv->ai_cmd_running = 0;
1741
1742         /*  test if cmd is valid */
1743         if (cmd == NULL) {
1744                 DEBUG("s626_ai_cmd: NULL command\n");
1745                 return -EINVAL;
1746         } else {
1747                 DEBUG("s626_ai_cmd: command received!!!\n");
1748         }
1749
1750         if (dev->irq == 0) {
1751                 comedi_error(dev,
1752                              "s626_ai_cmd: cannot run command without an irq");
1753                 return -EIO;
1754         }
1755
1756         s626_ai_load_polllist(ppl, cmd);
1757         devpriv->ai_cmd_running = 1;
1758         devpriv->ai_convert_count = 0;
1759
1760         switch (cmd->scan_begin_src) {
1761         case TRIG_FOLLOW:
1762                 break;
1763         case TRIG_TIMER:
1764                 /*  set a conter to generate adc trigger at scan_begin_arg interval */
1765                 k = &encpriv[5];
1766                 tick = s626_ns_to_timer((int *)&cmd->scan_begin_arg,
1767                                         cmd->flags & TRIG_ROUND_MASK);
1768
1769                 /* load timer value and enable interrupt */
1770                 s626_timer_load(dev, k, tick);
1771                 k->SetEnable(dev, k, CLKENAB_ALWAYS);
1772
1773                 DEBUG("s626_ai_cmd: scan trigger timer is set with value %d\n",
1774                       tick);
1775
1776                 break;
1777         case TRIG_EXT:
1778                 /*  set the digital line and interrupt for scan trigger */
1779                 if (cmd->start_src != TRIG_EXT)
1780                         s626_dio_set_irq(dev, cmd->scan_begin_arg);
1781
1782                 DEBUG("s626_ai_cmd: External scan trigger is set!!!\n");
1783
1784                 break;
1785         }
1786
1787         switch (cmd->convert_src) {
1788         case TRIG_NOW:
1789                 break;
1790         case TRIG_TIMER:
1791                 /*  set a conter to generate adc trigger at convert_arg interval */
1792                 k = &encpriv[4];
1793                 tick = s626_ns_to_timer((int *)&cmd->convert_arg,
1794                                         cmd->flags & TRIG_ROUND_MASK);
1795
1796                 /* load timer value and enable interrupt */
1797                 s626_timer_load(dev, k, tick);
1798                 k->SetEnable(dev, k, CLKENAB_INDEX);
1799
1800                 DEBUG
1801                     ("s626_ai_cmd: convert trigger timer is set with value %d\n",
1802                      tick);
1803                 break;
1804         case TRIG_EXT:
1805                 /*  set the digital line and interrupt for convert trigger */
1806                 if (cmd->scan_begin_src != TRIG_EXT
1807                     && cmd->start_src == TRIG_EXT)
1808                         s626_dio_set_irq(dev, cmd->convert_arg);
1809
1810                 DEBUG("s626_ai_cmd: External convert trigger is set!!!\n");
1811
1812                 break;
1813         }
1814
1815         switch (cmd->stop_src) {
1816         case TRIG_COUNT:
1817                 /*  data arrives as one packet */
1818                 devpriv->ai_sample_count = cmd->stop_arg;
1819                 devpriv->ai_continous = 0;
1820                 break;
1821         case TRIG_NONE:
1822                 /*  continous acquisition */
1823                 devpriv->ai_continous = 1;
1824                 devpriv->ai_sample_count = 0;
1825                 break;
1826         }
1827
1828         ResetADC(dev, ppl);
1829
1830         switch (cmd->start_src) {
1831         case TRIG_NOW:
1832                 /*  Trigger ADC scan loop start by setting RPS Signal 0. */
1833                 /*  MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
1834
1835                 /*  Start executing the RPS program. */
1836                 MC_ENABLE(P_MC1, MC1_ERPS1);
1837
1838                 DEBUG("s626_ai_cmd: ADC triggered\n");
1839                 s->async->inttrig = NULL;
1840                 break;
1841         case TRIG_EXT:
1842                 /* configure DIO channel for acquisition trigger */
1843                 s626_dio_set_irq(dev, cmd->start_arg);
1844
1845                 DEBUG("s626_ai_cmd: External start trigger is set!!!\n");
1846
1847                 s->async->inttrig = NULL;
1848                 break;
1849         case TRIG_INT:
1850                 s->async->inttrig = s626_ai_inttrig;
1851                 break;
1852         }
1853
1854         /* enable interrupt */
1855         writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER);
1856
1857         DEBUG("s626_ai_cmd: command function terminated\n");
1858
1859         return 0;
1860 }
1861
1862 static int s626_ai_cmdtest(struct comedi_device *dev,
1863                            struct comedi_subdevice *s, struct comedi_cmd *cmd)
1864 {
1865         int err = 0;
1866         int tmp;
1867
1868         /* cmdtest tests a particular command to see if it is valid.  Using
1869          * the cmdtest ioctl, a user can create a valid cmd and then have it
1870          * executes by the cmd ioctl.
1871          *
1872          * cmdtest returns 1,2,3,4 or 0, depending on which tests the
1873          * command passes. */
1874
1875         /* step 1: make sure trigger sources are trivially valid */
1876
1877         tmp = cmd->start_src;
1878         cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT;
1879         if (!cmd->start_src || tmp != cmd->start_src)
1880                 err++;
1881
1882         tmp = cmd->scan_begin_src;
1883         cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
1884         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1885                 err++;
1886
1887         tmp = cmd->convert_src;
1888         cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
1889         if (!cmd->convert_src || tmp != cmd->convert_src)
1890                 err++;
1891
1892         tmp = cmd->scan_end_src;
1893         cmd->scan_end_src &= TRIG_COUNT;
1894         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1895                 err++;
1896
1897         tmp = cmd->stop_src;
1898         cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1899         if (!cmd->stop_src || tmp != cmd->stop_src)
1900                 err++;
1901
1902         if (err)
1903                 return 1;
1904
1905         /* step 2: make sure trigger sources are unique and mutually
1906            compatible */
1907
1908         /* note that mutual compatibility is not an issue here */
1909         if (cmd->scan_begin_src != TRIG_TIMER &&
1910             cmd->scan_begin_src != TRIG_EXT
1911             && cmd->scan_begin_src != TRIG_FOLLOW)
1912                 err++;
1913         if (cmd->convert_src != TRIG_TIMER &&
1914             cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
1915                 err++;
1916         if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1917                 err++;
1918
1919         if (err)
1920                 return 2;
1921
1922         /* step 3: make sure arguments are trivially compatible */
1923
1924         if (cmd->start_src != TRIG_EXT && cmd->start_arg != 0) {
1925                 cmd->start_arg = 0;
1926                 err++;
1927         }
1928
1929         if (cmd->start_src == TRIG_EXT && cmd->start_arg > 39) {
1930                 cmd->start_arg = 39;
1931                 err++;
1932         }
1933
1934         if (cmd->scan_begin_src == TRIG_EXT && cmd->scan_begin_arg > 39) {
1935                 cmd->scan_begin_arg = 39;
1936                 err++;
1937         }
1938
1939         if (cmd->convert_src == TRIG_EXT && cmd->convert_arg > 39) {
1940                 cmd->convert_arg = 39;
1941                 err++;
1942         }
1943 #define MAX_SPEED       200000  /* in nanoseconds */
1944 #define MIN_SPEED       2000000000      /* in nanoseconds */
1945
1946         if (cmd->scan_begin_src == TRIG_TIMER) {
1947                 if (cmd->scan_begin_arg < MAX_SPEED) {
1948                         cmd->scan_begin_arg = MAX_SPEED;
1949                         err++;
1950                 }
1951                 if (cmd->scan_begin_arg > MIN_SPEED) {
1952                         cmd->scan_begin_arg = MIN_SPEED;
1953                         err++;
1954                 }
1955         } else {
1956                 /* external trigger */
1957                 /* should be level/edge, hi/lo specification here */
1958                 /* should specify multiple external triggers */
1959 /*     if(cmd->scan_begin_arg>9){ */
1960 /*       cmd->scan_begin_arg=9; */
1961 /*       err++; */
1962 /*     } */
1963         }
1964         if (cmd->convert_src == TRIG_TIMER) {
1965                 if (cmd->convert_arg < MAX_SPEED) {
1966                         cmd->convert_arg = MAX_SPEED;
1967                         err++;
1968                 }
1969                 if (cmd->convert_arg > MIN_SPEED) {
1970                         cmd->convert_arg = MIN_SPEED;
1971                         err++;
1972                 }
1973         } else {
1974                 /* external trigger */
1975                 /* see above */
1976 /*     if(cmd->convert_arg>9){ */
1977 /*       cmd->convert_arg=9; */
1978 /*       err++; */
1979 /*     } */
1980         }
1981
1982         if (cmd->scan_end_arg != cmd->chanlist_len) {
1983                 cmd->scan_end_arg = cmd->chanlist_len;
1984                 err++;
1985         }
1986         if (cmd->stop_src == TRIG_COUNT) {
1987                 if (cmd->stop_arg > 0x00ffffff) {
1988                         cmd->stop_arg = 0x00ffffff;
1989                         err++;
1990                 }
1991         } else {
1992                 /* TRIG_NONE */
1993                 if (cmd->stop_arg != 0) {
1994                         cmd->stop_arg = 0;
1995                         err++;
1996                 }
1997         }
1998
1999         if (err)
2000                 return 3;
2001
2002         /* step 4: fix up any arguments */
2003
2004         if (cmd->scan_begin_src == TRIG_TIMER) {
2005                 tmp = cmd->scan_begin_arg;
2006                 s626_ns_to_timer((int *)&cmd->scan_begin_arg,
2007                                  cmd->flags & TRIG_ROUND_MASK);
2008                 if (tmp != cmd->scan_begin_arg)
2009                         err++;
2010         }
2011         if (cmd->convert_src == TRIG_TIMER) {
2012                 tmp = cmd->convert_arg;
2013                 s626_ns_to_timer((int *)&cmd->convert_arg,
2014                                  cmd->flags & TRIG_ROUND_MASK);
2015                 if (tmp != cmd->convert_arg)
2016                         err++;
2017                 if (cmd->scan_begin_src == TRIG_TIMER &&
2018                     cmd->scan_begin_arg <
2019                     cmd->convert_arg * cmd->scan_end_arg) {
2020                         cmd->scan_begin_arg =
2021                             cmd->convert_arg * cmd->scan_end_arg;
2022                         err++;
2023                 }
2024         }
2025
2026         if (err)
2027                 return 4;
2028
2029         return 0;
2030 }
2031
2032 static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
2033 {
2034         /*  Stop RPS program in case it is currently running. */
2035         MC_DISABLE(P_MC1, MC1_ERPS1);
2036
2037         /* disable master interrupt */
2038         writel(0, devpriv->base_addr + P_IER);
2039
2040         devpriv->ai_cmd_running = 0;
2041
2042         return 0;
2043 }
2044
2045 /* This function doesn't require a particular form, this is just what
2046  * happens to be used in some of the drivers.  It should convert ns
2047  * nanoseconds to a counter value suitable for programming the device.
2048  * Also, it should adjust ns so that it cooresponds to the actual time
2049  * that the device will use. */
2050 static int s626_ns_to_timer(int *nanosec, int round_mode)
2051 {
2052         int divider, base;
2053
2054         base = 500;             /* 2MHz internal clock */
2055
2056         switch (round_mode) {
2057         case TRIG_ROUND_NEAREST:
2058         default:
2059                 divider = (*nanosec + base / 2) / base;
2060                 break;
2061         case TRIG_ROUND_DOWN:
2062                 divider = (*nanosec) / base;
2063                 break;
2064         case TRIG_ROUND_UP:
2065                 divider = (*nanosec + base - 1) / base;
2066                 break;
2067         }
2068
2069         *nanosec = base * divider;
2070         return divider - 1;
2071 }
2072
2073 static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
2074                          struct comedi_insn *insn, unsigned int *data)
2075 {
2076
2077         int i;
2078         uint16_t chan = CR_CHAN(insn->chanspec);
2079         int16_t dacdata;
2080
2081         for (i = 0; i < insn->n; i++) {
2082                 dacdata = (int16_t) data[i];
2083                 devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[i];
2084                 dacdata -= (0x1fff);
2085
2086                 SetDAC(dev, chan, dacdata);
2087         }
2088
2089         return i;
2090 }
2091
2092 static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
2093                          struct comedi_insn *insn, unsigned int *data)
2094 {
2095         int i;
2096
2097         for (i = 0; i < insn->n; i++)
2098                 data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
2099
2100         return i;
2101 }
2102
2103 /* *************** DIGITAL I/O FUNCTIONS ***************
2104  * All DIO functions address a group of DIO channels by means of
2105  * "group" argument.  group may be 0, 1 or 2, which correspond to DIO
2106  * ports A, B and C, respectively.
2107  */
2108
2109 static void s626_dio_init(struct comedi_device *dev)
2110 {
2111         uint16_t group;
2112         struct comedi_subdevice *s;
2113
2114         /*  Prepare to treat writes to WRCapSel as capture disables. */
2115         DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
2116
2117         /*  For each group of sixteen channels ... */
2118         for (group = 0; group < S626_DIO_BANKS; group++) {
2119                 s = dev->subdevices + 2 + group;
2120                 DEBIwrite(dev, diopriv->WRIntSel, 0);   /*  Disable all interrupts. */
2121                 DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF);      /*  Disable all event */
2122                 /*  captures. */
2123                 DEBIwrite(dev, diopriv->WREdgSel, 0);   /*  Init all DIOs to */
2124                 /*  default edge */
2125                 /*  polarity. */
2126                 DEBIwrite(dev, diopriv->WRDOut, 0);     /*  Program all outputs */
2127                 /*  to inactive state. */
2128         }
2129         DEBUG("s626_dio_init: DIO initialized\n");
2130 }
2131
2132 /* DIO devices are slightly special.  Although it is possible to
2133  * implement the insn_read/insn_write interface, it is much more
2134  * useful to applications if you implement the insn_bits interface.
2135  * This allows packed reading/writing of the DIO channels.  The comedi
2136  * core can convert between insn_bits and insn_read/write */
2137
2138 static int s626_dio_insn_bits(struct comedi_device *dev,
2139                               struct comedi_subdevice *s,
2140                               struct comedi_insn *insn, unsigned int *data)
2141 {
2142
2143         /* Length of data must be 2 (mask and new data, see below) */
2144         if (insn->n == 0)
2145                 return 0;
2146
2147         if (insn->n != 2) {
2148                 printk
2149                     ("comedi%d: s626: s626_dio_insn_bits(): Invalid instruction length\n",
2150                      dev->minor);
2151                 return -EINVAL;
2152         }
2153
2154         /*
2155          * The insn data consists of a mask in data[0] and the new data in
2156          * data[1]. The mask defines which bits we are concerning about.
2157          * The new data must be anded with the mask.  Each channel
2158          * corresponds to a bit.
2159          */
2160         if (data[0]) {
2161                 /* Check if requested ports are configured for output */
2162                 if ((s->io_bits & data[0]) != data[0])
2163                         return -EIO;
2164
2165                 s->state &= ~data[0];
2166                 s->state |= data[0] & data[1];
2167
2168                 /* Write out the new digital output lines */
2169
2170                 DEBIwrite(dev, diopriv->WRDOut, s->state);
2171         }
2172         data[1] = DEBIread(dev, diopriv->RDDIn);
2173
2174         return 2;
2175 }
2176
2177 static int s626_dio_insn_config(struct comedi_device *dev,
2178                                 struct comedi_subdevice *s,
2179                                 struct comedi_insn *insn, unsigned int *data)
2180 {
2181
2182         switch (data[0]) {
2183         case INSN_CONFIG_DIO_QUERY:
2184                 data[1] =
2185                     (s->
2186                      io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
2187                     COMEDI_INPUT;
2188                 return insn->n;
2189                 break;
2190         case COMEDI_INPUT:
2191                 s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
2192                 break;
2193         case COMEDI_OUTPUT:
2194                 s->io_bits |= 1 << CR_CHAN(insn->chanspec);
2195                 break;
2196         default:
2197                 return -EINVAL;
2198                 break;
2199         }
2200         DEBIwrite(dev, diopriv->WRDOut, s->io_bits);
2201
2202         return 1;
2203 }
2204
2205 static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
2206 {
2207         unsigned int group;
2208         unsigned int bitmask;
2209         unsigned int status;
2210
2211         /* select dio bank */
2212         group = chan / 16;
2213         bitmask = 1 << (chan - (16 * group));
2214         DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n",
2215               chan - (16 * group), group);
2216
2217         /* set channel to capture positive edge */
2218         status = DEBIread(dev,
2219                           ((struct dio_private *)(dev->subdevices + 2 +
2220                                                   group)->private)->RDEdgSel);
2221         DEBIwrite(dev,
2222                   ((struct dio_private *)(dev->subdevices + 2 +
2223                                           group)->private)->WREdgSel,
2224                   bitmask | status);
2225
2226         /* enable interrupt on selected channel */
2227         status = DEBIread(dev,
2228                           ((struct dio_private *)(dev->subdevices + 2 +
2229                                                   group)->private)->RDIntSel);
2230         DEBIwrite(dev,
2231                   ((struct dio_private *)(dev->subdevices + 2 +
2232                                           group)->private)->WRIntSel,
2233                   bitmask | status);
2234
2235         /* enable edge capture write command */
2236         DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
2237
2238         /* enable edge capture on selected channel */
2239         status = DEBIread(dev,
2240                           ((struct dio_private *)(dev->subdevices + 2 +
2241                                                   group)->private)->RDCapSel);
2242         DEBIwrite(dev,
2243                   ((struct dio_private *)(dev->subdevices + 2 +
2244                                           group)->private)->WRCapSel,
2245                   bitmask | status);
2246
2247         return 0;
2248 }
2249
2250 static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
2251                               unsigned int mask)
2252 {
2253         DEBUG
2254             ("s626_dio_reset_irq: disable  interrupt on dio channel %d group %d\n",
2255              mask, group);
2256
2257         /* disable edge capture write command */
2258         DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
2259
2260         /* enable edge capture on selected channel */
2261         DEBIwrite(dev,
2262                   ((struct dio_private *)(dev->subdevices + 2 +
2263                                           group)->private)->WRCapSel, mask);
2264
2265         return 0;
2266 }
2267
2268 static int s626_dio_clear_irq(struct comedi_device *dev)
2269 {
2270         unsigned int group;
2271
2272         /* disable edge capture write command */
2273         DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
2274
2275         for (group = 0; group < S626_DIO_BANKS; group++) {
2276                 /* clear pending events and interrupt */
2277                 DEBIwrite(dev,
2278                           ((struct dio_private *)(dev->subdevices + 2 +
2279                                                   group)->private)->WRCapSel,
2280                           0xffff);
2281         }
2282
2283         return 0;
2284 }
2285
2286 /* Now this function initializes the value of the counter (data[0])
2287    and set the subdevice. To complete with trigger and interrupt
2288    configuration */
2289 static int s626_enc_insn_config(struct comedi_device *dev,
2290                                 struct comedi_subdevice *s,
2291                                 struct comedi_insn *insn, unsigned int *data)
2292 {
2293         uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /*  Preload upon */
2294             /*  index. */
2295             (INDXSRC_SOFT << BF_INDXSRC) |      /*  Disable hardware index. */
2296             (CLKSRC_COUNTER << BF_CLKSRC) |     /*  Operating mode is Counter. */
2297             (CLKPOL_POS << BF_CLKPOL) | /*  Active high clock. */
2298             /* ( CNTDIR_UP << BF_CLKPOL ) |      // Count direction is Down. */
2299             (CLKMULT_1X << BF_CLKMULT) |        /*  Clock multiplier is 1x. */
2300             (CLKENAB_INDEX << BF_CLKENAB);
2301         /*   uint16_t DisableIntSrc=TRUE; */
2302         /*  uint32_t Preloadvalue;              //Counter initial value */
2303         uint16_t valueSrclatch = LATCHSRC_AB_READ;
2304         uint16_t enab = CLKENAB_ALWAYS;
2305         struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
2306
2307         DEBUG("s626_enc_insn_config: encoder config\n");
2308
2309         /*   (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
2310
2311         k->SetMode(dev, k, Setup, TRUE);
2312         Preload(dev, k, *(insn->data));
2313         k->PulseIndex(dev, k);
2314         SetLatchSource(dev, k, valueSrclatch);
2315         k->SetEnable(dev, k, (uint16_t) (enab != 0));
2316
2317         return insn->n;
2318 }
2319
2320 static int s626_enc_insn_read(struct comedi_device *dev,
2321                               struct comedi_subdevice *s,
2322                               struct comedi_insn *insn, unsigned int *data)
2323 {
2324
2325         int n;
2326         struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
2327
2328         DEBUG("s626_enc_insn_read: encoder read channel %d\n",
2329               CR_CHAN(insn->chanspec));
2330
2331         for (n = 0; n < insn->n; n++)
2332                 data[n] = ReadLatch(dev, k);
2333
2334         DEBUG("s626_enc_insn_read: encoder sample %d\n", data[n]);
2335
2336         return n;
2337 }
2338
2339 static int s626_enc_insn_write(struct comedi_device *dev,
2340                                struct comedi_subdevice *s,
2341                                struct comedi_insn *insn, unsigned int *data)
2342 {
2343
2344         struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
2345
2346         DEBUG("s626_enc_insn_write: encoder write channel %d\n",
2347               CR_CHAN(insn->chanspec));
2348
2349         /*  Set the preload register */
2350         Preload(dev, k, data[0]);
2351
2352         /*  Software index pulse forces the preload register to load */
2353         /*  into the counter */
2354         k->SetLoadTrig(dev, k, 0);
2355         k->PulseIndex(dev, k);
2356         k->SetLoadTrig(dev, k, 2);
2357
2358         DEBUG("s626_enc_insn_write: End encoder write\n");
2359
2360         return 1;
2361 }
2362
2363 static void s626_timer_load(struct comedi_device *dev, struct enc_private *k,
2364                             int tick)
2365 {
2366         uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /*  Preload upon */
2367             /*  index. */
2368             (INDXSRC_SOFT << BF_INDXSRC) |      /*  Disable hardware index. */
2369             (CLKSRC_TIMER << BF_CLKSRC) |       /*  Operating mode is Timer. */
2370             (CLKPOL_POS << BF_CLKPOL) | /*  Active high clock. */
2371             (CNTDIR_DOWN << BF_CLKPOL) |        /*  Count direction is Down. */
2372             (CLKMULT_1X << BF_CLKMULT) |        /*  Clock multiplier is 1x. */
2373             (CLKENAB_INDEX << BF_CLKENAB);
2374         uint16_t valueSrclatch = LATCHSRC_A_INDXA;
2375         /*   uint16_t enab=CLKENAB_ALWAYS; */
2376
2377         k->SetMode(dev, k, Setup, FALSE);
2378
2379         /*  Set the preload register */
2380         Preload(dev, k, tick);
2381
2382         /*  Software index pulse forces the preload register to load */
2383         /*  into the counter */
2384         k->SetLoadTrig(dev, k, 0);
2385         k->PulseIndex(dev, k);
2386
2387         /* set reload on counter overflow */
2388         k->SetLoadTrig(dev, k, 1);
2389
2390         /* set interrupt on overflow */
2391         k->SetIntSrc(dev, k, INTSRC_OVER);
2392
2393         SetLatchSource(dev, k, valueSrclatch);
2394         /*   k->SetEnable(dev,k,(uint16_t)(enab != 0)); */
2395 }
2396
2397 /* ***********  DAC FUNCTIONS *********** */
2398
2399 /*  Slot 0 base settings. */
2400 #define VECT0   (XSD2 | RSD3 | SIB_A2)
2401 /*  Slot 0 always shifts in  0xFF and store it to  FB_BUFFER2. */
2402
2403 /*  TrimDac LogicalChan-to-PhysicalChan mapping table. */
2404 static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
2405
2406 /*  TrimDac LogicalChan-to-EepromAdrs mapping table. */
2407 static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
2408
2409 static void LoadTrimDACs(struct comedi_device *dev)
2410 {
2411         register uint8_t i;
2412
2413         /*  Copy TrimDac setpoint values from EEPROM to TrimDacs. */
2414         for (i = 0; i < ARRAY_SIZE(trimchan); i++)
2415                 WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i]));
2416 }
2417
2418 static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
2419                          uint8_t DacData)
2420 {
2421         uint32_t chan;
2422
2423         /*  Save the new setpoint in case the application needs to read it back later. */
2424         devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData;
2425
2426         /*  Map logical channel number to physical channel number. */
2427         chan = (uint32_t) trimchan[LogicalChan];
2428
2429         /* Set up TSL2 records for TrimDac write operation.  All slots shift
2430          * 0xFF in from pulled-up SD3 so that the end of the slot sequence
2431          * can be detected.
2432          */
2433
2434         SETVECT(2, XSD2 | XFIFO_1 | WS3);
2435         /* Slot 2: Send high uint8_t to target TrimDac. */
2436         SETVECT(3, XSD2 | XFIFO_0 | WS3);
2437         /* Slot 3: Send low uint8_t to target TrimDac. */
2438         SETVECT(4, XSD2 | XFIFO_3 | WS1);
2439         /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */
2440         SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS);
2441         /* Slot 5: Send NOP low  uint8_t to DAC0. */
2442
2443         /* Construct and transmit target DAC's serial packet:
2444          * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the
2445          * DAC channel's address, and D<7:0> is the DAC setpoint.  Append a
2446          * WORD value (that writes a channel 0 NOP command to a non-existent
2447          * main DAC channel) that serves to keep the clock running after the
2448          * packet has been sent to the target DAC.
2449          */
2450
2451         /*  Address the DAC channel within the trimdac device. */
2452         SendDAC(dev, ((uint32_t) chan << 8)
2453                 | (uint32_t) DacData);  /*  Include DAC setpoint data. */
2454 }
2455
2456 /* **************  EEPROM ACCESS FUNCTIONS  ************** */
2457 /*  Read uint8_t from EEPROM. */
2458
2459 static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
2460 {
2461         uint8_t rtnval;
2462
2463         /*  Send EEPROM target address. */
2464         if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW)
2465                          /* Byte2 = I2C command: write to I2C EEPROM  device. */
2466                          | I2C_B1(I2C_ATTRSTOP, addr)
2467                          /* Byte1 = EEPROM internal target address. */
2468                          | I2C_B0(I2C_ATTRNOP, 0))) {   /*  Byte0 = Not sent. */
2469                 /*  Abort function and declare error if handshake failed. */
2470                 DEBUG("I2Cread: error handshake I2Cread  a\n");
2471                 return 0;
2472         }
2473         /*  Execute EEPROM read. */
2474         if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR)
2475
2476                          /*  Byte2 = I2C */
2477                          /*  command: read */
2478                          /*  from I2C EEPROM */
2479                          /*  device. */
2480                          |I2C_B1(I2C_ATTRSTOP, 0)
2481
2482                          /*  Byte1 receives */
2483                          /*  uint8_t from */
2484                          /*  EEPROM. */
2485                          |I2C_B0(I2C_ATTRNOP, 0))) {    /*  Byte0 = Not  sent. */
2486
2487                 /*  Abort function and declare error if handshake failed. */
2488                 DEBUG("I2Cread: error handshake I2Cread b\n");
2489                 return 0;
2490         }
2491         /*  Return copy of EEPROM value. */
2492         rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16);
2493         return rtnval;
2494 }
2495
2496 static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
2497 {
2498         /*  Write I2C command to I2C Transfer Control shadow register. */
2499         WR7146(P_I2CCTRL, val);
2500
2501         /*  Upload I2C shadow registers into working registers and wait for */
2502         /*  upload confirmation. */
2503
2504         MC_ENABLE(P_MC2, MC2_UPLD_IIC);
2505         while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
2506                 ;
2507
2508         /*  Wait until I2C bus transfer is finished or an error occurs. */
2509         while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY)
2510                 ;
2511
2512         /*  Return non-zero if I2C error occurred. */
2513         return RR7146(P_I2CCTRL) & I2C_ERR;
2514
2515 }
2516
2517 /*  Private helper function: Write setpoint to an application DAC channel. */
2518
2519 static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
2520 {
2521         register uint16_t signmask;
2522         register uint32_t WSImage;
2523
2524         /*  Adjust DAC data polarity and set up Polarity Control Register */
2525         /*  image. */
2526         signmask = 1 << chan;
2527         if (dacdata < 0) {
2528                 dacdata = -dacdata;
2529                 devpriv->Dacpol |= signmask;
2530         } else
2531                 devpriv->Dacpol &= ~signmask;
2532
2533         /*  Limit DAC setpoint value to valid range. */
2534         if ((uint16_t) dacdata > 0x1FFF)
2535                 dacdata = 0x1FFF;
2536
2537         /* Set up TSL2 records (aka "vectors") for DAC update.  Vectors V2
2538          * and V3 transmit the setpoint to the target DAC.  V4 and V5 send
2539          * data to a non-existent TrimDac channel just to keep the clock
2540          * running after sending data to the target DAC.  This is necessary
2541          * to eliminate the clock glitch that would otherwise occur at the
2542          * end of the target DAC's serial data stream.  When the sequence
2543          * restarts at V0 (after executing V5), the gate array automatically
2544          * disables gating for the DAC clock and all DAC chip selects.
2545          */
2546
2547         WSImage = (chan & 2) ? WS1 : WS2;
2548         /* Choose DAC chip select to be asserted. */
2549         SETVECT(2, XSD2 | XFIFO_1 | WSImage);
2550         /* Slot 2: Transmit high data byte to target DAC. */
2551         SETVECT(3, XSD2 | XFIFO_0 | WSImage);
2552         /* Slot 3: Transmit low data byte to target DAC. */
2553         SETVECT(4, XSD2 | XFIFO_3 | WS3);
2554         /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
2555         SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS);
2556         /* Slot 5: running after writing target DAC's low data byte. */
2557
2558         /*  Construct and transmit target DAC's serial packet:
2559          * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>,
2560          * and D<12:0> is the DAC setpoint.  Append a WORD value (that writes
2561          * to a  non-existent TrimDac channel) that serves to keep the clock
2562          * running after the packet has been sent to the target DAC.
2563          */
2564         SendDAC(dev, 0x0F000000
2565                 /* Continue clock after target DAC data (write to non-existent trimdac). */
2566                 | 0x00004000
2567                 /* Address the two main dual-DAC devices (TSL's chip select enables
2568                  * target device). */
2569                 | ((uint32_t) (chan & 1) << 15)
2570                 /*  Address the DAC channel within the  device. */
2571                 | (uint32_t) dacdata);  /*  Include DAC setpoint data. */
2572
2573 }
2574
2575 /* Private helper function: Transmit serial data to DAC via Audio
2576  * channel 2.  Assumes: (1) TSL2 slot records initialized, and (2)
2577  * Dacpol contains valid target image.
2578  */
2579
2580 static void SendDAC(struct comedi_device *dev, uint32_t val)
2581 {
2582
2583         /* START THE SERIAL CLOCK RUNNING ------------- */
2584
2585         /* Assert DAC polarity control and enable gating of DAC serial clock
2586          * and audio bit stream signals.  At this point in time we must be
2587          * assured of being in time slot 0.  If we are not in slot 0, the
2588          * serial clock and audio stream signals will be disabled; this is
2589          * because the following DEBIwrite statement (which enables signals
2590          * to be passed through the gate array) would execute before the
2591          * trailing edge of WS1/WS3 (which turns off the signals), thus
2592          * causing the signals to be inactive during the DAC write.
2593          */
2594         DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol);
2595
2596         /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */
2597
2598         /* Copy DAC setpoint value to DAC's output DMA buffer. */
2599
2600         /* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */
2601         *devpriv->pDacWBuf = val;
2602
2603         /* enab the output DMA transfer.  This will cause the DMAC to copy
2604          * the DAC's data value to A2's output FIFO.  The DMA transfer will
2605          * then immediately terminate because the protection address is
2606          * reached upon transfer of the first DWORD value.
2607          */
2608         MC_ENABLE(P_MC1, MC1_A2OUT);
2609
2610         /*  While the DMA transfer is executing ... */
2611
2612         /* Reset Audio2 output FIFO's underflow flag (along with any other
2613          * FIFO underflow/overflow flags).  When set, this flag will
2614          * indicate that we have emerged from slot 0.
2615          */
2616         WR7146(P_ISR, ISR_AFOU);
2617
2618         /* Wait for the DMA transfer to finish so that there will be data
2619          * available in the FIFO when time slot 1 tries to transfer a DWORD
2620          * from the FIFO to the output buffer register.  We test for DMA
2621          * Done by polling the DMAC enable flag; this flag is automatically
2622          * cleared when the transfer has finished.
2623          */
2624         while ((RR7146(P_MC1) & MC1_A2OUT) != 0)
2625                 ;
2626
2627         /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
2628
2629         /* FIFO data is now available, so we enable execution of time slots
2630          * 1 and higher by clearing the EOS flag in slot 0.  Note that SD3
2631          * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
2632          * detection.
2633          */
2634         SETVECT(0, XSD2 | RSD3 | SIB_A2);
2635
2636         /* Wait for slot 1 to execute to ensure that the Packet will be
2637          * transmitted.  This is detected by polling the Audio2 output FIFO
2638          * underflow flag, which will be set when slot 1 execution has
2639          * finished transferring the DAC's data DWORD from the output FIFO
2640          * to the output buffer register.
2641          */
2642         while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0)
2643                 ;
2644
2645         /* Set up to trap execution at slot 0 when the TSL sequencer cycles
2646          * back to slot 0 after executing the EOS in slot 5.  Also,
2647          * simultaneously shift out and in the 0x00 that is ALWAYS the value
2648          * stored in the last byte to be shifted out of the FIFO's DWORD
2649          * buffer register.
2650          */
2651         SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS);
2652
2653         /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
2654
2655         /* Wait for the TSL to finish executing all time slots before
2656          * exiting this function.  We must do this so that the next DAC
2657          * write doesn't start, thereby enabling clock/chip select signals:
2658          *
2659          * 1. Before the TSL sequence cycles back to slot 0, which disables
2660          *    the clock/cs signal gating and traps slot // list execution.
2661          *    we have not yet finished slot 5 then the clock/cs signals are
2662          *    still gated and we have not finished transmitting the stream.
2663          *
2664          * 2. While slots 2-5 are executing due to a late slot 0 trap.  In
2665          *    this case, the slot sequence is currently repeating, but with
2666          *    clock/cs signals disabled.  We must wait for slot 0 to trap
2667          *    execution before setting up the next DAC setpoint DMA transfer
2668          *    and enabling the clock/cs signals.  To detect the end of slot 5,
2669          *    we test for the FB_BUFFER2 MSB contents to be equal to 0xFF.  If
2670          *    the TSL has not yet finished executing slot 5 ...
2671          */
2672         if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) {
2673                 /* The trap was set on time and we are still executing somewhere
2674                  * in slots 2-5, so we now wait for slot 0 to execute and trap
2675                  * TSL execution.  This is detected when FB_BUFFER2 MSB changes
2676                  * from 0xFF to 0x00, which slot 0 causes to happen by shifting
2677                  * out/in on SD2 the 0x00 that is always referenced by slot 5.
2678                  */
2679                 while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0)
2680                         ;
2681         }
2682         /* Either (1) we were too late setting the slot 0 trap; the TSL
2683          * sequencer restarted slot 0 before we could set the EOS trap flag,
2684          * or (2) we were not late and execution is now trapped at slot 0.
2685          * In either case, we must now change slot 0 so that it will store
2686          * value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes.
2687          * In order to do this, we reprogram slot 0 so that it will shift in
2688          * SD3, which is driven only by a pull-up resistor.
2689          */
2690         SETVECT(0, RSD3 | SIB_A2 | EOS);
2691
2692         /* Wait for slot 0 to execute, at which time the TSL is setup for
2693          * the next DAC write.  This is detected when FB_BUFFER2 MSB changes
2694          * from 0x00 to 0xFF.
2695          */
2696         while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0)
2697                 ;
2698 }
2699
2700 static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage)
2701 {
2702         DEBIwrite(dev, LP_MISC1, MISC1_WENABLE);        /*  enab writes to */
2703         /*  MISC2 register. */
2704         DEBIwrite(dev, LP_WRMISC2, NewImage);   /*  Write new image to MISC2. */
2705         DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE);       /*  Disable writes to MISC2. */
2706 }
2707
2708 /*  Initialize the DEBI interface for all transfers. */
2709
2710 static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
2711 {
2712         uint16_t retval;
2713
2714         /*  Set up DEBI control register value in shadow RAM. */
2715         WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
2716
2717         /*  Execute the DEBI transfer. */
2718         DEBItransfer(dev);
2719
2720         /*  Fetch target register value. */
2721         retval = (uint16_t) RR7146(P_DEBIAD);
2722
2723         /*  Return register value. */
2724         return retval;
2725 }
2726
2727 /*  Execute a DEBI transfer.  This must be called from within a */
2728 /*  critical section. */
2729 static void DEBItransfer(struct comedi_device *dev)
2730 {
2731         /*  Initiate upload of shadow RAM to DEBI control register. */
2732         MC_ENABLE(P_MC2, MC2_UPLD_DEBI);
2733
2734         /*  Wait for completion of upload from shadow RAM to DEBI control */
2735         /*  register. */
2736         while (!MC_TEST(P_MC2, MC2_UPLD_DEBI))
2737                 ;
2738
2739         /*  Wait until DEBI transfer is done. */
2740         while (RR7146(P_PSR) & PSR_DEBI_S)
2741                 ;
2742 }
2743
2744 /*  Write a value to a gate array register. */
2745 static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
2746 {
2747
2748         /*  Set up DEBI control register value in shadow RAM. */
2749         WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
2750         WR7146(P_DEBIAD, wdata);
2751
2752         /*  Execute the DEBI transfer. */
2753         DEBItransfer(dev);
2754 }
2755
2756 /* Replace the specified bits in a gate array register.  Imports: mask
2757  * specifies bits that are to be preserved, wdata is new value to be
2758  * or'd with the masked original.
2759  */
2760 static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
2761                         uint16_t wdata)
2762 {
2763
2764         /*  Copy target gate array register into P_DEBIAD register. */
2765         WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
2766         /* Set up DEBI control reg value in shadow RAM. */
2767         DEBItransfer(dev);      /*  Execute the DEBI Read transfer. */
2768
2769         /*  Write back the modified image. */
2770         WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
2771         /* Set up DEBI control reg value in shadow  RAM. */
2772
2773         WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask));
2774         /* Modify the register image. */
2775         DEBItransfer(dev);      /*  Execute the DEBI Write transfer. */
2776 }
2777
2778 static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
2779                       size_t bsize)
2780 {
2781         void *vbptr;
2782         dma_addr_t vpptr;
2783
2784         DEBUG("CloseDMAB: Entering S626DRV_CloseDMAB():\n");
2785         if (pdma == NULL)
2786                 return;
2787         /* find the matching allocation from the board struct */
2788
2789         vbptr = pdma->LogicalBase;
2790         vpptr = pdma->PhysicalBase;
2791         if (vbptr) {
2792                 pci_free_consistent(devpriv->pdev, bsize, vbptr, vpptr);
2793                 pdma->LogicalBase = 0;
2794                 pdma->PhysicalBase = 0;
2795
2796                 DEBUG("CloseDMAB(): Logical=%p, bsize=%d, Physical=0x%x\n",
2797                       vbptr, bsize, (uint32_t) vpptr);
2798         }
2799 }
2800
2801 /* ******  COUNTER FUNCTIONS  ******* */
2802 /* All counter functions address a specific counter by means of the
2803  * "Counter" argument, which is a logical counter number.  The Counter
2804  * argument may have any of the following legal values: 0=0A, 1=1A,
2805  * 2=2A, 3=0B, 4=1B, 5=2B.
2806  */
2807
2808 /* Forward declarations for functions that are common to both A and B counters: */
2809
2810 /* ******  PRIVATE COUNTER FUNCTIONS ****** */
2811
2812 /*  Read a counter's output latch. */
2813
2814 static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k)
2815 {
2816         register uint32_t value;
2817         /* DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n"); */
2818
2819         /*  Latch counts and fetch LSW of latched counts value. */
2820         value = (uint32_t) DEBIread(dev, k->MyLatchLsw);
2821
2822         /*  Fetch MSW of latched counts and combine with LSW. */
2823         value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16);
2824
2825         /*  DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); */
2826
2827         /*  Return latched counts. */
2828         return value;
2829 }
2830
2831 /*  Reset a counter's index and overflow event capture flags. */
2832
2833 static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k)
2834 {
2835         DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
2836                     CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
2837 }
2838
2839 static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k)
2840 {
2841         DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
2842                     CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B);
2843 }
2844
2845 /*  Return counter setup in a format (COUNTER_SETUP) that is consistent */
2846 /*  for both A and B counters. */
2847
2848 static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k)
2849 {
2850         register uint16_t cra;
2851         register uint16_t crb;
2852         register uint16_t setup;
2853
2854         /*  Fetch CRA and CRB register images. */
2855         cra = DEBIread(dev, k->MyCRA);
2856         crb = DEBIread(dev, k->MyCRB);
2857
2858         /*  Populate the standardized counter setup bit fields.  Note: */
2859         /*  IndexSrc is restricted to ENC_X or IndxPol. */
2860         setup = ((cra & STDMSK_LOADSRC) /*  LoadSrc  = LoadSrcA. */
2861                  |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)      /*  LatchSrc = LatchSrcA. */
2862                  |((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC)  /*  IntSrc   = IntSrcA. */
2863                  |((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC) /*  IndxSrc  = IndxSrcA<1>. */
2864                  |((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL)       /*  IndxPol  = IndxPolA. */
2865                  |((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB));     /*  ClkEnab  = ClkEnabA. */
2866
2867         /*  Adjust mode-dependent parameters. */
2868         if (cra & (2 << CRABIT_CLKSRC_A))       /*  If Timer mode (ClkSrcA<1> == 1): */
2869                 setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)       /*    Indicate Timer mode. */
2870                           |((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL) /*    Set ClkPol to indicate count direction (ClkSrcA<0>). */
2871                           |(MULT_X1 << STDBIT_CLKMULT));        /*    ClkMult must be 1x in Timer mode. */
2872
2873         else                    /*  If Counter mode (ClkSrcA<1> == 0): */
2874                 setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)     /*    Indicate Counter mode. */
2875                           |((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL) /*    Pass through ClkPol. */
2876                           |(((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ?       /*    Force ClkMult to 1x if not legal, else pass through. */
2877                             (MULT_X1 << STDBIT_CLKMULT) :
2878                             ((cra >> (CRABIT_CLKMULT_A -
2879                                       STDBIT_CLKMULT)) & STDMSK_CLKMULT)));
2880
2881         /*  Return adjusted counter setup. */
2882         return setup;
2883 }
2884
2885 static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
2886 {
2887         register uint16_t cra;
2888         register uint16_t crb;
2889         register uint16_t setup;
2890
2891         /*  Fetch CRA and CRB register images. */
2892         cra = DEBIread(dev, k->MyCRA);
2893         crb = DEBIread(dev, k->MyCRB);
2894
2895         /*  Populate the standardized counter setup bit fields.  Note: */
2896         /*  IndexSrc is restricted to ENC_X or IndxPol. */
2897         setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC)   /*  IntSrc   = IntSrcB. */
2898                  |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)      /*  LatchSrc = LatchSrcB. */
2899                  |((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC)       /*  LoadSrc  = LoadSrcB. */
2900                  |((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL)       /*  IndxPol  = IndxPolB. */
2901                  |((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB)       /*  ClkEnab  = ClkEnabB. */
2902                  |((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC));       /*  IndxSrc  = IndxSrcB<1>. */
2903
2904         /*  Adjust mode-dependent parameters. */
2905         if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B))  /*  If Extender mode (ClkMultB == MULT_X0): */
2906                 setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC)    /*    Indicate Extender mode. */
2907                           |(MULT_X1 << STDBIT_CLKMULT)  /*    Indicate multiplier is 1x. */
2908                           |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));       /*    Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
2909
2910         else if (cra & (2 << CRABIT_CLKSRC_B))  /*  If Timer mode (ClkSrcB<1> == 1): */
2911                 setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)       /*    Indicate Timer mode. */
2912                           |(MULT_X1 << STDBIT_CLKMULT)  /*    Indicate multiplier is 1x. */
2913                           |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));       /*    Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
2914
2915         else                    /*  If Counter mode (ClkSrcB<1> == 0): */
2916                 setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)     /*    Indicate Timer mode. */
2917                           |((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT)      /*    Clock multiplier is passed through. */
2918                           |((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL));       /*    Clock polarity is passed through. */
2919
2920         /*  Return adjusted counter setup. */
2921         return setup;
2922 }
2923
2924 /*
2925  * Set the operating mode for the specified counter.  The setup
2926  * parameter is treated as a COUNTER_SETUP data type.  The following
2927  * parameters are programmable (all other parms are ignored): ClkMult,
2928  * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
2929  */
2930
2931 static void SetMode_A(struct comedi_device *dev, struct enc_private *k,
2932                       uint16_t Setup, uint16_t DisableIntSrc)
2933 {
2934         register uint16_t cra;
2935         register uint16_t crb;
2936         register uint16_t setup = Setup;        /*  Cache the Standard Setup. */
2937
2938         /*  Initialize CRA and CRB images. */
2939         cra = ((setup & CRAMSK_LOADSRC_A)       /*  Preload trigger is passed through. */
2940                |((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))));       /*  IndexSrc is restricted to ENC_X or IndxPol. */
2941
2942         crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A   /*  Reset any pending CounterA event captures. */
2943                | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)));    /*  Clock enable is passed through. */
2944
2945         /*  Force IntSrc to Disabled if DisableIntSrc is asserted. */
2946         if (!DisableIntSrc)
2947                 cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
2948                                                     CRABIT_INTSRC_A));
2949
2950         /*  Populate all mode-dependent attributes of CRA & CRB images. */
2951         switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
2952         case CLKSRC_EXTENDER:   /*  Extender Mode: Force to Timer mode */
2953                 /*  (Extender valid only for B counters). */
2954
2955         case CLKSRC_TIMER:      /*  Timer Mode: */
2956                 cra |= ((2 << CRABIT_CLKSRC_A)  /*    ClkSrcA<1> selects system clock */
2957                         |((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) /*      with count direction (ClkSrcA<0>) obtained from ClkPol. */
2958                         |(1 << CRABIT_CLKPOL_A) /*    ClkPolA behaves as always-on clock enable. */
2959                         |(MULT_X1 << CRABIT_CLKMULT_A));        /*    ClkMult must be 1x. */
2960                 break;
2961
2962         default:                /*  Counter Mode: */
2963                 cra |= (CLKSRC_COUNTER  /*    Select ENC_C and ENC_D as clock/direction inputs. */
2964                         | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL))        /*    Clock polarity is passed through. */
2965                         |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?   /*    Force multiplier to x1 if not legal, otherwise pass through. */
2966                           (MULT_X1 << CRABIT_CLKMULT_A) :
2967                           ((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A -
2968                                                         STDBIT_CLKMULT))));
2969         }
2970
2971         /*  Force positive index polarity if IndxSrc is software-driven only, */
2972         /*  otherwise pass it through. */
2973         if (~setup & STDMSK_INDXSRC)
2974                 cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A -
2975                                                      STDBIT_INDXPOL));
2976
2977         /*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
2978         /*  enable mask to indicate the counter interrupt is disabled. */
2979         if (DisableIntSrc)
2980                 devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
2981
2982         /*  While retaining CounterB and LatchSrc configurations, program the */
2983         /*  new counter operating mode. */
2984         DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra);
2985         DEBIreplace(dev, k->MyCRB,
2986                     (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb);
2987 }
2988
2989 static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
2990                       uint16_t Setup, uint16_t DisableIntSrc)
2991 {
2992         register uint16_t cra;
2993         register uint16_t crb;
2994         register uint16_t setup = Setup;        /*  Cache the Standard Setup. */
2995
2996         /*  Initialize CRA and CRB images. */
2997         cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC));  /*  IndexSrc field is restricted to ENC_X or IndxPol. */
2998
2999         crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B   /*  Reset event captures and disable interrupts. */
3000                | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB))      /*  Clock enable is passed through. */
3001                |((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)));     /*  Preload trigger source is passed through. */
3002
3003         /*  Force IntSrc to Disabled if DisableIntSrc is asserted. */
3004         if (!DisableIntSrc)
3005                 crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
3006                                                     CRBBIT_INTSRC_B));
3007
3008         /*  Populate all mode-dependent attributes of CRA & CRB images. */
3009         switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
3010         case CLKSRC_TIMER:      /*  Timer Mode: */
3011                 cra |= ((2 << CRABIT_CLKSRC_B)  /*    ClkSrcB<1> selects system clock */
3012                         |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));       /*      with direction (ClkSrcB<0>) obtained from ClkPol. */
3013                 crb |= ((1 << CRBBIT_CLKPOL_B)  /*    ClkPolB behaves as always-on clock enable. */
3014                         |(MULT_X1 << CRBBIT_CLKMULT_B));        /*    ClkMultB must be 1x. */
3015                 break;
3016
3017         case CLKSRC_EXTENDER:   /*  Extender Mode: */
3018                 cra |= ((2 << CRABIT_CLKSRC_B)  /*    ClkSrcB source is OverflowA (same as "timer") */
3019                         |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));       /*      with direction obtained from ClkPol. */
3020                 crb |= ((1 << CRBBIT_CLKPOL_B)  /*    ClkPolB controls IndexB -- always set to active. */
3021                         |(MULT_X0 << CRBBIT_CLKMULT_B));        /*    ClkMultB selects OverflowA as the clock source. */
3022                 break;
3023
3024         default:                /*  Counter Mode: */
3025                 cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B);     /*    Select ENC_C and ENC_D as clock/direction inputs. */
3026                 crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B))  /*    ClkPol is passed through. */
3027                         |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?   /*    Force ClkMult to x1 if not legal, otherwise pass through. */
3028                           (MULT_X1 << CRBBIT_CLKMULT_B) :
3029                           ((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B -
3030                                                         STDBIT_CLKMULT))));
3031         }
3032
3033         /*  Force positive index polarity if IndxSrc is software-driven only, */
3034         /*  otherwise pass it through. */
3035         if (~setup & STDMSK_INDXSRC)
3036                 crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL -
3037                                                      CRBBIT_INDXPOL_B));
3038
3039         /*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
3040         /*  enable mask to indicate the counter interrupt is disabled. */
3041         if (DisableIntSrc)
3042                 devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
3043
3044         /*  While retaining CounterA and LatchSrc configurations, program the */
3045         /*  new counter operating mode. */
3046         DEBIreplace(dev, k->MyCRA,
3047                     (uint16_t) (~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B)), cra);
3048         DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb);
3049 }
3050
3051 /*  Return/set a counter's enable.  enab: 0=always enabled, 1=enabled by index. */
3052
3053 static void SetEnable_A(struct comedi_device *dev, struct enc_private *k,
3054                         uint16_t enab)
3055 {
3056         DEBUG("SetEnable_A: SetEnable_A enter 3541\n");
3057         DEBIreplace(dev, k->MyCRB,
3058                     (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)),
3059                     (uint16_t) (enab << CRBBIT_CLKENAB_A));
3060 }
3061
3062 static void SetEnable_B(struct comedi_device *dev, struct enc_private *k,
3063                         uint16_t enab)
3064 {
3065         DEBIreplace(dev, k->MyCRB,
3066                     (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)),
3067                     (uint16_t) (enab << CRBBIT_CLKENAB_B));
3068 }
3069
3070 static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k)
3071 {
3072         return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_A) & 1;
3073 }
3074
3075 static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
3076 {
3077         return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1;
3078 }
3079
3080 /* Return/set a counter pair's latch trigger source.  0: On read
3081  * access, 1: A index latches A, 2: B index latches B, 3: A overflow
3082  * latches B.
3083  */
3084
3085 static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
3086                            uint16_t value)
3087 {
3088         DEBUG("SetLatchSource: SetLatchSource enter 3550\n");
3089         DEBIreplace(dev, k->MyCRB,
3090                     (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)),
3091                     (uint16_t) (value << CRBBIT_LATCHSRC));
3092
3093         DEBUG("SetLatchSource: SetLatchSource exit\n");
3094 }
3095
3096 /*
3097  * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k )
3098  * {
3099  *      return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3;
3100  * }
3101  */
3102
3103 /*
3104  * Return/set the event that will trigger transfer of the preload
3105  * register into the counter.  0=ThisCntr_Index, 1=ThisCntr_Overflow,
3106  * 2=OverflowA (B counters only), 3=disabled.
3107  */
3108
3109 static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k,
3110                           uint16_t Trig)
3111 {
3112         DEBIreplace(dev, k->MyCRA, (uint16_t) (~CRAMSK_LOADSRC_A),
3113                     (uint16_t) (Trig << CRABIT_LOADSRC_A));
3114 }
3115
3116 static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k,
3117                           uint16_t Trig)
3118 {
3119         DEBIreplace(dev, k->MyCRB,
3120                     (uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)),
3121                     (uint16_t) (Trig << CRBBIT_LOADSRC_B));
3122 }
3123
3124 static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k)
3125 {
3126         return (DEBIread(dev, k->MyCRA) >> CRABIT_LOADSRC_A) & 3;
3127 }
3128
3129 static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k)
3130 {
3131         return (DEBIread(dev, k->MyCRB) >> CRBBIT_LOADSRC_B) & 3;
3132 }
3133
3134 /* Return/set counter interrupt source and clear any captured
3135  * index/overflow events.  IntSource: 0=Disabled, 1=OverflowOnly,
3136  * 2=IndexOnly, 3=IndexAndOverflow.
3137  */
3138
3139 static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
3140                         uint16_t IntSource)
3141 {
3142         /*  Reset any pending counter overflow or index captures. */
3143         DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
3144                     CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
3145
3146         /*  Program counter interrupt source. */
3147         DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A,
3148                     (uint16_t) (IntSource << CRABIT_INTSRC_A));
3149
3150         /*  Update MISC2 interrupt enable mask. */
3151         devpriv->CounterIntEnabs =
3152             (devpriv->CounterIntEnabs & ~k->
3153              MyEventBits[3]) | k->MyEventBits[IntSource];
3154 }
3155
3156 static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
3157                         uint16_t IntSource)
3158 {
3159         uint16_t crb;
3160
3161         /*  Cache writeable CRB register image. */
3162         crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;
3163
3164         /*  Reset any pending counter overflow or index captures. */
3165         DEBIwrite(dev, k->MyCRB,
3166                   (uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B));
3167
3168         /*  Program counter interrupt source. */
3169         DEBIwrite(dev, k->MyCRB,
3170                   (uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource <<
3171                                                           CRBBIT_INTSRC_B)));
3172
3173         /*  Update MISC2 interrupt enable mask. */
3174         devpriv->CounterIntEnabs =
3175             (devpriv->CounterIntEnabs & ~k->
3176              MyEventBits[3]) | k->MyEventBits[IntSource];
3177 }
3178
3179 static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k)
3180 {
3181         return (DEBIread(dev, k->MyCRA) >> CRABIT_INTSRC_A) & 3;
3182 }
3183
3184 static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k)
3185 {
3186         return (DEBIread(dev, k->MyCRB) >> CRBBIT_INTSRC_B) & 3;
3187 }
3188
3189 /*  Return/set the clock multiplier. */
3190
3191 /* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
3192 /* { */
3193 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKMULT ) | ( value << STDBIT_CLKMULT ) ), FALSE ); */
3194 /* } */
3195
3196 /* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k )  */
3197 /* { */
3198 /*   return ( k->GetMode(dev, k ) >> STDBIT_CLKMULT ) & 3; */
3199 /* } */
3200
3201 /* Return/set the clock polarity. */
3202
3203 /* static void SetClkPol( struct comedi_device *dev,struct enc_private *k, uint16_t value )  */
3204 /* { */
3205 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKPOL ) | ( value << STDBIT_CLKPOL ) ), FALSE ); */
3206 /* } */
3207
3208 /* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k )  */
3209 /* { */
3210 /*   return ( k->GetMode(dev, k ) >> STDBIT_CLKPOL ) & 1; */
3211 /* } */
3212
3213 /* Return/set the clock source.  */
3214
3215 /* static void SetClkSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value )  */
3216 /* { */
3217 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKSRC ) | ( value << STDBIT_CLKSRC ) ), FALSE ); */
3218 /* } */
3219
3220 /* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k )  */
3221 /* { */
3222 /*   return ( k->GetMode(dev, k ) >> STDBIT_CLKSRC ) & 3; */
3223 /* } */
3224
3225 /* Return/set the index polarity. */
3226
3227 /* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
3228 /* { */
3229 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXPOL ) | ( (value != 0) << STDBIT_INDXPOL ) ), FALSE ); */
3230 /* } */
3231
3232 /* static uint16_t GetIndexPol(struct comedi_device *dev, struct enc_private *k )  */
3233 /* { */
3234 /*   return ( k->GetMode(dev, k ) >> STDBIT_INDXPOL ) & 1; */
3235 /* } */
3236
3237 /*  Return/set the index source. */
3238
3239 /* static void SetIndexSrc(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
3240 /* { */
3241 /*   DEBUG("SetIndexSrc: set index src enter 3700\n"); */
3242 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXSRC ) | ( (value != 0) << STDBIT_INDXSRC ) ), FALSE ); */
3243 /* } */
3244
3245 /* static uint16_t GetIndexSrc(struct comedi_device *dev, struct enc_private *k )  */
3246 /* { */
3247 /*   return ( k->GetMode(dev, k ) >> STDBIT_INDXSRC ) & 1; */
3248 /* } */
3249
3250 /*  Generate an index pulse. */
3251
3252 static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k)
3253 {
3254         register uint16_t cra;
3255
3256         DEBUG("PulseIndex_A: pulse index enter\n");
3257
3258         cra = DEBIread(dev, k->MyCRA);  /*  Pulse index. */
3259         DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A));
3260         DEBUG("PulseIndex_A: pulse index step1\n");
3261         DEBIwrite(dev, k->MyCRA, cra);
3262 }
3263
3264 static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k)
3265 {
3266         register uint16_t crb;
3267
3268         crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;        /*  Pulse index. */
3269         DEBIwrite(dev, k->MyCRB, (uint16_t) (crb ^ CRBMSK_INDXPOL_B));
3270         DEBIwrite(dev, k->MyCRB, crb);
3271 }
3272
3273 /*  Write value into counter preload register. */
3274
3275 static void Preload(struct comedi_device *dev, struct enc_private *k,
3276                     uint32_t value)
3277 {
3278         DEBUG("Preload: preload enter\n");
3279         DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value);   /*  Write value to preload register. */
3280         DEBUG("Preload: preload step 1\n");
3281         DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2),
3282                   (uint16_t) (value >> 16));
3283 }
3284
3285 static void CountersInit(struct comedi_device *dev)
3286 {
3287         int chan;
3288         struct enc_private *k;
3289         uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /*  Preload upon */
3290             /*  index. */
3291             (INDXSRC_SOFT << BF_INDXSRC) |      /*  Disable hardware index. */
3292             (CLKSRC_COUNTER << BF_CLKSRC) |     /*  Operating mode is counter. */
3293             (CLKPOL_POS << BF_CLKPOL) | /*  Active high clock. */
3294             (CNTDIR_UP << BF_CLKPOL) |  /*  Count direction is up. */
3295             (CLKMULT_1X << BF_CLKMULT) |        /*  Clock multiplier is 1x. */
3296             (CLKENAB_INDEX << BF_CLKENAB);      /*  Enabled by index */
3297
3298         /*  Disable all counter interrupts and clear any captured counter events. */
3299         for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
3300                 k = &encpriv[chan];
3301                 k->SetMode(dev, k, Setup, TRUE);
3302                 k->SetIntSrc(dev, k, 0);
3303                 k->ResetCapFlags(dev, k);
3304                 k->SetEnable(dev, k, CLKENAB_ALWAYS);
3305         }
3306         DEBUG("CountersInit: counters initialized\n");
3307
3308 }
3309
3310 static struct comedi_driver s626_driver = {
3311         .driver_name    = "s626",
3312         .module         = THIS_MODULE,
3313         .attach         = s626_attach,
3314         .detach         = s626_detach,
3315 };
3316
3317 static int __devinit s626_pci_probe(struct pci_dev *dev,
3318                                     const struct pci_device_id *ent)
3319 {
3320         return comedi_pci_auto_config(dev, &s626_driver);
3321 }
3322
3323 static void __devexit s626_pci_remove(struct pci_dev *dev)
3324 {
3325         comedi_pci_auto_unconfig(dev);
3326 }
3327
3328 /*
3329  * For devices with vendor:device id == 0x1131:0x7146 you must specify
3330  * also subvendor:subdevice ids, because otherwise it will conflict with
3331  * Philips SAA7146 media/dvb based cards.
3332  */
3333 static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = {
3334         { PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626,
3335                 PCI_SUBVENDOR_ID_S626, PCI_SUBDEVICE_ID_S626, 0, 0, 0 },
3336         { 0 }
3337 };
3338 MODULE_DEVICE_TABLE(pci, s626_pci_table);
3339
3340 static struct pci_driver s626_pci_driver = {
3341         .name           = "s626",
3342         .id_table       = s626_pci_table,
3343         .probe          = s626_pci_probe,
3344         .remove         = __devexit_p(s626_pci_remove),
3345 };
3346 module_comedi_pci_driver(s626_driver, s626_pci_driver);
3347
3348 MODULE_AUTHOR("Gianluca Palli <gpalli@deis.unibo.it>");
3349 MODULE_DESCRIPTION("Sensoray 626 Comedi driver module");
3350 MODULE_LICENSE("GPL");