#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/delay.h>

#include "load_fpga.h"
#include "bitstream.h"

static void init_fpga(void);
static int write_bitstream(void);

static void init_fpga()
{

	printk(KERN_ALERT "Initialing FPGA...\n");
//------------------testing-------------------------//
//	outb(0xAA, TS7XXX_IOMEM + 0x9D);
//------------------------------------------------//

        outb(0x02, TS7XXX_IOMEM + CONFIG_REG);
        udelay(350);
        outb(0x16, TS7XXX_IOMEM + CONTROL_REG);
        udelay(350);
        outb(0x1E, TS7XXX_IOMEM + CONTROL_REG);
        udelay(350);
        outb(0x16, TS7XXX_IOMEM + CONTROL_REG);
        udelay(350);

        outb(0xFF, TS7XXX_IOMEM + DATA_REG);
        outb(0xFF, TS7XXX_IOMEM + DATA_REG);
        outb(0xFF, TS7XXX_IOMEM + DATA_REG);
        outb(0xFF, TS7XXX_IOMEM + DATA_REG);

}

static int write_bitstream(void)
{
        unsigned char in_meta = TRUE;
	int return_val = 0;
	unsigned long i = 0;

	for(i = 0; i < FILE_SIZE; i++)
	{
		if(in_meta == TRUE)
		{
			if(bitstream[i] == 0xaa &&
				bitstream[i+1] == 0x99 &&
				bitstream[i+2] == 0x55 &&
				bitstream[i+3] == 0x66)
			{
				in_meta = FALSE;
				outb(REVERSEBITS(bitstream[i]), 
					TS7XXX_IOMEM + DATA_REG);
			}

		} else //found magic number
		{
			outb(REVERSEBITS(bitstream[i]), 
				TS7XXX_IOMEM + DATA_REG);

		}
	}

		//Ensure DONE bit is set
		if((inb(TS7XXX_IOMEM + CONFIG_REG) & DONE_MSK) != DONE_MSK)
			return_val = -1;

	outb(0x1, TS7XXX_IOMEM + CONFIG_REG);

	return return_val;
}

static int init_module(void)
{
	init_fpga();
	return write_bitstream();
}


static void cleanup_module()
{

}

MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_SUPPORTED_DEVICE("TS-7KV");
