/*
 * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
 * Copyright (C) 2000-2001 Toshiba Corporation
 *
 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
 * terms of the GNU General Public License version 2. This program is
 * licensed "as is" without any warranty of any kind, whether express
 * or implied.
 *
 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
 */
#include <linux/config.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <asm/tx4938/spi.h>
#include <asm/tx4938/tx4938.h>

/* ATMEL 250x0 instructions */
#define	ATMEL_WREN	0x06
#define	ATMEL_WRDI	0x04
#define ATMEL_RDSR	0x05
#define ATMEL_WRSR	0x01
#define	ATMEL_READ	0x03
#define	ATMEL_WRITE	0x02

#define ATMEL_SR_BSY	0x01
#define ATMEL_SR_WEN	0x02
#define ATMEL_SR_BP0	0x04
#define ATMEL_SR_BP1	0x08

DEFINE_SPINLOCK(spi_eeprom_lock);

static struct spi_dev_desc seeprom_dev_desc = {
	.baud 		= 1500000,	/* 1.5Mbps */
	.tcss		= 1,
	.tcsh		= 1,
	.tcsr		= 1,
	.byteorder	= 1,		/* MSB-First */
	.polarity	= 0,		/* High-Active */
	.phase		= 0,		/* Sample-Then-Shift */

};
static inline int
spi_eeprom_io(int chipid,
	      unsigned char **inbufs, unsigned int *incounts,
	      unsigned char **outbufs, unsigned int *outcounts)
{
	return txx9_spi_io(chipid, &seeprom_dev_desc,
			   inbufs, incounts, outbufs, outcounts, 0);
}

int spi_eeprom_write_enable(int chipid, int enable)
{
	unsigned char inbuf[1];
	unsigned char *inbufs[1];
	unsigned int incounts[2];
	unsigned long flags;
	int stat;
	inbuf[0] = enable ? ATMEL_WREN : ATMEL_WRDI;
	inbufs[0] = inbuf;
	incounts[0] = sizeof(inbuf);
	incounts[1] = 0;
	spin_lock_irqsave(&spi_eeprom_lock, flags);
	stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
	return stat;
}

static int spi_eeprom_read_status_nolock(int chipid)
{
	unsigned char inbuf[2], outbuf[2];
	unsigned char *inbufs[1], *outbufs[1];
	unsigned int incounts[2], outcounts[2];
	int stat;
	inbuf[0] = ATMEL_RDSR;
	inbuf[1] = 0;
	inbufs[0] = inbuf;
	incounts[0] = sizeof(inbuf);
	incounts[1] = 0;
	outbufs[0] = outbuf;
	outcounts[0] = sizeof(outbuf);
	outcounts[1] = 0;
	stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
	if (stat < 0)
		return stat;
	return outbuf[1];
}

int spi_eeprom_read_status(int chipid)
{
	unsigned long flags;
	int stat;
	spin_lock_irqsave(&spi_eeprom_lock, flags);
	stat = spi_eeprom_read_status_nolock(chipid);
	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
	return stat;
}

int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len)
{
	unsigned char inbuf[2];
	unsigned char *inbufs[2], *outbufs[2];
	unsigned int incounts[2], outcounts[3];
	unsigned long flags;
	int stat;
	inbuf[0] = ATMEL_READ;
	inbuf[1] = address;
	inbufs[0] = inbuf;
	inbufs[1] = NULL;
	incounts[0] = sizeof(inbuf);
	incounts[1] = 0;
	outbufs[0] = NULL;
	outbufs[1] = buf;
	outcounts[0] = 2;
	outcounts[1] = len;
	outcounts[2] = 0;
	spin_lock_irqsave(&spi_eeprom_lock, flags);
	stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
	return stat;
}

int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len)
{
	unsigned char inbuf[2];
	unsigned char *inbufs[2];
	unsigned int incounts[3];
	unsigned long flags;
	int i, stat;

	if (address / 8 != (address + len - 1) / 8)
		return -EINVAL;
	stat = spi_eeprom_write_enable(chipid, 1);
	if (stat < 0)
		return stat;
	stat = spi_eeprom_read_status(chipid);
	if (stat < 0)
		return stat;
	if (!(stat & ATMEL_SR_WEN))
		return -EPERM;

	inbuf[0] = ATMEL_WRITE;
	inbuf[1] = address;
	inbufs[0] = inbuf;
	inbufs[1] = buf;
	incounts[0] = sizeof(inbuf);
	incounts[1] = len;
	incounts[2] = 0;
	spin_lock_irqsave(&spi_eeprom_lock, flags);
	stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
	if (stat < 0)
		goto unlock_return;

	/* write start.  max 10ms */
	for (i = 10; i > 0; i--) {
		int stat = spi_eeprom_read_status_nolock(chipid);
		if (stat < 0)
			goto unlock_return;
		if (!(stat & ATMEL_SR_BSY))
			break;
		mdelay(1);
	}
	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
	if (i == 0)
		return -EIO;
	return len;
 unlock_return:
	spin_unlock_irqrestore(&spi_eeprom_lock, flags);
	return stat;
}

#ifdef CONFIG_PROC_FS
#define MAX_SIZE	0x80	/* for ATMEL 25010 */
static int spi_eeprom_read_proc(char *page, char **start, off_t off,
				int count, int *eof, void *data)
{
	unsigned int size = MAX_SIZE;
	if (spi_eeprom_read((int)data, 0, (unsigned char *)page, size) < 0)
		size = 0;
	return size;
}

static int spi_eeprom_write_proc(struct file *file, const char *buffer,
				 unsigned long count, void *data)
{
	unsigned int size = MAX_SIZE;
	int i;
	if (file->f_pos >= size)
		return -EIO;
	if (file->f_pos + count > size)
		count = size - file->f_pos;
	for (i = 0; i < count; i += 8) {
		int len = count - i < 8 ? count - i : 8;
		if (spi_eeprom_write((int)data, file->f_pos,
				     (unsigned char *)buffer, len) < 0) {
			count = -EIO;
			break;
		}
		buffer += len;
		file->f_pos += len;
	}
	return count;
}

__init void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid)
{
	struct proc_dir_entry *entry;
	char name[128];
	sprintf(name, "seeprom-%d", chipid);
	entry = create_proc_entry(name, 0600, dir);
	if (entry) {
		entry->read_proc = spi_eeprom_read_proc;
		entry->write_proc = spi_eeprom_write_proc;
		entry->data = (void *)chipid;
	}
}
#endif /* CONFIG_PROC_FS */
