/*

 *            Copyright (c) 1998-2004 by NETsilicon Inc.

 *

 *  This software is copyrighted by and is the sole property of

 *  NETsilicon.  All rights, title, ownership, or other interests

 *  in the software remain the property of NETsilicon.  This

 *  software may only be used in accordance with the corresponding

 *  license agreement.  Any unauthorized use, duplication, transmission,

 *  distribution, or disclosure of this software is expressly forbidden.

 *

 *  This Copyright notice may not be removed or modified without prior

 *  written consent of NETsilicon.

 *

 *  NETsilicon, reserves the right to modify this software

 *  without notice.

 *

 *  NETsilicon

 *  411 Waverley Oaks Road                  USA 781.647.1234

 *  Suite 227                               http://www.netsilicon.com

 *  Waltham, MA 02452                       AmericaSales@netsilicon.com

 *

 * Description:

 *

 *  This file contains the functions for DDI interface

 *

 */



#include <string.h>

#include <stdlib.h>

#include <errno.h>

#include <tx_port.h>

#include <semaphore.h>

#include <ddi.h>

#include <netosIo.h>

#include <reg_def.h>



#include <serParam.h>



#include "netos_spi.h"

#include <NA_ISR.h>

#include <Dma_def.h>

#include <sysClock.h>

#include <reg_def.h>

#include <bool.h>

#include <tx_api.h>

#include <ncc_init.h>

#include "spi_mod.h"



#define EEPROM_SUPPORT  1



#ifdef EEPROM_SUPPORT



/*

 * Function: spi_set_command

 *

 * Description: prepare SPI buffer form sending command to EEPROM

 *

 * Called by: sendEEPROMCommand, 

 *

 * Input : q- pointer to the data buffer

 *         request - requested command

 *         arg     - arguments for the requested command 

 *          

 *         

 */

static void spi_set_command(SPIBUFFER volatile *q,char request,int arg)

{

    q->ptrSerData = (char *)q->serBufferData.bufferData;

    q->serBufferData.bufferData[0] = request ;

    q->serBufferData.bufferData[1] = arg ;

    q->countServData = 2;           

    q->ptrDataBuffer = NULL;

    q->countForBufferData = 0;

}





/*

 * Function: spi_copy_reply

 *

 * Description: copy reply received from  EEPROM

 *

 * Called by: sendEEPROMCommand, 

 *

 * Input : q- pointer to the data buffer

 *         arg     - pointer to the int to hold reply 

 *          

 *         

 */

static void spi_copy_reply(SPIBUFFER volatile *q,int *arg)

{

    *arg = q->serBufferData.bufferData[1];

}





/*

 * Function: sendEEPROMCommand()

 *

 * Description: write or read value to/from EEPROM registry

 *

 * Called by: onspiIoctl

 *

 * Input : pChan - Poiner to the cahnnel description

 *         request request from ioctl

 *         arg     argument from ioctl

 *

 * Return: EBADF 

 *         EINVAL

 *         EBUSY

 *         EAGAIN

 *         EXIT_SUCCESS

 *

 */

int sendEEPROMCommand(ONSPI_CHAN *pChan,int request,int *arg)

{

    int channel;

     

    SPIBUFFER volatile *activBaffer;

    int status;

 

    channel = pChan->port;

   

    if (request == SIO_SET_REG)

    {

    	pChan->readInProgres = false;



	    /* First enable write operation */



    	status = sendWriteEnable(pChan);



	    if (status != EXIT_SUCCESS)

        {

	        return (status);

        }



	    spiResetChannel(pChan,true);  /* Reset the channel because send write is doing IO */

	

    	spi_set_command(&spiDataBuffer[channel],XICOR_WRSR ,*arg);

	    if (pChan->openmode & O_DMA)

        {

	        status = spi_init_tx_dma(pChan);

        }

    	else

        {

	        status = onspiTxStartup (pChan);

        }



	    activBaffer = &spiDataBuffer[channel];

    }

    else

    {

    	spiResetChannel(pChan,true);  /* Reset the channel because we do not know status */

	    spi_set_command(&spiDataBuffer[channel],XICOR_RDSR , *arg);

    	spi_set_command (&spiInBuffer[channel],XICOR_RDSR,  *arg);

	    pChan->readInProgres = TRUE;

    	if (pChan->openmode & O_DMA)

	    {

	        spi_init_rx_dma(pChan);

    	    status = spi_init_tx_dma(pChan);

	    }

    	else

	    {

	        onspiRxStartup (pChan);

    	    status = onspiTxStartup (pChan);

	    }



    	activBaffer = &spiInBuffer[channel];

    }



    if (status != TX_SUCCESS)

    {

	    return (status);

    }

    

    if (!waitForCompletion(activBaffer,pChan,0))

    {

	    return (EAGAIN);

    }

    

    spi_copy_reply(activBaffer,arg);

     

    return (EXIT_SUCCESS); 

}



#endif

