addi_common.h revision 1783fbfe023b7c2b912fbb020e01ff46985aa0ab
1/*
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 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/sched.h>
21#include <linux/mm.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>
30#include <linux/io.h>
31#include <linux/kmod.h>
32#include <linux/uaccess.h>
33#include "../../comedidev.h"
34#include "addi_amcc_s5933.h"
35
36#define ERROR	-1
37#define SUCCESS	1
38
39/* variable type definition */
40typedef short SHORT, *PSHORT;
41typedef unsigned short USHORT, *PUSHORT;
42typedef unsigned short WORD, *PWORD;
43typedef int INT, *PINT;;
44typedef unsigned int UINT, *PUINT;
45typedef int LONG, *PLONG;		/* 32-bit */
46typedef unsigned int ULONG, *PULONG;	/* 32-bit */
47typedef unsigned int DWORD, *PDWORD;	/* 32-bit */
48typedef unsigned long ULONG_PTR;
49
50typedef const struct comedi_lrange *PCRANGE;
51
52#define LOBYTE(W)	(unsigned char)((W) & 0xFF)
53#define HIBYTE(W)	(unsigned char)(((W) >> 8) & 0xFF)
54#define MAKEWORD(H, L)	(USHORT)((L) | ((H) << 8))
55#define LOWORD(W)	(USHORT)((W) & 0xFFFF)
56#define HIWORD(W)	(USHORT)(((W) >> 16) & 0xFFFF)
57#define MAKEDWORD(H, L)	(UINT)((L) | ((H) << 16))
58
59#define ADDI_ENABLE		1
60#define ADDI_DISABLE		0
61#define APCI1710_SAVE_INTERRUPT	1
62
63#define ADDIDATA_EEPROM		1
64#define ADDIDATA_NO_EEPROM	0
65#define ADDIDATA_93C76		"93C76"
66#define ADDIDATA_S5920		"S5920"
67#define ADDIDATA_S5933		"S5933"
68#define ADDIDATA_9054		"9054"
69
70/* ADDIDATA Enable Disable */
71#define ADDIDATA_ENABLE		1
72#define ADDIDATA_DISABLE	0
73
74/* Structures */
75
76/* structure for the boardtype */
77typedef struct {
78	const char *pc_DriverName;	// driver name
79	INT i_VendorId;		//PCI vendor a device ID of card
80	INT i_DeviceId;
81	INT i_IorangeBase0;
82	INT i_IorangeBase1;
83	INT i_IorangeBase2;	//  base 2 range
84	INT i_IorangeBase3;	//  base 3 range
85	INT i_PCIEeprom;	// eeprom present or not
86	char *pc_EepromChip;	// type of chip
87	INT i_NbrAiChannel;	// num of A/D chans
88	INT i_NbrAiChannelDiff;	// num of A/D chans in diff mode
89	INT i_AiChannelList;	// len of chanlist
90	INT i_NbrAoChannel;	// num of D/A chans
91	INT i_AiMaxdata;	// resolution of A/D
92	INT i_AoMaxdata;	// resolution of D/A
93	PCRANGE pr_AiRangelist;	// rangelist for A/D
94	PCRANGE pr_AoRangelist;	// rangelist for D/A
95
96	INT i_NbrDiChannel;	// Number of DI channels
97	INT i_NbrDoChannel;	// Number of DO channels
98	INT i_DoMaxdata;	// data to set all chanels high
99
100	INT i_NbrTTLChannel;	// Number of TTL channels
101	PCRANGE pr_TTLRangelist;	// rangelist for TTL
102
103	INT i_Dma;		// dma present or not
104	INT i_Timer;		//   timer subdevice present or not
105	unsigned char b_AvailableConvertUnit;
106	UINT ui_MinAcquisitiontimeNs;	// Minimum Acquisition in Nano secs
107	UINT ui_MinDelaytimeNs;	// Minimum Delay in Nano secs
108
109	/* interrupt and reset */
110	void (*v_hwdrv_Interrupt)(int irq, void *d);
111	int (*i_hwdrv_Reset)(struct comedi_device *dev);
112
113	/* Subdevice functions */
114
115	/* ANALOG INPUT */
116	int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev,
117					     struct comedi_subdevice *s,
118					     struct comedi_insn *insn,
119					     unsigned int *data);
120	int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev,
121					    struct comedi_subdevice *s,
122					    struct comedi_insn *insn,
123					    unsigned int *data);
124	int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev,
125					    struct comedi_subdevice *s,
126					    struct comedi_insn *insn,
127					    unsigned int *data);
128	int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev,
129					   struct comedi_subdevice *s,
130					   struct comedi_insn *insn,
131					   unsigned int *data);
132	int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev,
133					      struct comedi_subdevice *s,
134					      struct comedi_cmd *cmd);
135	int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev,
136					  struct comedi_subdevice *s);
137	int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev,
138					 struct comedi_subdevice *s);
139
140	/* Analog Output */
141	int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev,
142					      struct comedi_subdevice *s,
143					      struct comedi_insn *insn,
144					      unsigned int *data);
145	int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev,
146					     struct comedi_subdevice *s,
147					     struct comedi_insn *insn,
148					     unsigned int *data);
149	int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev,
150					    struct comedi_subdevice *s,
151					    struct comedi_insn *insn,
152					    unsigned int *data);
153
154	/* Digital Input */
155	int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev,
156					       struct comedi_subdevice *s,
157					       struct comedi_insn *insn,
158					       unsigned int *data);
159	int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev,
160					     struct comedi_subdevice *s,
161					     struct comedi_insn *insn,
162					     unsigned int *data);
163	int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev,
164					      struct comedi_subdevice *s,
165					      struct comedi_insn *insn,
166					      unsigned int *data);
167	int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev,
168					     struct comedi_subdevice *s,
169					     struct comedi_insn *insn,
170					     unsigned int *data);
171
172	/* Digital Output */
173	int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev,
174					       struct comedi_subdevice *s,
175					       struct comedi_insn *insn,
176					       unsigned int *data);
177	int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev,
178					      struct comedi_subdevice *s,
179					      struct comedi_insn *insn,
180					      unsigned int *data);
181	int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev,
182					     struct comedi_subdevice *s,
183					     struct comedi_insn *insn,
184					     unsigned int *data);
185	int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev,
186					     struct comedi_subdevice *s,
187					     struct comedi_insn *insn,
188					     unsigned int *data);
189
190	/* TIMER */
191	int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev,
192				       struct comedi_subdevice *s,
193				       struct comedi_insn *insn, unsigned int *data);
194	int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev,
195				      struct comedi_subdevice *s, struct comedi_insn *insn,
196				      unsigned int *data);
197	int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
198				     struct comedi_insn *insn, unsigned int *data);
199	int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
200				     struct comedi_insn *insn, unsigned int *data);
201
202	/* TTL IO */
203	int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev,
204				      struct comedi_subdevice *s, struct comedi_insn *insn,
205				      unsigned int *data);
206	int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s,
207				    struct comedi_insn *insn, unsigned int *data);
208	int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev,
209					    struct comedi_subdevice *s,
210					    struct comedi_insn *insn,
211					    unsigned int *data);
212	int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev,
213					 struct comedi_subdevice *s,
214					 struct comedi_insn *insn, unsigned int *data);
215} boardtype;
216
217//MODULE INFO STRUCTURE
218
219typedef union {
220	/* Incremental counter infos */
221	struct {
222		union {
223			struct {
224				unsigned char b_ModeRegister1;
225				unsigned char b_ModeRegister2;
226				unsigned char b_ModeRegister3;
227				unsigned char b_ModeRegister4;
228			} s_ByteModeRegister;
229			DWORD dw_ModeRegister1_2_3_4;
230		} s_ModeRegister;
231
232		struct {
233			unsigned int b_IndexInit:1;
234			unsigned int b_CounterInit:1;
235			unsigned int b_ReferenceInit:1;
236			unsigned int b_IndexInterruptOccur:1;
237			unsigned int b_CompareLogicInit:1;
238			unsigned int b_FrequencyMeasurementInit:1;
239			unsigned int b_FrequencyMeasurementEnable:1;
240		} s_InitFlag;
241
242	} s_SiemensCounterInfo;
243
244	/* SSI infos */
245	struct {
246		unsigned char b_SSIProfile;
247		unsigned char b_PositionTurnLength;
248		unsigned char b_TurnCptLength;
249		unsigned char b_SSIInit;
250	} s_SSICounterInfo;
251
252	/* TTL I/O infos */
253	struct {
254		unsigned char b_TTLInit;
255		unsigned char b_PortConfiguration[4];
256	} s_TTLIOInfo;
257
258	/* Digital I/O infos */
259	struct {
260		unsigned char b_DigitalInit;
261		unsigned char b_ChannelAMode;
262		unsigned char b_ChannelBMode;
263		unsigned char b_OutputMemoryEnabled;
264		DWORD dw_OutputMemory;
265	} s_DigitalIOInfo;
266
267      /*********************/
268	/* 82X54 timer infos */
269      /*********************/
270
271	struct {
272		struct {
273			unsigned char b_82X54Init;
274			unsigned char b_InputClockSelection;
275			unsigned char b_InputClockLevel;
276			unsigned char b_OutputLevel;
277			unsigned char b_HardwareGateLevel;
278			DWORD dw_ConfigurationWord;
279		} s_82X54TimerInfo[3];
280		unsigned char b_InterruptMask;
281	} s_82X54ModuleInfo;
282
283      /*********************/
284	/* Chronometer infos */
285      /*********************/
286
287	struct {
288		unsigned char b_ChronoInit;
289		unsigned char b_InterruptMask;
290		unsigned char b_PCIInputClock;
291		unsigned char b_TimingUnit;
292		unsigned char b_CycleMode;
293		double d_TimingInterval;
294		DWORD dw_ConfigReg;
295	} s_ChronoModuleInfo;
296
297      /***********************/
298	/* Pulse encoder infos */
299      /***********************/
300
301	struct {
302		struct {
303			unsigned char b_PulseEncoderInit;
304		} s_PulseEncoderInfo[4];
305		DWORD dw_SetRegister;
306		DWORD dw_ControlRegister;
307		DWORD dw_StatusRegister;
308	} s_PulseEncoderModuleInfo;
309
310	/* Tor conter infos */
311	struct {
312		struct {
313			unsigned char b_TorCounterInit;
314			unsigned char b_TimingUnit;
315			unsigned char b_InterruptEnable;
316			double d_TimingInterval;
317			ULONG ul_RealTimingInterval;
318		} s_TorCounterInfo[2];
319		unsigned char b_PCIInputClock;
320	} s_TorCounterModuleInfo;
321
322	/* PWM infos */
323	struct {
324		struct {
325			unsigned char b_PWMInit;
326			unsigned char b_TimingUnit;
327			unsigned char b_InterruptEnable;
328			double d_LowTiming;
329			double d_HighTiming;
330			ULONG ul_RealLowTiming;
331			ULONG ul_RealHighTiming;
332		} s_PWMInfo[2];
333		unsigned char b_ClockSelection;
334	} s_PWMModuleInfo;
335
336	/* ETM infos */
337	struct {
338		struct {
339			unsigned char b_ETMEnable;
340			unsigned char b_ETMInterrupt;
341		} s_ETMInfo[2];
342		unsigned char b_ETMInit;
343		unsigned char b_TimingUnit;
344		unsigned char b_ClockSelection;
345		double d_TimingInterval;
346		ULONG ul_Timing;
347	} s_ETMModuleInfo;
348
349	/* CDA infos */
350	struct {
351		unsigned char b_CDAEnable;
352		unsigned char b_CDAInterrupt;
353		unsigned char b_CDAInit;
354		unsigned char b_FctSelection;
355		unsigned char b_CDAReadFIFOOverflow;
356	} s_CDAModuleInfo;
357
358} str_ModuleInfo;
359
360/* Private structure for the addi_apci3120 driver */
361typedef struct {
362
363	INT iobase;
364	INT i_IobaseAmcc;	// base+size for AMCC chip
365	INT i_IobaseAddon;	//addon base address
366	INT i_IobaseReserved;
367	ULONG_PTR dw_AiBase;
368	struct pcilst_struct *amcc;	// ptr too AMCC data
369	unsigned char allocated;		// we have blocked card
370	unsigned char b_ValidDriver;	// driver is ok
371	unsigned char b_AiContinuous;	// we do unlimited AI
372	unsigned char b_AiInitialisation;
373	UINT ui_AiActualScan;	//how many scans we finished
374	UINT ui_AiBufferPtr;	// data buffer ptr in samples
375	UINT ui_AiNbrofChannels;	// how many channels is measured
376	UINT ui_AiScanLength;	// Length of actual scanlist
377	UINT ui_AiActualScanPosition;	// position in actual scan
378	PUINT pui_AiChannelList;	// actual chanlist
379	UINT ui_AiChannelList[32];	// actual chanlist
380	unsigned char b_AiChannelConfiguration[32];	// actual chanlist
381	UINT ui_AiReadData[32];
382	DWORD dw_AiInitialised;
383	UINT ui_AiTimer0;	//Timer Constant for Timer0
384	UINT ui_AiTimer1;	//Timer constant for Timer1
385	UINT ui_AiFlags;
386	UINT ui_AiDataLength;
387	short *AiData;	// Pointer to sample data
388	UINT ui_AiNbrofScans;	// number of scans to do
389	USHORT us_UseDma;	// To use Dma or not
390	unsigned char b_DmaDoubleBuffer;	// we can use double buffering
391	UINT ui_DmaActualBuffer;	// which buffer is used now
392	//*UPDATE-0.7.57->0.7.68
393	//ULONG               ul_DmaBufferVirtual[2];// pointers to begin of DMA buffer
394	short *ul_DmaBufferVirtual[2];	// pointers to begin of DMA buffer
395	ULONG ul_DmaBufferHw[2];	// hw address of DMA buff
396	UINT ui_DmaBufferSize[2];	// size of dma buffer in bytes
397	UINT ui_DmaBufferUsesize[2];	// which size we may now used for transfer
398	UINT ui_DmaBufferSamples[2];	// size in samples
399	UINT ui_DmaBufferPages[2];	// number of pages in buffer
400	unsigned char b_DigitalOutputRegister;	// Digital Output Register
401	unsigned char b_OutputMemoryStatus;
402	unsigned char b_AnalogInputChannelNbr;	// Analog input channel Nbr
403	unsigned char b_AnalogOutputChannelNbr;	// Analog input Output  Nbr
404	unsigned char b_TimerSelectMode;	// Contain data written at iobase + 0C
405	unsigned char b_ModeSelectRegister;	// Contain data written at iobase + 0E
406	USHORT us_OutputRegister;	// Contain data written at iobase + 0
407	unsigned char b_InterruptState;
408	unsigned char b_TimerInit;	// Specify if InitTimerWatchdog was load
409	unsigned char b_TimerStarted;	// Specify if timer 2 is running or not
410	unsigned char b_Timer2Mode;	// Specify the timer 2 mode
411	unsigned char b_Timer2Interrupt;	//Timer2  interrupt enable or disable
412	unsigned char b_AiCyclicAcquisition;	// indicate cyclic acquisition
413	unsigned char b_InterruptMode;	// eoc eos or dma
414	unsigned char b_EocEosInterrupt;	// Enable disable eoc eos interrupt
415	UINT ui_EocEosConversionTime;
416	unsigned char b_EocEosConversionTimeBase;
417	unsigned char b_SingelDiff;
418	unsigned char b_ExttrigEnable;	/* To enable or disable external trigger */
419
420	/* Pointer to the current process */
421	struct task_struct *tsk_Current;
422	boardtype *ps_BoardInfo;
423
424	/* Hardware board infos for 1710 */
425	struct {
426		UINT ui_Address;	/* Board address */
427		UINT ui_FlashAddress;
428		unsigned char b_InterruptNbr;	/* Board interrupt number */
429		unsigned char b_SlotNumber;	/* PCI slot number */
430		unsigned char b_BoardVersion;
431		DWORD dw_MolduleConfiguration[4];	/* Module config */
432	} s_BoardInfos;
433
434	/* Interrupt infos */
435	struct {
436		ULONG ul_InterruptOccur;	/* 0   : No interrupt occur */
437						/* > 0 : Interrupt occur */
438		UINT ui_Read;	/* Read FIFO */
439		UINT ui_Write;	/* Write FIFO */
440		struct {
441			unsigned char b_OldModuleMask;
442			ULONG ul_OldInterruptMask;	/* Interrupt mask */
443			ULONG ul_OldCounterLatchValue;	/* Interrupt counter value */
444		} s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
445	} s_InterruptParameters;
446
447	str_ModuleInfo s_ModuleInfo[4];
448	ULONG ul_TTLPortConfiguration[10];
449
450} addi_private;
451
452static unsigned short pci_list_builded;	/* set to 1 when list of card is known */
453
454/* Function declarations */
455static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it);
456static int i_ADDI_Detach(struct comedi_device *dev);
457static int i_ADDI_Reset(struct comedi_device *dev);
458
459static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG);
460static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
461				     struct comedi_insn *insn, unsigned int *data);
462