⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keypad.c

📁 linux环境下的键盘驱动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 + -