/*
 *  U-Boot command for OneNAND support
 *
 *  Copyright (C) 2005-2007 Samsung Electronics
 *  Kyungmin Park <kyungmin.park@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

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

#include <linux/mtd/compat.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>

#include <asm/io.h>

extern struct mtd_info onenand_mtd;
extern struct onenand_chip onenand_chip;

int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	int ret = 0;

	switch (argc) {
	case 0:
	case 1:
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;

	case 2:
		if (strncmp(argv[1], "open", 4) == 0) {
			onenand_init();
			return 0;
		}
		printf("%s\n", onenand_mtd.name);
		return 0;

	default:
		/* At least 4 args */
		if (strncmp(argv[1], "erase", 5) == 0) {
			struct erase_info instr = {
				.callback	= NULL,
			};
			ulong start, end;
			ulong block;
			char *endtail;

			if (strncmp(argv[2], "block", 5) == 0) {
				start = simple_strtoul(argv[3], NULL, 10);
				endtail = strchr(argv[3], '-');
				end = simple_strtoul(endtail + 1, NULL, 10);
			} else {
				start = simple_strtoul(argv[2], NULL, 10);
				end = simple_strtoul(argv[3], NULL, 10);

				start >>= onenand_chip.erase_shift;
				end >>= onenand_chip.erase_shift;
				/* Don't include the end block */
				end--;
			}

			if (!end || end < 0)
				end = start;

			printf("Erase block from %lu to %lu\n", start, end);

			for (block = start; block <= end; block++) {
				instr.addr = block << onenand_chip.erase_shift;
				instr.len = 1 << onenand_chip.erase_shift;
				ret = onenand_erase(&onenand_mtd, &instr);
				if (ret) {
					printf("erase failed %lu\n", block);
					break;
				}
			}

			return 0;
		}

		if (strncmp(argv[1], "read", 4) == 0) {
			ulong addr = simple_strtoul(argv[2], NULL, 16);
			ulong ofs = simple_strtoul(argv[3], NULL, 16);
			size_t len = simple_strtoul(argv[4], NULL, 16);
			int oob = strncmp(argv[1], "read.oob", 8) ? 0 : 1;
			struct mtd_oob_ops ops;

			ops.mode = MTD_OOB_PLACE;

			if (oob) {
				ops.len = 0;
				ops.datbuf = NULL;
				ops.ooblen = len;
				ops.oobbuf = (u_char *) addr;
			} else {
				ops.len = len;
				ops.datbuf = (u_char *) addr;
				ops.ooblen = 0;
				ops.oobbuf = NULL;
			}
			ops.retlen = ops.oobretlen = 0;

			onenand_mtd.read_oob(&onenand_mtd, ofs, &ops);
			printf("Done\n");

			return 0;
		}

		if (strncmp(argv[1], "write", 5) == 0) {
			ulong addr = simple_strtoul(argv[2], NULL, 16);
			ulong ofs = simple_strtoul(argv[3], NULL, 16);
			size_t len = simple_strtoul(argv[4], NULL, 16);
			size_t retlen = 0;

			onenand_write(&onenand_mtd, ofs, len, &retlen,
				      (u_char *) addr);
			printf("Done\n");

			return 0;
		}

		if (strncmp(argv[1], "block", 5) == 0) {
			ulong addr = simple_strtoul(argv[2], NULL, 16);
			ulong block = simple_strtoul(argv[3], NULL, 10);
			ulong page = simple_strtoul(argv[4], NULL, 10);
			size_t len = simple_strtol(argv[5], NULL, 10);
			ulong ofs;
			int oob = strncmp(argv[1], "block.oob", 9) ? 0 : 1;
			struct mtd_oob_ops ops;

			ops.mode = MTD_OOB_PLACE;


			ofs = block << onenand_chip.erase_shift;
			if (page)
				ofs += page << onenand_chip.page_shift;

			if (!len) {
				if (oob)
					ops.ooblen = 64;
				else
					ops.len = 512;
			}

			if (oob) {
				ops.datbuf = NULL;
				ops.oobbuf = (u_char *) addr;
			} else {
				ops.datbuf = (u_char *) addr;
				ops.oobbuf = NULL;
			}
			ops.retlen = ops.oobretlen = 0;

			onenand_read_oob(&onenand_mtd, ofs, &ops);
			return 0;
		}

		break;
	}

	return 0;
}

U_BOOT_CMD(
	onenand,	6,	1,	do_onenand,
	"onenand - OneNAND sub-system\n",
	"info   - show available OneNAND devices\n"
	"onenand read[.oob] addr ofs len - read data at ofs with len to addr\n"
	"onenand write addr ofs len - write data at ofs with len from addr\n"
	"onenand erase saddr eaddr - erase block start addr to end addr\n"
	"onenand block[.oob] addr block [page] [len] - "
		"read data with (block [, page]) to addr"
);
