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

📄 keypad.old

📁 之前在 embedded linux 上写 keypad driver 参考的源代码,有写 keypad driver 需要的朋友可以参考
💻 OLD
字号:
#include <linux/init.h>     /*for init and cleanup*/#include <linux/module.h>#include <linux/config.h>#include <linux/kernel.h>   /* printk() */#include <linux/sched.h>#include <linux/fs.h>       /* everything... */#include <linux/errno.h>    /* error codes */#include <linux/types.h>    /* size_t */#include <linux/timer.h>#ifdef UCSIMM#   include<asm/MC68EZ328.h>#endif#ifdef PCPARPORT#   include <linux/ioport.h>   /*for pc parport control*/#endif#include "sysdep.h"#ifndef __KERNEL__#  define __KERNEL__#endif#ifndef MODULE#  define MODULE#endif#ifdef LINUX_20#  error "This module will not run with linux-2.0" #endif #define TRUE 1#define FALSE 0#define KPBUFSIZE 100 #ifdef PCPARPORT#   define KP_PORT_READ         (inb(base+1))#   define KP_PORT_WRITE(A)     (outb((A),base))#endif#ifdef UCSIMM#   define KP_PORT_READ         (PDDATA)#   define KP_PORT_WRITE(A)     ((PDDATA) = (A))#endifstatic int keypad_major = 0;MODULE_PARM(keypad_major, "i");   /* let the user choose the major number */MODULE_AUTHOR("John Jarvis - jarv@verizon.net");/* * ssize_t = signed size type * loff_t = long offset type (usually 64 bits wide) */static int pop (void);static void push (int);int keypad_open(struct inode *inode, struct file *filp);int keypad_release(struct inode *inode, struct file *filp);size_t keypad_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);#ifdef PCPARPORTstatic unsigned long base = 0x378;MODULE_PARM(base, "l");  /*override the parport base address*/#endif/*circular char buffer*/static struct kpcircbuf  {    int start;    int end;    int isfull;    int isempty;    int buf[KPBUFSIZE];} kpbuf = { 0,0,FALSE,TRUE };/* WAIT PROCESS QUEUE FOR BLOCKING I/O */DECLARE_WAIT_QUEUE_HEAD(kp_queue);/**/static int kpkeystate = 0;static struct timer_list poll_timer;struct file_operations keypad_fops = {    read:       keypad_read,    open:       keypad_open,    release:    keypad_release,    owner:      THIS_MODULE,};int keypad_open(struct inode *inode, struct file *filp){    printk("keypad_open()\n");    MOD_INC_USE_COUNT;    return(0);}int keypad_release(struct inode *inode, struct file *filp){    MOD_DEC_USE_COUNT;    return 0;}size_t keypad_read(struct file *filp, char *buf, size_t count, loff_t *f_pos){    int popd_key,cnt;    int retval = count;    //char key;    char userbuf[KPBUFSIZE] = {0};     if (kpbuf.isempty)    //if our circular buffer is empty we block until a keypress           interruptible_sleep_on(&kp_queue);     /*  * This loop pops keys off our circular FIFO buffer  *      and adds them to a local buffer which later gets copied to userspace.   * This will not grab more than the user requests (count).   * If the user requests more than what is in our FIFO buffer than it will break out *      early and return what we have. * */    for (cnt = 0; cnt < count; cnt++) {         popd_key = pop();        if (popd_key == -1)              break;        //key = (char)(popd_key);  /*m68k doesn't like this :( */        sprintf(userbuf, "%s%c",userbuf,popd_key);     }#ifdef DEBUG    printk("before copy_to_user\n");#endif    copy_to_user(buf, userbuf, cnt);#ifdef DEBUG    printk("after copy_to_user\n");#endif    retval = cnt;    return retval; }/* * Below we have our simple keypad matrix scan * When it detects a keypress it pushs the ascii code of the key on our * circular buffer. * */void keypad_poll(void){    del_timer(&poll_timer);    KP_PORT_WRITE(0xE);    wmb();         if (!(KP_PORT_READ & 0x10))  {            if (!(kpkeystate & 0x200)) push(57); //printk("keypress 9 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x200;         }        else kpkeystate = kpkeystate & 0xDFF;                         if (!(KP_PORT_READ  & 0x20))  {            if (!(kpkeystate & 0x100)) push(56); //printk("keypress 8 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x100;         }        else kpkeystate = kpkeystate & 0xEFF;                                 if (!(KP_PORT_READ & 0x40 ))  {            if (!(kpkeystate & 0x080)) push(55); //printk("keypress 7 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x080;         }        else kpkeystate = kpkeystate & 0xF7F;             rmb();        KP_PORT_WRITE(0xD);     wmb();              if (!(KP_PORT_READ & 0x10))  {            if (!(kpkeystate & 0x040)) push(54); //printk("keypress 6 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x040;         }                else kpkeystate = kpkeystate & 0xFBF;         if (!(KP_PORT_READ & 0x20))  {            if (!(kpkeystate & 0x020)) push(53); //printk("keypress 5 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x020;         }        else kpkeystate = kpkeystate & 0xFDF;        if (!(KP_PORT_READ & 0x40))  {            if (!(kpkeystate & 0x010)) push(52); //printk("keypress 4 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x010;        }        else kpkeystate = kpkeystate & 0xFEF;     rmb();        KP_PORT_WRITE(0xB);    wmb();                 if (!(KP_PORT_READ & 0x10))  {            if (!(kpkeystate & 0x008)) push(51); //printk("keypress 3 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x008;         }        else kpkeystate = kpkeystate & 0xFF7;                         if (!(KP_PORT_READ  & 0x20))  {            if (!(kpkeystate & 0x004)) push(50); //printk("keypress 2 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x004;         }        else kpkeystate = kpkeystate & 0xFFB;                                 if (!(KP_PORT_READ & 0x40 ))  {            if (!(kpkeystate & 0x002)) push(49); //printk("keypress 1 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x002;         }        else kpkeystate = kpkeystate & 0xFFD;             rmb();    KP_PORT_WRITE(0x7);    wmb();          if (!(KP_PORT_READ & 0x10))  {            if (!(kpkeystate & 0x400)) push(42); //printk("keypress * - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x400;         }        else kpkeystate = kpkeystate & 0xBFF;                         if (!(KP_PORT_READ  & 0x20))  {            if (!(kpkeystate & 0x001)) push(48); //printk("keypress 0 - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x001;         }        else kpkeystate = kpkeystate & 0xFFE;                                 if (!(KP_PORT_READ & 0x40 ))  {            if (!(kpkeystate & 0x800)) push(35); //printk("keypress # - %ld\n",jiffies);            kpkeystate = kpkeystate | 0x800;         }        else kpkeystate = kpkeystate & 0x7FF;             rmb();                poll_timer.expires = jiffies + 1;    add_timer(&poll_timer);}static void push (int x){#ifdef DEBUG    printk("push!\n");#endif   	if (!kpbuf.isfull) {		kpbuf.buf[kpbuf.end] = x;        kpbuf.end = kpbuf.end + 1;		kpbuf.isempty = FALSE;		if (kpbuf.end == KPBUFSIZE) kpbuf.end = 0;	}	(kpbuf.end == kpbuf.start) ? (kpbuf.isfull = TRUE) : (kpbuf.isfull = FALSE);    wake_up_interruptible(&kp_queue);  // a button was pushed! wake up!}static int pop (void){	int retval = -1;#ifdef DEBUG    printk("pop!\n");#endif	if (!kpbuf.isempty) {		retval = kpbuf.buf[kpbuf.start];        kpbuf.start = kpbuf.start + 1;		if (kpbuf.start == KPBUFSIZE) kpbuf.start = 0;	}	(kpbuf.start == kpbuf.end) ? (kpbuf.isempty = TRUE) : (kpbuf.isempty = FALSE);	return(retval);}static int my_init(void) {    int result;    result = register_chrdev(keypad_major, "keypad", &keypad_fops);    if (result < 0)  {        printk(KERN_WARNING "keypad: unable to get major %d\n", keypad_major);        return result;    }    if (keypad_major == 0)        keypad_major = result;#ifdef UCSIMM      PDSEL = 0x7f;  //select PD0-PD6 for I/O      PDDIR = 0x0f;  //select PD0-PD3 for output#endif#ifdef PCPARPORT     /* attempt to allocate the I/O region for the PC parport  */    result = check_region(base,1);    if (result) {        printk(KERN_INFO "keypad: can't get I/O address 0x%ld\n",base);        return result;    }    request_region(base,1,"keypad");    /* init the port to zero */    outb(0,base);    wmb();  /*write memory barrier*/#endif    /* set up kernel timer */    poll_timer.expires = jiffies + 1;    poll_timer.function = keypad_poll;    add_timer(&poll_timer);        printk("<1>keypad Module Loaded\n");    return 0;}static void my_cleanup(void) {#ifdef PCPARPORT    /* release I/O region for parport */     release_region(base,1);#endif    /* remove our kernel timer */    del_timer(&poll_timer);    unregister_chrdev(keypad_major, "keypad");    printk("<1>keypad Module Unloaded\n");}/*<1> is the priority of the message*/module_init(my_init);module_exit(my_cleanup);    

⌨️ 快捷键说明

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