/** @file dig_inputs.c
 
   Contains all functions to read digital inputs of the APCIE-1532.
 
   @par CREATION  
   @author Krauth Julien
   @date   07.01.09
   
   @par VERSION
   @verbatim
   $LastChangedRevision:$
   $LastChangedDate:$
   @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 <apcie1532-kapi.h> 
#include "apcie1532-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 all digital inputs of the APCIE-1532.
 *
 * @param [in,out]	pdev	Pointer on the device structure.
 * @param [in]		cmd		IOCTL command. The command is <br>
 * 							CMD_APCIE1532_Read16DigitalInputs when using the IOCTL function.
 * @param [out]		arg		Port state (0 to 65535).
 *
 * @retval 0		No error. 
 * @retval -EFAULT	Can't return parameters.
 */
int do_CMD_APCIE1532_Read16DigitalInputs(struct pci_dev *pdev, unsigned int cmd, unsigned long arg)
{
	int ret;
	uint32_t PortState = 0;		/**< Port state:<br>
                                 One port is composed of 16 channels.<br>
                                 One channel can be 1 (high) or 0 (low) */

	/* no need to lock since no private data are accessed */

	/* Get the state of port 0 */
	
	if ( (ret = APCIE1532_Read16DigitalInputs(pdev, &PortState) ) )
		return ret;
	
	if ( copy_to_user((uint32_t __user *) arg, (uint32_t*)&PortState, sizeof(uint32_t)) )
		return -EFAULT;

	return 0;
}

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

/** Initialise and start digital input interrupts of the APCIE-1532.
 *
 * @param [in,out]	pdev	Pointer on the device structure.
 * @param [in]		cmd		IOCTL command. The command is <br>
 * 							CMD_APCIE1532_InitAndStartDigitalInputInterrupt when using the IOCTL fundtion.
 * @param [in]		arg		The followin initialisation structure:<br>
 * 
 * 	struct<br>
 * 	{<br>
 * 		int InterruptLogic;<br>
 * 		uint32_t InterruptMaskMode1;<br>
 * 		uint32_t InterruptMaskMode2;<br>
 * 	} params;<br>
 *
 * @retval 0		No error. 
 * @retval -EFAULT	Can't get parameters.
 */
int do_CMD_APCIE1532_InitAndStartDigitalInputInterrupt (struct pci_dev *pdev, unsigned int cmd, unsigned long arg)
{
	struct
	{
		int InterruptLogic;
		uint32_t InterruptMaskMode1;
		uint32_t InterruptMaskMode2;
	} params;
	
	if ( copy_from_user(&params, (void __user *) arg, sizeof(params) ) )
		return -EFAULT;
	
	return APCIE1532_InitAndStartDigitalInputInterrupt (pdev, params.InterruptLogic, params.InterruptMaskMode1,params.InterruptMaskMode2);
}

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

/** Clear and stop digital input interrupts of the APCIE-1532.
 *
 * @param [in,out]	pdev	Pointer on the device structure.
 * @param [in]		cmd		IOCTL command. The command is <br>
 * 							CMD_APCIE1532_ClearAndStopDigitalInputInterrupt when using the IOCTL fundtion.
 *
 * @retval 0		No error. 
 */
int do_CMD_APCIE1532_ClearAndStopDigitalInputInterrupt (struct pci_dev *pdev, unsigned int cmd, unsigned long arg)
{
	return APCIE1532_ClearAndStopDigitalInputInterrupt (pdev);
}

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

/** Get digital input interrupts parameters of the APCIE-1532.
 *
 * @param [in,out]	pdev	Pointer on the device structure.
 * @param [in]		cmd		IOCTL command. The command is <br>
 * 							CMD_APCIE1532_GetDigitalInputInterruptConfig when using the IOCTL fundtion.
 * @param [out]		arg		The followin initialisation structure:<br>
 * 
 * 	struct<br>
 * 	{<br>
 * 		int InterruptLogic;<br>
 * 		uint32_t InterruptMaskMode1;<br>
 * 		uint32_t InterruptMaskMode2;<br>
 * 	} params;<br>
 *
 * @retval 0		No error. 
 * @retval -EFAULT	Can't get parameters.
 */
int do_CMD_APCIE1532_GetDigitalInputInterruptConfig (struct pci_dev *pdev, unsigned int cmd, unsigned long arg)
{
	struct
	{
		int Enabled;
		int InterruptLogic;
		uint32_t InterruptMaskMode1;
		uint32_t InterruptMaskMode2;
	} params;
	
	{
		int ret = APCIE1532_GetDigitalInputInterruptConfig (pdev, &(params.Enabled), &(params.InterruptLogic), &(params.InterruptMaskMode1), &(params.InterruptMaskMode2) );
		if (ret)
			return ret;
	}
	
	if ( copy_to_user( (void __user *) arg, &params , sizeof(params) ) )
	{
		return -EFAULT;
	}
	return 0;
}

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