/*
 * Quantis PCI driver
 *
 * Copyright (c) 2004-2010 id Quantique SA, Carouge/Geneva, Switzerland
 * All rights reserved.
 *
 * ----------------------------------------------------------------------------
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY.
 *
 * ----------------------------------------------------------------------------
 *
 * Alternatively, this software may be distributed under the terms of the
 * terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * ----------------------------------------------------------------------------
 *
 * For history of changes, ChangeLog.txt
 *
 * This header file describes the register of the Quantis PCI card. The code has been adapted from
 * a microsoft provided sample file.
 *
 Module Name:

    QuantisReg.h  - Quantis Register definitions

    Refer to the "quantispci_mapping.pdf" document
    for details on these register definitions.

Environment:

    Kernel mode
 */

#ifndef __QUANTIS_REG_H_
#define __QUANTIS_REG_H_

#include "CommonWindows.h"

QUANTIS_EXTERN_C_START

//Generic type of a configuration register on Quantis board
typedef u_int32_t QuantisConfReg, *PQuantisConfReg;
typedef QuantisConfReg NotUsed; //Register not used or reserved on the Quantis board

//And the type of the value which can be put or set in a register. This could be different from "QuantisConfReg".
//For instance if the register type would have been a sequence number "QuantisConfReg" were probably an 
//"unsigned char" while the value of the register would still be an "u_int32_t".
typedef u_int32_t QuantisConfRegValue;
typedef QuantisConfRegValue RandomData;

//-----------------------------------------------------------------------------
// Define the Interrupt Control/Status Register (INTCSR) and the general
// status register (depending if the system is driven by interrupts or by polling)
//-----------------------------------------------------------------------------

typedef struct _INTCSR_REG {
    QuantisConfReg  IrEmp       : 1;  // bit 0 Interrupt Request FIFO Empty mask
    QuantisConfReg  IrFl1       : 1;  // bit 1 Interrupt Request FIFO Flag 1 mask (buffer 1/4 full)
    QuantisConfReg  IrFl2       : 1;  // bit 2 Interrupt Request FIFO Flag 2 mask (buffer 1/2 full)
    QuantisConfReg  IrFl3       : 1;  // bit 3 Interrupt Request FIFO Flag 3 mask (buffer 3/4 full)
    QuantisConfReg  NotUsed1    : 2;  // bit 4-5 Reserved
    QuantisConfReg  IrFull      : 1;  // bit 6 Interrupt Request FIFO full
    QuantisConfReg  IrErr       : 1;  // bit 7 Interrupt Request FIFO Error mask
    QuantisConfReg  IrErrWR     : 1;  // bit 8 Interrupt Request FIFO Write Error mask
    QuantisConfReg  IrErrRD     : 1;  // bit 9 Interrupt Request FIFO READ Error mask
    QuantisConfReg  NotUsed2    : 22; // bits 10-32 Reserved
} INTCSR_REG, * PINTCSR_REG;

// Define when a interrupt has arose (all the one bits for intterupt)
#define IS_QUANTIS_INTERRUPT 0x3CF
// Bits for the individual flags
#define QUANTIS_FIFO_EMPTY    1
#define QUANTIS_FIFO_FL1      2
#define QUANTIS_FIFO_FL2      4
#define QUANTIS_FIFO_FL3      8
#define QUANTIS_FIFO_FULL     64
#define QUANTIS_FIFO_ERROR    128
#define QUANTIS_FIFO_WRITE_ERROR 256
#define QUANTIS_FIFO_READ_ERROR 512
 

//-----------------------------------------------------------------------------
// Define the Quantis modules status register (QMSR)
// a board can be made of 1 to 4 Quantis number generators. Each module
// can be hardware activated (it is activated when the module is build on the board)
// and hardware in low or high status (low status is a transitional status when
// random numbers can not be used during hardware initialisation). In addition
// to the hardware status, each module can be deactivated by setting a flag in a register.
// A transitionnal status can then occure before random generator can be used again.
// Finally, a software test mode is available.
//
// The Quantis modules status register describes all the status possible
// by devoting one char (8bits) to each modules (at most 4 modules are
// available by card)
//-----------------------------------------------------------------------------

typedef struct _QMS_REG {
    QuantisConfReg M0SD             : 1; // bit 0 Software Shutdown of the Module 0
                                         // 0 = Software Shutdown of Module 0 is disabled
                                         // 1 = Software Shutdown of Module 0 is enabled
    QuantisConfReg M0EN             : 1; // bit 1 Module 0 Software Enable
                                         // 0 = Data Acquisition of the Module 0 is deactivated
                                         // 1 = Data Acquisition of the Module 0 is activated
    QuantisConfReg M0TM             : 1; // bit 2 Test Mode Enable on the Module 0
                                         // 0 = Test Mode of Module 0 is disabled
                                         // 1 = Test Mode of Module 0 is enabled
    QuantisConfReg Res0             : 3; // bit 3-5 Reserved
    QuantisConfReg M0HEN            : 1; // bit 6 Hardware Enable of Module 0
                                         // 0 = Hardware Module 0 is not present
                                         // 1 = Hardware Module 0 is present
    QuantisConfReg M0HST            : 1; // bit 7 Hardware Status of Module 0
                                         // 0 = Hardware Status of Module 0 is low
                                         // 1 = Hardware Status of Module 0 is high
    // Similar values for the second module
    QuantisConfReg M1SD             : 1;  // bit 8
    QuantisConfReg M1EN             : 1;  // bit 9
    QuantisConfReg M1TM             : 1;  // bit 10
    QuantisConfReg Res1             : 3;  // bit 11-13
    QuantisConfReg M1HEN            : 1;  // bit 14
    QuantisConfReg M1HST            : 1;  // bit 15
    // Similar values for the third module
    QuantisConfReg M2SD             : 1;  // bit 16
    QuantisConfReg M2EN             : 1;  // bit 17
    QuantisConfReg M2TM             : 1;  // bit 18
    QuantisConfReg Res2             : 3;  // bit 19-21
    QuantisConfReg M2HEN            : 1;  // bit 22
    QuantisConfReg M2HST            : 1;  // bit 23
    // Similar values for the fourth module
    QuantisConfReg M3SD             : 1;  // bit 24
    QuantisConfReg M3EN             : 1;  // bit 25
    QuantisConfReg M3TM             : 1;  // bit 26
    QuantisConfReg Res3             : 3;  // bit 27-29
    QuantisConfReg M3HEN            : 1;  // bit 30
    QuantisConfReg M3HST            : 1;  // bit 31
} QMS_REG, * PQMS_REG;

//This type of register is similar to the Quantis Module Status Register,
//but the harware bits are not defined since they can not be set by software.
//The "Quantis Module Register" matches the "IDQ MODULE X CONTROL Enable/Disable Register".
//In the "disable" register, the value 0 has no effect and the value 1 disable the 
//corresponding bit while the opposite is true in the "enable" register.
typedef struct _QM_REG {
    QuantisConfReg M0SD             : 1;  // bit 0 Software Reset of the Module 0
    QuantisConfReg M0SEN            : 1;  // bit 1 Module 0 Software Enable/Disable  of the module 0
    QuantisConfReg M0TM             : 1;  // bit 2 Test Mode Enable/Disable on the Module 0
    QuantisConfReg Res0             : 5;  // bit 3-7 Reserved
    // Similar values for the second module
    QuantisConfReg M1SD             : 1;  // bit 8
    QuantisConfReg M1EN             : 1;  // bit 9
    QuantisConfReg M1TM             : 1;  // bit 10
    QuantisConfReg Res1             : 5;  // bit 11-15
    // Similar values for the third module
    QuantisConfReg M2SD             : 1;  // bit 16
    QuantisConfReg M2EN             : 1;  // bit 17
    QuantisConfReg M2TM             : 1;  // bit 18
    QuantisConfReg Res2             : 5;  // bit 19-23
    // Similar values for the fourth module
    QuantisConfReg M3SD             : 1;  // bit 24
    QuantisConfReg M3EN             : 1;  // bit 25
    QuantisConfReg M3TM             : 1;  // bit 26
    QuantisConfReg Res3             : 5;  // bit 27-31
} QM_REG, * PQM_REG;
// Specific bits in modules registers
#define MX_SOFTWARE_RESET   0     
#define MX_SOFTWARE_ENABLE  1
#define MX_SOFTWARE_TEST_MODE   2
#define MX_HARDWARE_ENABLE  6
#define MX_HARDWARE_READY  7

// This register is used to determine the version of card (Quantis Version Register)
typedef struct _QV_REG{
   QuantisConfReg Release           : 8;  //bit 0-7 Release number of the IDQ core
   QuantisConfReg Day               : 8;  //bit 8-15 Day when the IDQ core was released
   QuantisConfReg Month             : 8;  //bit 16-23 Month when the IDQ core was released
   QuantisConfReg Year              : 8;  //bit 24-31 Year when the IDQ core was released
} QV_REG, *PQV_REG;

// This register allow a global soft reset of the card. As usual,
// this register is used to enable/disable and show the status of register.
typedef struct _QGRST_REG{
   QuantisConfReg Reset             :1;  //bit 0 Software Reset of the IDQ
                                         //core A software-triggered hardware reset of the IDQ core is performed.
                                         //This software Reset allows to reset the four modules.
   QuantisConfReg Res               :31; //bit 1-31
} QGRST_REG, *PQGRST_REG;

//-----------------------------------------------------------------------------
// Quantis structure (abbreviations are from IDQuantique)
//-----------------------------------------------------------------------------
/**
 * Quantis PCI Registers
 *
 * The Quantis PCI device has a memory register page 20 words long,
 * consisting of 10 registers. These registers are split into the
 * following functional groups:
 *  -> Core Control group:
 *      - Enable Register `CC_ER'
 *      - Disable Register `CC_DR' 
 *      - Status Register `CC_SR'.
 *  -> Core Version group:
 *      - Status Register `CV_SR', which is used to get the board version.
 *  -> FIFO Status group:
 *      - FIFO Flush Register `FS_CA', 
 *      - FIFO Status Register `FS_RR'
 *      - FIFO Data Read Register `FD_RR'.
 *  -> Module Group:
 *      - Enable Register `MX_ER'
 *      - Disable Register `MX_DR'
 *      - Status Register `MX_SR'
 ** used to enable and disable card modules,
 *  -> Interrupt group
 *      - Enable Interrupt register  `IR_ER'
 *      - Disable Interrupt register `IR_DR'
 *      - Interrupt status register  `IR_SR'
 **/
 
 typedef struct _QUANTIS_REG {

    QuantisConfReg      CC_ER;  // 0, Write only, IDQ CORE CONTROL Enable Register
    QuantisConfReg      CC_DR;  // 1, Write only, IDQ CORE CONTROL Disable Register
    NotUsed        Res1;       // 2
    QuantisConfReg      CC_SR;  // 3, Read only,  IDQ CORE CONTROL Status Register
    NotUsed        Res2;       // 4
    NotUsed        Res3;       // 5
    NotUsed        Res4;       // 6
    QuantisConfReg         CV_SR;  // 7, Read only, IDQ CORE VERSION Status Register
    QuantisConfReg FC_CA;  // 8, Write only, IDQ FIFO CONTROL Clear Access
                               //    Writing any value on this register will CLEAR the FIFO machine
                               //    and the on-chip tester.
    NotUsed        Res5;       // 9
    QuantisConfReg     FS_RR;  // 10, Read only, IDQ FIFO STATUS Read Register
    RandomData     FD_RR;  // 11, Read only, IDQ FIFO DATA Read Register
    QuantisConfReg         MX_ER;  // 12, Write only, IDQ MODULE X Enable Register
    QuantisConfReg         MX_DR;  // 13, Write only, IDQ MODULE X Disable Register
    NotUsed        Res6;       // 14
    QuantisConfReg        MX_SR;  // 15, Read only, IDQ MODULE X Status Register
    QuantisConfReg     IR_ER;  // 16, Write only, IDQ IRQ Enable Register
    QuantisConfReg     IR_DR;  // 17, Write only, IDQ IRQ Disable Register
    NotUsed        Res7;       // 18
    QuantisConfReg     IR_SR;  // 19, Read only, IDQ IRQ Status Register
} QUANTIS_REG, * PQUANTIS_REG;

QUANTIS_EXTERN_C_END

#endif  // __QUANTIS_REG_H_

