/*****************************************************************************
* Copyright (c) 2005 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/

#ifndef	SDIO_API_H
#define	SDIO_API_H

#define NA_SDIO_R2_RESPONSE_LENGTH 16

/*ad*
 *
 * SDIO Driver card types
 * 
 * This list of card types specifies the capabilities of the card. The
 * capabilities include memory, IO, capacity, and combination (both
 * memory and IO). It does not include the type of IO capability, which
 * the application must determine.
 *
 * @external
 * @category BSP:Device_Drivers:SDIO
 * @since 7.3
 *
 * @param SDIO_CARD_TYPE_NONE	card type unknown or initialization failed.
 * @param SDIO_CARD_TYPE_HC_MEM	high capacity memory card
 * @param SDIO_CARD_TYPE_SC_MEM	standard capacity memory card
 * @param SDIO_CARD_TYPE_IO		IO card
 * @param SDIO_CARD_TYPE_HC_COMBO	high capacity memory card and IO card
 * @param SDIO_CARD_TYPE_SC_COMBO	standard capacity memory card and IO card
 *
 *ad*/

typedef enum {
	SDIO_CARD_TYPE_NONE,
	SDIO_CARD_TYPE_HC_MEM,
	SDIO_CARD_TYPE_SC_MEM,
	SDIO_CARD_TYPE_IO,
	SDIO_CARD_TYPE_HC_COMBO,
	SDIO_CARD_TYPE_SC_COMBO
} NaSdioCardType_t;

/*ad*
 *
 * SDIO Driver bus width values
 * 
 * @external
 * @category BSP:Device_Drivers:SDIO
 * @since 7.3
 *
 * @param NA_SDIO_BUS_WIDTH1	use a one bit bus for data transfer
 * @param NA_SDIO_BUS_WIDTH4	use a four bit bus for data transfer
 *
 *ad*/

typedef enum
{
	NA_SDIO_BUS_WIDTH1	= 0,
	NA_SDIO_BUS_WIDTH4	= 2
} NaSdioBusWidth_t;

typedef enum 
{
	PIC_27_TO_36_VOLTS = 1,
	PIC_LOW_VOLTAGE = 2
} NaSdioVoltageWindow_t ;

/*ad*
 *
 * SDIO Driver relative card address.
 *
 * This is the address a card advertises as the means for
 * the SD host to communicate with it.
 * 
 * @external
 * @category BSP:Device_Drivers:SDIO
 * @since 7.3
 *
 *ad*/

typedef unsigned int NaSdioRca_t;

/*ad*
 *
 * SDIO Driver response type values
 * 
 * @external
 * @category BSP:Device_Drivers:SDIO
 * @since 7.3
 *
 * @param NA_SDIO_R1	normal response command (48 bits)
 * @param NA_SDIO_R2	CID or CSD register value from card (136 bits)
 * @param NA_SDIO_R3	OCR register from card (48 bits)
 * @param NA_SDIO_R4	IO send operating condition response (SDIO only) (48 bits)
 * @param NA_SDIO_R5	CMD52 response (SDIO only) (48 bits)
 * @param NA_SDIO_R6	published RCA response from card (48 bits)
 * @param NA_SDIO_R7	card interface condition (48 bits)
 *
 *ad*/

typedef enum NaSdioResponse_s {
	NA_SDIO_R1 = 1,
	NA_SDIO_R2 = 2,
	NA_SDIO_R3 = 3,
	NA_SDIO_R4 = 4,
	NA_SDIO_R5 = 5,
	NA_SDIO_R6 = 6,
	NA_SDIO_R7 = 7
} NaSdioResponse_t;

/* big enough to hold big and small responses, and multiple of 4 */
#define NA_SDIO_RESPONSE_BUFFER_LENGTH	20

/* structure used by application to initiate a command.
 * It can be used to send a command, get a response, and send or
 * receive data. */

/*ad*
 *
 * SDIO Driver command structure.
 *
 * This filled-in structure is used by naSdioCardExecuteCommand() to
 * direct the SDI driver as to how to send a command to the card and
 * how to handle the response. The response is supplied back to the
 * caller in the structure.
 *
 * @external
 * @category BSP:Device_Drivers:SDIO
 * @since 7.3
 *
 * @param commandIndex type of command to send
 * @param commandArgument 32 bit data value to send in body of command
 * @param responseType type of response to expect
 * @param transmitDataLength if block transfer write, length of block, else 0
 * @param transmitData if block transfer write, pointer block, else NULL
 * @param receiveDataLength if block transfer read, length of block, else 0
 * @param receiveData if block transfer read, pointer to block, else NULL
 * @param timeout timeout value for DMA transfer
 * @param response byte array holding data in response
 *
 * @see @link naSdioCardExecuteCommand
 *
 *ad*/

typedef struct
{
	unsigned commandIndex;
	unsigned commandArgument;
	NaSdioResponse_t responseType;
	unsigned transmitDataLength;
	unsigned char *transmitData;
	unsigned receiveDataLength;
	unsigned char *receiveData;
	unsigned timeout;
	unsigned char response[NA_SDIO_RESPONSE_BUFFER_LENGTH];
} NaSdioCommand_t;

#define	NA_SDIO_APP_SPECIFIC 0x1000

#define	NA_SDIO_CMD0	0
#define	NA_SDIO_CMD2	2
#define	NA_SDIO_CMD3	3
#define	NA_SDIO_CMD4	4
#define	NA_SDIO_CMD5	5
#define	NA_SDIO_CMD6	6
#define	NA_SDIO_CMD7	7
#define	NA_SDIO_CMD8	8
#define	NA_SDIO_CMD9	9
#define	NA_SDIO_CMD10	10
#define	NA_SDIO_CMD12	12
#define	NA_SDIO_CMD13	13
#define	NA_SDIO_CMD15	15
#define	NA_SDIO_CMD16	16
#define	NA_SDIO_CMD17	17
#define	NA_SDIO_CMD18	18
#define	NA_SDIO_CMD24	24
#define	NA_SDIO_CMD25	25
#define	NA_SDIO_CMD27	27
#define	NA_SDIO_CMD28	28
#define	NA_SDIO_CMD29	29
#define	NA_SDIO_CMD30	30
#define	NA_SDIO_CMD32	32
#define	NA_SDIO_CMD33	33
#define	NA_SDIO_CMD38	38
#define	NA_SDIO_CMD42	42
#define	NA_SDIO_CMD52	52
#define	NA_SDIO_CMD53	53
#define	NA_SDIO_CMD55	55
#define	NA_SDIO_CMD56	56
#define	NA_SDIO_ACMD6	(NA_SDIO_APP_SPECIFIC | 6)
#define	NA_SDIO_ACMD13	(NA_SDIO_APP_SPECIFIC | 13)
#define	NA_SDIO_ACMD22	(NA_SDIO_APP_SPECIFIC | 22)
#define	NA_SDIO_ACMD23	(NA_SDIO_APP_SPECIFIC | 23)
#define	NA_SDIO_ACMD41	(NA_SDIO_APP_SPECIFIC | 41)
#define	NA_SDIO_ACMD42	(NA_SDIO_APP_SPECIFIC | 42)
#define	NA_SDIO_ACMD51	(NA_SDIO_APP_SPECIFIC | 51)
#define	NA_SDIO_ACMD56	(NA_SDIO_APP_SPECIFIC | 56)

/*
 * Command <- response pairing:
 * CMD2  <- RSP2 w/ CID (128)
 * CMD10 <- RSP2 w/ CID (128)
 * CMD9  <- RSP2 w/ CSD (128)
 * ACMD41<- RSP3 w/ OCR (32)
 * CMD3  <- RSP6 w/ RCA (16) and CSR bits 23, 22, 19, 12:9
 * CMD8  <- RSP7 w/ voltage range and echoed check pattern
 * ACMD51 <- SCR (64)
 * ACMD13 <- SSR (512) on data bus (card state tran_state)
 *
 * IO card only command <- response pairs
 * CMD52 <- R5
 * CMD5 <- R4
 *
 * CMD27 modifies programmable parts of CSD
 */

/* these typedefs lay out the complete response content */

typedef struct sdioRspR1 {
	unsigned char reserve;	/* mask 0x3f */
	unsigned char reservestatus[4];
	unsigned char crc;	/* mask 0xfe */
} SdioRspR1;

typedef struct sdioRspR2 {
	unsigned char reserve;	/* mask 0x3f */
	unsigned char cid_csd[NA_SDIO_R2_RESPONSE_LENGTH];	/* mask last bit */
} SdioRspR2;

typedef struct sdioRspR3 {
	unsigned char reserve;	/* mask 0x3f */
	unsigned char ocr[4];
	unsigned char crc;	/* mask 0xfe */
} SdioRspR3;

typedef struct sdioRspR6 {
	unsigned char cmdNdx;	/* mask 0x3f */
	unsigned char rca[2];
	unsigned char status[2];	/* table 4.36 Phys Layer */
	unsigned char crc;	/* mask 0xfe */
} SdioRspR6;

typedef struct sdioRspR7 {
	unsigned char cmdNdx;	/* mask 0x3f */
	unsigned char rsv1;
	unsigned char rsv2;
	unsigned char voltage;	/* mask 0xf */
	unsigned char echo_chk;
	unsigned char crc;		/* mask 0xfe */
} SdioRspR7;

/* These two are for IO cards only */
typedef struct sdioRspR5 {
	unsigned char cmdNdx;	/* mask 0x3f (should be 0x34) */
	unsigned char stuff[2];
	unsigned char flags;
	unsigned char data;
	unsigned char crc;		/* mask 0xfe */
} SdioRspR5;

typedef struct sdioRspR4 {
	unsigned char cmdNdx;	/* mask 0x3f */
	unsigned char c_io_mem;	/* c:1, num IO funs:3, mem present:1, stuff:3 */
	unsigned char io_ocr[3];
	unsigned char reserve;
} SdioRspR4;

typedef union spio_rsp_msg {
	unsigned char	data[6];
	SdioRspR1	R1;
	SdioRspR2	R2;
	SdioRspR3	R3;
	SdioRspR6	R6;
	SdioRspR7	R7;
	SdioRspR5	R5;
	SdioRspR4	R4;
} SPIO_RSP_MSG;

typedef struct
{
	unsigned cardStatus;
} NaSdioR1Response_t;

typedef struct
{
	unsigned char cidCsd[NA_SDIO_R2_RESPONSE_LENGTH];
} NaSdioR2Response_t;

typedef struct
{
	unsigned ocr;
} NaSdioR3Response_t;

typedef struct
{
	unsigned numberOfIoFunctions;
	unsigned isMemoryPresent;
	unsigned ioOcr;
} NaSdioR4Response_t;

typedef struct
{
	unsigned responseFlags;
	unsigned rwData;
} NaSdioR5Response_t;

typedef struct
{
	unsigned rca;
	unsigned cardStatus;
} NaSdioR6Response_t;

typedef struct
{
	NaSdioVoltageWindow_t voltageAccepted;
	unsigned char echoPattern;
} NaSdioR7Response_t;

typedef union
{
	NaSdioR1Response_t r1;
	NaSdioR2Response_t r2;
	NaSdioR3Response_t r3;
	NaSdioR4Response_t r4;
	NaSdioR5Response_t r5;
	NaSdioR6Response_t r6;
	NaSdioR7Response_t r7;
} NaSdioCookedResponse_t;

typedef struct spioCmdFmt {
	unsigned char cmdNdx;	/* 0x40 | cmd index */
	unsigned char arg[4];
	unsigned char crc;		/* or with 1 */
} SdioCmdFmt;

/* IO CMD52 defines */
#define	SDIO_CMD52_WRT_FLG	0x80000000
#define	SDIO_CMD52_RW_SHFT	27
#define	SDIO_CMD52_FCN_MSK	7
#define	SDIO_CMD52_FCN_SHFT	28
#define	SDIO_CMD52_ADDR_SHFT	9
#define	SDIO_CMD52_DAT_MSK	0xff

/* API function prototypes */

typedef void (*NaSdioIsrCallback_t)(unsigned interface, void *context);

typedef void (*NaSdioSemaphoreFn_t)(unsigned interface, void *context);

NaStatus naSdioCardExecuteCommand(unsigned interface, NaSdioCommand_t *command);

NaStatus naSdioCardInitialize(unsigned interface, NaSdioCardType_t *type, 
             NaSdioBusWidth_t *width, NaSdioRca_t *sdRca, NaSdioRca_t *sdioRca);

NaStatus naSdioCardParseResponse(unsigned commandIndex,
			NaSdioResponse_t responseType, unsigned char *rawResponse, 
			NaSdioCookedResponse_t *cookedResponse);

NaStatus naSdioInitialize(unsigned interface);

NaStatus naSdioInterfaceBusSetWidth(unsigned interface, NaSdioBusWidth_t width);

NaStatus naSdioInterfaceGetCount(unsigned *count);
        
NaStatus naSdioInterfaceRestart(unsigned interface);

NaStatus naSdioInterruptEnable(unsigned interface);

NaStatus naSdioIsrInstall(unsigned interface, NaSdioIsrCallback_t callback, void *context);

NaStatus naSdioIsrUninstall(unsigned interface, NaSdioIsrCallback_t callback, void *context);

NaStatus naSdioSetCrcSupport(unsigned interface, unsigned calculateCrcOnReceiveData);

NaStatus NaSdioGetStatus(unsigned char *pBuf, unsigned int len);

NaStatus naSdioQueryCSD(unsigned interface, unsigned char *pCsd);

NaStatus naSdioSetDriverBusWidth(unsigned interface, unsigned width);

#endif	/* SDIO_API_H */

