Commit | Line | Data |
---|---|---|
c995fe94 | 1 | /* |
15d8826a GKH |
2 | * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. |
3 | * | |
4 | * ADDI-DATA GmbH | |
5 | * Dieselstrasse 3 | |
6 | * D-77833 Ottersweier | |
7 | * Tel: +19(0)7223/9493-0 | |
8 | * Fax: +49(0)7223/9493-92 | |
9 | * http://www.addi-data-com | |
10 | * info@addi-data.com | |
11 | * | |
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) | |
15 | * any later version. | |
16 | */ | |
c995fe94 ADG |
17 | |
18 | #include <linux/kernel.h> | |
19 | #include <linux/module.h> | |
20 | #include <linux/sched.h> | |
21 | #include <linux/mm.h> | |
c995fe94 ADG |
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> | |
15d8826a GKH |
30 | #include <linux/io.h> |
31 | #include <linux/kmod.h> | |
32 | #include <linux/uaccess.h> | |
c995fe94 ADG |
33 | #include "../../comedidev.h" |
34 | #include "addi_amcc_s5933.h" | |
c995fe94 | 35 | |
15d8826a GKH |
36 | #define ERROR -1 |
37 | #define SUCCESS 1 | |
c995fe94 | 38 | |
15d8826a | 39 | /* variable type definition */ |
c995fe94 ADG |
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; | |
15d8826a | 49 | typedef int LONG, *PLONG; /* 32-bit */ |
c995fe94 ADG |
50 | typedef unsigned int ULONG, *PULONG; /* 32-bit */ |
51 | typedef unsigned int DWORD, *PDWORD; /* 32-bit */ | |
52 | typedef unsigned long ULONG_PTR; | |
53 | ||
54 | typedef const comedi_lrange *PCRANGE; | |
c995fe94 | 55 | |
15d8826a GKH |
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)) | |
62 | ||
63 | #define ADDI_ENABLE 1 | |
64 | #define ADDI_DISABLE 0 | |
65 | #define APCI1710_SAVE_INTERRUPT 1 | |
66 | ||
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" | |
73 | ||
74 | /* ADDIDATA Enable Disable */ | |
75 | #define ADDIDATA_ENABLE 1 | |
76 | #define ADDIDATA_DISABLE 0 | |
77 | ||
78 | /* Structures */ | |
79 | ||
80 | /* structure for the boardtype */ | |
81 | typedef struct { | |
c995fe94 ADG |
82 | PCSTR pc_DriverName; // driver name |
83 | INT i_VendorId; //PCI vendor a device ID of card | |
84 | INT i_DeviceId; | |
85 | INT i_IorangeBase0; | |
86 | INT i_IorangeBase1; | |
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 | |
99 | ||
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 | |
103 | ||
104 | INT i_NbrTTLChannel; // Number of TTL channels | |
105 | PCRANGE pr_TTLRangelist; // rangelist for TTL | |
106 | ||
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 | |
112 | ||
15d8826a GKH |
113 | /* interrupt and reset */ |
114 | void (*v_hwdrv_Interrupt)(int irq, void *d); | |
115 | int (*i_hwdrv_Reset)(comedi_device *dev); | |
116 | ||
117 | /* Subdevice functions */ | |
118 | ||
119 | /* ANALOG INPUT */ | |
120 | int (*i_hwdrv_InsnConfigAnalogInput)(comedi_device *dev, | |
121 | comedi_subdevice *s, | |
122 | comedi_insn *insn, | |
123 | lsampl_t *data); | |
124 | int (*i_hwdrv_InsnReadAnalogInput)(comedi_device *dev, | |
125 | comedi_subdevice *s, | |
126 | comedi_insn *insn, | |
127 | lsampl_t *data); | |
128 | int (*i_hwdrv_InsnWriteAnalogInput)(comedi_device *dev, | |
129 | comedi_subdevice *s, | |
130 | comedi_insn *insn, | |
131 | lsampl_t *data); | |
132 | int (*i_hwdrv_InsnBitsAnalogInput)(comedi_device *dev, | |
133 | comedi_subdevice *s, | |
134 | comedi_insn *insn, | |
135 | lsampl_t *data); | |
136 | int (*i_hwdrv_CommandTestAnalogInput)(comedi_device *dev, | |
137 | comedi_subdevice *s, | |
138 | comedi_cmd *cmd); | |
139 | int (*i_hwdrv_CommandAnalogInput)(comedi_device *dev, | |
140 | comedi_subdevice *s); | |
141 | int (*i_hwdrv_CancelAnalogInput)(comedi_device *dev, | |
142 | comedi_subdevice *s); | |
143 | ||
144 | /* Analog Output */ | |
145 | int (*i_hwdrv_InsnConfigAnalogOutput)(comedi_device *dev, | |
146 | comedi_subdevice *s, | |
147 | comedi_insn *insn, | |
148 | lsampl_t *data); | |
149 | int (*i_hwdrv_InsnWriteAnalogOutput)(comedi_device *dev, | |
150 | comedi_subdevice *s, | |
151 | comedi_insn *insn, | |
152 | lsampl_t *data); | |
153 | int (*i_hwdrv_InsnBitsAnalogOutput)(comedi_device *dev, | |
154 | comedi_subdevice *s, | |
155 | comedi_insn *insn, | |
156 | lsampl_t *data); | |
157 | ||
158 | /* Digital Input */ | |
159 | int (*i_hwdrv_InsnConfigDigitalInput) (comedi_device *dev, | |
160 | comedi_subdevice *s, | |
161 | comedi_insn *insn, | |
162 | lsampl_t *data); | |
163 | int (*i_hwdrv_InsnReadDigitalInput) (comedi_device *dev, | |
164 | comedi_subdevice *s, | |
165 | comedi_insn *insn, | |
166 | lsampl_t *data); | |
167 | int (*i_hwdrv_InsnWriteDigitalInput) (comedi_device *dev, | |
168 | comedi_subdevice *s, | |
169 | comedi_insn *insn, | |
170 | lsampl_t *data); | |
171 | int (*i_hwdrv_InsnBitsDigitalInput) (comedi_device *dev, | |
172 | comedi_subdevice *s, | |
173 | comedi_insn *insn, | |
174 | lsampl_t *data); | |
175 | ||
176 | /* Digital Output */ | |
177 | int (*i_hwdrv_InsnConfigDigitalOutput)(comedi_device *dev, | |
178 | comedi_subdevice *s, | |
179 | comedi_insn *insn, | |
180 | lsampl_t *data); | |
181 | int (*i_hwdrv_InsnWriteDigitalOutput)(comedi_device *dev, | |
182 | comedi_subdevice *s, | |
183 | comedi_insn *insn, | |
184 | lsampl_t *data); | |
185 | int (*i_hwdrv_InsnBitsDigitalOutput)(comedi_device *dev, | |
186 | comedi_subdevice *s, | |
187 | comedi_insn *insn, | |
188 | lsampl_t *data); | |
189 | int (*i_hwdrv_InsnReadDigitalOutput)(comedi_device *dev, | |
190 | comedi_subdevice *s, | |
191 | comedi_insn *insn, | |
192 | lsampl_t *data); | |
193 | ||
194 | /* TIMER */ | |
195 | int (*i_hwdrv_InsnConfigTimer)(comedi_device *dev, | |
196 | comedi_subdevice *s, | |
197 | comedi_insn *insn, lsampl_t *data); | |
198 | int (*i_hwdrv_InsnWriteTimer)(comedi_device *dev, | |
199 | comedi_subdevice *s, comedi_insn *insn, | |
200 | lsampl_t *data); | |
201 | int (*i_hwdrv_InsnReadTimer)(comedi_device *dev, comedi_subdevice *s, | |
202 | comedi_insn *insn, lsampl_t *data); | |
203 | int (*i_hwdrv_InsnBitsTimer)(comedi_device *dev, comedi_subdevice *s, | |
204 | comedi_insn *insn, lsampl_t *data); | |
205 | ||
206 | /* TTL IO */ | |
207 | int (*i_hwdr_ConfigInitTTLIO)(comedi_device *dev, | |
208 | comedi_subdevice *s, comedi_insn *insn, | |
209 | lsampl_t *data); | |
210 | int (*i_hwdr_ReadTTLIOBits)(comedi_device *dev, comedi_subdevice *s, | |
211 | comedi_insn *insn, lsampl_t *data); | |
212 | int (*i_hwdr_ReadTTLIOAllPortValue)(comedi_device *dev, | |
213 | comedi_subdevice *s, | |
214 | comedi_insn *insn, | |
215 | lsampl_t *data); | |
216 | int (*i_hwdr_WriteTTLIOChlOnOff)(comedi_device *dev, | |
217 | comedi_subdevice *s, | |
218 | comedi_insn *insn, lsampl_t *data); | |
c995fe94 ADG |
219 | } boardtype; |
220 | ||
221 | //MODULE INFO STRUCTURE | |
222 | ||
223 | typedef union { | |
c995fe94 | 224 | /* Incremental counter infos */ |
c995fe94 ADG |
225 | struct { |
226 | union { | |
227 | struct { | |
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; | |
234 | } s_ModeRegister; | |
235 | ||
236 | struct { | |
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; | |
244 | } s_InitFlag; | |
245 | ||
246 | } s_SiemensCounterInfo; | |
247 | ||
c995fe94 | 248 | /* SSI infos */ |
c995fe94 ADG |
249 | struct { |
250 | BYTE b_SSIProfile; | |
251 | BYTE b_PositionTurnLength; | |
252 | BYTE b_TurnCptLength; | |
253 | BYTE b_SSIInit; | |
254 | } s_SSICounterInfo; | |
255 | ||
c995fe94 | 256 | /* TTL I/O infos */ |
c995fe94 ADG |
257 | struct { |
258 | BYTE b_TTLInit; | |
259 | BYTE b_PortConfiguration[4]; | |
260 | } s_TTLIOInfo; | |
261 | ||
c995fe94 | 262 | /* Digital I/O infos */ |
c995fe94 ADG |
263 | struct { |
264 | BYTE b_DigitalInit; | |
265 | BYTE b_ChannelAMode; | |
266 | BYTE b_ChannelBMode; | |
267 | BYTE b_OutputMemoryEnabled; | |
268 | DWORD dw_OutputMemory; | |
269 | } s_DigitalIOInfo; | |
270 | ||
271 | /*********************/ | |
272 | /* 82X54 timer infos */ | |
273 | /*********************/ | |
274 | ||
275 | struct { | |
276 | struct { | |
277 | BYTE b_82X54Init; | |
278 | BYTE b_InputClockSelection; | |
279 | BYTE b_InputClockLevel; | |
280 | BYTE b_OutputLevel; | |
281 | BYTE b_HardwareGateLevel; | |
282 | DWORD dw_ConfigurationWord; | |
283 | } s_82X54TimerInfo[3]; | |
284 | BYTE b_InterruptMask; | |
285 | } s_82X54ModuleInfo; | |
286 | ||
287 | /*********************/ | |
288 | /* Chronometer infos */ | |
289 | /*********************/ | |
290 | ||
291 | struct { | |
292 | BYTE b_ChronoInit; | |
293 | BYTE b_InterruptMask; | |
294 | BYTE b_PCIInputClock; | |
295 | BYTE b_TimingUnit; | |
296 | BYTE b_CycleMode; | |
297 | double d_TimingInterval; | |
298 | DWORD dw_ConfigReg; | |
299 | } s_ChronoModuleInfo; | |
300 | ||
301 | /***********************/ | |
302 | /* Pulse encoder infos */ | |
303 | /***********************/ | |
304 | ||
305 | struct { | |
306 | struct { | |
307 | BYTE b_PulseEncoderInit; | |
308 | } s_PulseEncoderInfo[4]; | |
309 | DWORD dw_SetRegister; | |
310 | DWORD dw_ControlRegister; | |
311 | DWORD dw_StatusRegister; | |
312 | } s_PulseEncoderModuleInfo; | |
313 | ||
c995fe94 | 314 | /* Tor conter infos */ |
c995fe94 ADG |
315 | struct { |
316 | struct { | |
317 | BYTE b_TorCounterInit; | |
318 | BYTE b_TimingUnit; | |
319 | BYTE b_InterruptEnable; | |
320 | double d_TimingInterval; | |
321 | ULONG ul_RealTimingInterval; | |
322 | } s_TorCounterInfo[2]; | |
323 | BYTE b_PCIInputClock; | |
324 | } s_TorCounterModuleInfo; | |
325 | ||
c995fe94 | 326 | /* PWM infos */ |
c995fe94 ADG |
327 | struct { |
328 | struct { | |
329 | BYTE b_PWMInit; | |
330 | BYTE b_TimingUnit; | |
331 | BYTE b_InterruptEnable; | |
332 | double d_LowTiming; | |
333 | double d_HighTiming; | |
334 | ULONG ul_RealLowTiming; | |
335 | ULONG ul_RealHighTiming; | |
336 | } s_PWMInfo[2]; | |
337 | BYTE b_ClockSelection; | |
338 | } s_PWMModuleInfo; | |
339 | ||
c995fe94 | 340 | /* ETM infos */ |
c995fe94 ADG |
341 | struct { |
342 | struct { | |
343 | BYTE b_ETMEnable; | |
344 | BYTE b_ETMInterrupt; | |
345 | } s_ETMInfo[2]; | |
346 | BYTE b_ETMInit; | |
347 | BYTE b_TimingUnit; | |
348 | BYTE b_ClockSelection; | |
349 | double d_TimingInterval; | |
350 | ULONG ul_Timing; | |
351 | } s_ETMModuleInfo; | |
352 | ||
c995fe94 | 353 | /* CDA infos */ |
c995fe94 ADG |
354 | struct { |
355 | BYTE b_CDAEnable; | |
356 | BYTE b_CDAInterrupt; | |
357 | BYTE b_CDAInit; | |
358 | BYTE b_FctSelection; | |
359 | BYTE b_CDAReadFIFOOverflow; | |
360 | } s_CDAModuleInfo; | |
361 | ||
362 | } str_ModuleInfo; | |
c995fe94 | 363 | |
15d8826a | 364 | /* Private structure for the addi_apci3120 driver */ |
c995fe94 ADG |
365 | typedef struct { |
366 | ||
367 | INT iobase; | |
368 | INT i_IobaseAmcc; // base+size for AMCC chip | |
369 | INT i_IobaseAddon; //addon base address | |
370 | INT i_IobaseReserved; | |
371 | ULONG_PTR dw_AiBase; | |
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 | |
389 | UINT ui_AiFlags; | |
390 | UINT ui_AiDataLength; | |
391 | sampl_t *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 | sampl_t *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; | |
421 | BYTE b_SingelDiff; | |
15d8826a | 422 | BYTE b_ExttrigEnable; /* To enable or disable external trigger */ |
c995fe94 | 423 | |
15d8826a GKH |
424 | /* Pointer to the current process */ |
425 | struct task_struct *tsk_Current; | |
c995fe94 ADG |
426 | boardtype *ps_BoardInfo; |
427 | ||
15d8826a | 428 | /* Hardware board infos for 1710 */ |
c995fe94 | 429 | struct { |
15d8826a | 430 | UINT ui_Address; /* Board address */ |
c995fe94 | 431 | UINT ui_FlashAddress; |
15d8826a GKH |
432 | BYTE b_InterruptNbr; /* Board interrupt number */ |
433 | BYTE b_SlotNumber; /* PCI slot number */ | |
c995fe94 | 434 | BYTE b_BoardVersion; |
15d8826a | 435 | DWORD dw_MolduleConfiguration[4]; /* Module config */ |
c995fe94 ADG |
436 | } s_BoardInfos; |
437 | ||
c995fe94 | 438 | /* Interrupt infos */ |
c995fe94 | 439 | struct { |
15d8826a GKH |
440 | ULONG ul_InterruptOccur; /* 0 : No interrupt occur */ |
441 | /* > 0 : Interrupt occur */ | |
442 | UINT ui_Read; /* Read FIFO */ | |
443 | UINT ui_Write; /* Write FIFO */ | |
c995fe94 ADG |
444 | struct { |
445 | BYTE b_OldModuleMask; | |
15d8826a | 446 | ULONG ul_OldInterruptMask; /* Interrupt mask */ |
c995fe94 ADG |
447 | ULONG ul_OldCounterLatchValue; /* Interrupt counter value */ |
448 | } s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT]; | |
449 | } s_InterruptParameters; | |
450 | ||
451 | str_ModuleInfo s_ModuleInfo[4]; | |
452 | ULONG ul_TTLPortConfiguration[10]; | |
453 | ||
454 | } addi_private; | |
455 | ||
15d8826a | 456 | static unsigned short pci_list_builded; /* set to 1 when list of card is known */ |
c995fe94 | 457 | |
15d8826a GKH |
458 | /* Function declarations */ |
459 | static int i_ADDI_Attach(comedi_device *dev, comedi_devconfig *it); | |
460 | static int i_ADDI_Detach(comedi_device *dev); | |
461 | static int i_ADDI_Reset(comedi_device *dev); | |
c995fe94 ADG |
462 | |
463 | static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG); | |
15d8826a GKH |
464 | static int i_ADDIDATA_InsnReadEeprom(comedi_device *dev, comedi_subdevice *s, |
465 | comedi_insn *insn, lsampl_t *data); |