aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers/addi-data/addi_common.h
blob: 19df5c1444a4036157d8bbef58316f708ad4b486 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
/*
 *  Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
 *
 *	ADDI-DATA GmbH
 *	Dieselstrasse 3
 *	D-77833 Ottersweier
 *	Tel: +19(0)7223/9493-0
 *	Fax: +49(0)7223/9493-92
 *	http://www.addi-data-com
 *	info@addi-data.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/kmod.h>
#include <linux/uaccess.h>
#include "../../comedidev.h"
#include "addi_amcc_s5933.h"

#define ERROR	-1
#define SUCCESS	1

/* variable type definition */
typedef unsigned char BYTE, *PBYTE;
typedef short SHORT, *PSHORT;
typedef unsigned short USHORT, *PUSHORT;
typedef unsigned short WORD, *PWORD;
typedef int INT, *PINT;;
typedef unsigned int UINT, *PUINT;
typedef int LONG, *PLONG;		/* 32-bit */
typedef unsigned int ULONG, *PULONG;	/* 32-bit */
typedef unsigned int DWORD, *PDWORD;	/* 32-bit */
typedef unsigned long ULONG_PTR;

typedef const struct comedi_lrange *PCRANGE;

#define LOBYTE(W)	(BYTE)((W) & 0xFF)
#define HIBYTE(W)	(BYTE)(((W) >> 8) & 0xFF)
#define MAKEWORD(H, L)	(USHORT)((L) | ((H) << 8))
#define LOWORD(W)	(USHORT)((W) & 0xFFFF)
#define HIWORD(W)	(USHORT)(((W) >> 16) & 0xFFFF)
#define MAKEDWORD(H, L)	(UINT)((L) | ((H) << 16))

#define ADDI_ENABLE		1
#define ADDI_DISABLE		0
#define APCI1710_SAVE_INTERRUPT	1

#define ADDIDATA_EEPROM		1
#define ADDIDATA_NO_EEPROM	0
#define ADDIDATA_93C76		"93C76"
#define ADDIDATA_S5920		"S5920"
#define ADDIDATA_S5933		"S5933"
#define ADDIDATA_9054		"9054"

/* ADDIDATA Enable Disable */
#define ADDIDATA_ENABLE		1
#define ADDIDATA_DISABLE	0

/* Structures */

/* structure for the boardtype */
typedef struct {
	const char *pc_DriverName;	// driver name
	INT i_VendorId;		//PCI vendor a device ID of card
	INT i_DeviceId;
	INT i_IorangeBase0;
	INT i_IorangeBase1;
	INT i_IorangeBase2;	//  base 2 range
	INT i_IorangeBase3;	//  base 3 range
	INT i_PCIEeprom;	// eeprom present or not
	char *pc_EepromChip;	// type of chip
	INT i_NbrAiChannel;	// num of A/D chans
	INT i_NbrAiChannelDiff;	// num of A/D chans in diff mode
	INT i_AiChannelList;	// len of chanlist
	INT i_NbrAoChannel;	// num of D/A chans
	INT i_AiMaxdata;	// resolution of A/D
	INT i_AoMaxdata;	// resolution of D/A
	PCRANGE pr_AiRangelist;	// rangelist for A/D
	PCRANGE pr_AoRangelist;	// rangelist for D/A

	INT i_NbrDiChannel;	// Number of DI channels
	INT i_NbrDoChannel;	// Number of DO channels
	INT i_DoMaxdata;	// data to set all chanels high

	INT i_NbrTTLChannel;	// Number of TTL channels
	PCRANGE pr_TTLRangelist;	// rangelist for TTL

	INT i_Dma;		// dma present or not
	INT i_Timer;		//   timer subdevice present or not
	BYTE b_AvailableConvertUnit;
	UINT ui_MinAcquisitiontimeNs;	// Minimum Acquisition in Nano secs
	UINT ui_MinDelaytimeNs;	// Minimum Delay in Nano secs

	/* interrupt and reset */
	void (*v_hwdrv_Interrupt)(int irq, void *d);
	int (*i_hwdrv_Reset)(struct comedi_device *dev);

	/* Subdevice functions */

	/* ANALOG INPUT */
	int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev,
					     struct comedi_subdevice *s,
					     struct comedi_insn *insn,
					     unsigned int *data);
	int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev,
					    struct comedi_subdevice *s,
					    struct comedi_insn *insn,
					    unsigned int *data);
	int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev,
					    struct comedi_subdevice *s,
					    struct comedi_insn *insn,
					    unsigned int *data);
	int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev,
					   struct comedi_subdevice *s,
					   struct comedi_insn *insn,
					   unsigned int *data);
	int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev,
					      struct comedi_subdevice *s,
					      struct comedi_cmd *cmd);
	int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev,
					  struct comedi_subdevice *s);
	int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev,
					 struct comedi_subdevice *s);

	/* Analog Output */
	int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev,
					      struct comedi_subdevice *s,
					      struct comedi_insn *insn,
					      unsigned int *data);
	int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev,
					     struct comedi_subdevice *s,
					     struct comedi_insn *insn,
					     unsigned int *data);
	int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev,
					    struct comedi_subdevice *s,
					    struct comedi_insn *insn,
					    unsigned int *data);

	/* Digital Input */
	int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev,
					       struct comedi_subdevice *s,
					       struct comedi_insn *insn,
					       unsigned int *data);
	int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev,
					     struct comedi_subdevice *s,
					     struct comedi_insn *insn,
					     unsigned int *data);
	int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev,
					      struct comedi_subdevice *s,
					      struct comedi_insn *insn,
					      unsigned int *data);
	int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev,
					     struct comedi_subdevice *s,
					     struct comedi_insn *insn,
					     unsigned int *data);

	/* Digital Output */
	int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev,
					       struct comedi_subdevice *s,
					       struct comedi_insn *insn,
					       unsigned int *data);
	int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev,
					      struct comedi_subdevice *s,
					      struct comedi_insn *insn,
					      unsigned int *data);
	int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev,
					     struct comedi_subdevice *s,
					     struct comedi_insn *insn,
					     unsigned int *data);
	int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev,
					     struct comedi_subdevice *s,
					     struct comedi_insn *insn,
					     unsigned int *data);

	/* TIMER */
	int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev,
				       struct comedi_subdevice *s,
				       struct comedi_insn *insn, unsigned int *data);
	int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev,
				      struct comedi_subdevice *s, struct comedi_insn *insn,
				      unsigned int *data);
	int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
				     struct comedi_insn *insn, unsigned int *data);
	int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
				     struct comedi_insn *insn, unsigned int *data);

	/* TTL IO */
	int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev,
				      struct comedi_subdevice *s, struct comedi_insn *insn,
				      unsigned int *data);
	int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s,
				    struct comedi_insn *insn, unsigned int *data);
	int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev,
					    struct comedi_subdevice *s,
					    struct comedi_insn *insn,
					    unsigned int *data);
	int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev,
					 struct comedi_subdevice *s,
					 struct comedi_insn *insn, unsigned int *data);
} boardtype;

//MODULE INFO STRUCTURE

typedef union {
	/* Incremental counter infos */
	struct {
		union {
			struct {
				BYTE b_ModeRegister1;
				BYTE b_ModeRegister2;
				BYTE b_ModeRegister3;
				BYTE b_ModeRegister4;
			} s_ByteModeRegister;
			DWORD dw_ModeRegister1_2_3_4;
		} s_ModeRegister;

		struct {
			unsigned int b_IndexInit:1;
			unsigned int b_CounterInit:1;
			unsigned int b_ReferenceInit:1;
			unsigned int b_IndexInterruptOccur:1;
			unsigned int b_CompareLogicInit:1;
			unsigned int b_FrequencyMeasurementInit:1;
			unsigned int b_FrequencyMeasurementEnable:1;
		} s_InitFlag;

	} s_SiemensCounterInfo;

	/* SSI infos */
	struct {
		BYTE b_SSIProfile;
		BYTE b_PositionTurnLength;
		BYTE b_TurnCptLength;
		BYTE b_SSIInit;
	} s_SSICounterInfo;

	/* TTL I/O infos */
	struct {
		BYTE b_TTLInit;
		BYTE b_PortConfiguration[4];
	} s_TTLIOInfo;

	/* Digital I/O infos */
	struct {
		BYTE b_DigitalInit;
		BYTE b_ChannelAMode;
		BYTE b_ChannelBMode;
		BYTE b_OutputMemoryEnabled;
		DWORD dw_OutputMemory;
	} s_DigitalIOInfo;

      /*********************/
	/* 82X54 timer infos */
      /*********************/

	struct {
		struct {
			BYTE b_82X54Init;
			BYTE b_InputClockSelection;
			BYTE b_InputClockLevel;
			BYTE b_OutputLevel;
			BYTE b_HardwareGateLevel;
			DWORD dw_ConfigurationWord;
		} s_82X54TimerInfo[3];
		BYTE b_InterruptMask;
	} s_82X54ModuleInfo;

      /*********************/
	/* Chronometer infos */
      /*********************/

	struct {
		BYTE b_ChronoInit;
		BYTE b_InterruptMask;
		BYTE b_PCIInputClock;
		BYTE b_TimingUnit;
		BYTE b_CycleMode;
		double d_TimingInterval;
		DWORD dw_ConfigReg;
	} s_ChronoModuleInfo;

      /***********************/
	/* Pulse encoder infos */
      /***********************/

	struct {
		struct {
			BYTE b_PulseEncoderInit;
		} s_PulseEncoderInfo[4];
		DWORD dw_SetRegister;
		DWORD dw_ControlRegister;
		DWORD dw_StatusRegister;
	} s_PulseEncoderModuleInfo;

	/* Tor conter infos */
	struct {
		struct {
			BYTE b_TorCounterInit;
			BYTE b_TimingUnit;
			BYTE b_InterruptEnable;
			double d_TimingInterval;
			ULONG ul_RealTimingInterval;
		} s_TorCounterInfo[2];
		BYTE b_PCIInputClock;
	} s_TorCounterModuleInfo;

	/* PWM infos */
	struct {
		struct {
			BYTE b_PWMInit;
			BYTE b_TimingUnit;
			BYTE b_InterruptEnable;
			double d_LowTiming;
			double d_HighTiming;
			ULONG ul_RealLowTiming;
			ULONG ul_RealHighTiming;
		} s_PWMInfo[2];
		BYTE b_ClockSelection;
	} s_PWMModuleInfo;

	/* ETM infos */
	struct {
		struct {
			BYTE b_ETMEnable;
			BYTE b_ETMInterrupt;
		} s_ETMInfo[2];
		BYTE b_ETMInit;
		BYTE b_TimingUnit;
		BYTE b_ClockSelection;
		double d_TimingInterval;
		ULONG ul_Timing;
	} s_ETMModuleInfo;

	/* CDA infos */
	struct {
		BYTE b_CDAEnable;
		BYTE b_CDAInterrupt;
		BYTE b_CDAInit;
		BYTE b_FctSelection;
		BYTE b_CDAReadFIFOOverflow;
	} s_CDAModuleInfo;

} str_ModuleInfo;

/* Private structure for the addi_apci3120 driver */
typedef struct {

	INT iobase;
	INT i_IobaseAmcc;	// base+size for AMCC chip
	INT i_IobaseAddon;	//addon base address
	INT i_IobaseReserved;
	ULONG_PTR dw_AiBase;
	struct pcilst_struct *amcc;	// ptr too AMCC data
	BYTE allocated;		// we have blocked card
	BYTE b_ValidDriver;	// driver is ok
	BYTE b_AiContinuous;	// we do unlimited AI
	BYTE b_AiInitialisation;
	UINT ui_AiActualScan;	//how many scans we finished
	UINT ui_AiBufferPtr;	// data buffer ptr in samples
	UINT ui_AiNbrofChannels;	// how many channels is measured
	UINT ui_AiScanLength;	// Length of actual scanlist
	UINT ui_AiActualScanPosition;	// position in actual scan
	PUINT pui_AiChannelList;	// actual chanlist
	UINT ui_AiChannelList[32];	// actual chanlist
	BYTE b_AiChannelConfiguration[32];	// actual chanlist
	UINT ui_AiReadData[32];
	DWORD dw_AiInitialised;
	UINT ui_AiTimer0;	//Timer Constant for Timer0
	UINT ui_AiTimer1;	//Timer constant for Timer1
	UINT ui_AiFlags;
	UINT ui_AiDataLength;
	short *AiData;	// Pointer to sample data
	UINT ui_AiNbrofScans;	// number of scans to do
	USHORT us_UseDma;	// To use Dma or not
	BYTE b_DmaDoubleBuffer;	// we can use double buffering
	UINT ui_DmaActualBuffer;	// which buffer is used now
	//*UPDATE-0.7.57->0.7.68
	//ULONG               ul_DmaBufferVirtual[2];// pointers to begin of DMA buffer
	short *ul_DmaBufferVirtual[2];	// pointers to begin of DMA buffer
	ULONG ul_DmaBufferHw[2];	// hw address of DMA buff
	UINT ui_DmaBufferSize[2];	// size of dma buffer in bytes
	UINT ui_DmaBufferUsesize[2];	// which size we may now used for transfer
	UINT ui_DmaBufferSamples[2];	// size in samples
	UINT ui_DmaBufferPages[2];	// number of pages in buffer
	BYTE b_DigitalOutputRegister;	// Digital Output Register
	BYTE b_OutputMemoryStatus;
	BYTE b_AnalogInputChannelNbr;	// Analog input channel Nbr
	BYTE b_AnalogOutputChannelNbr;	// Analog input Output  Nbr
	BYTE b_TimerSelectMode;	// Contain data written at iobase + 0C
	BYTE b_ModeSelectRegister;	// Contain data written at iobase + 0E
	USHORT us_OutputRegister;	// Contain data written at iobase + 0
	BYTE b_InterruptState;
	BYTE b_TimerInit;	// Specify if InitTimerWatchdog was load
	BYTE b_TimerStarted;	// Specify if timer 2 is running or not
	BYTE b_Timer2Mode;	// Specify the timer 2 mode
	BYTE b_Timer2Interrupt;	//Timer2  interrupt enable or disable
	BYTE b_AiCyclicAcquisition;	// indicate cyclic acquisition
	BYTE b_InterruptMode;	// eoc eos or dma
	BYTE b_EocEosInterrupt;	// Enable disable eoc eos interrupt
	UINT ui_EocEosConversionTime;
	BYTE b_EocEosConversionTimeBase;
	BYTE b_SingelDiff;
	BYTE b_ExttrigEnable;	/* To enable or disable external trigger */

	/* Pointer to the current process */
	struct task_struct *tsk_Current;
	boardtype *ps_BoardInfo;

	/* Hardware board infos for 1710 */
	struct {
		UINT ui_Address;	/* Board address */
		UINT ui_FlashAddress;
		BYTE b_InterruptNbr;	/* Board interrupt number */
		BYTE b_SlotNumber;	/* PCI slot number */
		BYTE b_BoardVersion;
		DWORD dw_MolduleConfiguration[4];	/* Module config */
	} s_BoardInfos;

	/* Interrupt infos */
	struct {
		ULONG ul_InterruptOccur;	/* 0   : No interrupt occur */
						/* > 0 : Interrupt occur */
		UINT ui_Read;	/* Read FIFO */
		UINT ui_Write;	/* Write FIFO */
		struct {
			BYTE b_OldModuleMask;
			ULONG ul_OldInterruptMask;	/* Interrupt mask */
			ULONG ul_OldCounterLatchValue;	/* Interrupt counter value */
		} s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
	} s_InterruptParameters;

	str_ModuleInfo s_ModuleInfo[4];
	ULONG ul_TTLPortConfiguration[10];

} addi_private;

static unsigned short pci_list_builded;	/* set to 1 when list of card is known */

/* Function declarations */
static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it);
static int i_ADDI_Detach(struct comedi_device *dev);
static int i_ADDI_Reset(struct comedi_device *dev);

static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG);
static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
				     struct comedi_insn *insn, unsigned int *data);