/*
 * Atari Keyboard driver for 680x0 Linux
 *
 * 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.
 */

/*
 * Atari support by Robert de Vries
 * enhanced by Bjoern Brauel and Roman Hodek
 *
 * 2.6 and input cleanup (removed autorepeat stuff) for 2.6.21
 * 06/07 Michael Schmitz
 */

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/keyboard.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/kd.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/kbd_kern.h>

#include <asm/atariints.h>
#include <asm/atarihw.h>
#include <asm/atarikb.h>
#include <asm/atari_joystick.h>
#include <asm/irq.h>


/* Hook for MIDI serial driver */
void (*atari_MIDI_interrupt_hook) (void);
/* Hook for mouse driver */
void (*atari_mouse_interrupt_hook) (char *);
/* Hook for keyboard inputdev  driver */
void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
/* Hook for mouse inputdev  driver */
void (*atari_input_mouse_interrupt_hook) (char *);
EXPORT_SYMBOL(atari_mouse_interrupt_hook);
EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook);
EXPORT_SYMBOL(atari_input_mouse_interrupt_hook);

/* variables for IKBD self test: */

/* state: 0: off; >0: in progress; >1: 0xf1 received */
static volatile int ikbd_self_test;
/* timestamp when last received a char */
static volatile unsigned long self_test_last_rcv;
/* bitmap of keys reported as broken */
static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, };

#define BREAK_MASK	(0x80)

/*
 * ++roman: The following changes were applied manually:
 *
 *  - The Alt (= Meta) key works in combination with Shift and
 *    Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends
 *    Meta-Ctrl-A (0x81) ...
 *
 *  - The parentheses on the keypad send '(' and ')' with all
 *    modifiers (as would do e.g. keypad '+'), but they cannot be used as
 *    application keys (i.e. sending Esc O c).
 *
 *  - HELP and UNDO are mapped to be F21 and F24, resp, that send the
 *    codes "\E[M" and "\E[P". (This is better than the old mapping to
 *    F11 and F12, because these codes are on Shift+F1/2 anyway.) This
 *    way, applications that allow their own keyboard mappings
 *    (e.g. tcsh, X Windows) can be configured to use them in the way
 *    the label suggests (providing help or undoing).
 *
 *  - Console switching is done with Alt+Fx (consoles 1..10) and
 *    Shift+Alt+Fx (consoles 11..20).
 *
 *  - The misc. special function implemented in the kernel are mapped
 *    to the following key combinations:
 *
 *      ClrHome          -> Home/Find
 *      Shift + ClrHome  -> End/Select
 *      Shift + Up       -> Page Up
 *      Shift + Down     -> Page Down
 *      Alt + Help       -> show system status
 *      Shift + Help     -> show memory info
 *      Ctrl + Help      -> show registers
 *      Ctrl + Alt + Del -> Reboot
 *      Alt + Undo       -> switch to last console
 *      Shift + Undo     -> send interrupt
 *      Alt + Insert     -> stop/start output (same as ^S/^Q)
 *      Alt + Up         -> Scroll back console (if implemented)
 *      Alt + Down       -> Scroll forward console (if implemented)
 *      Alt + CapsLock   -> NumLock
 *
 * ++Andreas:
 *
 *  - Help mapped to K_HELP
 *  - Undo mapped to K_UNDO (= K_F246)
 *  - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR]
 */

typedef enum kb_state_t {
	KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC
} KB_STATE_T;

#define	IS_SYNC_CODE(sc)	((sc) >= 0x04 && (sc) <= 0xfb)

typedef struct keyboard_state {
	unsigned char buf[6];
	int len;
	KB_STATE_T state;
} KEYBOARD_STATE;

KEYBOARD_STATE kb_state;

/* ++roman: If a keyboard overrun happened, we can't tell in general how much
 * bytes have been lost and in which state of the packet structure we are now.
 * This usually causes keyboards bytes to be interpreted as mouse movements
 * and vice versa, which is very annoying. It seems better to throw away some
 * bytes (that are usually mouse bytes) than to misinterpret them. Therefore I
 * introduced the RESYNC state for IKBD data. In this state, the bytes up to
 * one that really looks like a key event (0x04..0xf2) or the start of a mouse
 * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least
 * speeds up the resynchronization of the event structure, even if maybe a
 * mouse movement is lost. However, nothing is perfect. For bytes 0x01..0x03,
 * it's really hard to decide whether they're mouse or keyboard bytes. Since
 * overruns usually occur when moving the Atari mouse rapidly, they're seen as
 * mouse bytes here. If this is wrong, only a make code of the keyboard gets
 * lost, which isn't too bad. Loosing a break code would be disastrous,
 * because then the keyboard repeat strikes...
 */

static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy)
{
	u_char acia_stat;
	int scancode;
	int break_flag;

repeat:
	if (acia.mid_ctrl & ACIA_IRQ)
		if (atari_MIDI_interrupt_hook)
			atari_MIDI_interrupt_hook();
	acia_stat = acia.key_ctrl;
	/* check out if the interrupt came from this ACIA */
	if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ))
		return IRQ_HANDLED;

	if (acia_stat & ACIA_OVRN) {
		/* a very fast typist or a slow system, give a warning */
		/* ...happens often if interrupts were disabled for too long */
		printk(KERN_DEBUG "Keyboard overrun\n");
		scancode = acia.key_data;
		if (ikbd_self_test)
			/* During self test, don't do resyncing, just process the code */
			goto interpret_scancode;
		else if (IS_SYNC_CODE(scancode)) {
			/* This code seem already to be the start of a new packet or a
			 * single scancode */
			kb_state.state = KEYBOARD;
			goto interpret_scancode;
		} else {
			/* Go to RESYNC state and skip this byte */
			kb_state.state = RESYNC;
			kb_state.len = 1;	/* skip max. 1 another byte */
			goto repeat;
		}
	}

	if (acia_stat & ACIA_RDRF) {
		/* received a character */
		scancode = acia.key_data;	/* get it or reset the ACIA, I'll get it! */
		tasklet_schedule(&keyboard_tasklet);
	interpret_scancode:
		switch (kb_state.state) {
		case KEYBOARD:
			switch (scancode) {
			case 0xF7:
				kb_state.state = AMOUSE;
				kb_state.len = 0;
				break;

			case 0xF8:
			case 0xF9:
			case 0xFA:
			case 0xFB:
				kb_state.state = RMOUSE;
				kb_state.len = 1;
				kb_state.buf[0] = scancode;
				break;

			case 0xFC:
				kb_state.state = CLOCK;
				kb_state.len = 0;
				break;

			case 0xFE:
			case 0xFF:
				kb_state.state = JOYSTICK;
				kb_state.len = 1;
				kb_state.buf[0] = scancode;
				break;

			case 0xF1:
				/* during self-test, note that 0xf1 received */
				if (ikbd_self_test) {
					++ikbd_self_test;
					self_test_last_rcv = jiffies;
					break;
				}
				/* FALL THROUGH */

			default:
				break_flag = scancode & BREAK_MASK;
				scancode &= ~BREAK_MASK;
				if (ikbd_self_test) {
					/* Scancodes sent during the self-test stand for broken
					 * keys (keys being down). The code *should* be a break
					 * code, but nevertheless some AT keyboard interfaces send
					 * make codes instead. Therefore, simply ignore
					 * break_flag...
					 */
					int keyval, keytyp;

					set_bit(scancode, broken_keys);
					self_test_last_rcv = jiffies;
					/* new Linux scancodes; approx. */
					keyval = scancode;
					keytyp = KTYP(keyval) - 0xf0;
					keyval = KVAL(keyval);

					printk(KERN_WARNING "Key with scancode %d ", scancode);
					if (keytyp == KT_LATIN || keytyp == KT_LETTER) {
						if (keyval < ' ')
							printk("('^%c') ", keyval + '@');
						else
							printk("('%c') ", keyval);
					}
					printk("is broken -- will be ignored.\n");
					break;
				} else if (test_bit(scancode, broken_keys))
					break;

				if (atari_input_keyboard_interrupt_hook)
					atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag);
				break;
			}
			break;

		case AMOUSE:
			kb_state.buf[kb_state.len++] = scancode;
			if (kb_state.len == 5) {
				kb_state.state = KEYBOARD;
				/* not yet used */
				/* wake up someone waiting for this */
			}
			break;

		case RMOUSE:
			kb_state.buf[kb_state.len++] = scancode;
			if (kb_state.len == 3) {
				kb_state.state = KEYBOARD;
				if (atari_mouse_interrupt_hook)
					atari_mouse_interrupt_hook(kb_state.buf);
			}
			break;

		case JOYSTICK:
			kb_state.buf[1] = scancode;
			kb_state.state = KEYBOARD;
#ifdef FIXED_ATARI_JOYSTICK
			atari_joystick_interrupt(kb_state.buf);
#endif
			break;

		case CLOCK:
			kb_state.buf[kb_state.len++] = scancode;
			if (kb_state.len == 6) {
				kb_state.state = KEYBOARD;
				/* wake up someone waiting for this.
				   But will this ever be used, as Linux keeps its own time.
				   Perhaps for synchronization purposes? */
				/* wake_up_interruptible(&clock_wait); */
			}
			break;

		case RESYNC:
			if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
				kb_state.state = KEYBOARD;
				goto interpret_scancode;
			}
			kb_state.len--;
			break;
		}
	}

#if 0
	if (acia_stat & ACIA_CTS)
		/* cannot happen */;
#endif

	if (acia_stat & (ACIA_FE | ACIA_PE)) {
		printk("Error in keyboard communication\n");
	}

	/* handle_scancode() can take a lot of time, so check again if
	 * some character arrived
	 */
	goto repeat;
}

/*
 * I write to the keyboard without using interrupts, I poll instead.
 * This takes for the maximum length string allowed (7) at 7812.5 baud
 * 8 data 1 start 1 stop bit: 9.0 ms
 * If this takes too long for normal operation, interrupt driven writing
 * is the solution. (I made a feeble attempt in that direction but I
 * kept it simple for now.)
 */
void ikbd_write(const char *str, int len)
{
	u_char acia_stat;

	if ((len < 1) || (len > 7))
		panic("ikbd: maximum string length exceeded");
	while (len) {
		acia_stat = acia.key_ctrl;
		if (acia_stat & ACIA_TDRE) {
			acia.key_data = *str++;
			len--;
		}
	}
}

/* Reset (without touching the clock) */
void ikbd_reset(void)
{
	static const char cmd[2] = { 0x80, 0x01 };

	ikbd_write(cmd, 2);

	/*
	 * if all's well code 0xF1 is returned, else the break codes of
	 * all keys making contact
	 */
}

/* Set mouse button action */
void ikbd_mouse_button_action(int mode)
{
	char cmd[2] = { 0x07, mode };

	ikbd_write(cmd, 2);
}

/* Set relative mouse position reporting */
void ikbd_mouse_rel_pos(void)
{
	static const char cmd[1] = { 0x08 };

	ikbd_write(cmd, 1);
}
EXPORT_SYMBOL(ikbd_mouse_rel_pos);

/* Set absolute mouse position reporting */
void ikbd_mouse_abs_pos(int xmax, int ymax)
{
	char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF };

	ikbd_write(cmd, 5);
}

/* Set mouse keycode mode */
void ikbd_mouse_kbd_mode(int dx, int dy)
{
	char cmd[3] = { 0x0A, dx, dy };

	ikbd_write(cmd, 3);
}

/* Set mouse threshold */
void ikbd_mouse_thresh(int x, int y)
{
	char cmd[3] = { 0x0B, x, y };

	ikbd_write(cmd, 3);
}
EXPORT_SYMBOL(ikbd_mouse_thresh);

/* Set mouse scale */
void ikbd_mouse_scale(int x, int y)
{
	char cmd[3] = { 0x0C, x, y };

	ikbd_write(cmd, 3);
}

/* Interrogate mouse position */
void ikbd_mouse_pos_get(int *x, int *y)
{
	static const char cmd[1] = { 0x0D };

	ikbd_write(cmd, 1);

	/* wait for returning bytes */
}

/* Load mouse position */
void ikbd_mouse_pos_set(int x, int y)
{
	char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF };

	ikbd_write(cmd, 6);
}

/* Set Y=0 at bottom */
void ikbd_mouse_y0_bot(void)
{
	static const char cmd[1] = { 0x0F };

	ikbd_write(cmd, 1);
}

/* Set Y=0 at top */
void ikbd_mouse_y0_top(void)
{
	static const char cmd[1] = { 0x10 };

	ikbd_write(cmd, 1);
}
EXPORT_SYMBOL(ikbd_mouse_y0_top);

/* Resume */
void ikbd_resume(void)
{
	static const char cmd[1] = { 0x11 };

	ikbd_write(cmd, 1);
}

/* Disable mouse */
void ikbd_mouse_disable(void)
{
	static const char cmd[1] = { 0x12 };

	ikbd_write(cmd, 1);
}
EXPORT_SYMBOL(ikbd_mouse_disable);

/* Pause output */
void ikbd_pause(void)
{
	static const char cmd[1] = { 0x13 };

	ikbd_write(cmd, 1);
}

/* Set joystick event reporting */
void ikbd_joystick_event_on(void)
{
	static const char cmd[1] = { 0x14 };

	ikbd_write(cmd, 1);
}

/* Set joystick interrogation mode */
void ikbd_joystick_event_off(void)
{
	static const char cmd[1] = { 0x15 };

	ikbd_write(cmd, 1);
}

/* Joystick interrogation */
void ikbd_joystick_get_state(void)
{
	static const char cmd[1] = { 0x16 };

	ikbd_write(cmd, 1);
}

#if 0
/* This disables all other ikbd activities !!!! */
/* Set joystick monitoring */
void ikbd_joystick_monitor(int rate)
{
	static const char cmd[2] = { 0x17, rate };

	ikbd_write(cmd, 2);

	kb_state.state = JOYSTICK_MONITOR;
}
#endif

/* some joystick routines not in yet (0x18-0x19) */

/* Disable joysticks */
void ikbd_joystick_disable(void)
{
	static const char cmd[1] = { 0x1A };

	ikbd_write(cmd, 1);
}

/* Time-of-day clock set */
void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second)
{
	char cmd[7] = { 0x1B, year, month, day, hour, minute, second };

	ikbd_write(cmd, 7);
}

/* Interrogate time-of-day clock */
void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second)
{
	static const char cmd[1] = { 0x1C };

	ikbd_write(cmd, 1);
}

/* Memory load */
void ikbd_mem_write(int address, int size, char *data)
{
	panic("Attempt to write data into keyboard memory");
}

/* Memory read */
void ikbd_mem_read(int address, char data[6])
{
	char cmd[3] = { 0x21, address>>8, address&0xFF };

	ikbd_write(cmd, 3);

	/* receive data and put it in data */
}

/* Controller execute */
void ikbd_exec(int address)
{
	char cmd[3] = { 0x22, address>>8, address&0xFF };

	ikbd_write(cmd, 3);
}

/* Status inquiries (0x87-0x9A) not yet implemented */

/* Set the state of the caps lock led. */
void atari_kbd_leds(unsigned int leds)
{
	char cmd[6] = {32, 0, 4, 1, 254 + ((leds & 4) != 0), 0};

	ikbd_write(cmd, 6);
}

/*
 * The original code sometimes left the interrupt line of
 * the ACIAs low forever. I hope, it is fixed now.
 *
 * Martin Rogge, 20 Aug 1995
 */

static int atari_keyb_done = 0;

int atari_keyb_init(void)
{
	int error;

	if (atari_keyb_done)
		return 0;

	kb_state.state = KEYBOARD;
	kb_state.len = 0;

	error = request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt,
			    IRQ_TYPE_SLOW, "keyboard/mouse/MIDI",
			    atari_keyboard_interrupt);
	if (error)
		return error;

	atari_turnoff_irq(IRQ_MFP_ACIA);
	do {
		/* reset IKBD ACIA */
		acia.key_ctrl = ACIA_RESET |
				((atari_switches & ATARI_SWITCH_IKBD) ?
				 ACIA_RHTID : 0);
		(void)acia.key_ctrl;
		(void)acia.key_data;

		/* reset MIDI ACIA */
		acia.mid_ctrl = ACIA_RESET |
				((atari_switches & ATARI_SWITCH_MIDI) ?
				 ACIA_RHTID : 0);
		(void)acia.mid_ctrl;
		(void)acia.mid_data;

		/* divide 500kHz by 64 gives 7812.5 baud */
		/* 8 data no parity 1 start 1 stop bit */
		/* receive interrupt enabled */
		/* RTS low (except if switch selected), transmit interrupt disabled */
		acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) |
				((atari_switches & ATARI_SWITCH_IKBD) ?
				 ACIA_RHTID : ACIA_RLTID);

		acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S |
				((atari_switches & ATARI_SWITCH_MIDI) ?
				 ACIA_RHTID : 0);

	/* make sure the interrupt line is up */
	} while ((st_mfp.par_dt_reg & 0x10) == 0);

	/* enable ACIA Interrupts */
	st_mfp.active_edge &= ~0x10;
	atari_turnon_irq(IRQ_MFP_ACIA);

	ikbd_self_test = 1;
	ikbd_reset();
	/* wait for a period of inactivity (here: 0.25s), then assume the IKBD's
	 * self-test is finished */
	self_test_last_rcv = jiffies;
	while (time_before(jiffies, self_test_last_rcv + HZ/4))
		barrier();
	/* if not incremented: no 0xf1 received */
	if (ikbd_self_test == 1)
		printk(KERN_ERR "WARNING: keyboard self test failed!\n");
	ikbd_self_test = 0;

	ikbd_mouse_disable();
	ikbd_joystick_disable();

#ifdef FIXED_ATARI_JOYSTICK
	atari_joystick_init();
#endif

	// flag init done
	atari_keyb_done = 1;
	return 0;
}
EXPORT_SYMBOL_GPL(atari_keyb_init);
