/*
 * LCD, LED and Button interface for Cobalt
 *
 * 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.
 *
 * Copyright (C) 1996, 1997 by Andrew Bose
 *
 * Linux kernel version history:
 *       March 2001: Ported from 2.0.34  by Liam Davies
 *
 */

#define RTC_IO_EXTENT	0x10	/*Only really two ports, but... */

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/mc146818rtc.h>
#include <linux/netdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/delay.h>

#include "lcd.h"

static DEFINE_SPINLOCK(lcd_lock);

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

static unsigned int lcd_present = 1;

/* used in arch/mips/cobalt/reset.c */
int led_state = 0;

#if defined(CONFIG_TULIP) && 0

#define MAX_INTERFACES	8
static linkcheck_func_t linkcheck_callbacks[MAX_INTERFACES];
static void *linkcheck_cookies[MAX_INTERFACES];

int lcd_register_linkcheck_func(int iface_num, void *func, void *cookie)
{
	if (iface_num < 0 ||
	    iface_num >= MAX_INTERFACES ||
	    linkcheck_callbacks[iface_num] != NULL)
		return -1;
	linkcheck_callbacks[iface_num] = (linkcheck_func_t) func;
	linkcheck_cookies[iface_num] = cookie;
	return 0;
}
#endif

static int lcd_ioctl(struct inode *inode, struct file *file,
		     unsigned int cmd, unsigned long arg)
{
	struct lcd_display button_display;
	unsigned long address, a;

	switch (cmd) {
	case LCD_On:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x0F);
		break;

	case LCD_Off:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x08);
		break;

	case LCD_Reset:
		udelay(150);
		LCDWriteInst(0x3F);
		udelay(150);
		LCDWriteInst(0x3F);
		udelay(150);
		LCDWriteInst(0x3F);
		udelay(150);
		LCDWriteInst(0x3F);
		udelay(150);
		LCDWriteInst(0x01);
		udelay(150);
		LCDWriteInst(0x06);
		break;

	case LCD_Clear:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x01);
		break;

	case LCD_Cursor_Left:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x10);
		break;

	case LCD_Cursor_Right:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x14);
		break;

	case LCD_Cursor_Off:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x0C);
		break;

	case LCD_Cursor_On:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x0F);
		break;

	case LCD_Blink_Off:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x0E);
		break;

	case LCD_Get_Cursor_Pos:{
			struct lcd_display display;

			udelay(150);
			BusyCheck();
			display.cursor_address = (LCDReadInst);
			display.cursor_address =
			    (display.cursor_address & 0x07F);
			if (copy_to_user
			    ((struct lcd_display *) arg, &display,
			     sizeof(struct lcd_display)))
				return -EFAULT;

			break;
		}


	case LCD_Set_Cursor_Pos:{
			struct lcd_display display;

			if (copy_from_user
			    (&display, (struct lcd_display *) arg,
			     sizeof(struct lcd_display)))
				return -EFAULT;

			a = (display.cursor_address | kLCD_Addr);

			udelay(150);
			BusyCheck();
			LCDWriteInst(a);

			break;
		}

	case LCD_Get_Cursor:{
			struct lcd_display display;

			udelay(150);
			BusyCheck();
			display.character = LCDReadData;

			if (copy_to_user
			    ((struct lcd_display *) arg, &display,
			     sizeof(struct lcd_display)))
				return -EFAULT;
			udelay(150);
			BusyCheck();
			LCDWriteInst(0x10);

			break;
		}

	case LCD_Set_Cursor:{
			struct lcd_display display;

			if (copy_from_user
			    (&display, (struct lcd_display *) arg,
			     sizeof(struct lcd_display)))
				return -EFAULT;

			udelay(150);
			BusyCheck();
			LCDWriteData(display.character);
			udelay(150);
			BusyCheck();
			LCDWriteInst(0x10);

			break;
		}


	case LCD_Disp_Left:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x18);
		break;

	case LCD_Disp_Right:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x1C);
		break;

	case LCD_Home:
		udelay(150);
		BusyCheck();
		LCDWriteInst(0x02);
		break;

	case LCD_Write:{
			struct lcd_display display;
			unsigned int index;


			if (copy_from_user
			    (&display, (struct lcd_display *) arg,
			     sizeof(struct lcd_display)))
				return -EFAULT;

			udelay(150);
			BusyCheck();
			LCDWriteInst(0x80);
			udelay(150);
			BusyCheck();

			for (index = 0; index < (display.size1); index++) {
				udelay(150);
				BusyCheck();
				LCDWriteData(display.line1[index]);
				BusyCheck();
			}

			udelay(150);
			BusyCheck();
			LCDWriteInst(0xC0);
			udelay(150);
			BusyCheck();
			for (index = 0; index < (display.size2); index++) {
				udelay(150);
				BusyCheck();
				LCDWriteData(display.line2[index]);
			}

			break;
		}

	case LCD_Read:{
			struct lcd_display display;

			BusyCheck();
			for (address = kDD_R00; address <= kDD_R01;
			     address++) {
				a = (address | kLCD_Addr);

				udelay(150);
				BusyCheck();
				LCDWriteInst(a);
				udelay(150);
				BusyCheck();
				display.line1[address] = LCDReadData;
			}

			display.line1[0x27] = '\0';

			for (address = kDD_R10; address <= kDD_R11;
			     address++) {
				a = (address | kLCD_Addr);

				udelay(150);
				BusyCheck();
				LCDWriteInst(a);

				udelay(150);
				BusyCheck();
				display.line2[address - 0x40] =
				    LCDReadData;
			}

			display.line2[0x27] = '\0';

			if (copy_to_user
			    ((struct lcd_display *) arg, &display,
			     sizeof(struct lcd_display)))
				return -EFAULT;
			break;
		}

//  set all GPIO leds to led_display.leds

	case LED_Set:{
			struct lcd_display led_display;


			if (copy_from_user
			    (&led_display, (struct lcd_display *) arg,
			     sizeof(struct lcd_display)))
				return -EFAULT;

			led_state = led_display.leds;
			LEDSet(led_state);

			break;
		}


//  set only bit led_display.leds

	case LED_Bit_Set:{
			unsigned int i;
			int bit = 1;
			struct lcd_display led_display;


			if (copy_from_user
			    (&led_display, (struct lcd_display *) arg,
			     sizeof(struct lcd_display)))
				return -EFAULT;

			for (i = 0; i < (int) led_display.leds; i++) {
				bit = 2 * bit;
			}

			led_state = led_state | bit;
			LEDSet(led_state);
			break;
		}

//  clear only bit led_display.leds

	case LED_Bit_Clear:{
			unsigned int i;
			int bit = 1;
			struct lcd_display led_display;


			if (copy_from_user
			    (&led_display, (struct lcd_display *) arg,
			     sizeof(struct lcd_display)))
				return -EFAULT;

			for (i = 0; i < (int) led_display.leds; i++) {
				bit = 2 * bit;
			}

			led_state = led_state & ~bit;
			LEDSet(led_state);
			break;
		}


	case BUTTON_Read:{
			button_display.buttons = GPIRead;
			if (copy_to_user
			    ((struct lcd_display *) arg, &button_display,
			     sizeof(struct lcd_display)))
				return -EFAULT;
			break;
		}

	case LINK_Check:{
			button_display.buttons =
			    *((volatile unsigned long *) (0xB0100060));
			if (copy_to_user
			    ((struct lcd_display *) arg, &button_display,
			     sizeof(struct lcd_display)))
				return -EFAULT;
			break;
		}

	case LINK_Check_2:{
			int iface_num;

			/* panel-utils should pass in the desired interface status is wanted for
			 * in "buttons" of the structure.  We will set this to non-zero if the
			 * link is in fact up for the requested interface.  --DaveM
			 */
			if (copy_from_user
			    (&button_display, (struct lcd_display *) arg,
			     sizeof(button_display)))
				return -EFAULT;
			iface_num = button_display.buttons;
#if defined(CONFIG_TULIP) && 0
			if (iface_num >= 0 &&
			    iface_num < MAX_INTERFACES &&
			    linkcheck_callbacks[iface_num] != NULL) {
				button_display.buttons =
				    linkcheck_callbacks[iface_num]
				    (linkcheck_cookies[iface_num]);
			} else
#endif
				button_display.buttons = 0;

			if (__copy_to_user
			    ((struct lcd_display *) arg, &button_display,
			     sizeof(struct lcd_display)))
				return -EFAULT;
			break;
		}

//  Erase the flash

	case FLASH_Erase:{

			int ctr = 0;

			if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;

			pr_info(LCD "Erasing Flash\n");

			// Chip Erase Sequence
			WRITE_FLASH(kFlash_Addr1, kFlash_Data1);
			WRITE_FLASH(kFlash_Addr2, kFlash_Data2);
			WRITE_FLASH(kFlash_Addr1, kFlash_Erase3);
			WRITE_FLASH(kFlash_Addr1, kFlash_Data1);
			WRITE_FLASH(kFlash_Addr2, kFlash_Data2);
			WRITE_FLASH(kFlash_Addr1, kFlash_Erase6);

			while ((!dqpoll(0x00000000, 0xFF))
			       && (!timeout(0x00000000))) {
				ctr++;
			}

			if (READ_FLASH(0x07FFF0) == 0xFF) {
				pr_info(LCD "Erase Successful\n");
			} else if (timeout) {
				pr_info(LCD "Erase Timed Out\n");
			}

			break;
		}

// burn the flash

	case FLASH_Burn:{

			volatile unsigned long burn_addr;
			unsigned long flags;
			unsigned int i, index;
			unsigned char *rom;


			struct lcd_display display;

			if ( !capable(CAP_SYS_ADMIN) ) return -EPERM;

			if (copy_from_user
			    (&display, (struct lcd_display *) arg,
			     sizeof(struct lcd_display)))
				return -EFAULT;
			rom = (unsigned char *) kmalloc((128), GFP_ATOMIC);
			if (rom == NULL) {
				printk(KERN_ERR LCD "kmalloc() failed in %s\n",
						__FUNCTION__);
				return -ENOMEM;
			}

			pr_info(LCD "Starting Flash burn\n");
			for (i = 0; i < FLASH_SIZE; i = i + 128) {

				if (copy_from_user
				    (rom, display.RomImage + i, 128)) {
					kfree(rom);
					return -EFAULT;
				}
				burn_addr = kFlashBase + i;
				spin_lock_irqsave(&lcd_lock, flags);
				for (index = 0; index < (128); index++) {

					WRITE_FLASH(kFlash_Addr1,
						    kFlash_Data1);
					WRITE_FLASH(kFlash_Addr2,
						    kFlash_Data2);
					WRITE_FLASH(kFlash_Addr1,
						    kFlash_Prog);
					*((volatile unsigned char *)burn_addr) =
					  (volatile unsigned char) rom[index];

					while ((!dqpoll (burn_addr,
						(volatile unsigned char)
						rom[index])) &&
						(!timeout(burn_addr))) { }
					burn_addr++;
				}
				spin_unlock_irqrestore(&lcd_lock, flags);
				if (* ((volatile unsigned char *)
					(burn_addr - 1)) ==
					(volatile unsigned char)
					rom[index - 1]) {
				} else if (timeout) {
					pr_info(LCD "Flash burn timed out\n");
				}


			}
			kfree(rom);

			pr_info(LCD "Flash successfully burned\n");

			break;
		}

//  read the flash all at once

	case FLASH_Read:{

			unsigned char *user_bytes;
			volatile unsigned long read_addr;
			unsigned int i;

			user_bytes =
			    &(((struct lcd_display *) arg)->RomImage[0]);

			if (!access_ok
			    (VERIFY_WRITE, user_bytes, FLASH_SIZE))
				return -EFAULT;

			pr_info(LCD "Reading Flash");
			for (i = 0; i < FLASH_SIZE; i++) {
				unsigned char tmp_byte;
				read_addr = kFlashBase + i;
				tmp_byte =
				    *((volatile unsigned char *)
				      read_addr);
				if (__put_user(tmp_byte, &user_bytes[i]))
					return -EFAULT;
			}


			break;
		}

	default:
		return -EINVAL;

	}

	return 0;

}

static int lcd_open(struct inode *inode, struct file *file)
{
	if (!lcd_present)
		return -ENXIO;
	else
		return 0;
}

/* Only RESET or NEXT counts as button pressed */

static inline int button_pressed(void)
{
	unsigned long buttons = GPIRead;

	if ((buttons == BUTTON_Next) || (buttons == BUTTON_Next_B)
	    || (buttons == BUTTON_Reset_B))
		return buttons;
	return 0;
}

/* LED daemon sits on this and we wake him up once a key is pressed. */

static int lcd_waiters = 0;

static ssize_t lcd_read(struct file *file, char *buf,
		     size_t count, loff_t *ofs)
{
	long buttons_now;

	if (lcd_waiters > 0)
		return -EINVAL;

	lcd_waiters++;
	while (((buttons_now = (long) button_pressed()) == 0) &&
	       !(signal_pending(current))) {
		msleep_interruptible(2000);
	}
	lcd_waiters--;

	if (signal_pending(current))
		return -ERESTARTSYS;
	return buttons_now;
}

/*
 *	The various file operations we support.
 */

static const struct file_operations lcd_fops = {
	.read = lcd_read,
	.ioctl = lcd_ioctl,
	.open = lcd_open,
};

static struct miscdevice lcd_dev = {
	MISC_DYNAMIC_MINOR,
	"lcd",
	&lcd_fops
};

static int lcd_init(void)
{
	int ret;
	unsigned long data;

	pr_info("%s\n", LCD_DRIVER);
	ret = misc_register(&lcd_dev);
	if (ret) {
		printk(KERN_WARNING LCD "Unable to register misc device.\n");
		return ret;
	}

	/* Check region? Naaah! Just snarf it up. */
/*	request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/

	udelay(150);
	data = LCDReadData;
	if ((data & 0x000000FF) == (0x00)) {
		lcd_present = 0;
		pr_info(LCD "LCD Not Present\n");
	} else {
		lcd_present = 1;
		WRITE_GAL(kGal_DevBank2PReg, kGal_DevBank2Cfg);
		WRITE_GAL(kGal_DevBank3PReg, kGal_DevBank3Cfg);
	}

	return 0;
}

static void __exit lcd_exit(void)
{
	misc_deregister(&lcd_dev);
}

//
// Function: dqpoll
//
// Description:  Polls the data lines to see if the flash is busy
//
// In: address, byte data
//
// Out: 0 = busy, 1 = write or erase complete
//
//

static int dqpoll(volatile unsigned long address, volatile unsigned char data)
{
	volatile unsigned char dq7;

	dq7 = data & 0x80;

	return ((READ_FLASH(address) & 0x80) == dq7);
}

//
// Function: timeout
//
// Description: Checks to see if erase or write has timed out
//              By polling dq5
//
// In: address
//
//
// Out: 0 = not timed out, 1 = timed out

static int timeout(volatile unsigned long address)
{
	return (READ_FLASH(address) & 0x20) == 0x20;
}

module_init(lcd_init);
module_exit(lcd_exit);

MODULE_AUTHOR("Andrew Bose");
MODULE_LICENSE("GPL");
