/** @file dig_io.c
 
   Contains digital I/O ioctl functions.
 
   @par CREATION  
   @author Krauth Julien
   @date   16.07.07
   
   @par VERSION
   @verbatim
   $LastChangedRevision:$
   $LastChangedDate:$
   @endverbatim   
   
   @par LICENCE
   @verbatim
   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.

   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 "apci3001-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

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

/** Read 4 digital input.
 * 
 * @param [in] pdev                       : The device to manage.
 * @param [out] arg (b_DigitalInputValue) : Digital input value.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval -EFAULT : Fail to retrieve user data.
 */
int do_CMD_APCI3001_Read4DigitalInput (struct pci_dev *pdev, unsigned int cmd, unsigned long arg)
{
	INT i_ErrorCode = 0;
	BYTE b_Tmp = 0;

	{
		unsigned long irqstate;
		APCI3001_LOCK(pdev,&irqstate);
		{
			i_ErrorCode = i_APCI3001_Read4DigitalInput (pdev, &b_Tmp);
		}
		APCI3001_UNLOCK(pdev, irqstate);
	}									
	if (i_ErrorCode != 0)
		return (i_ErrorCode);		
			
	if ( copy_to_user( (BYTE __user *)arg , &b_Tmp, sizeof(b_Tmp) ) )
		return -EFAULT;													
												
	return (i_ErrorCode);
}			

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

/** Set digital output memory on.
 *
 * When output memory is setting on. Output state is holding, and <br>
 * the new output(s) is(are) set or reset.
 *
 * @param [in] pdev                 : The device to manage.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 */
int do_CMD_APCI3001_SetOutputMemoryOn (struct pci_dev *pdev, unsigned int cmd, unsigned long arg)
{
	INT i_ErrorCode = 0;

	{
		unsigned long irqstate;
		APCI3001_LOCK(pdev,&irqstate);
		{
			i_ErrorCode = i_APCI3001_SetOutputMemoryOn (pdev);
		}
		APCI3001_UNLOCK(pdev, irqstate);
	}								
		return (i_ErrorCode);
}

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

/** Set digital output memory off.
 *
 * @param [in] pdev                 : The device to manage.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 */
int do_CMD_APCI3001_SetOutputMemoryOff (struct pci_dev *pdev, unsigned int cmd, unsigned long arg)
{
	INT i_ErrorCode = 0;

	{
		unsigned long irqstate;
		APCI3001_LOCK(pdev,&irqstate);
		{
			i_ErrorCode = i_APCI3001_SetOutputMemoryOff (pdev);
		}
		APCI3001_UNLOCK(pdev, irqstate);
	}								
		return (i_ErrorCode);
}

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

/** Set 4 digital output on.
 *
 * @param [in] pdev                       : The device to manage.
 * @param [in] arg (b_DigitalOutputValue) : Digital output value.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval 2: The digital output value is wrong.
 */
int do_CMD_APCI3001_Set4DigitalOutputOn (struct pci_dev *pdev, unsigned int cmd, unsigned long arg)
{
	INT i_ErrorCode = 0;

	{
		unsigned long irqstate;
		APCI3001_LOCK(pdev,&irqstate);
		{
			i_ErrorCode = i_APCI3001_Set4DigitalOutputOn (pdev, (uint8_t)arg);
		}
		APCI3001_UNLOCK(pdev, irqstate);
	}
	return (i_ErrorCode);
}	

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

/** Set 4 digital output off.
 *
 * Can only be used when i_APCI3001_SetOutputMemoryOn has been called.
 *
 * @param [in] pdev                 : The device to manage.
 * @param [in] arg (b_DigitalOutputValue) : Digital output value.
 *
 * @retval 0: No error.
 * @retval 1: The handle parameter of the board is wrong.
 * @retval 2: The digital output value is wrong.
 * @retval 3: Output memory is not activated (please use i_APCI3001_SetOutputMemoryOn).
 */
int do_CMD_APCI3001_Set4DigitalOutputOff (struct pci_dev *pdev, unsigned int cmd, unsigned long arg)
{
	INT i_ErrorCode = 0;

	{
		unsigned long irqstate;
		APCI3001_LOCK(pdev,&irqstate);
		{
			i_ErrorCode = i_APCI3001_Set4DigitalOutputOff (pdev, (uint8_t)arg);
		}
		APCI3001_UNLOCK(pdev, irqstate);
	}
	return (i_ErrorCode);
}	

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


