#include <common.h>
#include <command.h>
#include <errno.h>
#include <fs.h>

#ifdef CONFIG_COMCERTO_NAND_ERASE_FBB
#include <getopt.h>
#include <linux/stat.h>
#include <fcntl.h>
#include <ioctl.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/mtd-abi.h>
#endif /* CONFIG_COMCERTO_NAND_ERASE_FBB */

#define NANDDEVNAME "nand0"

#ifdef CONFIG_COMCERTO_NAND_ERASE_FBB
extern int erase_old_nand_fmt(struct mtd_info *mtd, u8 bb_old_layout);

static int do_erase_old_nand_fmt(struct command *cmdtp, int argc, char *argv[])
{
	struct mtd_info_user user;
	int fd, ret = 0;
	char *filename = NULL;
	struct stat s;
	unsigned long start = 0, size = ~0;

        if (argc != 2) {
                printf ("Usage:\n%s\n", cmdtp->usage);
		return COMMAND_ERROR_USAGE;
        }

	filename = argv[1];

	if (stat(filename, &s)) {
		printf("stat %s: %s\n", filename, errno_str());
		return 1;
	}

	size = s.st_size;

	if (!filename) {
		printf("missing filename\n");
		return 1;
	}

	fd = open(filename, O_RDWR);
	if (fd < 0) {
		printf("open %s: %s", filename, errno_str());
		return 1;
	}

	ret = ioctl(fd, MEMGETINFO, &user);

	/* Change ecc layout to HW BCH-8 */
	erase_old_nand_fmt(user.mtd, 0);

	if (erase(fd, size, start)) {
		perror("erase");
		ret = 1;
	}

	/* Change ecc layout to SW BCH */
	erase_old_nand_fmt(user.mtd, 1);

	if (erase(fd, size, start)) {
		perror("erase");
		ret = 1;
	}

	printf("\t\t\t\t!!Erasure of old NAND format completed!!\n");
	printf("\t\t\t\t!!!! Please reboot the system now !!!!\n");

	return 0;
}

static const __maybe_unused char cmd_erase_old_nand_fmt_help[] =
"Usage: erase_old_nand_fmt <mtddev>\n"
"Example: erase_old_nand_fmt /dev/nand0 \n"
"Erase old NAND format on <mtddev>\n";


BAREBOX_CMD_START(erase_old_nand_fmt)
        .cmd            = do_erase_old_nand_fmt,
        .usage          = "Erase old NAND format",
	BAREBOX_CMD_HELP(cmd_erase_old_nand_fmt_help)
BAREBOX_CMD_END

#endif /* CONFIG_COMCERTO_NAND_ERASE_FBB */

#ifdef CONFIG_NAND_WRITE
int erase_nand(ulong offset, ulong count)
{
        struct cdev *cdev;
        int err;

        cdev = cdev_by_name(NANDDEVNAME);

        printf("Erasing from offset 0x%lx count 0x%lx ...\n", offset, count);
        err = cdev->ops->erase(cdev, count, offset);
        if (err) {
		perror("erase failed\n");
                perror("erase");
                return -1;
        } else {
		printf("Erase completed\n");
	}

        printf("Done\n");

        return 0;
}

EXPORT_SYMBOL(erase_nand);

static int do_erase_nand(struct command *cmdtp, int argc, char *argv[])
{
        ulong offset, count;

        if (argc != 3) {
                printf ("Usage:\n%s\n", cmdtp->usage);
                return 1;
        }


        offset = simple_strtoul(argv[1], NULL, 16);

        count = simple_strtoul(argv[2], NULL, 16);

        if (count == 0) {
                puts ("Zero length ???\n");
                return 1;
        }

	if(erase_nand(offset, count) < 0)
	{
		printf("ERROR: NAND Erase FAIL !!\n");
		return -1;
	}

	return 0;
}

static const __maybe_unused char cmd_nand_erase_help[] =
"Usage: erase_nand  <nand offset> <count>\n"
"Erase memory at nand offset\n";

BAREBOX_CMD_START(erase_nand)
        .cmd            = do_erase_nand,
        .usage          = "Erase the NAND",
	BAREBOX_CMD_HELP(cmd_nand_erase_help)
BAREBOX_CMD_END

int update_nand(ulong src, ulong offset, ulong count)
{
        struct cdev *cdev;
        int err;

        cdev = cdev_by_name(NANDDEVNAME);

        printf("Erasing from offset 0x%lx count 0x%lx ...\n", offset, count);
        err = cdev->ops->erase(cdev, count, offset);
        if (err) {
		perror("erase failed\n");
                perror("erase");
                return -1;
        } else {
		printf("Erase completed\n");
	}

#if 1
        printf("Writing ...\n");
        err = cdev->ops->write(cdev, (char *)src, count, offset, 0);
        if(err == -1)
        {
		perror("write failed\n");
                perror("write");
                return -1;
        }
#endif
        printf("Done\n");

        return 0;
}

EXPORT_SYMBOL(update_nand);

static int do_update_nand(struct command *cmdtp, int argc, char *argv[])
{
        ulong   src, offset, count;

        if (argc != 4) {
                printf ("Usage:\n%s\n", cmdtp->usage);
                return 1;
        }

        src = simple_strtoul(argv[1], NULL, 16);

        offset = simple_strtoul(argv[2], NULL, 16);

        count = simple_strtoul(argv[3], NULL, 16);

        if (count == 0) {
                puts ("Zero length ???\n");
                return 1;
        }

	if(update_nand(src, offset, count) < 0)
	{
		printf("ERROR: NAND Update FAIL !!\n");
		return -1;
	}

	return 0;
}

static const __maybe_unused char cmd_nand_help[] =
"Usage: update_nand  <ddr src> <nand offset> <count>\n"
"Copy memory at <src> of <count> bytes to <dst>\n";


BAREBOX_CMD_START(update_nand)
        .cmd            = do_update_nand,
        .usage          = "Flash the NAND",
	BAREBOX_CMD_HELP(cmd_nand_help)
BAREBOX_CMD_END
#endif  /* CONFIG_NAND_WRITE */

int read_nand(ulong src, ulong offset, ulong count)
{
        struct cdev *cdev;
        int err;

        cdev = cdev_by_name(NANDDEVNAME);

        printf("Reading ...\n");
        err = cdev->ops->read(cdev, (char *)src, count, offset, 0);
        if(err < 0)
        {
                perror("read failed %d\n");
                return -1;
        }

        printf("Done...Bytes read 0x%x\n", err);

        return 0;
}

EXPORT_SYMBOL(read_nand);


static int do_read_nand(struct command *cmdtp, int argc, char *argv[])
{
        ulong   src, offset, count;

        if (argc != 4) {
                printf ("Usage:\n%s\n", cmdtp->usage);
                return 1;
        }

        src = simple_strtoul(argv[1], NULL, 16);

        offset = simple_strtoul(argv[2], NULL, 16);

        count = simple_strtoul(argv[3], NULL, 16);

        if (count == 0) {
                puts ("Zero length ???\n");
                return 1;
        }

        if(read_nand(src, offset, count) < 0)
        {
                printf("ERROR: NAND Read FAIL !!\n");
                return -1;
        }

        return 0;
}

static const __maybe_unused char cmd_nand_read_help[] =
"Usage: read_nand  <ddr src> <nand offset> <count>\n"
"Read NAND to <src> of <count> bytes from <offset>\n";


BAREBOX_CMD_START(read_nand)
        .cmd            = do_read_nand,
        .usage          = "Read the NAND",
        BAREBOX_CMD_HELP(cmd_nand_read_help)
BAREBOX_CMD_END

