/*
 * Blackfin On-Chip OTP Memory Interface
 *
 * Copyright 2007-2009 Analog Devices Inc.
 *
 * Enter bugs at http://blackfin.uclinux.org/
 *
 * Licensed under the GPL-2 or later.
 */

#include <linux/device.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/types.h>
#include <mtd/mtd-abi.h>

#include <asm/blackfin.h>
#include <asm/bfrom.h>
#include <linux/uaccess.h>

#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
#define stampit() stamp("here i am")
#define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); })

#define DRIVER_NAME "bfin-otp"
#define PFX DRIVER_NAME ": "

static DEFINE_MUTEX(bfin_otp_lock);

/**
 *	bfin_otp_read - Read OTP pages
 *
 *	All reads must be in half page chunks (half page == 64 bits).
 */
static ssize_t bfin_otp_read(struct file *file, char __user *buff, size_t count, loff_t *pos)
{
	ssize_t bytes_done;
	u32 page, flags, ret;
	u64 content;

	stampit();

	if (count % sizeof(u64))
		return -EMSGSIZE;

	if (mutex_lock_interruptible(&bfin_otp_lock))
		return -ERESTARTSYS;

	bytes_done = 0;
	page = *pos / (sizeof(u64) * 2);
	while (bytes_done < count) {
		flags = (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF);
		stamp("processing page %i (0x%x:%s)", page, flags,
			(flags & OTP_UPPER_HALF ? "upper" : "lower"));
		ret = bfrom_OtpRead(page, flags, &content);
		if (ret & OTP_MASTER_ERROR) {
			stamp("error from otp: 0x%x", ret);
			bytes_done = -EIO;
			break;
		}
		if (copy_to_user(buff + bytes_done, &content, sizeof(content))) {
			bytes_done = -EFAULT;
			break;
		}
		if (flags & OTP_UPPER_HALF)
			++page;
		bytes_done += sizeof(content);
		*pos += sizeof(content);
	}

	mutex_unlock(&bfin_otp_lock);

	return bytes_done;
}

#ifdef CONFIG_BFIN_OTP_WRITE_ENABLE
static bool allow_writes;

/**
 *	bfin_otp_init_timing - setup OTP timing parameters
 *
 *	Required before doing any write operation.  Algorithms from HRM.
 */
static u32 bfin_otp_init_timing(void)
{
	u32 tp1, tp2, tp3, timing;

	tp1 = get_sclk() / 1000000;
	tp2 = (2 * get_sclk() / 10000000) << 8;
	tp3 = (0x1401) << 15;
	timing = tp1 | tp2 | tp3;
	if (bfrom_OtpCommand(OTP_INIT, timing))
		return 0;

	return timing;
}

/**
 *	bfin_otp_deinit_timing - set timings to only allow reads
 *
 *	Should be called after all writes are done.
 */
static void bfin_otp_deinit_timing(u32 timing)
{
	/* mask bits [31:15] so that any attempts to write fail */
	bfrom_OtpCommand(OTP_CLOSE, 0);
	bfrom_OtpCommand(OTP_INIT, timing & ~(-1 << 15));
	bfrom_OtpCommand(OTP_CLOSE, 0);
}

/**
 *	bfin_otp_write - write OTP pages
 *
 *	All writes must be in half page chunks (half page == 64 bits).
 */
static ssize_t bfin_otp_write(struct file *filp, const char __user *buff, size_t count, loff_t *pos)
{
	ssize_t bytes_done;
	u32 timing, page, base_flags, flags, ret;
	u64 content;

	if (!allow_writes)
		return -EACCES;

	if (count % sizeof(u64))
		return -EMSGSIZE;

	if (mutex_lock_interruptible(&bfin_otp_lock))
		return -ERESTARTSYS;

	stampit();

	timing = bfin_otp_init_timing();
	if (timing == 0) {
		mutex_unlock(&bfin_otp_lock);
		return -EIO;
	}

	base_flags = OTP_CHECK_FOR_PREV_WRITE;

	bytes_done = 0;
	page = *pos / (sizeof(u64) * 2);
	while (bytes_done < count) {
		flags = base_flags | (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF);
		stamp("processing page %i (0x%x:%s) from %p", page, flags,
			(flags & OTP_UPPER_HALF ? "upper" : "lower"), buff + bytes_done);
		if (copy_from_user(&content, buff + bytes_done, sizeof(content))) {
			bytes_done = -EFAULT;
			break;
		}
		ret = bfrom_OtpWrite(page, flags, &content);
		if (ret & OTP_MASTER_ERROR) {
			stamp("error from otp: 0x%x", ret);
			bytes_done = -EIO;
			break;
		}
		if (flags & OTP_UPPER_HALF)
			++page;
		bytes_done += sizeof(content);
		*pos += sizeof(content);
	}

	bfin_otp_deinit_timing(timing);

	mutex_unlock(&bfin_otp_lock);

	return bytes_done;
}

static long bfin_otp_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
{
	stampit();

	switch (cmd) {
	case OTPLOCK: {
		u32 timing;
		int ret = -EIO;

		if (!allow_writes)
			return -EACCES;

		if (mutex_lock_interruptible(&bfin_otp_lock))
			return -ERESTARTSYS;

		timing = bfin_otp_init_timing();
		if (timing) {
			u32 otp_result = bfrom_OtpWrite(arg, OTP_LOCK, NULL);
			stamp("locking page %lu resulted in 0x%x", arg, otp_result);
			if (!(otp_result & OTP_MASTER_ERROR))
				ret = 0;

			bfin_otp_deinit_timing(timing);
		}

		mutex_unlock(&bfin_otp_lock);

		return ret;
	}

	case MEMLOCK:
		allow_writes = false;
		return 0;

	case MEMUNLOCK:
		allow_writes = true;
		return 0;
	}

	return -EINVAL;
}
#else
# define bfin_otp_write NULL
# define bfin_otp_ioctl NULL
#endif

static const struct file_operations bfin_otp_fops = {
	.owner          = THIS_MODULE,
	.unlocked_ioctl = bfin_otp_ioctl,
	.read           = bfin_otp_read,
	.write          = bfin_otp_write,
	.llseek		= default_llseek,
};

static struct miscdevice bfin_otp_misc_device = {
	.minor    = MISC_DYNAMIC_MINOR,
	.name     = DRIVER_NAME,
	.fops     = &bfin_otp_fops,
};
module_misc_device(bfin_otp_misc_device);

MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
MODULE_DESCRIPTION("Blackfin OTP Memory Interface");
MODULE_LICENSE("GPL");
