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

📄 kdriver.c

📁 嵌入式linux下的4*5键盘驱动功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: khello-driver.c,v 0.01 2008/10/01  $ * *  Copyright (c) 2005-2008 69zsx * *  Based on the work of: *	vojtech Exp *//* * scan keyboard driver for Linux/arm/at91rm9200 *//* * 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 * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/input.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/timer.h>#include <linux/wait.h>#include <asm/irq.h>//#include <asm/arch/AT91RM9200_SYS.h>#include <asm/arch-at91rm9200/hardware.h>#include <asm/delay.h>#include <asm/uaccess.h>#define KB_ROWS			4#define KB_COLS			5#define KB_ROWMASK(r)		(1 << (r))#define SCANCODE(r,c)		( ((r)<<2) + (c) + r )#define	NR_SCANCODES		20#define SCAN_INTERVAL		(HZ/10)#define SCAN_KBD_PRESSED		1MODULE_DESCRIPTION("at91rm9200 keyboard module");MODULE_AUTHOR("69zsx");MODULE_LICENSE("GPL");static unsigned long kbd_status = 0;/*static unsigned char scan_kbd_keycode[20] = {	[0]	 = KEY_DOWN,	[1]	 = KEY_UP,	[2]	 = KEY_3,	[3]	 = KEY_6,	[4]	 = KEY_9,	[5]	 = 0,	[6]	 = KEY_0,	[7]	 = KEY_2,	[8]	 = KEY_5,	[9]	 = KEY_8,	[10]	 = 0,		[11]	 = 0,		[12]	 = KEY_1,	[13]	 = KEY_4,		[14]	 = KEY_7,	[15]	 = 0,		[16]	 = KEY_BACKSPACE,	[17]	 = KEY_ESC,	[18]	 = KEY_ENTER,	[19]	 = KEY_DOT,};*//*static unsigned char scan_kbd_keycode[20] = {	0,KEY_1,KEY_2,KEY_ESC,KEY_ENTER,	KEY_DOWN,KEY_UP,KEY_9,KEY_6,KEY_3,	0,KEY_0,KEY_8,KEY_5,KEY_2,	0,0,KEY_7,KEY_4,KEY_1,};*///转换后的键码CHANGE:  1 PRINT:  2static unsigned char scan_kbd_keycode[20] = {	[0]	 = 0,	[1]	 = KEY_TAB,	[2]	 = KEY_TAB,	[3]	 = KEY_ESC,	[4]	 = KEY_ENTER,	[5]	 = KEY_DOWN,	[6]	 = KEY_UP,	[7]	 = KEY_9,	[8]	 = KEY_6,	[9]	 = KEY_3,	[10]	 = 0,	[11]	 = KEY_0,	[12]	 = KEY_8,	[13]	 = KEY_5,	[14]	 = KEY_2,	[15]	 = 0,	[16]	 = 0,	[17]	 = KEY_7,	[18]	 = KEY_4,	[19]	 = KEY_1,};struct scankbd {	unsigned char keycode[20];	struct input_dev scan_kbd_dev;	char phys[32];	unsigned char state[20];	spinlock_t lock;	struct timer_list scan_timer;	};struct scankbd *scankbd_dev;static void handle_scancode(unsigned int pressed,unsigned int scancode, struct scankbd *scankbd_data){//pressed = 0 	if (pressed && !(scankbd_data->state[scancode] & SCAN_KBD_PRESSED)) {		scankbd_data->state[scancode] |= SCAN_KBD_PRESSED;//1 		input_report_key(&scankbd_data->scan_kbd_dev, scankbd_data->keycode[scancode], 1);		printk(KERN_ALERT "keycode %i\n", scankbd_data->keycode[scancode]);	} else if (!pressed && scankbd_data->state[scancode] & SCAN_KBD_PRESSED) {		scankbd_data->state[scancode] &= ~SCAN_KBD_PRESSED;//		//input_report_key(&scankbd_data->scan_kbd_dev, scankbd_data->keycode[scancode], 0);		printk(KERN_ALERT "keycode %i\n", scankbd_data->keycode[scancode]);	}}static char *scan_kbd_name = "scan 4*5 keyboard";static char *scan_kbd_phys = "scankbd";unsigned int readr;/* Helper functions for reading the keyboard matrix * Note: We should really be using pxa_gpio_mode to alter GPDR but it *       requires a function call per GPIO bit which is excessive *       when we need to access 12 bits at once multiple times. * These functions must be called within local_irq_save()/local_irq_restore() * or similar. */void  KBD_CLOSE_INT(void){//interrupt enable register  IER/interrupt disable register IDR	AT91_SYS->PIOB_IER  &=  ~( AT91C_PIO_PB9 | AT91C_PIO_PB10 | AT91C_PIO_PB11 | AT91C_PIO_PB12 );//	AT91_SYS->PIOB_IDR  |=  ( AT91C_PIO_PB9 | AT91C_PIO_PB10 | AT91C_PIO_PB11 | AT91C_PIO_PB12 );}  unsigned char ISKBD_DOWN(void){    	unsigned int status  = AT91C_PIO_PB9 | AT91C_PIO_PB10 | AT91C_PIO_PB11 | AT91C_PIO_PB12;	if( (AT91_SYS->PIOB_PDSR & status) !=  status)//pin data status register		return  1;	else		return  0;} 	void KBD_OPEN_INT(void){	AT91_SYS->PIOB_IER  |=  ( AT91C_PIO_PB9 | AT91C_PIO_PB10 | AT91C_PIO_PB11 | AT91C_PIO_PB12 );	AT91_SYS->PIOB_IDR  &=  ~( AT91C_PIO_PB9 | AT91C_PIO_PB10 | AT91C_PIO_PB11 | AT91C_PIO_PB12 );}void scan_kbd_discharge_all(void){//all set high//	at91_set_gpio_value(AT91_PIN_PB1,0);//	at91_set_gpio_value(AT91_PIN_PB2,0);//	at91_set_gpio_value(AT91_PIN_PB6,0);//	at91_set_gpio_value(AT91_PIN_PA24,0);	at91_set_gpio_value(AT91_PIN_PB7,0);	at91_set_gpio_value(AT91_PIN_PB8,0);	at91_set_gpio_value(AT91_PIN_PB15,0);	at91_set_gpio_value(AT91_PIN_PB16,0);	at91_set_gpio_value(AT91_PIN_PB17,0);}static inline void scan_kbd_activate_all(void){//	at91_set_gpio_value(AT91_PIN_PB1,1);//	at91_set_gpio_value(AT91_PIN_PB2,1);//	at91_set_gpio_value(AT91_PIN_PB6,1);//	at91_set_gpio_value(AT91_PIN_PA24,1);	at91_set_gpio_value(AT91_PIN_PB7,1);	at91_set_gpio_value(AT91_PIN_PB8,1);	at91_set_gpio_value(AT91_PIN_PB15,1);	at91_set_gpio_value(AT91_PIN_PB16,1);	at91_set_gpio_value(AT91_PIN_PB17,1);}static inline int GET_ROWS_STATUS(int col){//read all rows'status /*   	int rd=0;	int rd_t=0;	rd = at91_get_gpio_value(AT91_PIN_PB1);	rd_t |= !rd;	rd = at91_get_gpio_value(AT91_PIN_PB2);	rd_t |= (!rd)<<1;	rd = at91_get_gpio_value(AT91_PIN_PB6);	rd_t |= (!rd)<<2;	rd = at91_get_gpio_value(AT91_PIN_PA24);	rd_t |= (!rd)<<3;	//printk(KERN_ALERT "rd %i\n", rd_t);*/	//udelay(10);	unsigned int rd=0xf;	unsigned int rd_t=0;		rd_t |= rd & at91_get_gpio_value(AT91_PIN_PA24);	rd_t |= rd & (at91_get_gpio_value(AT91_PIN_PB1)<<1);	rd_t |= rd & (at91_get_gpio_value(AT91_PIN_PB2)<<2);	rd_t |= rd & (at91_get_gpio_value(AT91_PIN_PB6)<<3);	rd_t = ~rd_t & 0xf;	//printk(KERN_ALERT "rd %i\n", rd_t);	return rd_t;}static inline void scan_kbd_activate_col(int col){//Set one col is 0		switch(col)	{		case 0:			at91_set_gpio_value(AT91_PIN_PB7,1);			break;		case 1:			at91_set_gpio_value(AT91_PIN_PB8,1);			break;		case 2:			at91_set_gpio_value(AT91_PIN_PB15,1);			break;		case 3:			at91_set_gpio_value(AT91_PIN_PB16,1);			break;		case 4:			at91_set_gpio_value(AT91_PIN_PB17,1);			break;	}}static inline void scan_kbd_reset_col(int col){//reset cols 1	switch(col)	{		case 0:			at91_set_gpio_value(AT91_PIN_PB7,0);			break;		case 1:			at91_set_gpio_value(AT91_PIN_PB8,0);			break;		case 2:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -