 /* @file privadata.h
  * 
  * @brief Holds definition for driver's private data and its manipulation functions. 
  * 
  * 
  * 
  */

/** @par LICENCE
* @verbatim
    Copyright (C) 2009  ADDI-DATA GmbH for the source code of this module.
        
    ADDI-DATA GmbH
    Airpark Business Center
    Airport Boulevard B210
    77836 Rheinmünster
    Germany
    Tel: +49(0)7229/1847-0
    Fax: +49(0)7229/1847-200
    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.

    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 shoud find the complete GPL in the COPYING file accompanying 
    this source code. 
* @endverbatim
*/

#ifndef __APCI3001_PRIVDATA_H_
#define __APCI3001_PRIVDATA_H_

#include <linux/version.h>

union csTimerCtr0_t
{
	struct
	{
			unsigned int timer_select : 2;
			unsigned int dummy        : 2;
			unsigned int digOutReg    : 4;
	};
	uint8_t raw;
};

/* internal driver data */
struct apci3001_str_BoardInformations
{
	spinlock_t lock; /**< protect the board data */
	
	/* Asynchronous IO signal implementation - send a SIGIO to all registered processes*/
	/* If using signal to inform user mode, uncomment following line: */
	// struct fasync_struct * async_queue; /* asynchronous readers */
	
	BYTE	intrpt;				/* holds the PCI interrupt # */
	BYTE	nrAnaIn;
	union csTimerCtr0_t crt0;
	BYTE	crt1;				/* saved HW register */
	BYTE	modeSelect;			/* saved HW register: APCI3120_WRITE_MODE_SELECT */
	USHORT	nWrAddr;			/* saved HW register: APCI3120_WR_ADDRESS */
	BYTE	digOutMem;
	BYTE	lastChannel;
	BYTE	intMode;
	BYTE	interruptInitialized;	
};

/** initialise board's private data - fill it when adding new members and ioctl handlers */
static __inline__ void apci3001_init_priv_data(struct apci3001_str_BoardInformations * data)
{
	/* Be carefull, don't put a memset data after spin_lock_init!! */
	// FILLME
	
	memset (data, 0, sizeof(struct apci3001_str_BoardInformations));
	
	/* Set a default value for the number of input channels */
	data->nrAnaIn = 16;	

	spin_lock_init(& (data->lock) );
}

/** return the private data field of a pci_dev structure. 
 * @note The implementation of this function differs in 2.4 and 2.6 kernel
 */
static __inline__ struct apci3001_str_BoardInformations * APCI3001_PRIVDATA(struct pci_dev * pdev)
{	
	return (struct apci3001_str_BoardInformations *) pci_get_drvdata(pdev);
}

/** lock the board */
static __inline__ void APCI3001_LOCK(struct pci_dev * pdev, unsigned long * flags)
{
	spin_lock_irqsave(& (APCI3001_PRIVDATA(pdev)->lock) , *flags );
}

/** unlock the board */
static __inline__ void APCI3001_UNLOCK(struct pci_dev * pdev, unsigned long flags )
{
	spin_unlock_irqrestore(& (APCI3001_PRIVDATA(pdev)->lock) , flags );
}

#endif // __APCI3001_PRIVDATA_H_
