/** @file dig_outputs.c
 
   Contains all functions to set digital outputs of the APCIE-1516.
 
   @par CREATION  
   @author Krauth Julien
   @date   14.06.05
   
   @par VERSION
   @verbatim
   $LastChangedRevision:$
   $LastChangedDate:$
   @endverbatim   
   
   @par COMPILER
   @verbatim
   Compiler	: gcc
   Version	: gcc (GCC) 3.3.6 (Debian 1:3.3.6-5)   
   kernel	: 2.4.26
   @endverbatim  
   
   @par UPDATES
   @verbatim
   Date			:
   Author		: 
   Description	: 
   @endverbatim    
    
   @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 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

   You shoud also find the complete GPL in the COPYING file 
   accompanying this source code.
   @endverbatim   
 */

#include <apcie1516-kapi.h>  
#include "apcie1516-private.h"

/**@def EXPORT_NO_SYMBOLS
 * Function in this file are not exported.
 */
EXPORT_NO_SYMBOLS;

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27)
	#define __user 
#endif


//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

/** Set all digital outputs of the APCIE-1516 on.
 *
 * @param [in,out]	pdev	Pointer on the device structure.
 * @param [in]		arg		Function argument. An unsigned char that has contain port state to set.
 *
 * @retval 0		No error. 
 * @retval -EFAULT	Can't return parameters.
 */
int APCIE1516_Set8DigitalOutputsOn(struct pci_dev *pdev, uint8_t arg)
{
	/* Test if output memory is used */
  	if ( APCIE1516_PRIVDATA(pdev)->OutputMemoryStatus )
    {
        /* Copy state to set in the board structure */         	
        APCIE1516_PRIVDATA(pdev)->RegisterDigitalOutput |= arg; 
    } 
  	else
    {
        /* Copy state to set in the board structure */         	
        APCIE1516_PRIVDATA(pdev)->RegisterDigitalOutput = arg; 
    }

	/* Apply new output state */
	outl(APCIE1516_PRIVDATA(pdev)->RegisterDigitalOutput, ((GET_BAR3(pdev) + APCIE1516_WRITEREG)));
 
	return 0;
}

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

/** Set all digital outputs of the APCIE-1516 off.
 *
 * @param [in,out]	pdev	Pointer on the device structure.
 * @param [in]		cmd		IOCTL command. The command is <br>
 * 							CMD_APCIE1516_Set8DigitalOutputsOn when using the IOCTL funktion.<br>
 * 							To call the function in kernel mode, cmd must be 0.
 * @param [in]		arg		Function argument. An unsigned char that has contain port state to reset.
 *
 * @retval 0		No error. 
 * @retval -EPERM	Output memory is not activated.
 * @retval -EFAULT	Can't return parameters.
 */
int APCIE1516_Set8DigitalOutputsOff(struct pci_dev *pdev, unsigned long arg)
{
	/* Test the value to reset */
	if (arg > 255 )
    	return -EFAULT;   

	/* Test if output memory is used */
	if ( !APCIE1516_PRIVDATA(pdev)->OutputMemoryStatus )
	{
    	return -EPERM;
	}
	/* Copy state to set in the board structure */         	
	APCIE1516_PRIVDATA(pdev)->RegisterDigitalOutput &= (~arg);

	/* Apply new output state */
	outl(APCIE1516_PRIVDATA(pdev)->RegisterDigitalOutput, ((GET_BAR3(pdev) + APCIE1516_WRITEREG)));

	return 0;
}

//------------------------------------------------------------------------------

//------------------------------------------------------------------------------

/** Set the digital output memory on.
 *
 * @param [in,out]	pdev	Pointer on the device structure. *
 * @retval 0		No error.
 */
int APCIE1516_SetDigitalOutputMemoryOn(struct pci_dev *pdev)
{

	/* Get the state of port 0 */
	APCIE1516_PRIVDATA(pdev)->RegisterDigitalOutput = inl((GET_BAR3(pdev) + APCIE1516_WRITEREG));
	             
	/* Set the digital output memory flag on */
	APCIE1516_PRIVDATA(pdev)->OutputMemoryStatus = 1;

    return 0;
}

//------------------------------------------------------------------------------

/** Set the digital output memory off.
 *
 * @param [in,out]	pdev	Pointer on the device structure.

 * @retval 0		No error.
 */
int APCIE1516_SetDigitalOutputMemoryOff(struct pci_dev *pdev)
{

	/* Set the state of port 0 */
    APCIE1516_PRIVDATA(pdev)->RegisterDigitalOutput = 0;
      
    /* Set the digital output memory flag off */
    APCIE1516_PRIVDATA(pdev)->OutputMemoryStatus = 0;

    return 0;
}

//------------------------------------------------------------------------------

/** Get all digital outputs states of the APCIE-1516.
 *
 * @param [in,out]	pdev	Pointer on the device structure.
 * @param [out]		arg		Function argument. An unsigned char that contain port state.
 *
 * @retval 0		No error. 
 * @retval -EFAULT	Can't return parameters.
 */
int APCIE1516_Get8DigitalOutputStatus(struct pci_dev *pdev, uint8_t * PortState)
{
	/* Get the state of port 0 */
	APCIE1516_PRIVDATA(pdev)->RegisterDigitalOutput = inl((GET_BAR3(pdev) + APCIE1516_WRITEREG));      
		  
	*PortState = APCIE1516_PRIVDATA(pdev)->RegisterDigitalOutput;

	return 0;
}
	

