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