/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../comedidev.h" #include "addi_amcc_s5933.h" #define ERROR -1 #define SUCCESS 1 #define LOBYTE(W) (unsigned char)((W) & 0xFF) #define HIBYTE(W) (unsigned char)(((W) >> 8) & 0xFF) #define MAKEWORD(H, L) (unsigned short)((L) | ((H) << 8)) #define LOWORD(W) (unsigned short)((W) & 0xFFFF) #define HIWORD(W) (unsigned short)(((W) >> 16) & 0xFFFF) #define MAKEDWORD(H, L) (unsigned int)((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 */ struct addi_board { 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 */ const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */ const struct comedi_lrange *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 channels high */ int i_NbrTTLChannel; /* Number of TTL channels */ const struct comedi_lrange *pr_TTLRangelist; /* rangelist for TTL */ int i_Dma; /* dma present or not */ int i_Timer; /* timer subdevice present or not */ unsigned char b_AvailableConvertUnit; unsigned int ui_MinAcquisitiontimeNs; /* Minimum Acquisition in Nano secs */ unsigned int 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); }; /* MODULE INFO STRUCTURE */ union str_ModuleInfo { /* Incremental counter infos */ struct { union { struct { unsigned char b_ModeRegister1; unsigned char b_ModeRegister2; unsigned char b_ModeRegister3; unsigned char b_ModeRegister4; } s_ByteModeRegister; unsigned int 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 { unsigned char b_SSIProfile; unsigned char b_PositionTurnLength; unsigned char b_TurnCptLength; unsigned char b_SSIInit; } s_SSICounterInfo; /* TTL I/O infos */ struct { unsigned char b_TTLInit; unsigned char b_PortConfiguration[4]; } s_TTLIOInfo; /* Digital I/O infos */ struct { unsigned char b_DigitalInit; unsigned char b_ChannelAMode; unsigned char b_ChannelBMode; unsigned char b_OutputMemoryEnabled; unsigned int dw_OutputMemory; } s_DigitalIOInfo; /*********************/ /* 82X54 timer infos */ /*********************/ struct { struct { unsigned char b_82X54Init; unsigned char b_InputClockSelection; unsigned char b_InputClockLevel; unsigned char b_OutputLevel; unsigned char b_HardwareGateLevel; unsigned int dw_ConfigurationWord; } s_82X54TimerInfo[3]; unsigned char b_InterruptMask; } s_82X54ModuleInfo; /*********************/ /* Chronometer infos */ /*********************/ struct { unsigned char b_ChronoInit; unsigned char b_InterruptMask; unsigned char b_PCIInputClock; unsigned char b_TimingUnit; unsigned char b_CycleMode; double d_TimingInterval; unsigned int dw_ConfigReg; } s_ChronoModuleInfo; /***********************/ /* Pulse encoder infos */ /***********************/ struct { struct { unsigned char b_PulseEncoderInit; } s_PulseEncoderInfo[4]; unsigned int dw_SetRegister; unsigned int dw_ControlRegister; unsigned int dw_StatusRegister; } s_PulseEncoderModuleInfo; /* Tor conter infos */ struct { struct { unsigned char b_TorCounterInit; unsigned char b_TimingUnit; unsigned char b_InterruptEnable; double d_TimingInterval; unsigned int ul_RealTimingInterval; } s_TorCounterInfo[2]; unsigned char b_PCIInputClock; } s_TorCounterModuleInfo; /* PWM infos */ struct { struct { unsigned char b_PWMInit; unsigned char b_TimingUnit; unsigned char b_InterruptEnable; double d_LowTiming; double d_HighTiming; unsigned int ul_RealLowTiming; unsigned int ul_RealHighTiming; } s_PWMInfo[2]; unsigned char b_ClockSelection; } s_PWMModuleInfo; /* ETM infos */ struct { struct { unsigned char b_ETMEnable; unsigned char b_ETMInterrupt; } s_ETMInfo[2]; unsigned char b_ETMInit; unsigned char b_TimingUnit; unsigned char b_ClockSelection; double d_TimingInterval; unsigned int ul_Timing; } s_ETMModuleInfo; /* CDA infos */ struct { unsigned char b_CDAEnable; unsigned char b_CDAInterrupt; unsigned char b_CDAInit; unsigned char b_FctSelection; unsigned char b_CDAReadFIFOOverflow; } s_CDAModuleInfo; }; /* Private structure for the addi_apci3120 driver */ struct addi_private { int iobase; int i_IobaseAmcc; /* base+size for AMCC chip */ int i_IobaseAddon; /* addon base address */ int i_IobaseReserved; unsigned long dw_AiBase; struct pcilst_struct *amcc; /* ptr too AMCC data */ unsigned char allocated; /* we have blocked card */ unsigned char b_ValidDriver; /* driver is ok */ unsigned char b_AiContinuous; /* we do unlimited AI */ unsigned char b_AiInitialisation; unsigned int ui_AiActualScan; /* how many scans we finished */ unsigned int ui_AiBufferPtr; /* data buffer ptr in samples */ unsigned int ui_AiNbrofChannels; /* how many channels is measured */ unsigned int ui_AiScanLength; /* Length of actual scanlist */ unsigned int ui_AiActualScanPosition; /* position in actual scan */ unsigned int *pui_AiChannelList; /* actual chanlist */ unsigned int ui_AiChannelList[32]; /* actual chanlist */ unsigned char b_AiChannelConfiguration[32]; /* actual chanlist */ unsigned int ui_AiReadData[32]; unsigned int dw_AiInitialised; unsigned int ui_AiTimer0; /* Timer Constant for Timer0 */ unsigned int ui_AiTimer1; /* Timer constant for Timer1 */ unsigned int ui_AiFlags; unsigned int ui_AiDataLength; short *AiData; /* Pointer to sample data */ unsigned int ui_AiNbrofScans; /* number of scans to do */ unsigned short us_UseDma; /* To use Dma or not */ unsigned char b_DmaDoubleBuffer; /* we can use double buffering */ unsigned int ui_DmaActualBuffer; /* which buffer is used now */ /* UPDATE-0.7.57->0.7.68 */ /* unsigned int ul_DmaBufferVirtual[2]; pointers to begin of DMA buffer */ short *ul_DmaBufferVirtual[2]; /* pointers to begin of DMA buffer */ unsigned int ul_DmaBufferHw[2]; /* hw address of DMA buff */ unsigned int ui_DmaBufferSize[2]; /* size of dma buffer in bytes */ unsigned int ui_DmaBufferUsesize[2]; /* which size we may now used for transfer */ unsigned int ui_DmaBufferSamples[2]; /* size in samples */ unsigned int ui_DmaBufferPages[2]; /* number of pages in buffer */ unsigned char b_DigitalOutputRegister; /* Digital Output Register */ unsigned char b_OutputMemoryStatus; unsigned char b_AnalogInputChannelNbr; /* Analog input channel Nbr */ unsigned char b_AnalogOutputChannelNbr; /* Analog input Output Nbr */ unsigned char b_TimerSelectMode; /* Contain data written at iobase + 0C */ unsigned char b_ModeSelectRegister; /* Contain data written at iobase + 0E */ unsigned short us_OutputRegister; /* Contain data written at iobase + 0 */ unsigned char b_InterruptState; unsigned char b_TimerInit; /* Specify if InitTimerWatchdog was load */ unsigned char b_TimerStarted; /* Specify if timer 2 is running or not */ unsigned char b_Timer2Mode; /* Specify the timer 2 mode */ unsigned char b_Timer2Interrupt; /* Timer2 interrupt enable or disable */ unsigned char b_AiCyclicAcquisition; /* indicate cyclic acquisition */ unsigned char b_InterruptMode; /* eoc eos or dma */ unsigned char b_EocEosInterrupt; /* Enable disable eoc eos interrupt */ unsigned int ui_EocEosConversionTime; unsigned char b_EocEosConversionTimeBase; unsigned char b_SingelDiff; unsigned char b_ExttrigEnable; /* To enable or disable external trigger */ /* Pointer to the current process */ struct task_struct *tsk_Current; struct addi_board *ps_BoardInfo; /* Hardware board infos for 1710 */ struct { unsigned int ui_Address; /* Board address */ unsigned int ui_FlashAddress; unsigned char b_InterruptNbr; /* Board interrupt number */ unsigned char b_SlotNumber; /* PCI slot number */ unsigned char b_BoardVersion; unsigned int dw_MolduleConfiguration[4]; /* Module config */ } s_BoardInfos; /* Interrupt infos */ struct { unsigned int ul_InterruptOccur; /* 0 : No interrupt occur */ /* > 0 : Interrupt occur */ unsigned int ui_Read; /* Read FIFO */ unsigned int ui_Write; /* Write FIFO */ struct { unsigned char b_OldModuleMask; unsigned int ul_OldInterruptMask; /* Interrupt mask */ unsigned int ul_OldCounterLatchValue; /* Interrupt counter value */ } s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT]; } s_InterruptParameters; union str_ModuleInfo s_ModuleInfo[4]; unsigned int ul_TTLPortConfiguration[10]; }; 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); static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);