/* * (C) Copyright 2003 * * Thomas Frieden (ThomasF@hyperion-entertainment.com) * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * */ #include #include #include #include #include #include "memio.h" #include "catweasel.h" #include "cw4.h" #include "../menu/menu.h" #define CATW_PCI_VENDOR 0xe159 #define CATW_PCI_PRODUCT 0x0001 #define CATW4_SUBSYS_VENDOR 0x5213 #define CATW4_SUBSYS_ID1 0x0002 #define CATW4_SUBSYS_ID2 0x0003 #define CATW_KEY_DATA 0xd0 #define CATW_KEY_STATUS 0xd4 #define CATW_KS_READY 0x80 #define CATW_NAME "amikbd" #define CATW4_FILEID FileID('C','A','T','4') #undef CATW_DEBUG #ifdef CATW_DEBUG #define dprintf(fmt,args...) printf (fmt ,##args) #else #define dprintf(fmt,args...) #endif int catw_getc(void); int catw_testc(void); static int catw_pci = -1; static unsigned long catw_iobase = 0; static int catw_poll_delay = 20000; static char catw_shift_state = 0; static unsigned char catw_normal_xlate[0x70] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 00 - 0F */ '`','1','2','3','4','5','6','7','8','9','0','ß','\'','\\',0, '0', /* 10 - 1F */ 'q','w','e','r','t','z','u','i','o','p','ü','+', 0 ,'1','2','3', /* 20 - 2F */ 'a','s','d','f','g','h','j','k','l','ö','ä','#', 0 ,'4','5','6', /* 30 - 3F */ '<','y','x','c','v','b','n','m',',','.','-', 0 , 0 ,'7','8','9', /* 40 - 4F */ ' ', 8 , 9 , 13, 13, 27,127, 0 , 0 , 0 ,'-', 0 , 0 , 0 , 0 , 0 , /* 50 - 5F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,'[',']','/','*','+', 0 , /* 60 - 6F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; static unsigned char catw_shifted_xlate[0x70] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 00 - 0F */ '~','!','"','§','$','%','&','/','(',')','=','?','`','|', 0, '0', /* 10 - 1F */ 'Q','W','E','R','T','Z','U','I','O','P','Ü','*', 0 ,'1','2','3', /* 20 - 2F */ 'A','S','D','F','G','H','J','K','L','Ö','Ä','^', 0 ,'4','5','6', /* 30 - 3F */ '>','Y','X','C','V','B','N','M',';',':','_', 0 , 0 ,'7','8','9', /* 40 - 4F */ ' ', 8 , 9 , 13, 13, 27,127, 0 , 0 , 0 ,'-', 0 , 0 , 0 , 0 , 0 , /* 50 - 5F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,'{','}','/','*','+', 0 , /* 60 - 6F */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; //" #define CATW_BUFFER_SIZE 20 static unsigned char catw_buffer[CATW_BUFFER_SIZE]; static int catw_inptr = 0, catw_outptr = 0; void catw_handle(int c) { int kup = (c&0x80); int key = (c&0x7f); switch (key) { case 0x60: case 0x61: case 0x62: if (kup) catw_shift_state = 0; else catw_shift_state = 1; break; case 0x78: /* Reset */ dprintf("Reset!\n"); break; } } int catw_xlate(int c) { c &= 0x7f; switch(c) { case 0x4C: return KEY_PREV_ITEM; case 0x4D: return KEY_NEXT_ITEM; case 0x4E: return KEY_NEXT_OPTION; case 0x4F: return KEY_PREV_OPTION; default: if (catw_shift_state) return catw_shifted_xlate[c]; else return catw_normal_xlate[c]; } } static int catw_fpga_ready(void) { if ((in_byte(catw_iobase + 0x07) & 8) == 8) return 1; else return 0; } static int catw_config_done(void) { if ((in_byte(catw_iobase + 0x07) & 4) == 4) return 1; else return 0; } static void catw_reset_fpga(void) { dprintf("Resetting fpga...\n"); out_byte(catw_iobase + 0x02, 227); out_byte(catw_iobase + 0x03, 0); udelay(1000); out_byte(catw_iobase + 0x03, 65); dprintf("Done\n"); } static void *catw_get_config(uint32 *size) { *size = 59215; return &cw4[0]; } static int catw_program_fpga_config(void) { uint32 length; uint8 b; int i; int try; uint8 *config = (uint8*)catw_get_config(&length); if (!config) { dprintf("Couldn't find core config\n"); return 0; } #ifdef CATW_DEBUG dprintf("Found a config string of %d bytes\n", length); dprintf("starting with...\n"); { int i; for (i=0; i<40; i++) { dprintf("%02x ", *(config+i)); } dprintf("\n"); dprintf("...\n"); for (i=0; i<40; i++) { dprintf("%02x ", *(config+length-40+i)); } dprintf("\n"); } #endif for (i=0; i= CATW_BUFFER_SIZE-1) catw_outptr = 0; else ++catw_outptr; return (int)catw_buffer[catw_outptr]; } static void catw_poll(void) { int x; x = in_byte(catw_iobase + CATW_KEY_STATUS); if (x & CATW_KS_READY) { x = in_byte(catw_iobase + CATW_KEY_DATA); dprintf("got char: %x\n", x); catw_handle(x); if (!(x&0x80)) { x = catw_xlate(x); if (x) { dprintf("xlate: %x\n", x); catw_push((unsigned char)x); } } udelay(1000); out_byte(catw_iobase + CATW_KEY_DATA, 0); } } int catw_getc(void) { int c; do { udelay(catw_poll_delay); catw_poll(); c = catw_pop(); } while (c == -1); return c; } unsigned long long get_ticks(void); unsigned long ticks2usec(unsigned long ticks); int catw_testc(void) { catw_poll(); if (catw_inptr == catw_outptr) return 0; else return 1; }