/*
 * linux/atari/atakeyb.c
 *
 * atari Keyboard driver for 680x0 Linux
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file README.legal in the main directory of this archive
 * for more details.
 */

/*
 * atari support by Bj”rn Brauel
 */

#include <linux/config.h>
#include <linux/sched.h>
#include <linux/keyboard.h>
#include <linux/delay.h>
#include <linux/interrupt.h>

#include <linux/ataritypes.h>
#include <linux/atariints.h>
#include <linux/atarihw.h>

extern void process_scancode (int);

#define ATAKEY_CAPS	(0x3a)
#define BREAK_MASK	(0x80)

/*
 * This table maps the atari keyboard scan codes to
 * the Linux "virtual" scan codes.  These "virtual" scan
 * codes mostly conform to the scan codes given by an IBM
 * keyboard, except that the E0 xx codes are given unique
 * codes.  These are the codes > 96.  See linux/keyboard.h
 */


static unsigned char ata_kmap[] =
{
               KB_NONE,
/* 00-03 */    KB_ESCAPE,   KB_1,	    KB_2,	  KB_3,
/* 04-07 */    KB_4,	      KB_5,	    KB_6,	  KB_7,
/* 08-0B */    KB_8,	      KB_9,	    KB_0,	  KB_KPMINUS,
/* 0C-0F */    KB_EQUAL,    KB_BACKSPACE, KB_TAB,	  KB_Q,
/* 10-13 */    KB_W,	      KB_E,	    KB_R,	  KB_T,
/* 14-17 */    KB_Y,	      KB_U,	    KB_I,	  KB_O,
/* 18-1B */    KB_P,	 	    KB_LSQUARE,   KB_RSQUARE, KB_ENTER,
/* 1C-1F */    KB_LCTRL,    KB_A,	    KB_S,	  KB_D,
/* 20-23 */    KB_F,	      KB_G,	    KB_H,	  KB_J,
/* 24-27 */    KB_K,	      KB_L,	    KB_SEMICOLON,	 KB_APOSTROPHE,
/* 28-2B */    KB_NONE,     KB_LSHIFT,    KB_BACKSLASH,	  KB_Z ,
/* 2C-2F */    KB_X,        KB_C,	    KB_V,	  KB_B,
/* 30-33 */    KB_N,	      KB_M,	    KB_COMMA,	  KB_PERIOD,
/* 34-37 */    KB_SLASH,    KB_RSHIFT,    KB_NONE,	  KB_LALT,
/* 38-3B */    KB_SPACE,    KB_CAPS,    KB_F1,	  KB_F2,
/* 3C-3F */    KB_F3,       KB_F4,	    KB_F5,	  KB_F6,
/* 40-43 */    KB_F7,       KB_F8,	    KB_F9,	  KB_F10,
/* 44-47 */    KB_NONE,     KB_NONE,	    KB_NONE,	  KB_UP,
/* 48-4B */    KB_NONE,     KB_KPMINUS,	  KB_LEFT,	  KB_NONE,
/* 4C-4F */    KB_RIGHT,    KB_KPPLUS,	    KB_NONE,	  KB_DOWN,
/* 50-53 */    KB_NONE,     KB_NONE,	    KB_DELETE,	  KB_NONE,
/* 54-57 */    KB_NONE,     KB_NONE,	    KB_NONE,	  KB_NONE,
/* 58-5B */    KB_NONE,     KB_NONE,	    KB_NONE,	  KB_NONE,
/* 5B-5F */    KB_NONE,     KB_NONE,	    KB_NONE,	  KB_NONE,
/* 60-63 */    KB_NONE,     KB_NONE,	    KB_NONE,	  KB_NONE,
/* 64-67 */    KB_NONE,     KB_NONE,	    KB_KP7,	  KB_KP8,
/* 68-6B */    KB_KP9,      KB_KP4,	    KB_KP5,	  KB_KP6,
/* 6C-6F */    KB_KP1,      KB_KP2,	    KB_KP3,	  KB_KP0,
/* 70-73 */    KB_NONE,     KB_KPENTER,	    KB_NONE,	  KB_NONE,
/* 74-77 */    KB_NONE,     KB_NONE,	    KB_NONE,	  KB_NONE,
/* 78-7B */    KB_NONE,     KB_NONE,	    KB_NONE,	  KB_NONE,
/* 7C-7F */    KB_NONE,     KB_NONE,	    KB_NONE
};

static void keyboard_interrupt(struct intframe *fp, void *data)
{
    unsigned short acia_str;
    unsigned short acia_dta;
    unsigned char scancode, break_flag;
    
    acia_str=acia.key_ctrl;
    acia_dta=acia.key_data;
    
    acia_str &= 0x80;                   /* Is it really Keyboard ACIA ? */
    if(acia_str!=0x00)
     {
      scancode=acia_dta;    
      break_flag = scancode & BREAK_MASK;
      scancode &= (unsigned char )~BREAK_MASK;

      if (scancode == ATAKEY_CAPS) {
	      /* if the key is CAPS, fake a press/release. */
	      process_scancode (ata_kmap[ATAKEY_CAPS]);
	      process_scancode (BREAK_MASK | ata_kmap[ATAKEY_CAPS]);
       } else
      process_scancode (break_flag | ata_kmap[scancode]);
     }
    return;
}

unsigned long atari_keyb_init (unsigned long mem_start)
{
    long i;
    add_isr (IRQ_MFP_ACIA, keyboard_interrupt, 0, NULL);

    return mem_start;
}
