
#ifndef __DRIVER_H__
#define __DRIVER_H__

#include "linux/types.h"
#include "com_gpio.h"
#include "stm32f429xx.h"

#define MAJOR_PLATFORM	100
#define MAJOR_I2C	101
#define MAJOR_FMC	102
#define MAJOR_GPIO	103
#define MAJOR_SPI	104
#define MAJOR_ADC	105
#define MAJOR_GPIO_I2C 	106
#define MAJOR_CRYPTO 	107
#define MAJOR_IWDG	108
#define MAJOR_IFLASH 109

#define IOCTL_MAGIC	'x' 
#define GENERATE_CMD(__MAGIC__, __MAJOR__, __CMD__)	\
	((0x3<<30) | (__MAJOR__<<16) | (__MAGIC__<<8) | __CMD__)


/* I2C command */
#define SET_I2C_SPEED			GENERATE_CMD(IOCTL_MAGIC, MAJOR_I2C, 0)
#define GET_I2C_SPEED			GENERATE_CMD(IOCTL_MAGIC, MAJOR_I2C, 1)
#define SET_I2C_ADDR			GENERATE_CMD(IOCTL_MAGIC, MAJOR_I2C, 2)
#define GET_I2C_ADDR			GENERATE_CMD(IOCTL_MAGIC, MAJOR_I2C, 3)
#define I2C_MASTER_TRANSFER		GENERATE_CMD(IOCTL_MAGIC, MAJOR_I2C, 4)
#define I2C_MASTER_RECEIVE		GENERATE_CMD(IOCTL_MAGIC, MAJOR_I2C, 5)
#define I2C_SLAVE_RECEIVE_IT	GENERATE_CMD(IOCTL_MAGIC, MAJOR_I2C, 6)
#define I2C_MASTER_TRANSFER_RECEIVE GENERATE_CMD(IOCTL_MAGIC, MAJOR_I2C, 7)
/* FMC command */
#define WRITE_BYTE				GENERATE_CMD(IOCTL_MAGIC, MAJOR_FMC, 0)
#define READ_BYTE				GENERATE_CMD(IOCTL_MAGIC, MAJOR_FMC, 1)
#define WRITE_SHORT				GENERATE_CMD(IOCTL_MAGIC, MAJOR_FMC, 2)
#define READ_SHORT				GENERATE_CMD(IOCTL_MAGIC, MAJOR_FMC, 3)
#define WRITE_WORD				GENERATE_CMD(IOCTL_MAGIC, MAJOR_FMC, 4)
#define READ_WORD				GENERATE_CMD(IOCTL_MAGIC, MAJOR_FMC, 5)
#define BUS_8BIT				GENERATE_CMD(IOCTL_MAGIC, MAJOR_FMC, 6)
#define BUS_16BIT				GENERATE_CMD(IOCTL_MAGIC, MAJOR_FMC, 7)

/* SPI command */
#define SPI_MASTER_TRANSFER		GENERATE_CMD(IOCTL_MAGIC, MAJOR_SPI, 0)
#define SPI_MASTER_RECEIVE		GENERATE_CMD(IOCTL_MAGIC, MAJOR_SPI, 1)

/* GPIO command */
#define GPIO_INIT				GENERATE_CMD(IOCTL_MAGIC, MAJOR_GPIO, 0)
#define GPIO_WRITE_PIN			GENERATE_CMD(IOCTL_MAGIC, MAJOR_GPIO, 1)
#define GPIO_READ_PIN			GENERATE_CMD(IOCTL_MAGIC, MAJOR_GPIO, 2)
#define GPIO_SET_DIR 			GENERATE_CMD(IOCTL_MAGIC, MAJOR_GPIO, 3)

/* ADC command */
#define ADC_GET_RESULT			GENERATE_CMD(IOCTL_MAGIC, MAJOR_ADC, 0)


/* GPIO I2C command */
#define GPIO_I2C_MASTER_TRANSFER		GENERATE_CMD(IOCTL_MAGIC, MAJOR_GPIO_I2C, 0)
#define GPIO_I2C_MASTER_RECEIVE			GENERATE_CMD(IOCTL_MAGIC, MAJOR_GPIO_I2C, 1)
#define	GPIO_I2C_MASTER_TRANSFER_RECV	GENERATE_CMD(IOCTL_MAGIC, MAJOR_GPIO_I2C, 2)	

/* Platform command */
#define SET_PRIORITY_GROUP 				GENERATE_CMD(IOCTL_MAGIC, MAJOR_PLATFORM, 0)
#define GET_PRIORITY_GROUP 				GENERATE_CMD(IOCTL_MAGIC, MAJOR_PLATFORM, 1)
#define RESET_MCU 						GENERATE_CMD(IOCTL_MAGIC, MAJOR_PLATFORM, 2)
#define GET_32BIT_RANDOM 				GENERATE_CMD(IOCTL_MAGIC, MAJOR_PLATFORM, 3)

/* Crypto AT88SC0104C */
#define CRYPTO_WAIT_CLOCK				GENERATE_CMD(IOCTL_MAGIC, MAJOR_CRYPTO, 0)	
#define CRYPTO_SEND_COMMAND				GENERATE_CMD(IOCTL_MAGIC, MAJOR_CRYPTO, 1)	
#define CRYPTO_RECEIVE_DATA				GENERATE_CMD(IOCTL_MAGIC, MAJOR_CRYPTO, 2)	
#define CRYPTO_SEND_DATA				GENERATE_CMD(IOCTL_MAGIC, MAJOR_CRYPTO, 3)	
#define CRYPTO_POWER_ON					GENERATE_CMD(IOCTL_MAGIC, MAJOR_CRYPTO, 4)	
#define CRYPTO_POWER_OFF				GENERATE_CMD(IOCTL_MAGIC, MAJOR_CRYPTO, 5)		
#define CRYPTO_SEND_CMD_BYTE			GENERATE_CMD(IOCTL_MAGIC, MAJOR_CRYPTO, 6)		

/* IWDG */
#define FEED_WATCHDOG					GENERATE_CMD(IOCTL_MAGIC, MAJOR_IWDG, 0)		
#define START_IWATCHDOG					GENERATE_CMD(IOCTL_MAGIC, MAJOR_IWDG, 1)		
#define STOP_IWATCHDOG					GENERATE_CMD(IOCTL_MAGIC, MAJOR_IWDG, 2)	

/* Internal flash */
#define IFLASH_UNLOCK					GENERATE_CMD(IOCTL_MAGIC, MAJOR_IFLASH, 0)		
#define IFLASH_LOCK 					GENERATE_CMD(IOCTL_MAGIC, MAJOR_IFLASH, 1)		
#define IFLASH_ERASESECTOR				GENERATE_CMD(IOCTL_MAGIC, MAJOR_IFLASH, 2)		
#define IFLASH_WRITEWORD				GENERATE_CMD(IOCTL_MAGIC, MAJOR_IFLASH, 3)		
#define IFLASH_WRITEHALFWORD			GENERATE_CMD(IOCTL_MAGIC, MAJOR_IFLASH, 4)		
#define IFLASH_WRITEBYTE				GENERATE_CMD(IOCTL_MAGIC, MAJOR_IFLASH, 5)			
#define IFLASH_WRITE_BYTES				GENERATE_CMD(IOCTL_MAGIC, MAJOR_IFLASH, 6)	

typedef struct {
	uint32_t address;
	uint16_t length;
	uint8_t  data[1024];
} fmc_cpld_t;

typedef struct {
	GPIO_TypeDef* 		GPIOx;
	uint16_t 			GPIO_pin;
	uint8_t 			Direct;
	GPIO_PinState		Data;
	GPIO_InitTypeDef	GPIO_Init;
} gpio_t;

typedef struct {
	uint8_t	 DevAddress;		/* 8 bit */
	uint8_t	 WriteLen;
	uint8_t	 ReadLen;
	uint8_t  Buf[256];
	

} gpio_i2c_t;


typedef struct {
	uint32_t ClockSpeed;		/*!< Specifies the clock frequency.
								 This parameter must be set to a value lower than 400kHz */
	uint32_t OwnAddress1;		/*!< Specifies the first device own address.
								 This parameter must be a 7-bit address. */
	uint8_t	 DevAddress;		/* 8 bit */
	uint8_t	 WriteLen;
	uint8_t  ReadLen;
	uint8_t  Buf[256];
	

} i2c_arg_t;

typedef struct {
	uint8_t buf[300];
	uint32_t Size;
} spi_arg_t;

typedef struct {
	uint8_t	 channel;
	uint16_t value[10];
} adc_arg_t;

typedef struct {
	uint32_t	priority_group;
	uint32_t 	random_32bit;
} platform_arg_t;

typedef struct {
	uint8_t  size;
	uint8_t  data[256];
	uint8_t  loop;
} crypto_t;

typedef struct {
	uint8_t  sector;
	uint32_t address;
	uint32_t len;
	uint8_t  data[256];
} iflash_t;

#endif /* __DRIVER_H__ */
