/*
 * Copyright 2004 Freescale Semiconductor, Inc. All Rights Reserved.
 */

/*
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */ 
    
 /*!
  * @file spi-internal.h
  * @brief This header file contains SPI driver core functions prototypes.
  *
  * @ingroup SPI
  */

#ifndef SPI_INTERNAL_H_
#define SPI_INTERNAL_H_

#include <asm/hardware.h>
#include "spi.h"

//#define DBG_SPI 1

#define SPI_TEST_CODE 

#ifdef DBG_SPI
#define DBG_PRINTK(fmt, args...) printk(fmt,##args)
#else
#define DBG_PRINTK(fmt, args...)
#endif

#define TRANSFER_8_BITS  8

#if defined(CONFIG_ARCH_MX3)
#define CONFIG_SPI_NB_MAX      0x03
#else
#define CONFIG_SPI_NB_MAX      0x02
#endif

/*!
 * The maximum of pending client
 */
#define MAX_SPI_CLIENTS 5
#define MAX_PRIORITY    4

/*!
 * This structure is a way for the low level driver to define their own
 * \b spi_port adresses structure. This structure includes elements that are 
 * specifically required by this low-level driver.
 */
typedef struct {
        /*!
         * The SPI Base Register Address.
         */
        unsigned long base_address;
        /*!
         * The SPI RX Register Address.
         */
        unsigned long rx_address;
        /*!
         * The SPI TX Register Address.
         */
        unsigned long tx_address;
        /*!
         * The SPI Control Register Address.
         */
        unsigned long ctrl_address;
        /*!
         * The SPI Interrupt Register Address.
         */
        unsigned long int_address;
        /*!
         * The SPI STAT Register Address.
         */
        unsigned long stat_address;
        /*!
         * The SPI PERIOD Register Address.
         */
        unsigned long period_address;
        /*!
         * The SPI TEST Register Address.
         */
        unsigned long test_address;
} spi_mxc_add;

/*!
 * This structure is a way for the low level driver to define their own
 * \b spi_port structure. This structure includes elements that are 
 * specifically required by this low-level driver.
 */
typedef struct {
        /*!
         * The SPI config.
         */
        spi_config *hw_config;
        /*!
         * Number of received bytes.
         */
        int bytes_received;
        /*!
         * The number of bytes to send
         */
        int bytes_to_send;
        /*! 
         * The reception buffer
         */
        char *rx_buffer;
        /*!
         * Determines whether the SPI module is in use or not
         */
        bool in_use;
        /*! 
         * Stores the number of pending clients
         */
        int  pending_clients[MAX_PRIORITY];
        /*!
         * The mutex to lock/unlock pending clients
         */
        struct semaphore pending_mutex[MAX_PRIORITY][MAX_SPI_CLIENTS];
        /*!
         * The pointer on the current SPI config
         */
        void *current_config_handle;
        /*!
         *  port Mutex
         */
        struct semaphore access_mutex;
        /*!
         *  synchronous interface Mutex
         */
        struct semaphore sync_interface;
        /*!
         * Interrupt number
         */
         unsigned long int_cspi; 
} spi_mxc_port;

/* Internal functions */

/*!
 * This function frees resources when unloaded.
 * It unbinds the interrupts.
 *
 * @return       This function returns 0 if successful, -EPERM otherwise.
 */
int spi_core_exit(void);

/*!
 * This function configures the SPI module from an hardware perspective.
 *
 * @return       This function returns 0 if successful, -EPERM otherwise.
 */
int spi_hw_init(void);

#endif
