/**
 *  \file   SPI_soc.c
 *
 *  \brief  AM437x device specific hardware attributes.
 *
 */

/*
 * Copyright (C) 2014-2015 Texas Instruments Incorporated - http://www.ti.com/
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * Neither the name of Texas Instruments Incorporated nor the names of
 * its contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#include <ti/drv/spi/SPI.h>
#include <ti/starterware/include/hw/am437x.h>
#include <ti/drv/spi/soc/QSPI_v1.h>
#include <ti/drv/spi/soc/SPI_v1.h>
#include <ti/csl/src/ip/mcspi/V0/hw_mcspi.h>
#include <ti/csl/src/ip/mcspi/V0/mcspi.h>

#define CSL_MCSPI_PER_CNT   (5U)
#define CSL_QSPI_PER_CNT    1U
#define CSL_SPI_PER_CNT     (CSL_MCSPI_PER_CNT + CSL_QSPI_PER_CNT)

/* SPI configuration structure */
SPI_v1_HWAttrs spiInitCfg[CSL_MCSPI_PER_CNT] =
{
    {
        SOC_MCSPI0_REG,
        97,
        91,
        SPI_PINMODE_4_PIN,
        MCSPI_DATA_LINE_COMM_MODE_1,
        MCSPI_CHANNEL_0,
        MCSPI_SINGLE_CH,
        MCSPI_CS_POL_LOW,
        true,
        48000000
    },
    {
        SOC_MCSPI1_REG,
        157,
        92,
        SPI_PINMODE_4_PIN,
        MCSPI_DATA_LINE_COMM_MODE_7,
        MCSPI_CHANNEL_0,
        MCSPI_SINGLE_CH,
        MCSPI_CS_POL_LOW,
		true,
        48000000
    },
    {
        SOC_MCSPI2_REG,
        158,
        38,
        SPI_PINMODE_4_PIN,
        MCSPI_DATA_LINE_COMM_MODE_7,
        MCSPI_CHANNEL_0,
        MCSPI_SINGLE_CH,
        MCSPI_CS_POL_LOW,
		true,
        48000000
    },
    {
        SOC_MCSPI3_REG,
        168,
        74,
        SPI_PINMODE_4_PIN,
        MCSPI_DATA_LINE_COMM_MODE_7,
        MCSPI_CHANNEL_0,
        MCSPI_SINGLE_CH,
        MCSPI_CS_POL_LOW,
		true,
        48000000
    },
    {
        SOC_MCSPI4_REG,
        169,
        74,
        SPI_PINMODE_4_PIN,
        MCSPI_DATA_LINE_COMM_MODE_7,
        MCSPI_CHANNEL_0,
        MCSPI_SINGLE_CH,
        MCSPI_CS_POL_LOW,
		true,
        48000000
    },
};


/* SPI objects */
SPI_v1_Object SpiObjects[CSL_MCSPI_PER_CNT];

/* SPI configuration structure */
QSPI_HwAttrs qspiInitCfg[CSL_QSPI_PER_CNT] =
{
    {
        SOC_QSPI_ADDRSP0_REG,  /* register baseAddr */
        SOC_QSPI_REG,          /* memMappedBaseAddr */
        48000000,              /*Input frequency */
        170,
        0,
        QSPI_OPER_MODE_MMAP,            /* operMode */
        0U,                            /* chipSelect */
        QSPI_CS_POL_ACTIVE_LOW,        /* csPol */
        QSPI_CLK_MODE_3,               /* frmFmt */
        QSPI_DATA_DELAY_0,             /* dataDelay */
        QSPI_RX_LINES_QUAD,          /* rxLines */
        false,
    }
};


/* QSPI objects */
QSPI_v1_Object QspiObjects[CSL_QSPI_PER_CNT];


/* SPI configuration structure */
const SPI_config_list SPI_config = {
    {
        &SPI_FxnTable_v1,
        &SpiObjects[0],
        &spiInitCfg[0]
    },
    {
        &SPI_FxnTable_v1,
        &SpiObjects[1],
        &spiInitCfg[1]
    },
    {
        &SPI_FxnTable_v1,
        &SpiObjects[2],
        &spiInitCfg[2]
    },
    {
        &SPI_FxnTable_v1,
        &SpiObjects[3],
        &spiInitCfg[3]
    },
    {
        &SPI_FxnTable_v1,
        &SpiObjects[4],
        &spiInitCfg[4]
    },
    {
        &QSPI_FxnTable_v1,
        &QspiObjects[0],
        &qspiInitCfg[0]
    },
    /* "pad to full predefined length of array" */
    {NULL, NULL, NULL}
};

/**
 * \brief  This API gets the SoC level of SPI intial configuration
 *
 * \param  index     SPI instance index.
 * \param  cfg       Pointer to SPI SOC initial config.
 *
 * \return 0 success: -1: error
 *
 */
int32_t SPI_socGetInitCfg(uint32_t index, SPI_v1_HWAttrs *cfg)
{
	int32_t ret = 0;

	if (index < CSL_MCSPI_PER_CNT)
    {
        *cfg = spiInitCfg[index];
    }
    else
    {
        ret = -1;
    }
    return ret;
}

/**
 * \brief  This API sets the SoC level of SPI intial configuration
 *
 * \param  index     SPI instance index.
 * \param  cfg       Pointer to SPI SOC initial config.
 *
 * \return           0 success: -1: error
 *
 */
int32_t SPI_socSetInitCfg(uint32_t index, const SPI_v1_HWAttrs *cfg)
{
	int32_t ret = 0;

	if (index < CSL_MCSPI_PER_CNT)
    {
        spiInitCfg[index] = *cfg;
    }
    else
    {
        ret = -1;
    }
    return ret;
}

