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 void VOID
, *PVOID
;
41 typedef char CHAR
, *PCHAR
;
42 typedef const CHAR
*PCSTR
;
43 typedef unsigned char BYTE
, *PBYTE
;
44 typedef short SHORT
, *PSHORT
;
45 typedef unsigned short USHORT
, *PUSHORT
;
46 typedef unsigned short WORD
, *PWORD
;
47 typedef int INT
, *PINT
;;
48 typedef unsigned int UINT
, *PUINT
;
49 typedef int LONG
, *PLONG
; /* 32-bit */
50 typedef unsigned int ULONG
, *PULONG
; /* 32-bit */
51 typedef unsigned int DWORD
, *PDWORD
; /* 32-bit */
52 typedef unsigned long ULONG_PTR
;
54 typedef const struct comedi_lrange
*PCRANGE
;
56 #define LOBYTE(W) (BYTE)((W) & 0xFF)
57 #define HIBYTE(W) (BYTE)(((W) >> 8) & 0xFF)
58 #define MAKEWORD(H, L) (USHORT)((L) | ((H) << 8))
59 #define LOWORD(W) (USHORT)((W) & 0xFFFF)
60 #define HIWORD(W) (USHORT)(((W) >> 16) & 0xFFFF)
61 #define MAKEDWORD(H, L) (UINT)((L) | ((H) << 16))
64 #define ADDI_DISABLE 0
65 #define APCI1710_SAVE_INTERRUPT 1
67 #define ADDIDATA_EEPROM 1
68 #define ADDIDATA_NO_EEPROM 0
69 #define ADDIDATA_93C76 "93C76"
70 #define ADDIDATA_S5920 "S5920"
71 #define ADDIDATA_S5933 "S5933"
72 #define ADDIDATA_9054 "9054"
74 /* ADDIDATA Enable Disable */
75 #define ADDIDATA_ENABLE 1
76 #define ADDIDATA_DISABLE 0
80 /* structure for the boardtype */
82 PCSTR pc_DriverName
; // driver name
83 INT i_VendorId
; //PCI vendor a device ID of card
87 INT i_IorangeBase2
; // base 2 range
88 INT i_IorangeBase3
; // base 3 range
89 INT i_PCIEeprom
; // eeprom present or not
90 PCHAR pc_EepromChip
; // type of chip
91 INT i_NbrAiChannel
; // num of A/D chans
92 INT i_NbrAiChannelDiff
; // num of A/D chans in diff mode
93 INT i_AiChannelList
; // len of chanlist
94 INT i_NbrAoChannel
; // num of D/A chans
95 INT i_AiMaxdata
; // resolution of A/D
96 INT i_AoMaxdata
; // resolution of D/A
97 PCRANGE pr_AiRangelist
; // rangelist for A/D
98 PCRANGE pr_AoRangelist
; // rangelist for D/A
100 INT i_NbrDiChannel
; // Number of DI channels
101 INT i_NbrDoChannel
; // Number of DO channels
102 INT i_DoMaxdata
; // data to set all chanels high
104 INT i_NbrTTLChannel
; // Number of TTL channels
105 PCRANGE pr_TTLRangelist
; // rangelist for TTL
107 INT i_Dma
; // dma present or not
108 INT i_Timer
; // timer subdevice present or not
109 BYTE b_AvailableConvertUnit
;
110 UINT ui_MinAcquisitiontimeNs
; // Minimum Acquisition in Nano secs
111 UINT ui_MinDelaytimeNs
; // Minimum Delay in Nano secs
113 /* interrupt and reset */
114 void (*v_hwdrv_Interrupt
)(int irq
, void *d
);
115 int (*i_hwdrv_Reset
)(struct comedi_device
*dev
);
117 /* Subdevice functions */
120 int (*i_hwdrv_InsnConfigAnalogInput
)(struct comedi_device
*dev
,
121 struct comedi_subdevice
*s
,
124 int (*i_hwdrv_InsnReadAnalogInput
)(struct comedi_device
*dev
,
125 struct comedi_subdevice
*s
,
128 int (*i_hwdrv_InsnWriteAnalogInput
)(struct comedi_device
*dev
,
129 struct comedi_subdevice
*s
,
132 int (*i_hwdrv_InsnBitsAnalogInput
)(struct comedi_device
*dev
,
133 struct comedi_subdevice
*s
,
136 int (*i_hwdrv_CommandTestAnalogInput
)(struct comedi_device
*dev
,
137 struct comedi_subdevice
*s
,
138 struct comedi_cmd
*cmd
);
139 int (*i_hwdrv_CommandAnalogInput
)(struct comedi_device
*dev
,
140 struct comedi_subdevice
*s
);
141 int (*i_hwdrv_CancelAnalogInput
)(struct comedi_device
*dev
,
142 struct comedi_subdevice
*s
);
145 int (*i_hwdrv_InsnConfigAnalogOutput
)(struct comedi_device
*dev
,
146 struct comedi_subdevice
*s
,
149 int (*i_hwdrv_InsnWriteAnalogOutput
)(struct comedi_device
*dev
,
150 struct comedi_subdevice
*s
,
153 int (*i_hwdrv_InsnBitsAnalogOutput
)(struct comedi_device
*dev
,
154 struct comedi_subdevice
*s
,
159 int (*i_hwdrv_InsnConfigDigitalInput
) (struct comedi_device
*dev
,
160 struct comedi_subdevice
*s
,
163 int (*i_hwdrv_InsnReadDigitalInput
) (struct comedi_device
*dev
,
164 struct comedi_subdevice
*s
,
167 int (*i_hwdrv_InsnWriteDigitalInput
) (struct comedi_device
*dev
,
168 struct comedi_subdevice
*s
,
171 int (*i_hwdrv_InsnBitsDigitalInput
) (struct comedi_device
*dev
,
172 struct comedi_subdevice
*s
,
177 int (*i_hwdrv_InsnConfigDigitalOutput
)(struct comedi_device
*dev
,
178 struct comedi_subdevice
*s
,
181 int (*i_hwdrv_InsnWriteDigitalOutput
)(struct comedi_device
*dev
,
182 struct comedi_subdevice
*s
,
185 int (*i_hwdrv_InsnBitsDigitalOutput
)(struct comedi_device
*dev
,
186 struct comedi_subdevice
*s
,
189 int (*i_hwdrv_InsnReadDigitalOutput
)(struct comedi_device
*dev
,
190 struct comedi_subdevice
*s
,
195 int (*i_hwdrv_InsnConfigTimer
)(struct comedi_device
*dev
,
196 struct comedi_subdevice
*s
,
197 comedi_insn
*insn
, unsigned int *data
);
198 int (*i_hwdrv_InsnWriteTimer
)(struct comedi_device
*dev
,
199 struct comedi_subdevice
*s
, comedi_insn
*insn
,
201 int (*i_hwdrv_InsnReadTimer
)(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
202 comedi_insn
*insn
, unsigned int *data
);
203 int (*i_hwdrv_InsnBitsTimer
)(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
204 comedi_insn
*insn
, unsigned int *data
);
207 int (*i_hwdr_ConfigInitTTLIO
)(struct comedi_device
*dev
,
208 struct comedi_subdevice
*s
, comedi_insn
*insn
,
210 int (*i_hwdr_ReadTTLIOBits
)(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
211 comedi_insn
*insn
, unsigned int *data
);
212 int (*i_hwdr_ReadTTLIOAllPortValue
)(struct comedi_device
*dev
,
213 struct comedi_subdevice
*s
,
216 int (*i_hwdr_WriteTTLIOChlOnOff
)(struct comedi_device
*dev
,
217 struct comedi_subdevice
*s
,
218 comedi_insn
*insn
, unsigned int *data
);
221 //MODULE INFO STRUCTURE
224 /* Incremental counter infos */
228 BYTE b_ModeRegister1
;
229 BYTE b_ModeRegister2
;
230 BYTE b_ModeRegister3
;
231 BYTE b_ModeRegister4
;
232 } s_ByteModeRegister
;
233 DWORD dw_ModeRegister1_2_3_4
;
237 unsigned int b_IndexInit
:1;
238 unsigned int b_CounterInit
:1;
239 unsigned int b_ReferenceInit
:1;
240 unsigned int b_IndexInterruptOccur
:1;
241 unsigned int b_CompareLogicInit
:1;
242 unsigned int b_FrequencyMeasurementInit
:1;
243 unsigned int b_FrequencyMeasurementEnable
:1;
246 } s_SiemensCounterInfo
;
251 BYTE b_PositionTurnLength
;
252 BYTE b_TurnCptLength
;
259 BYTE b_PortConfiguration
[4];
262 /* Digital I/O infos */
267 BYTE b_OutputMemoryEnabled
;
268 DWORD dw_OutputMemory
;
271 /*********************/
272 /* 82X54 timer infos */
273 /*********************/
278 BYTE b_InputClockSelection
;
279 BYTE b_InputClockLevel
;
281 BYTE b_HardwareGateLevel
;
282 DWORD dw_ConfigurationWord
;
283 } s_82X54TimerInfo
[3];
284 BYTE b_InterruptMask
;
287 /*********************/
288 /* Chronometer infos */
289 /*********************/
293 BYTE b_InterruptMask
;
294 BYTE b_PCIInputClock
;
297 double d_TimingInterval
;
299 } s_ChronoModuleInfo
;
301 /***********************/
302 /* Pulse encoder infos */
303 /***********************/
307 BYTE b_PulseEncoderInit
;
308 } s_PulseEncoderInfo
[4];
309 DWORD dw_SetRegister
;
310 DWORD dw_ControlRegister
;
311 DWORD dw_StatusRegister
;
312 } s_PulseEncoderModuleInfo
;
314 /* Tor conter infos */
317 BYTE b_TorCounterInit
;
319 BYTE b_InterruptEnable
;
320 double d_TimingInterval
;
321 ULONG ul_RealTimingInterval
;
322 } s_TorCounterInfo
[2];
323 BYTE b_PCIInputClock
;
324 } s_TorCounterModuleInfo
;
331 BYTE b_InterruptEnable
;
334 ULONG ul_RealLowTiming
;
335 ULONG ul_RealHighTiming
;
337 BYTE b_ClockSelection
;
348 BYTE b_ClockSelection
;
349 double d_TimingInterval
;
359 BYTE b_CDAReadFIFOOverflow
;
364 /* Private structure for the addi_apci3120 driver */
368 INT i_IobaseAmcc
; // base+size for AMCC chip
369 INT i_IobaseAddon
; //addon base address
370 INT i_IobaseReserved
;
372 struct pcilst_struct
*amcc
; // ptr too AMCC data
373 BYTE allocated
; // we have blocked card
374 BYTE b_ValidDriver
; // driver is ok
375 BYTE b_AiContinuous
; // we do unlimited AI
376 BYTE b_AiInitialisation
;
377 UINT ui_AiActualScan
; //how many scans we finished
378 UINT ui_AiBufferPtr
; // data buffer ptr in samples
379 UINT ui_AiNbrofChannels
; // how many channels is measured
380 UINT ui_AiScanLength
; // Length of actual scanlist
381 UINT ui_AiActualScanPosition
; // position in actual scan
382 PUINT pui_AiChannelList
; // actual chanlist
383 UINT ui_AiChannelList
[32]; // actual chanlist
384 BYTE b_AiChannelConfiguration
[32]; // actual chanlist
385 UINT ui_AiReadData
[32];
386 DWORD dw_AiInitialised
;
387 UINT ui_AiTimer0
; //Timer Constant for Timer0
388 UINT ui_AiTimer1
; //Timer constant for Timer1
390 UINT ui_AiDataLength
;
391 short *AiData
; // Pointer to sample data
392 UINT ui_AiNbrofScans
; // number of scans to do
393 USHORT us_UseDma
; // To use Dma or not
394 BYTE b_DmaDoubleBuffer
; // we can use double buffering
395 UINT ui_DmaActualBuffer
; // which buffer is used now
396 //*UPDATE-0.7.57->0.7.68
397 //ULONG ul_DmaBufferVirtual[2];// pointers to begin of DMA buffer
398 short *ul_DmaBufferVirtual
[2]; // pointers to begin of DMA buffer
399 ULONG ul_DmaBufferHw
[2]; // hw address of DMA buff
400 UINT ui_DmaBufferSize
[2]; // size of dma buffer in bytes
401 UINT ui_DmaBufferUsesize
[2]; // which size we may now used for transfer
402 UINT ui_DmaBufferSamples
[2]; // size in samples
403 UINT ui_DmaBufferPages
[2]; // number of pages in buffer
404 BYTE b_DigitalOutputRegister
; // Digital Output Register
405 BYTE b_OutputMemoryStatus
;
406 BYTE b_AnalogInputChannelNbr
; // Analog input channel Nbr
407 BYTE b_AnalogOutputChannelNbr
; // Analog input Output Nbr
408 BYTE b_TimerSelectMode
; // Contain data written at iobase + 0C
409 BYTE b_ModeSelectRegister
; // Contain data written at iobase + 0E
410 USHORT us_OutputRegister
; // Contain data written at iobase + 0
411 BYTE b_InterruptState
;
412 BYTE b_TimerInit
; // Specify if InitTimerWatchdog was load
413 BYTE b_TimerStarted
; // Specify if timer 2 is running or not
414 BYTE b_Timer2Mode
; // Specify the timer 2 mode
415 BYTE b_Timer2Interrupt
; //Timer2 interrupt enable or disable
416 BYTE b_AiCyclicAcquisition
; // indicate cyclic acquisition
417 BYTE b_InterruptMode
; // eoc eos or dma
418 BYTE b_EocEosInterrupt
; // Enable disable eoc eos interrupt
419 UINT ui_EocEosConversionTime
;
420 BYTE b_EocEosConversionTimeBase
;
422 BYTE b_ExttrigEnable
; /* To enable or disable external trigger */
424 /* Pointer to the current process */
425 struct task_struct
*tsk_Current
;
426 boardtype
*ps_BoardInfo
;
428 /* Hardware board infos for 1710 */
430 UINT ui_Address
; /* Board address */
431 UINT ui_FlashAddress
;
432 BYTE b_InterruptNbr
; /* Board interrupt number */
433 BYTE b_SlotNumber
; /* PCI slot number */
435 DWORD dw_MolduleConfiguration
[4]; /* Module config */
438 /* Interrupt infos */
440 ULONG ul_InterruptOccur
; /* 0 : No interrupt occur */
441 /* > 0 : Interrupt occur */
442 UINT ui_Read
; /* Read FIFO */
443 UINT ui_Write
; /* Write FIFO */
445 BYTE b_OldModuleMask
;
446 ULONG ul_OldInterruptMask
; /* Interrupt mask */
447 ULONG ul_OldCounterLatchValue
; /* Interrupt counter value */
448 } s_FIFOInterruptParameters
[APCI1710_SAVE_INTERRUPT
];
449 } s_InterruptParameters
;
451 str_ModuleInfo s_ModuleInfo
[4];
452 ULONG ul_TTLPortConfiguration
[10];
456 static unsigned short pci_list_builded
; /* set to 1 when list of card is known */
458 /* Function declarations */
459 static int i_ADDI_Attach(struct comedi_device
*dev
, comedi_devconfig
*it
);
460 static int i_ADDI_Detach(struct comedi_device
*dev
);
461 static int i_ADDI_Reset(struct comedi_device
*dev
);
463 static irqreturn_t
v_ADDI_Interrupt(int irq
, void *d PT_REGS_ARG
);
464 static int i_ADDIDATA_InsnReadEeprom(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
465 comedi_insn
*insn
, unsigned int *data
);