📄 s3c2410_kbd.c
字号:
/* * Copyright (C) 2002 SAMSUNG ELECTRONICS * SW.LEE <hitchcar@sec.samsung.com> * * This keyboard driver drives a PS/2 keyboard and mouse connected * to the KMI interfaces. The KMI interfaces are nothing more than * a uart; there is no inteligence in them to do keycode translation. * We leave all that up to the keyboard itself. * * Author: SW.LEE <hitchcar@sec.samsung.com> * Date : $Date: 2002/10/14 09:00:06 $ * * $Revision: 1.1.2.6 $ unknown SW.LEE <hitchcar@sec.samsung.com> - initial Wed Aug 14 2002 Yong-iL Joh <tolkien@mizi.com> - new irq scheme Mon Aug 19 2002 Yong-iL Joh <tolkien@mizi.com> - rearrange smdk's keyboard mapping. - TODO: add kbd_setkeycode/kbd_getkeycode * * 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. */#include <linux/config.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/interrupt.h> /* for in_interrupt */#include <linux/timer.h>#include <linux/init.h>#include <linux/delay.h> /* for udelay */#include <linux/kbd_kern.h> /* for keyboard_tasklet */#include <linux/kbd_ll.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/hardware.h>#include <asm/keyboard.h>/* * Responses : SPI STATUS Reigster SPSTA */#define SPI_COLLISION_ERROR 0x4#define SPI_MULTI_MASTER_ERROR 0x2#define SPI_RX_TX_READY 0x1#define UNSET_OUTPUT() write_gpio_bit(GPIO_KBD_nSS, 0)#define SET_OUTPUT() write_gpio_bit(GPIO_KBD_nSS, 1)#define SPI_WRITE(c) (SPTDAT1 = c)#define SPI_READ(c) (c = SPRDAT1 )/* * key map */static char kbmap[128] = {KK_NONE, KK_LALT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_AGR, KK_BSLH, KK_TAB, KK_Z, KK_A, KK_X, KK_NONE,KK_NONE, KK_NONE, KK_LSFT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_LCTL, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_21, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_ESC, KK_DEL, KK_Q, KK_CAPS, KK_S, KK_C, KK_3,KK_NONE, KK_1, KK_NONE, KK_W, KK_NONE, KK_D, KK_V, KK_4,KK_NONE, KK_2, KK_T, KK_E, KK_NONE, KK_F, KK_B, KK_5, KK_NONE, KK_9, KK_Y, KK_R, KK_K, KK_G, KK_N, KK_6,KK_NONE, KK_0, KK_U, KK_O, KK_L, KK_H, KK_M, KK_7,KK_NONE, KK_MINS, KK_I, KK_P, KK_SEMI, KK_J, KK_COMA, KK_8,KK_NONE, KK_EQLS, KK_ENTR, KK_LSBK, KK_SQOT, KK_FSLH, KK_DOT, KK_NONE,KK_NONE, KK_NONE, KK_RSFT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_BKSP, KK_DOWN, KK_RSBK, KK_UP, KK_LEFT, KK_SPCE, KK_RGHT,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE};static char kbmapFN[128] = {KK_NONE, KK_LALT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_LSFT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_LCTL, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_21, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F3,KK_NONE, KK_F1, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F4,KK_NONE, KK_F2, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F5,KK_NONE, KK_F9, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F6,KK_NONE, KK_F10, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F7,KK_NONE, KK_NUML, KK_NONE, KK_INS, KK_PRNT, KK_NONE, KK_NONE, KK_F8,KK_NONE, KK_BRK, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_RSFT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_PGDN, KK_SCRL, KK_PGUP, KK_HOME, KK_NONE, KK_END,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE};static char kbmapNL[128] = {KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KP_9, KK_NONE, KK_NONE, KP_2, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KP_STR, KP_4, KP_6, KP_3, KK_NONE, KP_0, KP_7,KK_NONE, KK_NONE, KP_5, KP_MNS , KP_PLS, KP_1, KK_NONE, KP_8,KK_NONE, KK_NONE, KP_ENT, KK_NONE, KK_NONE, KP_SLH, KP_DOT, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE};/****************************************************//* * The "program" we send to the keyboard to set it up how we want it: * - default typematic delays * - scancode set 1 */#define KBCTL_NODATA -1#define KBCTL_AGAIN -2static void key_interrupt(int nr, void *devid, struct pt_regs *regs){ static int lastc = -1; static int key_fn_down = 0; static int key_numl_down = 0; u_int val = 0; int x = 0 ,y = 0; int ret = 0; kbd_pt_regs = regs; UNSET_OUTPUT(); while (!((SPSTA1) & SPSTA_READY)); SPI_WRITE(0x0); while (!((SPSTA1) & SPSTA_READY)); SPI_READ(val); SET_OUTPUT(); x = val & 0xff; /* get char by sending one */ if (x == lastc || x == 0 || x == 0xff) { ret = KBCTL_NODATA; tasklet_schedule(&keyboard_tasklet); } lastc = x; if ( x & 0x80) { /* key up */ x &= 0x7f; if (x == 0x21) { /* fn key up */ key_fn_down = 0; ret = KBCTL_AGAIN; } else { if (key_fn_down) { /* this is a fn modified key */ y = kbmapFN[x]; if (y == KK_NUML) ret = KBCTL_AGAIN; } else { if (key_numl_down) /* this is a numlock modified key */ y = kbmapNL[x]; else y = kbmap[x]; } } ret = (y | 0x80); } else { /* key down */ if (x == 0x21) { /* fn key down */ key_fn_down = 1; ret = KBCTL_AGAIN; } else { if (key_fn_down) { /* this is a fn modified key */ y = kbmapFN[x]; if (y == KK_NUML) { /* toggle local numlock */ key_numl_down = !key_numl_down; ret = KBCTL_AGAIN; } } else { if (key_numl_down) /* this is a numlock modified key */ y = kbmapNL[x]; else y = kbmap[x]; } } ret = y; } if ( ret != KBCTL_NODATA ) { if ( ret != KBCTL_AGAIN && ret != KK_NONE) handle_scancode(ret, !(ret & 0x80)); tasklet_schedule(&keyboard_tasklet); } }/* * You must see SPIcoder 06 UR5HCSPI-06 manual and Schematic of S3C2410 */static int __init HW_kbd_init(void){ int ret = -ENODEV; int delay ; set_external_irq(IRQ_KBD, EXT_FALLING_EDGE, GPIO_PULLUP_DIS); set_gpio_ctrl(GPIO_KBD_SPIMISO); set_gpio_ctrl(GPIO_KBD_SPIMOSI); set_gpio_ctrl(GPIO_KBD_SPICLK); set_gpio_ctrl(GPIO_KBD_nSS); set_gpio_ctrl(GPIO_KBD_PWR); write_gpio_bit(GPIO_KBD_PWR, 0); // Setup SPI registers /* Interrupt mode, prescaler enable, master mode, active high clock, format B, normal mode */ SPCON1 = (SPCON_SMOD_INT | SPCON_ENSCK | SPCON_MSTR | SPCON_CPOL_HIGH | SPCON_CPHA_FMTB); /* Developer MUST change the value of prescaler properly whenever value of PCLK is changed. */ SPPRE1 = 255; // 99.121K = 203M/4/2/(255+1) PCLK=50.75Mhz FCLK=203Mhz SPICLK=99.121Khz for (delay=0; delay < 10; delay++) SPI_WRITE(0xff); /* * Claim the appropriate interrupts */ ret = request_irq(IRQ_KBD, key_interrupt, SA_INTERRUPT, "keyboard", key_interrupt); if (ret) { printk(KERN_INFO "request IRQ failed (%d)\n", IRQ_KBD); return ret; } return ret;}static int s3c_kbd_translate(u_char scancode, u_char *keycode, char raw_mode){// *keycode = scancode & 0x7f; *keycode = scancode; return 1;}int __init s3c2410_kbd_init(void) { int ret = -ENODEV; ret = HW_kbd_init(); if (ret) return ret; /* include/asm/keyboard.h , we have not key_ops_struct */ k_translate = s3c_kbd_translate; return 0;}/* | $Id: s3c2410_kbd.c,v 1.1.2.6 2002/10/14 09:00:06 nandy Exp $ | | Local Variables: | mode: c | mode: font-lock | version-control: t | delete-old-versions: t | End: | | -*- End-Of-File -*- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -