lkml.org 
[lkml]   [2000]   [Oct]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] interface for pc-keyb extetion
Hallo,

I have a few PS2 / POS-Keyboard's (POS = Point of sale).
All the Keyboard have all additional devices, they ar Keylock,
Magnetical Reader, and Display's. All the Devices work
over the pc-Keyboard Controller.
I have written an extention for the pc_keyb.c Modul.
With this modul can I use the Standard - Functionen from
the pc-Keyb, but I can handle the additional Scancodes.
I can use a additions write routine for write Display-Data
and Spezially init Sequences.

Expample: A keylock-Change send's the scancode sequence
<Make Ctrl><Break Ctrl><Break Ctrl> 'K' {Keyposition}

My extention is simple, I think this Patch is interrest for
all the exotic Keyboard'a with exotic Key's.

I test the patch with the kernel 2.2.16

I have attacht a Simple Modul what use the extention,
(sorry a first test module)


Thank's

Michael Westermann


--- linux.org/include/linux/pc_keyb.h Mon Aug 9 21:04:41 1999
+++ linux/include/linux/pc_keyb.h Mon Oct 9 13:25:31 2000
@@ -128,3 +128,17 @@
struct fasync_struct *fasync;
unsigned char buf[AUX_BUF_SIZE];
};
+
+typedef struct {
+ void (*kbd_write_command_w)(int data);
+ void (*kbd_write_output_w) (int data);
+ int (*do_acknowledge) (unsigned char scancode);
+ int (*kbd_check_event) (unsigned char * scancode);
+ unsigned char reply_expected;
+ unsigned char acknowledge;
+ unsigned char resend;
+} pc_keyb_t;
+
+int register_kbd_ex (pc_keyb_t * kb);
+int unregister_kbd_ex (pc_keyb_t * kb);
+
--- linux.org/drivers/char/pc_keyb.c Thu Jul 6 22:21:31 2000
+++ linux/drivers/char/pc_keyb.c Tue Oct 10 10:25:01 2000
@@ -13,10 +13,12 @@
* Code fixes to handle mouse ACKs properly.
* C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
*
+ * Include a interface for pc keyboard's with extentions
+ * M.Westermann <mw@microdata-pos.de> Tue, 10 Oct 2000
*/

#include <linux/config.h>
-
+#include <linux/module.h>
#include <asm/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
@@ -41,6 +43,9 @@

#include <linux/pc_keyb.h>

+EXPORT_SYMBOL(unregister_kbd_ex);
+EXPORT_SYMBOL(register_kbd_ex);
+
/* Simple translation table for the SysRq keys */

#ifdef CONFIG_MAGIC_SYSRQ
@@ -64,10 +69,9 @@
static unsigned char handle_kbd_event(void);

/* used only by send_data - set by keyboard_interrupt */
-static volatile unsigned char reply_expected = 0;
-static volatile unsigned char acknowledge = 0;
-static volatile unsigned char resend = 0;
-
+static volatile pc_keyb_t kbd_ex_mem;
+static volatile pc_keyb_t * kbd_ex;
+static volatile pc_keyb_t * kbd_store;

#if defined CONFIG_PSMOUSE
/*
@@ -260,19 +264,19 @@

static int do_acknowledge(unsigned char scancode)
{
- if (reply_expected) {
+ if (kbd_ex->reply_expected) {
/* Unfortunately, we must recognise these codes only if we know they
* are known to be valid (i.e., after sending a command), because there
* are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
* keys with such codes :(
*/
if (scancode == KBD_REPLY_ACK) {
- acknowledge = 1;
- reply_expected = 0;
+ kbd_ex->acknowledge = 1;
+ kbd_ex->reply_expected = 0;
return 0;
} else if (scancode == KBD_REPLY_RESEND) {
- resend = 1;
- reply_expected = 0;
+ kbd_ex->resend = 1;
+ kbd_ex->reply_expected = 0;
return 0;
}
/* Should not happen... */
@@ -448,11 +452,15 @@
# ifdef CHECK_RECONNECT_SCANCODE
printk(KERN_INFO "-=db=-: kbd_read_input() : scancode == %d\n",scancode);
# endif
+ // printk("scancode = %02x\n",scancode);
if (status & KBD_STAT_MOUSE_OBF) {
handle_mouse_event(scancode);
} else {
- if (do_acknowledge(scancode))
- handle_scancode(scancode, !(scancode & 0x80));
+ if (kbd_ex->do_acknowledge(scancode)) {
+ if (kbd_ex->kbd_check_event)
+ kbd_ex->kbd_check_event(&scancode);
+ handle_scancode(scancode, !(scancode & 0x80));
+ }
mark_bh(KEYBOARD_BH);
}

@@ -495,14 +503,14 @@
do {
unsigned long timeout = KBD_TIMEOUT;

- acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
- resend = 0;
- reply_expected = 1;
+ kbd_ex->acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
+ kbd_ex->resend = 0;
+ kbd_ex->reply_expected = 1;
kbd_write_output_w(data);
for (;;) {
- if (acknowledge)
+ if (kbd_ex->acknowledge)
return 1;
- if (resend)
+ if (kbd_ex->resend)
break;
mdelay(1);
if (!--timeout) {
@@ -721,8 +729,61 @@
return NULL;
}

+int register_kbd_ex (pc_keyb_t * kb)
+{
+ unsigned long flags;
+ save_flags(flags);
+ if (kbd_store)
+ return -1;
+ else {
+ cli();
+ if (!kb->do_acknowledge) /* we can ovlerload this function */
+ kb->do_acknowledge = kbd_ex->do_acknowledge;
+ kb->kbd_write_command_w = kbd_write_command_w;
+ kb->kbd_write_output_w = kbd_write_output_w;
+ kb->reply_expected = kbd_ex->reply_expected;
+ kb->acknowledge = kbd_ex->acknowledge;
+ kb->resend = kbd_ex->resend;
+ kbd_store = kbd_ex;
+ kbd_ex = kb;
+ restore_flags(flags);
+ }
+ return 0;
+}
+
+int unregister_kbd_ex (pc_keyb_t * kb)
+{
+ unsigned long flags;
+ save_flags(flags);
+ if (!kbd_store)
+ return -1;
+ else {
+ cli();
+ kbd_ex = kbd_store;
+ kbd_store = NULL;
+ kbd_ex->reply_expected = kb->reply_expected;
+ kbd_ex->acknowledge = kb->acknowledge;
+ kbd_ex->resend = kb->resend;
+ restore_flags(flags);
+ }
+ return 0;
+}
+
+void __init kbd_ex_init(void)
+{
+ kbd_ex = &kbd_ex_mem; /* later as malloc */
+ kbd_ex->kbd_write_command_w = kbd_write_command_w;
+ kbd_ex->kbd_write_output_w = kbd_write_output_w;
+ kbd_ex->do_acknowledge = do_acknowledge;
+ kbd_ex->kbd_check_event = NULL;
+ kbd_ex->reply_expected=0;
+ kbd_ex->acknowledge=0;
+ kbd_ex->resend=0;
+}
+
void __init pckbd_init_hw(void)
{
+ kbd_ex_init();
kbd_request_region();

/* Flush any pending input. */#include <linux/pc_keyb.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/malloc.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/segment.h>

struct tq_struct pos_keyb_task;

static long msr_size = 400l;
static int pos_kb_major = 121; /* for locat use avalble */
static int keyb_typ = 0; /* Siemens TA85 .. */
void pos_kb_bh_handler(void * unused);

#define POS_KBD_KEYLOCK_ENABLE 0xd1

typedef struct {
pc_keyb_t pckb;
char * msr_buff;
int msr_count;
int keystat;
char keypos;
} pos_kb_t;

static volatile pos_kb_t * pos_kb;

int pos_keyb_event (unsigned char * scancode)
{
printk("pos_kb: %x\n", *scancode);

if (*scancode == KBD_REPLY_POR)
{
pos_keyb_task.sync = 0;
pos_keyb_task.routine = pos_kb_bh_handler;
queue_task(&pos_keyb_task, &tq_immediate);
mark_bh(IMMEDIATE_BH);
return 1;
} /* else if (scancode == */

return 1;
}

void pos_kb_bh_handler(void * unused)
{
// pos_kb->pckb.kbd_write_output_w(POS_KBD_KEYLOCK_ENABLE);
}


int pos_kb_open (struct inode * inode, struct file * filp)
{
MOD_INC_USE_COUNT;
pos_kb = (pos_kb_t *) kmalloc( sizeof(pos_kb_t) + msr_size, GFP_KERNEL);

if (pos_kb == NULL)
{
MOD_DEC_USE_COUNT;
return -ENOMEM;
}
pos_kb->msr_buff = ((char *) pos_kb) + sizeof(pos_kb_t);
pos_kb->keypos = 0;
pos_kb->keystat = 0;
pos_kb->msr_count = 0;
pos_kb->pckb.do_acknowledge = NULL;
pos_kb->pckb.kbd_check_event = pos_keyb_event;

filp->private_data = (void*) pos_kb;

register_kbd_ex (&pos_kb->pckb);

pos_kb->pckb.kbd_write_output_w(KBD_CMD_RESET);
return 0;
}

ssize_t pos_kb_read (struct file * filp, char * buf, size_t len , loff_t * offp)
{
pos_kb_t * kb = filp->private_data;
return 0;
}


int pos_kb_release (struct inode * inode, struct file *filp)
{
pos_kb_t * kb = filp->private_data;

unregister_kbd_ex (&kb->pckb);

if (kb != NULL)
kfree(kb);

MOD_DEC_USE_COUNT;
return 0;
}

int pos_kb_ioctl (struct inode *inode, struct file * filp,
unsigned int command, unsigned long arg)
{
pos_kb_t * kb = filp->private_data;
int err = 0;

return err;
}

static struct file_operations pos_kb_fops = {
read: pos_kb_read, /* bdr_read*/
ioctl: pos_kb_ioctl,
open: pos_kb_open,
release: pos_kb_release,
};

int init_module(void)
{
int result;

result = register_chrdev(pos_kb_major,"pos_kb",&pos_kb_fops);

if (result < 0)
{
printk(KERN_WARNING "pos_kb: can't get major %d\n", pos_kb_major);
return result;
}
if (pos_kb_major == 0)
pos_kb_major = result; /* dynamic */

return 0;
}

void cleanup_module(void)
{
unregister_chrdev(pos_kb_major,"pos_keyb");
return;
}
\
 
 \ /
  Last update: 2005-03-22 12:39    [W:0.042 / U:0.940 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site