/*
 * MTD chip driver for pre-CFI Sharp flash chips
 *
 * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
 *           2000,2001 Lineo, Inc.
 *
 * $Id: sharp.c,v 1.17 2005/11/29 14:28:28 gleixner Exp $
 *
 * Devices supported:
 *   LH28F016SCT Symmetrical block flash memory, 2Mx8
 *   LH28F008SCT Symmetrical block flash memory, 1Mx8
 *
 * Documentation:
 *   http://www.sharpmeg.com/datasheets/memic/flashcmp/
 *   http://www.sharpmeg.com/datasheets/memic/flashcmp/01symf/16m/016sctl9.pdf
 *   016sctl9.pdf
 *
 * Limitations:
 *   This driver only supports 4x1 arrangement of chips.
 *   Not tested on anything but PowerPC.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/cfi.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/slab.h>

#define CMD_RESET		0xffffffff
#define CMD_READ_ID		0x90909090
#define CMD_READ_STATUS		0x70707070
#define CMD_CLEAR_STATUS	0x50505050
#define CMD_BLOCK_ERASE_1	0x20202020
#define CMD_BLOCK_ERASE_2	0xd0d0d0d0
#define CMD_BYTE_WRITE		0x40404040
#define CMD_SUSPEND		0xb0b0b0b0
#define CMD_RESUME		0xd0d0d0d0
#define CMD_SET_BLOCK_LOCK_1	0x60606060
#define CMD_SET_BLOCK_LOCK_2	0x01010101
#define CMD_SET_MASTER_LOCK_1	0x60606060
#define CMD_SET_MASTER_LOCK_2	0xf1f1f1f1
#define CMD_CLEAR_BLOCK_LOCKS_1	0x60606060
#define CMD_CLEAR_BLOCK_LOCKS_2	0xd0d0d0d0

#define SR_READY		0x80808080 // 1 = ready
#define SR_ERASE_SUSPEND	0x40404040 // 1 = block erase suspended
#define SR_ERROR_ERASE		0x20202020 // 1 = error in block erase or clear lock bits
#define SR_ERROR_WRITE		0x10101010 // 1 = error in byte write or set lock bit
#define	SR_VPP			0x08080808 // 1 = Vpp is low
#define SR_WRITE_SUSPEND	0x04040404 // 1 = byte write suspended
#define SR_PROTECT		0x02020202 // 1 = lock bit set
#define SR_RESERVED		0x01010101

#define SR_ERRORS (SR_ERROR_ERASE|SR_ERROR_WRITE|SR_VPP|SR_PROTECT)

/* Configuration options */

#undef AUTOUNLOCK  /* automatically unlocks blocks before erasing */

static struct mtd_info *sharp_probe(struct map_info *);

static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);

static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
	size_t *retlen, u_char *buf);
static int sharp_write(struct mtd_info *mtd, loff_t from, size_t len,
	size_t *retlen, const u_char *buf);
static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr);
static void sharp_sync(struct mtd_info *mtd);
static int sharp_suspend(struct mtd_info *mtd);
static void sharp_resume(struct mtd_info *mtd);
static void sharp_destroy(struct mtd_info *mtd);

static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
	unsigned long adr, __u32 datum);
static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
	unsigned long adr);
#ifdef AUTOUNLOCK
static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
	unsigned long adr);
#endif


struct sharp_info{
	struct flchip *chip;
	int bogus;
	int chipshift;
	int numchips;
	struct flchip chips[1];
};

static void sharp_destroy(struct mtd_info *mtd);

static struct mtd_chip_driver sharp_chipdrv = {
	.probe		= sharp_probe,
	.destroy	= sharp_destroy,
	.name		= "sharp",
	.module		= THIS_MODULE
};


static struct mtd_info *sharp_probe(struct map_info *map)
{
	struct mtd_info *mtd = NULL;
	struct sharp_info *sharp = NULL;
	int width;

	mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);
	if(!mtd)
		return NULL;

	sharp = kzalloc(sizeof(*sharp), GFP_KERNEL);
	if(!sharp) {
		kfree(mtd);
		return NULL;
	}

	width = sharp_probe_map(map,mtd);
	if(!width){
		kfree(mtd);
		kfree(sharp);
		return NULL;
	}

	mtd->priv = map;
	mtd->type = MTD_NORFLASH;
	mtd->erase = sharp_erase;
	mtd->read = sharp_read;
	mtd->write = sharp_write;
	mtd->sync = sharp_sync;
	mtd->suspend = sharp_suspend;
	mtd->resume = sharp_resume;
	mtd->flags = MTD_CAP_NORFLASH;
	mtd->writesize = 1;
	mtd->name = map->name;

	sharp->chipshift = 23;
	sharp->numchips = 1;
	sharp->chips[0].start = 0;
	sharp->chips[0].state = FL_READY;
	sharp->chips[0].mutex = &sharp->chips[0]._spinlock;
	sharp->chips[0].word_write_time = 0;
	init_waitqueue_head(&sharp->chips[0].wq);
	spin_lock_init(&sharp->chips[0]._spinlock);

	map->fldrv = &sharp_chipdrv;
	map->fldrv_priv = sharp;

	__module_get(THIS_MODULE);
	return mtd;
}

static inline void sharp_send_cmd(struct map_info *map, unsigned long cmd, unsigned long adr)
{
	map_word map_cmd;
	map_cmd.x[0] = cmd;
	map_write(map, map_cmd, adr);
}

static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
{
	map_word tmp, read0, read4;
	unsigned long base = 0;
	int width = 4;

	tmp = map_read(map, base+0);

	sharp_send_cmd(map, CMD_READ_ID, base+0);

	read0 = map_read(map, base+0);
	read4 = map_read(map, base+4);
	if(read0.x[0] == 0x89898989){
		printk("Looks like sharp flash\n");
		switch(read4.x[0]){
		case 0xaaaaaaaa:
		case 0xa0a0a0a0:
			/* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
			/* a0 - LH28F016SCT-Z4  2Mx8, 32 64k blocks*/
			mtd->erasesize = 0x10000 * width;
			mtd->size = 0x200000 * width;
			return width;
		case 0xa6a6a6a6:
			/* a6 - LH28F008SCT-L12 1Mx8, 16 64k blocks*/
			/* a6 - LH28F008SCR-L85 1Mx8, 16 64k blocks*/
			mtd->erasesize = 0x10000 * width;
			mtd->size = 0x100000 * width;
			return width;
#if 0
		case 0x00000000: /* unknown */
			/* XX - LH28F004SCT 512kx8, 8 64k blocks*/
			mtd->erasesize = 0x10000 * width;
			mtd->size = 0x80000 * width;
			return width;
#endif
		default:
			printk("Sort-of looks like sharp flash, 0x%08lx 0x%08lx\n",
				read0.x[0], read4.x[0]);
		}
	}else if((map_read(map, base+0).x[0] == CMD_READ_ID)){
		/* RAM, probably */
		printk("Looks like RAM\n");
		map_write(map, tmp, base+0);
	}else{
		printk("Doesn't look like sharp flash, 0x%08lx 0x%08lx\n",
			read0.x[0], read4.x[0]);
	}

	return 0;
}

/* This function returns with the chip->mutex lock held. */
static int sharp_wait(struct map_info *map, struct flchip *chip)
{
	int i;
	map_word status;
	unsigned long timeo = jiffies + HZ;
	DECLARE_WAITQUEUE(wait, current);
	int adr = 0;

retry:
	spin_lock_bh(chip->mutex);

	switch(chip->state){
	case FL_READY:
		sharp_send_cmd(map, CMD_READ_STATUS, adr);
		chip->state = FL_STATUS;
	case FL_STATUS:
		for(i=0;i<100;i++){
			status = map_read(map, adr);
			if((status.x[0] & SR_READY)==SR_READY)
				break;
			udelay(1);
		}
		break;
	default:
		printk("Waiting for chip\n");

		set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&chip->wq, &wait);

		spin_unlock_bh(chip->mutex);

		schedule();
		remove_wait_queue(&chip->wq, &wait);

		if(signal_pending(current))
			return -EINTR;

		timeo = jiffies + HZ;

		goto retry;
	}

	sharp_send_cmd(map, CMD_RESET, adr);

	chip->state = FL_READY;

	return 0;
}

static void sharp_release(struct flchip *chip)
{
	wake_up(&chip->wq);
	spin_unlock_bh(chip->mutex);
}

static int sharp_read(struct mtd_info *mtd, loff_t from, size_t len,
	size_t *retlen, u_char *buf)
{
	struct map_info *map = mtd->priv;
	struct sharp_info *sharp = map->fldrv_priv;
	int chipnum;
	int ret = 0;
	int ofs = 0;

	chipnum = (from >> sharp->chipshift);
	ofs = from & ((1 << sharp->chipshift)-1);

	*retlen = 0;

	while(len){
		unsigned long thislen;

		if(chipnum>=sharp->numchips)
			break;

		thislen = len;
		if(ofs+thislen >= (1<<sharp->chipshift))
			thislen = (1<<sharp->chipshift) - ofs;

		ret = sharp_wait(map,&sharp->chips[chipnum]);
		if(ret<0)
			break;

		map_copy_from(map,buf,ofs,thislen);

		sharp_release(&sharp->chips[chipnum]);

		*retlen += thislen;
		len -= thislen;
		buf += thislen;

		ofs = 0;
		chipnum++;
	}
	return ret;
}

static int sharp_write(struct mtd_info *mtd, loff_t to, size_t len,
	size_t *retlen, const u_char *buf)
{
	struct map_info *map = mtd->priv;
	struct sharp_info *sharp = map->fldrv_priv;
	int ret = 0;
	int i,j;
	int chipnum;
	unsigned long ofs;
	union { u32 l; unsigned char uc[4]; } tbuf;

	*retlen = 0;

	while(len){
		tbuf.l = 0xffffffff;
		chipnum = to >> sharp->chipshift;
		ofs = to & ((1<<sharp->chipshift)-1);

		j=0;
		for(i=ofs&3;i<4 && len;i++){
			tbuf.uc[i] = *buf;
			buf++;
			to++;
			len--;
			j++;
		}
		sharp_write_oneword(map, &sharp->chips[chipnum], ofs&~3, tbuf.l);
		if(ret<0)
			return ret;
		(*retlen)+=j;
	}

	return 0;
}

static int sharp_write_oneword(struct map_info *map, struct flchip *chip,
	unsigned long adr, __u32 datum)
{
	int ret;
	int timeo;
	int try;
	int i;
	map_word data, status;

	status.x[0] = 0;
	ret = sharp_wait(map,chip);

	for(try=0;try<10;try++){
		sharp_send_cmd(map, CMD_BYTE_WRITE, adr);
		/* cpu_to_le32 -> hack to fix the writel be->le conversion */
		data.x[0] = cpu_to_le32(datum);
		map_write(map, data, adr);

		chip->state = FL_WRITING;

		timeo = jiffies + (HZ/2);

		sharp_send_cmd(map, CMD_READ_STATUS, adr);
		for(i=0;i<100;i++){
			status = map_read(map, adr);
			if((status.x[0] & SR_READY) == SR_READY)
				break;
		}
		if(i==100){
			printk("sharp: timed out writing\n");
		}

		if(!(status.x[0] & SR_ERRORS))
			break;

		printk("sharp: error writing byte at addr=%08lx status=%08lx\n", adr, status.x[0]);

		sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
	}
	sharp_send_cmd(map, CMD_RESET, adr);
	chip->state = FL_READY;

	wake_up(&chip->wq);
	spin_unlock_bh(chip->mutex);

	return 0;
}

static int sharp_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	struct map_info *map = mtd->priv;
	struct sharp_info *sharp = map->fldrv_priv;
	unsigned long adr,len;
	int chipnum, ret=0;

//printk("sharp_erase()\n");
	if(instr->addr & (mtd->erasesize - 1))
		return -EINVAL;
	if(instr->len & (mtd->erasesize - 1))
		return -EINVAL;
	if(instr->len + instr->addr > mtd->size)
		return -EINVAL;

	chipnum = instr->addr >> sharp->chipshift;
	adr = instr->addr & ((1<<sharp->chipshift)-1);
	len = instr->len;

	while(len){
		ret = sharp_erase_oneblock(map, &sharp->chips[chipnum], adr);
		if(ret)return ret;

		adr += mtd->erasesize;
		len -= mtd->erasesize;
		if(adr >> sharp->chipshift){
			adr = 0;
			chipnum++;
			if(chipnum>=sharp->numchips)
				break;
		}
	}

	instr->state = MTD_ERASE_DONE;
	mtd_erase_callback(instr);

	return 0;
}

static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
	unsigned long adr)
{
	int ret;
	unsigned long timeo;
	map_word status;
	DECLARE_WAITQUEUE(wait, current);

	sharp_send_cmd(map, CMD_READ_STATUS, adr);
	status = map_read(map, adr);

	timeo = jiffies + HZ;

	while(time_before(jiffies, timeo)){
		sharp_send_cmd(map, CMD_READ_STATUS, adr);
		status = map_read(map, adr);
		if((status.x[0] & SR_READY)==SR_READY){
			ret = 0;
			goto out;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&chip->wq, &wait);

		//spin_unlock_bh(chip->mutex);

		schedule_timeout(1);
		schedule();
		remove_wait_queue(&chip->wq, &wait);

		//spin_lock_bh(chip->mutex);

		if (signal_pending(current)){
			ret = -EINTR;
			goto out;
		}

	}
	ret = -ETIME;
out:
	return ret;
}

static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip,
	unsigned long adr)
{
	int ret;
	//int timeo;
	map_word status;
	//int i;

//printk("sharp_erase_oneblock()\n");

#ifdef AUTOUNLOCK
	/* This seems like a good place to do an unlock */
	sharp_unlock_oneblock(map,chip,adr);
#endif

	sharp_send_cmd(map, CMD_BLOCK_ERASE_1, adr);
	sharp_send_cmd(map, CMD_BLOCK_ERASE_2, adr);

	chip->state = FL_ERASING;

	ret = sharp_do_wait_for_ready(map,chip,adr);
	if(ret<0)return ret;

	sharp_send_cmd(map, CMD_READ_STATUS, adr);
	status = map_read(map, adr);

	if(!(status.x[0] & SR_ERRORS)){
		sharp_send_cmd(map, CMD_RESET, adr);
		chip->state = FL_READY;
		//spin_unlock_bh(chip->mutex);
		return 0;
	}

	printk("sharp: error erasing block at addr=%08lx status=%08lx\n", adr, status.x[0]);
	sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);

	//spin_unlock_bh(chip->mutex);

	return -EIO;
}

#ifdef AUTOUNLOCK
static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip,
	unsigned long adr)
{
	int i;
	map_word status;

	sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_1, adr);
	sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_2, adr);

	udelay(100);

	status = map_read(map, adr);
	printk("status=%08lx\n", status.x[0]);

	for(i=0;i<1000;i++){
		//sharp_send_cmd(map, CMD_READ_STATUS, adr);
		status = map_read(map, adr);
		if((status.x[0] & SR_READY) == SR_READY)
			break;
		udelay(100);
	}
	if(i==1000){
		printk("sharp: timed out unlocking block\n");
	}

	if(!(status.x[0] & SR_ERRORS)){
		sharp_send_cmd(map, CMD_RESET, adr);
		chip->state = FL_READY;
		return;
	}

	printk("sharp: error unlocking block at addr=%08lx status=%08lx\n", adr, status.x[0]);
	sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
}
#endif

static void sharp_sync(struct mtd_info *mtd)
{
	//printk("sharp_sync()\n");
}

static int sharp_suspend(struct mtd_info *mtd)
{
	printk("sharp_suspend()\n");
	return -EINVAL;
}

static void sharp_resume(struct mtd_info *mtd)
{
	printk("sharp_resume()\n");

}

static void sharp_destroy(struct mtd_info *mtd)
{
	printk("sharp_destroy()\n");

}

static int __init sharp_probe_init(void)
{
	printk("MTD Sharp chip driver <ds@lineo.com>\n");

	register_mtd_chip_driver(&sharp_chipdrv);

	return 0;
}

static void __exit sharp_probe_exit(void)
{
	unregister_mtd_chip_driver(&sharp_chipdrv);
}

module_init(sharp_probe_init);
module_exit(sharp_probe_exit);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Schleef <ds@schleef.org>");
MODULE_DESCRIPTION("Old MTD chip driver for pre-CFI Sharp flash chips");
