/**HEADER********************************************************************
* 
* Copyright (c) 2010 Avnet Japan Co.,Ltd (NIKE Borad Project.)
* All Rights Reserved
*
*************************************************************************** 
*
* $FileName: AD7652.c$
* $Version : 0.1.0.0$
* $Date    : Jan-29-2010$
*
* Comments:
*
*   This file contains the qspi polled I/O (master) driver functions.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "fio.h"
#include "fio_prv.h"
#include "io.h"
#include "io_prv.h"
#include "serial.h"
#include "AD7652.h"
#include "AD7652_prv.h"


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _io_AD7652_install
* Input Value   : 
      [IN] A string that identifies the device for fopen 	: char_ptr identifier,
      [IN] The I/O init function							: _mqx_uint (_CODE_PTR_ init)(pointer, pointer _PTR_, char _PTR_)
      [IN] The I/O de-init function							: _mqx_uint (_CODE_PTR_ deinit)(pointer, pointer)
      [IN] The input function								: _mqx_int (_CODE_PTR_ recv)(pointer, char _PTR_, _mqx_int)
      [IN] The output function								: _mqx_int (_CODE_PTR_ xmit)(pointer, char _PTR_, _mqx_int)
      [IN] The I/O ioctl function							: _mqx_int (_CODE_PTR_ ioctl)(pointer, _mqx_uint, _mqx_uint_ptr)
      [IN] The I/O init data pointer						: pointer init_data_ptr
* Returned Value   : MQX_OK or a task error code
* Comments         :
*    Install the qspi device.
*
*END*----------------------------------------------------------------------*/

_mqx_uint _io_AD7652_install( char_ptr identifier,
		_mqx_uint (_CODE_PTR_ init)(pointer, char _PTR_),
		_mqx_uint (_CODE_PTR_ deinit)(pointer, pointer),
		_mqx_int (_CODE_PTR_ recv)(pointer, char _PTR_, _mqx_int),
		_mqx_int (_CODE_PTR_ xmit)(pointer, char _PTR_, _mqx_int),
		_mqx_int (_CODE_PTR_ ioctl)(pointer, _mqx_uint, _mqx_uint_ptr),
		pointer init_data_ptr)
{
	IO_AD7652_DEVICE_STRUCT_PTR polled_dev_ptr;

	polled_dev_ptr = (IO_AD7652_DEVICE_STRUCT_PTR)_mem_alloc_system_zero((_mem_size)sizeof(IO_AD7652_DEVICE_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
	if (polled_dev_ptr == NULL) {
		return(MQX_OUT_OF_MEMORY);
	}
#endif

	polled_dev_ptr->DEV_INIT          = init;
	polled_dev_ptr->DEV_DEINIT        = deinit;
	polled_dev_ptr->DEV_READ          = recv;
	polled_dev_ptr->DEV_WRITE         = xmit;
	polled_dev_ptr->DEV_IOCTL         = ioctl;
	polled_dev_ptr->DEV_INIT_DATA_PTR = init_data_ptr;

	return (_io_dev_install_ext(identifier, _io_AD7652_open, _io_AD7652_close, _io_AD7652_read,
		 _io_AD7652_write, _io_AD7652_ioctl, _io_AD7652_uninstall, (pointer)polled_dev_ptr));
}



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _io_AD7652_uninstall
* Input Value      :
      [IN] The IO device structure for the device: IO_DEVICE_STRUCT_PTR   io_dev_ptr

* Returned Value   : MQX_OK or a task error code
* Comments         :
*    Un-Install a polled serial device.
*
*END*----------------------------------------------------------------------*/
_mqx_int _io_AD7652_uninstall(IO_DEVICE_STRUCT_PTR io_dev_ptr)
{
	IO_AD7652_DEVICE_STRUCT_PTR polled_dev_ptr = io_dev_ptr->DRIVER_INIT_PTR;

	if (polled_dev_ptr->COUNT == 0) {
		if (polled_dev_ptr->DEV_DEINIT) {
			(*polled_dev_ptr->DEV_DEINIT)(polled_dev_ptr->DEV_INIT_DATA_PTR, polled_dev_ptr->DEV_INFO_PTR);
		}
		_mem_free(polled_dev_ptr);
		io_dev_ptr->DRIVER_INIT_PTR = NULL;

		return(IO_OK);
	}
	else {
		return(IO_ERROR_DEVICE_BUSY);
	}
}



/*FUNCTION****************************************************************
* 
* Function Name    : _io_AD7652_open
* Input Value      :
      [IN] the file handle for the device being opened 		: FILE_DEVICE_STRUCT_PTR fd_ptr
      [IN] the remaining portion of the name of the device	: char _PTR_ open_name_ptr
      [IN] the flags to be used during operation			:(echo, translation, xon/xoff.)	 char _PTR_ flags

* Returned Value   : MQX_OK or a task error code
* Comments         :
*    This routine initializes the QSPI I/O channel. It acquires
*    memory, then stores information into it about the channel.
*    It then calls the hardware interface function to initialize the channel.
* 
*END**********************************************************************/
_mqx_int _io_AD7652_open(FILE_DEVICE_STRUCT_PTR fd_ptr, char _PTR_ open_name_ptr, char _PTR_ flags)
{
	IO_DEVICE_STRUCT_PTR                io_dev_ptr;
	IO_AD7652_DEVICE_STRUCT_PTR    polled_dev_ptr;
	_mqx_int                            result = MQX_OK;

	io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
	polled_dev_ptr = (IO_AD7652_DEVICE_STRUCT_PTR)(io_dev_ptr->DRIVER_INIT_PTR);

	if (polled_dev_ptr->COUNT) {
		/* Device is already opened */
		polled_dev_ptr->COUNT++;
		fd_ptr->FLAGS = polled_dev_ptr->FLAGS;
		return(result);
	}

	polled_dev_ptr->FLAGS = (_mqx_uint)flags;
	fd_ptr->FLAGS         = (_mqx_uint)flags;

//	result = (*polled_dev_ptr->DEV_INIT)((pointer)polled_dev_ptr->DEV_INIT_DATA_PTR, &polled_dev_ptr->DEV_INFO_PTR, open_name_ptr);
	result = (*polled_dev_ptr->DEV_INIT)((pointer)polled_dev_ptr, open_name_ptr);
	if (result == MQX_OK) {
		polled_dev_ptr->COUNT = 1;
		polled_dev_ptr->RX_BUFF = NULL;
	}

	return(result);
}


/*FUNCTION****************************************************************
* 
* Function Name    : _io_AD7652_close
* Input Value      :
      [IN] the file handle for the device being closed	:FILE_DEVICE_STRUCT_PTR fd_ptr

* Returned Value   : MQX_OK or a task error code
* Comments         :
*    This routine closes the QSPI I/O channel.
* 
*END**********************************************************************/
_mqx_int _io_AD7652_close(FILE_DEVICE_STRUCT_PTR fd_ptr)
{
	IO_DEVICE_STRUCT_PTR             io_dev_ptr;
	IO_AD7652_DEVICE_STRUCT_PTR polled_dev_ptr;
	_mqx_int                         result = MQX_OK;

	io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
	polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

	if (--polled_dev_ptr->COUNT == 0) {
		if (polled_dev_ptr->DEV_DEINIT) {
			result = (*polled_dev_ptr->DEV_DEINIT)(polled_dev_ptr->DEV_INIT_DATA_PTR, polled_dev_ptr->DEV_INFO_PTR);
		}
	}

	return(result);
}


/*FUNCTION****************************************************************
* 
* Function Name    : _io_AD7652_read
* Input Value      : 
      [IN] the handle returned from _fopen 			: FILE_DEVICE_STRUCT_PTR fd_ptr,
      [IN] where the characters are to be stored	: char_ptr data_ptr,
      [IN] the number of bytes to read				: _mqx_int n

* Returned Value   : Number of bytes read
* Comments         :
*    Reads bytes into array from QSPI input buffers.
*    Returns number of bytes received.
*
*END*********************************************************************/
_mqx_int _io_AD7652_read(FILE_DEVICE_STRUCT_PTR fd_ptr, char_ptr data_ptr, _mqx_int n)
{
	IO_DEVICE_STRUCT_PTR                  io_dev_ptr;
	IO_AD7652_DEVICE_STRUCT_PTR      polled_dev_ptr;
	_mqx_int                              num = 0;

	io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
	polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

	num = (*polled_dev_ptr->DEV_READ)(polled_dev_ptr, data_ptr, n);

	return(num);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _io_AD7652_write
* Input Value      :
      [IN] the handle returned from _fopen 	: FILE_DEVICE_STRUCT_PTR fd_ptr,
      [IN] where the bytes are stored		: char_ptr data_ptr,
      [IN] the number of bytes to output	: _mqx_int	n

* Returned Value   : Number of bytes output
* Comments         :
*    This routine calls the appropriate write routine.
*
*END**********************************************************************/
_mqx_int _io_AD7652_write(FILE_DEVICE_STRUCT_PTR fd_ptr, char_ptr data_ptr, _mqx_int n)
{
	IO_DEVICE_STRUCT_PTR                  io_dev_ptr;
	IO_AD7652_DEVICE_STRUCT_PTR      polled_dev_ptr;
	_mqx_int                              num = 0;

	io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
	polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

	num = (*polled_dev_ptr->DEV_WRITE)(polled_dev_ptr, data_ptr, n);

	return(num);
}


/*FUNCTION*****************************************************************
* 
* Function Name    : _io_AD7652_ioctl
* Input Value      :
      [IN] the file handle for the device	: FILE_DEVICE_STRUCT_PTR fd_ptr,
      [IN] the ioctl command				: _mqx_uint cmd,
      [IN] the ioctl parameters				: pointer input_param_ptr

* Returned Value   : _mqx_int
* Comments         :
*    Returns result of qspi ioctl operation.
*
*END*********************************************************************/
_mqx_int _io_AD7652_ioctl(FILE_DEVICE_STRUCT_PTR fd_ptr, _mqx_uint cmd, pointer input_param_ptr)
{
	IO_DEVICE_STRUCT_PTR			io_dev_ptr;
	IO_AD7652_DEVICE_STRUCT_PTR		polled_dev_ptr;
	_mqx_int						result = MQX_OK;
	_mqx_uint_ptr					param_ptr = (_mqx_uint_ptr)input_param_ptr;

	io_dev_ptr     = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
	polled_dev_ptr = (pointer)io_dev_ptr->DRIVER_INIT_PTR;

	switch (cmd) {
		case IO_IOCTL_SERIAL_GET_FLAGS:
			*param_ptr = polled_dev_ptr->FLAGS;
			break;

		case IO_IOCTL_SERIAL_SET_FLAGS:
			polled_dev_ptr->FLAGS = *param_ptr;
			fd_ptr->FLAGS = *param_ptr;
			break;

		case IO_IOCTL_DEVICE_IDENTIFY :
			/* return the device identify */
			param_ptr[0] = IO_DEV_TYPE_PHYS_QSPI_POLLED;
			param_ptr[1] = 0;
			param_ptr[2] = IO_DEV_ATTR_POLL | IO_DEV_ATTR_READ | IO_DEV_ATTR_WRITE;
			result = MQX_OK;	
			break;
    		
		default:
			if (polled_dev_ptr->DEV_IOCTL != NULL) {
				result = (*polled_dev_ptr->DEV_IOCTL)(polled_dev_ptr->DEV_INFO_PTR, cmd, param_ptr);
			}
			break;
	}
	return(result);

} /* Endbody */

/* EOF */