patch-2.4.9 linux/drivers/char/pc_keyb.c
Next file: linux/drivers/char/pcmcia/serial_cs.c
Previous file: linux/drivers/char/n_r3964.c
Back to the patch index
Back to the overall index
- Lines: 146
- Date:
Tue Aug 14 15:49:50 2001
- Orig file:
v2.4.8/linux/drivers/char/pc_keyb.c
- Orig date:
Fri Apr 6 10:42:55 2001
diff -u --recursive --new-file v2.4.8/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
@@ -63,6 +63,7 @@
#ifdef CONFIG_PSMOUSE
static void aux_write_ack(int val);
static void __aux_write_ack(int val);
+static int aux_reconnect = 0;
#endif
static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
@@ -81,7 +82,8 @@
static int __init psaux_init(void);
-#define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */
+#define AUX_RECONNECT1 0xaa /* scancode1 when ps2 device is plugged (back) in */
+#define AUX_RECONNECT2 0x00 /* scancode2 when ps2 device is plugged (back) in */
static struct aux_queue *queue; /* Mouse data buffer. */
static int aux_count;
@@ -396,6 +398,7 @@
static inline void handle_mouse_event(unsigned char scancode)
{
#ifdef CONFIG_PSMOUSE
+ static unsigned char prev_code;
if (mouse_reply_expected) {
if (scancode == AUX_ACK) {
mouse_reply_expected--;
@@ -403,12 +406,15 @@
}
mouse_reply_expected = 0;
}
- else if(scancode == AUX_RECONNECT){
- queue->head = queue->tail = 0; /* Flush input queue */
+ else if(scancode == AUX_RECONNECT2 && prev_code == AUX_RECONNECT1
+ && aux_reconnect) {
+ printk (KERN_INFO "PS/2 mouse reconnect detected\n");
+ queue->head = queue->tail = 0; /* Flush input queue */
__aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */
return;
}
+ prev_code = scancode;
add_mouse_randomness(scancode);
if (aux_count) {
int head = queue->head;
@@ -533,6 +539,86 @@
}
}
+#define DEFAULT_KEYB_REP_DELAY 250
+#define DEFAULT_KEYB_REP_RATE 30 /* cps */
+
+static struct kbd_repeat kbdrate={
+ DEFAULT_KEYB_REP_DELAY,
+ DEFAULT_KEYB_REP_RATE
+};
+
+static unsigned char parse_kbd_rate(struct kbd_repeat *r)
+{
+ static struct r2v{
+ int rate;
+ unsigned char val;
+ } kbd_rates[]={ {5,0x14},
+ {7,0x10},
+ {10,0x0c},
+ {15,0x08},
+ {20,0x04},
+ {25,0x02},
+ {30,0x00}
+ };
+ static struct d2v{
+ int delay;
+ unsigned char val;
+ } kbd_delays[]={{250,0},
+ {500,1},
+ {750,2},
+ {1000,3}
+ };
+ int rate=0,delay=0;
+ if (r != NULL){
+ int i,new_rate=30,new_delay=250;
+ if (r->rate <= 0)
+ r->rate=kbdrate.rate;
+ if (r->delay <= 0)
+ r->delay=kbdrate.delay;
+ for (i=0; i < sizeof(kbd_rates)/sizeof(struct r2v); i++)
+ if (kbd_rates[i].rate == r->rate){
+ new_rate=kbd_rates[i].rate;
+ rate=kbd_rates[i].val;
+ break;
+ }
+ for (i=0; i < sizeof(kbd_delays)/sizeof(struct d2v); i++)
+ if (kbd_delays[i].delay == r->delay){
+ new_delay=kbd_delays[i].delay;
+ delay=kbd_delays[i].val;
+ break;
+ }
+ r->rate=new_rate;
+ r->delay=new_delay;
+ }
+ return (delay << 5) | rate;
+}
+
+static int write_kbd_rate(unsigned char r)
+{
+ if (!send_data(KBD_CMD_SET_RATE) || !send_data(r)){
+ send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
+ return 0;
+ }else
+ return 1;
+}
+
+int pckbd_rate(struct kbd_repeat *rep)
+{
+ if (rep == NULL)
+ return -EINVAL;
+ else{
+ unsigned char r=parse_kbd_rate(rep);
+ struct kbd_repeat old_rep;
+ memcpy(&old_rep,&kbdrate,sizeof(struct kbd_repeat));
+ if (write_kbd_rate(r)){
+ memcpy(&kbdrate,rep,sizeof(struct kbd_repeat));
+ memcpy(rep,&old_rep,sizeof(struct kbd_repeat));
+ return 0;
+ }
+ }
+ return -EIO;
+}
+
/*
* In case we run on a non-x86 hardware we need to initialize both the
* keyboard controller and the keyboard. On a x86, the BIOS will
@@ -754,6 +840,14 @@
}
#if defined CONFIG_PSMOUSE
+
+static int __init aux_reconnect_setup (char *str)
+{
+ aux_reconnect = 1;
+ return 1;
+}
+
+__setup("psaux-reconnect", aux_reconnect_setup);
/*
* Check if this is a dual port controller.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)