2 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
7 * Tel: +19(0)7223/9493-0
8 * Fax: +49(0)7223/9493-92
9 * http://www.addi-data-com
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 2 of the License, or (at your option)
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/sched.h>
22 #include <linux/slab.h>
23 #include <linux/errno.h>
24 #include <linux/ioport.h>
25 #include <linux/delay.h>
26 #include <linux/interrupt.h>
27 #include <linux/timex.h>
28 #include <linux/timer.h>
29 #include <linux/pci.h>
31 #include <linux/kmod.h>
32 #include <linux/uaccess.h>
33 #include "../../comedidev.h"
34 #include "addi_amcc_s5933.h"
39 /* variable type definition */
40 typedef unsigned long ULONG_PTR;
42 typedef const struct comedi_lrange *PCRANGE;
44 #define LOBYTE(W) (unsigned char)((W) & 0xFF)
45 #define HIBYTE(W) (unsigned char)(((W) >> 8) & 0xFF)
46 #define MAKEWORD(H, L) (unsigned short)((L) | ((H) << 8))
47 #define LOWORD(W) (unsigned short)((W) & 0xFFFF)
48 #define HIWORD(W) (unsigned short)(((W) >> 16) & 0xFFFF)
49 #define MAKEDWORD(H, L) (unsigned int)((L) | ((H) << 16))
52 #define ADDI_DISABLE 0
53 #define APCI1710_SAVE_INTERRUPT 1
55 #define ADDIDATA_EEPROM 1
56 #define ADDIDATA_NO_EEPROM 0
57 #define ADDIDATA_93C76 "93C76"
58 #define ADDIDATA_S5920 "S5920"
59 #define ADDIDATA_S5933 "S5933"
60 #define ADDIDATA_9054 "9054"
62 /* ADDIDATA Enable Disable */
63 #define ADDIDATA_ENABLE 1
64 #define ADDIDATA_DISABLE 0
68 /* structure for the boardtype */
70 const char *pc_DriverName; // driver name
71 int i_VendorId; //PCI vendor a device ID of card
75 int i_IorangeBase2; // base 2 range
76 int i_IorangeBase3; // base 3 range
77 int i_PCIEeprom; // eeprom present or not
78 char *pc_EepromChip; // type of chip
79 int i_NbrAiChannel; // num of A/D chans
80 int i_NbrAiChannelDiff; // num of A/D chans in diff mode
81 int i_AiChannelList; // len of chanlist
82 int i_NbrAoChannel; // num of D/A chans
83 int i_AiMaxdata; // resolution of A/D
84 int i_AoMaxdata; // resolution of D/A
85 PCRANGE pr_AiRangelist; // rangelist for A/D
86 PCRANGE pr_AoRangelist; // rangelist for D/A
88 int i_NbrDiChannel; // Number of DI channels
89 int i_NbrDoChannel; // Number of DO channels
90 int i_DoMaxdata; // data to set all chanels high
92 int i_NbrTTLChannel; // Number of TTL channels
93 PCRANGE pr_TTLRangelist; // rangelist for TTL
95 int i_Dma; // dma present or not
96 int i_Timer; // timer subdevice present or not
97 unsigned char b_AvailableConvertUnit;
98 unsigned int ui_MinAcquisitiontimeNs; // Minimum Acquisition in Nano secs
99 unsigned int ui_MinDelaytimeNs; // Minimum Delay in Nano secs
101 /* interrupt and reset */
102 void (*v_hwdrv_Interrupt)(int irq, void *d);
103 int (*i_hwdrv_Reset)(struct comedi_device *dev);
105 /* Subdevice functions */
108 int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev,
109 struct comedi_subdevice *s,
110 struct comedi_insn *insn,
112 int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev,
113 struct comedi_subdevice *s,
114 struct comedi_insn *insn,
116 int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev,
117 struct comedi_subdevice *s,
118 struct comedi_insn *insn,
120 int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev,
121 struct comedi_subdevice *s,
122 struct comedi_insn *insn,
124 int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev,
125 struct comedi_subdevice *s,
126 struct comedi_cmd *cmd);
127 int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev,
128 struct comedi_subdevice *s);
129 int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev,
130 struct comedi_subdevice *s);
133 int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev,
134 struct comedi_subdevice *s,
135 struct comedi_insn *insn,
137 int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev,
138 struct comedi_subdevice *s,
139 struct comedi_insn *insn,
141 int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev,
142 struct comedi_subdevice *s,
143 struct comedi_insn *insn,
147 int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev,
148 struct comedi_subdevice *s,
149 struct comedi_insn *insn,
151 int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev,
152 struct comedi_subdevice *s,
153 struct comedi_insn *insn,
155 int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev,
156 struct comedi_subdevice *s,
157 struct comedi_insn *insn,
159 int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev,
160 struct comedi_subdevice *s,
161 struct comedi_insn *insn,
165 int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev,
166 struct comedi_subdevice *s,
167 struct comedi_insn *insn,
169 int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev,
170 struct comedi_subdevice *s,
171 struct comedi_insn *insn,
173 int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev,
174 struct comedi_subdevice *s,
175 struct comedi_insn *insn,
177 int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev,
178 struct comedi_subdevice *s,
179 struct comedi_insn *insn,
183 int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev,
184 struct comedi_subdevice *s,
185 struct comedi_insn *insn, unsigned int *data);
186 int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev,
187 struct comedi_subdevice *s, struct comedi_insn *insn,
189 int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
190 struct comedi_insn *insn, unsigned int *data);
191 int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
192 struct comedi_insn *insn, unsigned int *data);
195 int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev,
196 struct comedi_subdevice *s, struct comedi_insn *insn,
198 int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s,
199 struct comedi_insn *insn, unsigned int *data);
200 int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev,
201 struct comedi_subdevice *s,
202 struct comedi_insn *insn,
204 int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev,
205 struct comedi_subdevice *s,
206 struct comedi_insn *insn, unsigned int *data);
209 //MODULE INFO STRUCTURE
212 /* Incremental counter infos */
216 unsigned char b_ModeRegister1;
217 unsigned char b_ModeRegister2;
218 unsigned char b_ModeRegister3;
219 unsigned char b_ModeRegister4;
220 } s_ByteModeRegister;
221 unsigned int dw_ModeRegister1_2_3_4;
225 unsigned int b_IndexInit:1;
226 unsigned int b_CounterInit:1;
227 unsigned int b_ReferenceInit:1;
228 unsigned int b_IndexInterruptOccur:1;
229 unsigned int b_CompareLogicInit:1;
230 unsigned int b_FrequencyMeasurementInit:1;
231 unsigned int b_FrequencyMeasurementEnable:1;
234 } s_SiemensCounterInfo;
238 unsigned char b_SSIProfile;
239 unsigned char b_PositionTurnLength;
240 unsigned char b_TurnCptLength;
241 unsigned char b_SSIInit;
246 unsigned char b_TTLInit;
247 unsigned char b_PortConfiguration[4];
250 /* Digital I/O infos */
252 unsigned char b_DigitalInit;
253 unsigned char b_ChannelAMode;
254 unsigned char b_ChannelBMode;
255 unsigned char b_OutputMemoryEnabled;
256 unsigned int dw_OutputMemory;
259 /*********************/
260 /* 82X54 timer infos */
261 /*********************/
265 unsigned char b_82X54Init;
266 unsigned char b_InputClockSelection;
267 unsigned char b_InputClockLevel;
268 unsigned char b_OutputLevel;
269 unsigned char b_HardwareGateLevel;
270 unsigned int dw_ConfigurationWord;
271 } s_82X54TimerInfo[3];
272 unsigned char b_InterruptMask;
275 /*********************/
276 /* Chronometer infos */
277 /*********************/
280 unsigned char b_ChronoInit;
281 unsigned char b_InterruptMask;
282 unsigned char b_PCIInputClock;
283 unsigned char b_TimingUnit;
284 unsigned char b_CycleMode;
285 double d_TimingInterval;
286 unsigned int dw_ConfigReg;
287 } s_ChronoModuleInfo;
289 /***********************/
290 /* Pulse encoder infos */
291 /***********************/
295 unsigned char b_PulseEncoderInit;
296 } s_PulseEncoderInfo[4];
297 unsigned int dw_SetRegister;
298 unsigned int dw_ControlRegister;
299 unsigned int dw_StatusRegister;
300 } s_PulseEncoderModuleInfo;
302 /* Tor conter infos */
305 unsigned char b_TorCounterInit;
306 unsigned char b_TimingUnit;
307 unsigned char b_InterruptEnable;
308 double d_TimingInterval;
309 unsigned int ul_RealTimingInterval;
310 } s_TorCounterInfo[2];
311 unsigned char b_PCIInputClock;
312 } s_TorCounterModuleInfo;
317 unsigned char b_PWMInit;
318 unsigned char b_TimingUnit;
319 unsigned char b_InterruptEnable;
322 unsigned int ul_RealLowTiming;
323 unsigned int ul_RealHighTiming;
325 unsigned char b_ClockSelection;
331 unsigned char b_ETMEnable;
332 unsigned char b_ETMInterrupt;
334 unsigned char b_ETMInit;
335 unsigned char b_TimingUnit;
336 unsigned char b_ClockSelection;
337 double d_TimingInterval;
338 unsigned int ul_Timing;
343 unsigned char b_CDAEnable;
344 unsigned char b_CDAInterrupt;
345 unsigned char b_CDAInit;
346 unsigned char b_FctSelection;
347 unsigned char b_CDAReadFIFOOverflow;
352 /* Private structure for the addi_apci3120 driver */
356 int i_IobaseAmcc; // base+size for AMCC chip
357 int i_IobaseAddon; //addon base address
358 int i_IobaseReserved;
360 struct pcilst_struct *amcc; // ptr too AMCC data
361 unsigned char allocated; // we have blocked card
362 unsigned char b_ValidDriver; // driver is ok
363 unsigned char b_AiContinuous; // we do unlimited AI
364 unsigned char b_AiInitialisation;
365 unsigned int ui_AiActualScan; //how many scans we finished
366 unsigned int ui_AiBufferPtr; // data buffer ptr in samples
367 unsigned int ui_AiNbrofChannels; // how many channels is measured
368 unsigned int ui_AiScanLength; // Length of actual scanlist
369 unsigned int ui_AiActualScanPosition; // position in actual scan
370 unsigned int * pui_AiChannelList; // actual chanlist
371 unsigned int ui_AiChannelList[32]; // actual chanlist
372 unsigned char b_AiChannelConfiguration[32]; // actual chanlist
373 unsigned int ui_AiReadData[32];
374 unsigned int dw_AiInitialised;
375 unsigned int ui_AiTimer0; //Timer Constant for Timer0
376 unsigned int ui_AiTimer1; //Timer constant for Timer1
377 unsigned int ui_AiFlags;
378 unsigned int ui_AiDataLength;
379 short *AiData; // Pointer to sample data
380 unsigned int ui_AiNbrofScans; // number of scans to do
381 unsigned short us_UseDma; // To use Dma or not
382 unsigned char b_DmaDoubleBuffer; // we can use double buffering
383 unsigned int ui_DmaActualBuffer; // which buffer is used now
384 /* UPDATE-0.7.57->0.7.68 */
385 /* unsigned int ul_DmaBufferVirtual[2]; pointers to begin of DMA buffer */
386 short *ul_DmaBufferVirtual[2]; // pointers to begin of DMA buffer
387 unsigned int ul_DmaBufferHw[2]; // hw address of DMA buff
388 unsigned int ui_DmaBufferSize[2]; // size of dma buffer in bytes
389 unsigned int ui_DmaBufferUsesize[2]; // which size we may now used for transfer
390 unsigned int ui_DmaBufferSamples[2]; // size in samples
391 unsigned int ui_DmaBufferPages[2]; // number of pages in buffer
392 unsigned char b_DigitalOutputRegister; // Digital Output Register
393 unsigned char b_OutputMemoryStatus;
394 unsigned char b_AnalogInputChannelNbr; // Analog input channel Nbr
395 unsigned char b_AnalogOutputChannelNbr; // Analog input Output Nbr
396 unsigned char b_TimerSelectMode; // Contain data written at iobase + 0C
397 unsigned char b_ModeSelectRegister; // Contain data written at iobase + 0E
398 unsigned short us_OutputRegister; // Contain data written at iobase + 0
399 unsigned char b_InterruptState;
400 unsigned char b_TimerInit; // Specify if InitTimerWatchdog was load
401 unsigned char b_TimerStarted; // Specify if timer 2 is running or not
402 unsigned char b_Timer2Mode; // Specify the timer 2 mode
403 unsigned char b_Timer2Interrupt; //Timer2 interrupt enable or disable
404 unsigned char b_AiCyclicAcquisition; // indicate cyclic acquisition
405 unsigned char b_InterruptMode; // eoc eos or dma
406 unsigned char b_EocEosInterrupt; // Enable disable eoc eos interrupt
407 unsigned int ui_EocEosConversionTime;
408 unsigned char b_EocEosConversionTimeBase;
409 unsigned char b_SingelDiff;
410 unsigned char b_ExttrigEnable; /* To enable or disable external trigger */
412 /* Pointer to the current process */
413 struct task_struct *tsk_Current;
414 boardtype *ps_BoardInfo;
416 /* Hardware board infos for 1710 */
418 unsigned int ui_Address; /* Board address */
419 unsigned int ui_FlashAddress;
420 unsigned char b_InterruptNbr; /* Board interrupt number */
421 unsigned char b_SlotNumber; /* PCI slot number */
422 unsigned char b_BoardVersion;
423 unsigned int dw_MolduleConfiguration[4]; /* Module config */
426 /* Interrupt infos */
428 unsigned int ul_InterruptOccur; /* 0 : No interrupt occur */
429 /* > 0 : Interrupt occur */
430 unsigned int ui_Read; /* Read FIFO */
431 unsigned int ui_Write; /* Write FIFO */
433 unsigned char b_OldModuleMask;
434 unsigned int ul_OldInterruptMask; /* Interrupt mask */
435 unsigned int ul_OldCounterLatchValue; /* Interrupt counter value */
436 } s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
437 } s_InterruptParameters;
439 str_ModuleInfo s_ModuleInfo[4];
440 unsigned int ul_TTLPortConfiguration[10];
444 static unsigned short pci_list_builded; /* set to 1 when list of card is known */
446 /* Function declarations */
447 static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it);
448 static int i_ADDI_Detach(struct comedi_device *dev);
449 static int i_ADDI_Reset(struct comedi_device *dev);
451 static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG);
452 static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
453 struct comedi_insn *insn, unsigned int *data);