📄 keypad.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 + -