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 */
41 typedef const struct comedi_lrange *PCRANGE;
43 #define LOBYTE(W) (unsigned char)((W) & 0xFF)
44 #define HIBYTE(W) (unsigned char)(((W) >> 8) & 0xFF)
45 #define MAKEWORD(H, L) (unsigned short)((L) | ((H) << 8))
46 #define LOWORD(W) (unsigned short)((W) & 0xFFFF)
47 #define HIWORD(W) (unsigned short)(((W) >> 16) & 0xFFFF)
48 #define MAKEDWORD(H, L) (unsigned int)((L) | ((H) << 16))
51 #define ADDI_DISABLE 0
52 #define APCI1710_SAVE_INTERRUPT 1
54 #define ADDIDATA_EEPROM 1
55 #define ADDIDATA_NO_EEPROM 0
56 #define ADDIDATA_93C76 "93C76"
57 #define ADDIDATA_S5920 "S5920"
58 #define ADDIDATA_S5933 "S5933"
59 #define ADDIDATA_9054 "9054"
61 /* ADDIDATA Enable Disable */
62 #define ADDIDATA_ENABLE 1
63 #define ADDIDATA_DISABLE 0
67 /* structure for the boardtype */
69 const char *pc_DriverName; // driver name
70 int i_VendorId; //PCI vendor a device ID of card
74 int i_IorangeBase2; // base 2 range
75 int i_IorangeBase3; // base 3 range
76 int i_PCIEeprom; // eeprom present or not
77 char *pc_EepromChip; // type of chip
78 int i_NbrAiChannel; // num of A/D chans
79 int i_NbrAiChannelDiff; // num of A/D chans in diff mode
80 int i_AiChannelList; // len of chanlist
81 int i_NbrAoChannel; // num of D/A chans
82 int i_AiMaxdata; // resolution of A/D
83 int i_AoMaxdata; // resolution of D/A
84 PCRANGE pr_AiRangelist; // rangelist for A/D
85 PCRANGE pr_AoRangelist; // rangelist for D/A
87 int i_NbrDiChannel; // Number of DI channels
88 int i_NbrDoChannel; // Number of DO channels
89 int i_DoMaxdata; // data to set all chanels high
91 int i_NbrTTLChannel; // Number of TTL channels
92 PCRANGE pr_TTLRangelist; // rangelist for TTL
94 int i_Dma; // dma present or not
95 int i_Timer; // timer subdevice present or not
96 unsigned char b_AvailableConvertUnit;
97 unsigned int ui_MinAcquisitiontimeNs; // Minimum Acquisition in Nano secs
98 unsigned int ui_MinDelaytimeNs; // Minimum Delay in Nano secs
100 /* interrupt and reset */
101 void (*v_hwdrv_Interrupt)(int irq, void *d);
102 int (*i_hwdrv_Reset)(struct comedi_device *dev);
104 /* Subdevice functions */
107 int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev,
108 struct comedi_subdevice *s,
109 struct comedi_insn *insn,
111 int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev,
112 struct comedi_subdevice *s,
113 struct comedi_insn *insn,
115 int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev,
116 struct comedi_subdevice *s,
117 struct comedi_insn *insn,
119 int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev,
120 struct comedi_subdevice *s,
121 struct comedi_insn *insn,
123 int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev,
124 struct comedi_subdevice *s,
125 struct comedi_cmd *cmd);
126 int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev,
127 struct comedi_subdevice *s);
128 int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev,
129 struct comedi_subdevice *s);
132 int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev,
133 struct comedi_subdevice *s,
134 struct comedi_insn *insn,
136 int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev,
137 struct comedi_subdevice *s,
138 struct comedi_insn *insn,
140 int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev,
141 struct comedi_subdevice *s,
142 struct comedi_insn *insn,
146 int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev,
147 struct comedi_subdevice *s,
148 struct comedi_insn *insn,
150 int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev,
151 struct comedi_subdevice *s,
152 struct comedi_insn *insn,
154 int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev,
155 struct comedi_subdevice *s,
156 struct comedi_insn *insn,
158 int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev,
159 struct comedi_subdevice *s,
160 struct comedi_insn *insn,
164 int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev,
165 struct comedi_subdevice *s,
166 struct comedi_insn *insn,
168 int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev,
169 struct comedi_subdevice *s,
170 struct comedi_insn *insn,
172 int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev,
173 struct comedi_subdevice *s,
174 struct comedi_insn *insn,
176 int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev,
177 struct comedi_subdevice *s,
178 struct comedi_insn *insn,
182 int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev,
183 struct comedi_subdevice *s,
184 struct comedi_insn *insn, unsigned int *data);
185 int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev,
186 struct comedi_subdevice *s, struct comedi_insn *insn,
188 int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
189 struct comedi_insn *insn, unsigned int *data);
190 int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
191 struct comedi_insn *insn, unsigned int *data);
194 int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev,
195 struct comedi_subdevice *s, struct comedi_insn *insn,
197 int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s,
198 struct comedi_insn *insn, unsigned int *data);
199 int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev,
200 struct comedi_subdevice *s,
201 struct comedi_insn *insn,
203 int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev,
204 struct comedi_subdevice *s,
205 struct comedi_insn *insn, unsigned int *data);
208 //MODULE INFO STRUCTURE
211 /* Incremental counter infos */
215 unsigned char b_ModeRegister1;
216 unsigned char b_ModeRegister2;
217 unsigned char b_ModeRegister3;
218 unsigned char b_ModeRegister4;
219 } s_ByteModeRegister;
220 unsigned int dw_ModeRegister1_2_3_4;
224 unsigned int b_IndexInit:1;
225 unsigned int b_CounterInit:1;
226 unsigned int b_ReferenceInit:1;
227 unsigned int b_IndexInterruptOccur:1;
228 unsigned int b_CompareLogicInit:1;
229 unsigned int b_FrequencyMeasurementInit:1;
230 unsigned int b_FrequencyMeasurementEnable:1;
233 } s_SiemensCounterInfo;
237 unsigned char b_SSIProfile;
238 unsigned char b_PositionTurnLength;
239 unsigned char b_TurnCptLength;
240 unsigned char b_SSIInit;
245 unsigned char b_TTLInit;
246 unsigned char b_PortConfiguration[4];
249 /* Digital I/O infos */
251 unsigned char b_DigitalInit;
252 unsigned char b_ChannelAMode;
253 unsigned char b_ChannelBMode;
254 unsigned char b_OutputMemoryEnabled;
255 unsigned int dw_OutputMemory;
258 /*********************/
259 /* 82X54 timer infos */
260 /*********************/
264 unsigned char b_82X54Init;
265 unsigned char b_InputClockSelection;
266 unsigned char b_InputClockLevel;
267 unsigned char b_OutputLevel;
268 unsigned char b_HardwareGateLevel;
269 unsigned int dw_ConfigurationWord;
270 } s_82X54TimerInfo[3];
271 unsigned char b_InterruptMask;
274 /*********************/
275 /* Chronometer infos */
276 /*********************/
279 unsigned char b_ChronoInit;
280 unsigned char b_InterruptMask;
281 unsigned char b_PCIInputClock;
282 unsigned char b_TimingUnit;
283 unsigned char b_CycleMode;
284 double d_TimingInterval;
285 unsigned int dw_ConfigReg;
286 } s_ChronoModuleInfo;
288 /***********************/
289 /* Pulse encoder infos */
290 /***********************/
294 unsigned char b_PulseEncoderInit;
295 } s_PulseEncoderInfo[4];
296 unsigned int dw_SetRegister;
297 unsigned int dw_ControlRegister;
298 unsigned int dw_StatusRegister;
299 } s_PulseEncoderModuleInfo;
301 /* Tor conter infos */
304 unsigned char b_TorCounterInit;
305 unsigned char b_TimingUnit;
306 unsigned char b_InterruptEnable;
307 double d_TimingInterval;
308 unsigned int ul_RealTimingInterval;
309 } s_TorCounterInfo[2];
310 unsigned char b_PCIInputClock;
311 } s_TorCounterModuleInfo;
316 unsigned char b_PWMInit;
317 unsigned char b_TimingUnit;
318 unsigned char b_InterruptEnable;
321 unsigned int ul_RealLowTiming;
322 unsigned int ul_RealHighTiming;
324 unsigned char b_ClockSelection;
330 unsigned char b_ETMEnable;
331 unsigned char b_ETMInterrupt;
333 unsigned char b_ETMInit;
334 unsigned char b_TimingUnit;
335 unsigned char b_ClockSelection;
336 double d_TimingInterval;
337 unsigned int ul_Timing;
342 unsigned char b_CDAEnable;
343 unsigned char b_CDAInterrupt;
344 unsigned char b_CDAInit;
345 unsigned char b_FctSelection;
346 unsigned char b_CDAReadFIFOOverflow;
351 /* Private structure for the addi_apci3120 driver */
355 int i_IobaseAmcc; // base+size for AMCC chip
356 int i_IobaseAddon; //addon base address
357 int i_IobaseReserved;
358 unsigned long dw_AiBase;
359 struct pcilst_struct *amcc; // ptr too AMCC data
360 unsigned char allocated; // we have blocked card
361 unsigned char b_ValidDriver; // driver is ok
362 unsigned char b_AiContinuous; // we do unlimited AI
363 unsigned char b_AiInitialisation;
364 unsigned int ui_AiActualScan; //how many scans we finished
365 unsigned int ui_AiBufferPtr; // data buffer ptr in samples
366 unsigned int ui_AiNbrofChannels; // how many channels is measured
367 unsigned int ui_AiScanLength; // Length of actual scanlist
368 unsigned int ui_AiActualScanPosition; // position in actual scan
369 unsigned int * pui_AiChannelList; // actual chanlist
370 unsigned int ui_AiChannelList[32]; // actual chanlist
371 unsigned char b_AiChannelConfiguration[32]; // actual chanlist
372 unsigned int ui_AiReadData[32];
373 unsigned int dw_AiInitialised;
374 unsigned int ui_AiTimer0; //Timer Constant for Timer0
375 unsigned int ui_AiTimer1; //Timer constant for Timer1
376 unsigned int ui_AiFlags;
377 unsigned int ui_AiDataLength;
378 short *AiData; // Pointer to sample data
379 unsigned int ui_AiNbrofScans; // number of scans to do
380 unsigned short us_UseDma; // To use Dma or not
381 unsigned char b_DmaDoubleBuffer; // we can use double buffering
382 unsigned int ui_DmaActualBuffer; // which buffer is used now
383 /* UPDATE-0.7.57->0.7.68 */
384 /* unsigned int ul_DmaBufferVirtual[2]; pointers to begin of DMA buffer */
385 short *ul_DmaBufferVirtual[2]; // pointers to begin of DMA buffer
386 unsigned int ul_DmaBufferHw[2]; // hw address of DMA buff
387 unsigned int ui_DmaBufferSize[2]; // size of dma buffer in bytes
388 unsigned int ui_DmaBufferUsesize[2]; // which size we may now used for transfer
389 unsigned int ui_DmaBufferSamples[2]; // size in samples
390 unsigned int ui_DmaBufferPages[2]; // number of pages in buffer
391 unsigned char b_DigitalOutputRegister; // Digital Output Register
392 unsigned char b_OutputMemoryStatus;
393 unsigned char b_AnalogInputChannelNbr; // Analog input channel Nbr
394 unsigned char b_AnalogOutputChannelNbr; // Analog input Output Nbr
395 unsigned char b_TimerSelectMode; // Contain data written at iobase + 0C
396 unsigned char b_ModeSelectRegister; // Contain data written at iobase + 0E
397 unsigned short us_OutputRegister; // Contain data written at iobase + 0
398 unsigned char b_InterruptState;
399 unsigned char b_TimerInit; // Specify if InitTimerWatchdog was load
400 unsigned char b_TimerStarted; // Specify if timer 2 is running or not
401 unsigned char b_Timer2Mode; // Specify the timer 2 mode
402 unsigned char b_Timer2Interrupt; //Timer2 interrupt enable or disable
403 unsigned char b_AiCyclicAcquisition; // indicate cyclic acquisition
404 unsigned char b_InterruptMode; // eoc eos or dma
405 unsigned char b_EocEosInterrupt; // Enable disable eoc eos interrupt
406 unsigned int ui_EocEosConversionTime;
407 unsigned char b_EocEosConversionTimeBase;
408 unsigned char b_SingelDiff;
409 unsigned char b_ExttrigEnable; /* To enable or disable external trigger */
411 /* Pointer to the current process */
412 struct task_struct *tsk_Current;
413 boardtype *ps_BoardInfo;
415 /* Hardware board infos for 1710 */
417 unsigned int ui_Address; /* Board address */
418 unsigned int ui_FlashAddress;
419 unsigned char b_InterruptNbr; /* Board interrupt number */
420 unsigned char b_SlotNumber; /* PCI slot number */
421 unsigned char b_BoardVersion;
422 unsigned int dw_MolduleConfiguration[4]; /* Module config */
425 /* Interrupt infos */
427 unsigned int ul_InterruptOccur; /* 0 : No interrupt occur */
428 /* > 0 : Interrupt occur */
429 unsigned int ui_Read; /* Read FIFO */
430 unsigned int ui_Write; /* Write FIFO */
432 unsigned char b_OldModuleMask;
433 unsigned int ul_OldInterruptMask; /* Interrupt mask */
434 unsigned int ul_OldCounterLatchValue; /* Interrupt counter value */
435 } s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
436 } s_InterruptParameters;
438 str_ModuleInfo s_ModuleInfo[4];
439 unsigned int ul_TTLPortConfiguration[10];
443 static unsigned short pci_list_builded; /* set to 1 when list of card is known */
445 /* Function declarations */
446 static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it);
447 static int i_ADDI_Detach(struct comedi_device *dev);
448 static int i_ADDI_Reset(struct comedi_device *dev);
450 static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG);
451 static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
452 struct comedi_insn *insn, unsigned int *data);