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