📄 keypad.c
字号:
/* * Copyright (C) 2004 Gexin TECH * * * * 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/module.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/modversions.h>#include <linux/version.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <asm/hardware.h>//------------------------------------------------------------------------------#include <linux/config.h>#include <linux/spinlock.h>//#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/tty.h>#include <linux/mm.h>#include <linux/signal.h>//#include <linux/init.h>#include <linux/kbd_ll.h>//#include <linux/delay.h>#include <linux/random.h>#include <linux/poll.h>#include <linux/miscdevice.h>#include <linux/slab.h>#include <linux/kbd_kern.h>#include <linux/vt_kern.h>#include <linux/smp_lock.h>#include <linux/kd.h>#include <linux/pm.h>#include <linux/vmalloc.h>#include <linux/fs.h>//#include <asm/keyboard.h>#include <asm/bitops.h>#include <asm/irq.h>#include <asm/system.h>#include <asm/io.h>//------------------------------------------------------------------------------#include "keypad.h"u32 old , pre_scancode, scancode;u8 ui8ScanCode;//#define HR_DEBUG 1//------------------------------------------------------------------------------#define IRQ_keypad_INT IRQ_EINT1#define GPIO_SimpleINT_EINT1 (GPIO_MODE_ALT0 | GPIO_PULLUP_EN | GPIO_F1) //For ringing detect#define ONEBIT 0x1#define KEYPADCSDIS (GPBDAT |=(ONEBIT << 6))#define KEYPADCSEN (GPBDAT &=~(ONEBIT << 6))#define KEYPADDIRMO (GPBDAT &=~(ONEBIT << 0))#define KEYPADDIRMI (GPBDAT |=(ONEBIT << 0))int numlock ;static int DELAY_TIME=100;//------------------------------------------------------------------------------//send command to keypad controllerint putcToKBCTL(u8 c){ u32 i;// UINT rxbuf[10];// UINT x; KEYPADCSEN; KEYPADDIRMO; udelay(60); while((SPSTA1 & ONEBIT)==0); // wait while busy SPTDAT1 = c; // write left justified data transfer/send while((SPSTA1 & ONEBIT)==0); // wait while busy KEYPADCSDIS; i = SPRDAT1; //receive return(i);}int KeyPadInit(){ int t; char dummy = (char)0xff; // Setup IO port for SPI interface & Keyboard // Setup EINT1 (KBDINT) GPFCON &= ~(0x3 << 2); // Clear GPF1 GPFCON |= (0x2 << 2); // Set GPF1 to EINT1 for Keyboard interrupt EXTINT0 &= ~(0x7 << 4); // Clear EINT1 EXTINT0 |= (0x2 << 4); // fallig edge triggered for EINT1 // setup SPI interface // GPG5 : SPIMISO (KBDSPIMISO) // GPG6 : SPIMOSI (KBDSPIMOSI) // GPG7 : SPICLK (KBDSPICLK) GPGCON &= ~((0x3 << 10) | (0x3 << 12) | (0x3 << 14)); // Clear GPG5,6,7 GPGCON |= ((0x3 << 10) | (0x3 << 12) | (0x3 << 14)); // Set GPG5,6,7 // setup _SS signal(nSS_KBD) GPBCON &= ~(0x3 << 12); // Clear GPB6 GPBCON |= (ONEBIT << 12); // Set Port GPB6 to output for nSS signal KEYPADCSDIS; // Set /SS high // setup Dir signal (KEYBOARD) CPU->7289 GPBCON &= ~(0x3 << 0); // Clear GPB0 GPBCON |= (ONEBIT << 0); // Set Port GPB0 to output for _PWR_OK signal // rGPDDAT &=~(ONEBIT << 0); // set _PWR_OK to 0 KEYPADDIRMO; // Setup SPI registers // Interrupt mode, prescaler enable, master mode, active high clock, format B, normal mode // rSPCON1 = (ONEBIT<<5)|(ONEBIT<<4)|(ONEBIT<<3)|(0x0<<2)|(ONEBIT<<1); // Poll mode, prescaler enable, master mode, active high clock, format A, normal mode SPCON1 = (0<<5)|(ONEBIT<<4)|(ONEBIT<<3)|(0x0<<2)|(0<<1); // 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 putcToKBCTL(0xa4); //send init command printk("Key Pad Init complete:\n"); numlock = 0;// rSRCPND = BIT_EINT1; //to clear the previous pending states// rINTPND = BIT_EINT1; //Define the keypad int entry// pISR_EINT1 = (unsigned)KeyPad_Int;// rINTMSK=~(BIT_EINT1); //enable Eint return(1);}u8 readKBValue(void){ unsigned char i; KEYPADCSEN; KEYPADDIRMO; udelay(60); while((SPSTA1 & ONEBIT)==0); // wait while busy SPTDAT1 = 0x15; // write read key value command while((SPSTA1 & ONEBIT)==0); // wait while busy udelay(30);//delay 30us KEYPADDIRMI; SPTDAT1 = 0xff; // write read key value command while((SPSTA1 & ONEBIT)==0); // wait while busy i = SPRDAT1; KEYPADCSDIS; KEYPADDIRMO; return(i);}void HR_del_pre_scancode(u32 p_scancode){ switch (p_scancode) { case KEYPAD0: if(numlock == 0) { handle_scancode(0x52,!(0x52 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xd2,!(0xd2 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); } else { handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0x52,!(0x52 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xd2,!(0xd2 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); }#ifdef HR_DEBUG printk("KEYPAD0\n");#endif break; case KEYPAD1: if(numlock == 0) { handle_scancode(0x4f,!(0x4f & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xcf,!(0xcf & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); } else { handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0x4f,!(0x4f & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xcf,!(0xcf & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); }#ifdef HR_DEBUG printk("KEYPAD1\n");#endif break; case KEYPAD2: if(numlock == 0) { handle_scancode(0x50,!(0x50 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xd0,!(0xd0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); } else { handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0x50,!(0x50 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xd0,!(0xd0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); }#ifdef HR_DEBUG printk("KEYPAD2\n");#endif break; case KEYPAD3: if(numlock == 0) { handle_scancode(0x51,!(0x51 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xd1,!(0xd1 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); } else { handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0x51,!(0x51 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xd1,!(0xd1 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); }#ifdef HR_DEBUG printk("KEYPAD3\n");#endif break; case KEYPAD4: if(numlock == 0) { handle_scancode(0x4b,!(0x4b & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xcb,!(0xcb & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); } else { handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0x4b,!(0x4b & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xe0,!(0xe0 & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xcb,!(0xcb & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); }#ifdef HR_DEBUG printk("KEYPAD4\n");#endif break; case KEYPAD5: handle_scancode(0x4c,!(0x4c & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xcc,!(0xcc & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME);#ifdef HR_DEBUG printk("KEYPAD5\n");#endif break; case KEYPAD6: if(numlock == 0) { handle_scancode(0x4d,!(0x4d & 0x80)); tasklet_schedule(&keyboard_tasklet); udelay(DELAY_TIME); handle_scancode(0xcd,!(0xcd & 0x80)); tasklet_schedule(&keyboard_tasklet);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -