/*
 * arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch.
 *
 * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
 *
 * LED control drive function added by kogiidena
 */
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/major.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/interrupt.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/landisk/iodata_landisk.h>

#define SHUTDOWN_BTN_MINOR	1	/* Shutdown button device minor no. */
#define LED_MINOR	       21	/* LED minor no. */
#define BTN_MINOR	       22	/* BUTTON minor no. */
#define GIO_MINOR	       40	/* GIO minor no. */

static int openCnt;
static int openCntLED;
static int openCntGio;
static int openCntBtn;
static int landisk_btn;
static int landisk_btnctrlpid;
/*
 * Functions prototypes
 */

static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
		     unsigned long arg);

static int swdrv_open(struct inode *inode, struct file *filp)
{
	int minor;

	minor = MINOR(inode->i_rdev);
	filp->private_data = (void *)minor;

	if (minor == SHUTDOWN_BTN_MINOR) {
		if (openCnt > 0) {
			return -EALREADY;
		} else {
			openCnt++;
			return 0;
		}
	} else if (minor == LED_MINOR) {
		if (openCntLED > 0) {
			return -EALREADY;
		} else {
			openCntLED++;
			return 0;
		}
	} else if (minor == BTN_MINOR) {
		if (openCntBtn > 0) {
			return -EALREADY;
		} else {
			openCntBtn++;
			return 0;
		}
	} else if (minor == GIO_MINOR) {
		if (openCntGio > 0) {
			return -EALREADY;
		} else {
			openCntGio++;
			return 0;
		}
	}
	return -ENOENT;

}

static int swdrv_close(struct inode *inode, struct file *filp)
{
	int minor;

	minor = MINOR(inode->i_rdev);
	if (minor == SHUTDOWN_BTN_MINOR) {
		openCnt--;
	} else if (minor == LED_MINOR) {
		openCntLED--;
	} else if (minor == BTN_MINOR) {
		openCntBtn--;
	} else if (minor == GIO_MINOR) {
		openCntGio--;
	}
	return 0;
}

static int swdrv_read(struct file *filp, char *buff, size_t count,
		      loff_t * ppos)
{
	int minor;
	minor = (int)(filp->private_data);

	if (!access_ok(VERIFY_WRITE, (void *)buff, count))
		return -EFAULT;

	if (minor == SHUTDOWN_BTN_MINOR) {
		if (landisk_btn & 0x10) {
			put_user(1, buff);
			return 1;
		} else {
			return 0;
		}
	}
	return 0;
}

static int swdrv_write(struct file *filp, const char *buff, size_t count,
		       loff_t * ppos)
{
	int minor;
	minor = (int)(filp->private_data);

	if (minor == SHUTDOWN_BTN_MINOR) {
		return count;
	}
	return count;
}

static irqreturn_t sw_interrupt(int irq, void *dev_id)
{
	landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS)));
	disable_irq(IRQ_BUTTON);
	disable_irq(IRQ_POWER);
	ctrl_outb(0x00, PA_PWRINT_CLR);

	if (landisk_btnctrlpid != 0) {
		kill_proc(landisk_btnctrlpid, SIGUSR1, 1);
		landisk_btnctrlpid = 0;
	}

	return IRQ_HANDLED;
}

static const struct file_operations swdrv_fops = {
	.read = swdrv_read,	/* read */
	.write = swdrv_write,	/* write */
	.open = swdrv_open,	/* open */
	.release = swdrv_close,	/* release */
	.ioctl = gio_ioctl,	/* ioctl */

};

static char banner[] __initdata =
    KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n";

int __init swdrv_init(void)
{
	int error;

	printk("%s", banner);

	openCnt = 0;
	openCntLED = 0;
	openCntBtn = 0;
	openCntGio = 0;
	landisk_btn = 0;
	landisk_btnctrlpid = 0;

	if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) {
		printk(KERN_ERR
		       "Button, LED and GIO driver:Couldn't register driver, error=%d\n",
		       error);
		return 1;
	}

	if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) {
		printk(KERN_ERR "Unable to get IRQ 11.\n");
		return 1;
	}
	if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) {
		printk(KERN_ERR "Unable to get IRQ 12.\n");
		return 1;
	}
	ctrl_outb(0x00, PA_PWRINT_CLR);

	return 0;
}

module_init(swdrv_init);

/*
 * gio driver
 *
 */

#include <asm/landisk/gio.h>

static int gio_ioctl(struct inode *inode, struct file *filp,
		     unsigned int cmd, unsigned long arg)
{
	int minor;
	unsigned int data, mask;
	static unsigned int addr = 0;

	minor = (int)(filp->private_data);

	/* access control */
	if (minor == GIO_MINOR) {
		;
	} else if (minor == LED_MINOR) {
		if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) {
			;
		} else {
			return -EINVAL;
		}
	} else if (minor == BTN_MINOR) {
		if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) {
			;
		} else {
			return -EINVAL;
		}
	} else {
		return -EINVAL;
	}

	if (cmd & 0x01) {	/* write */
		if (copy_from_user(&data, (int *)arg, sizeof(int))) {
			return -EFAULT;
		}
	}

	switch (cmd) {
	case GIODRV_IOCSGIOSETADDR:	/* addres set */
		addr = data;
		break;

	case GIODRV_IOCSGIODATA1:	/* write byte */
		ctrl_outb((unsigned char)(0x0ff & data), addr);
		break;

	case GIODRV_IOCSGIODATA2:	/* write word */
		if (addr & 0x01) {
			return -EFAULT;
		}
		ctrl_outw((unsigned short int)(0x0ffff & data), addr);
		break;

	case GIODRV_IOCSGIODATA4:	/* write long */
		if (addr & 0x03) {
			return -EFAULT;
		}
		ctrl_outl(data, addr);
		break;

	case GIODRV_IOCGGIODATA1:	/* read byte */
		data = ctrl_inb(addr);
		break;

	case GIODRV_IOCGGIODATA2:	/* read word */
		if (addr & 0x01) {
			return -EFAULT;
		}
		data = ctrl_inw(addr);
		break;

	case GIODRV_IOCGGIODATA4:	/* read long */
		if (addr & 0x03) {
			return -EFAULT;
		}
		data = ctrl_inl(addr);
		break;
	case GIODRV_IOCSGIO_LED:	/* write */
		mask = ((data & 0x00ffffff) << 8)
		    | ((data & 0x0000ffff) << 16)
		    | ((data & 0x000000ff) << 24);
		landisk_ledparam = data & (~mask);
		if (landisk_arch == 0) {	/* arch == landisk */
			landisk_ledparam &= 0x03030303;
			mask = (~(landisk_ledparam >> 22)) & 0x000c;
			landisk_ledparam |= mask;
		} else {	                /* arch == usl-5p */
			mask = (landisk_ledparam >> 24) & 0x0001;
			landisk_ledparam |= mask;
			landisk_ledparam &= 0x007f7f7f;
		}
		landisk_ledparam |= 0x80;
		break;
	case GIODRV_IOCGGIO_LED:	/* read */
		data = landisk_ledparam;
		if (landisk_arch == 0) {	/* arch == landisk */
			data &= 0x03030303;
		} else {	                /* arch == usl-5p */
			;
		}
		data &= (~0x080);
		break;
	case GIODRV_IOCSGIO_BUZZER:	/* write */
		landisk_buzzerparam = data;
		landisk_ledparam |= 0x80;
		break;
	case GIODRV_IOCGGIO_LANDISK:	/* read */
		data = landisk_arch & 0x01;
		break;
	case GIODRV_IOCGGIO_BTN:	/* read */
		data = (0x0ff & ctrl_inb(PA_PWRINT_CLR));
		data <<= 8;
		data |= (0x0ff & ctrl_inb(PA_IMASK));
		data <<= 8;
		data |= (0x0ff & landisk_btn);
		data <<= 8;
		data |= (0x0ff & (~ctrl_inb(PA_STATUS)));
		break;
	case GIODRV_IOCSGIO_BTNPID:	/* write */
		landisk_btnctrlpid = data;
		landisk_btn = 0;
		if (irq_desc[IRQ_BUTTON].depth) {
			enable_irq(IRQ_BUTTON);
		}
		if (irq_desc[IRQ_POWER].depth) {
			enable_irq(IRQ_POWER);
		}
		break;
	case GIODRV_IOCGGIO_BTNPID:	/* read */
		data = landisk_btnctrlpid;
		break;
	default:
		return -EFAULT;
		break;
	}

	if ((cmd & 0x01) == 0) {	/* read */
		if (copy_to_user((int *)arg, &data, sizeof(int))) {
			return -EFAULT;
		}
	}
	return 0;
}
