New set of input patches - 03-kbd98-interrupt.patch
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 2/9 New set of input patches - 03-kbd98-interrupt.patch
===================================================================
[email protected], 2004-05-10 01:26:53-05:00, [email protected]
Input: kbd98_interrupt should return irqreturn_t
98kbd.c | 26 +++++++++++++++----------- 1 files changed, 15 insertions(+), 11 deletions(-)
===================================================================
drivers/input/keyboard/98kbd.c +15 -11
@@ -109,8 +109,8 @@struct jis_kbd_conv jis[16 ]; }; -void kbd98_interrupt (struct serio *serio,unsigned char data, -unsigned int flags,struct pt_regs *regs) +irqreturn_t kbd98_interrupt (struct serio *serio,unsigned char data, +unsigned int flags,struct pt_regs *regs) {struct kbd98 *kbd98 = serio->private;unsigned char scancode, keycode;
@@ -119,15 +119,15 @@switch (data) {case KBD98_RET_ACK : kbd98->ack =1 ; -return ; + goto out;case KBD98_RET_NAK : kbd98->ack =-1 ; -return ; + goto out; }if (kbd98->cmdcnt) { kbd98->cmdbuf[--kbd98->cmdcnt] = data; -return ; + goto out; } scancode = data &KBD98_KEY ;
@@ -164,7 +164,7 @@ keycode = kbd98->jis[i].emul[kbd98->shift].keycode;if (keycode ==KBD98_KEY_NULL ) -return ; +break ;if (press) { kbd98->emul.scancode = scancode;
@@ -187,27 +187,31 @@ }input_sync (&kbd98->dev); -return ; +break ;case KEY_CAPSLOCK :input_report_key (&kbd98->dev, keycode,1 );input_sync (&kbd98->dev);input_report_key (&kbd98->dev, keycode,0 );input_sync (&kbd98->dev); -return ; +break ;case KBD98_KEY_NULL : -return ; +break ;case 0 :printk (KERN_WARNING "kbd98.c: Unknown key (scancode %#x) %s.\n" , data &KBD98_KEY , data &KBD98_RELEASE ?"released" :"pressed" ); -return ; +break ;default :input_report_key (&kbd98->dev, keycode, press);input_sync (&kbd98->dev); - } +break ; + } + +out: +return IRQ_HANDLED ; }/*
PATCH 1/9 New set of input patches - 02-kbd98io-interrupt.patch
In reply to a message not in the archive===================================================================
[email protected], 2004-05-10 01:25:24-05:00, [email protected]
Input: kbd98io_interrupt should return irqreturn_t
98kbd-io.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
===================================================================
drivers/input/serio/98kbd-io.c +3 -2
@@ -51,7 +51,7 @@static struct serio kbd98_port;extern struct pt_regs *kbd_pt_regs; -static void kbd98io_interrupt (int irq,void *dev_id,struct pt_regs *regs); +static irqreturn_t kbd98io_interrupt (int irq,void *dev_id,struct pt_regs *regs);/* * kbd98_flush() flushes all data that may be in the keyboard buffers
@@ -143,7 +143,7 @@* to the upper layers. */ -static void kbd98io_interrupt (int irq,void *dev_id,struct pt_regs *regs) +static irqreturn_t kbd98io_interrupt (int irq,void *dev_id,struct pt_regs *regs) {unsigned long flags;unsigned char data;
@@ -154,6 +154,7 @@spin_unlock_irqrestore (&kbd98io_lock, flags);serio_interrupt (&kbd98_port, data,0 , regs); +return IRQ_HANDLED ; }int __init kbd98io_init (void )
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 3/9 New set of input patches - 04-h3600-fixes.patch
===================================================================
[email protected], 2004-05-10 01:29:33-05:00, [email protected]
Input: various fixes for H3600 touchscreen driver
- h3600ts_interrupt, npower_button_handler and action_button_handler should return irqreturn_t
- fix missing argument in h3600ts_process_packet call
- add MODULE_AUTHOR, MODULE_DESCRIPTION and MODULE_LICENSE
- small formatting changes
h3600_ts_input.c | 32 +++++++++++++++++++++----------- 1 files changed, 21 insertions(+), 11 deletions(-)
===================================================================
drivers/input/touchscreen/h3600_ts_input.c +21 -11
@@ -45,6 +45,10 @@#include <asm/arch/hardware.h> #include <asm/arch/irqs.h> +MODULE_AUTHOR ("James Simmons <[email protected]>" ); +MODULE_DESCRIPTION ("H3600 touchscreen driver" ); +MODULE_LICENSE ("GPL" ); +/* * Definitions & global arrays. */
@@ -103,7 +107,7 @@char phys[32 ]; }; -static void action_button_handler (int irq,void *dev_id,struct pt_regs *regs) +static irqreturn_t action_button_handler (int irq,void *dev_id,struct pt_regs *regs) {int down = (GPLR &GPIO_BITSY_ACTION_BUTTON ) ?0 :1 ;struct input_dev *dev = (struct input_dev *) dev_id;
@@ -111,9 +115,11 @@input_regs (dev, regs);input_report_key (dev,KEY_ENTER , down);input_sync (dev); + +return IRQ_HANDLED ; } -static void npower_button_handler (int irq,void *dev_id,struct pt_regs *regs) +static irqreturn_t npower_button_handler (int irq,void *dev_id,struct pt_regs *regs) {int down = (GPLR &GPIO_BITSY_NPOWER_BUTTON ) ?0 :1 ;struct input_dev *dev = (struct input_dev *) dev_id;
@@ -126,6 +132,8 @@input_report_key (dev,KEY_SUSPEND ,1 );input_report_key (dev,KEY_SUSPEND , down);input_sync (dev); + +return IRQ_HANDLED ; }#ifdef CONFIG_PM
@@ -141,7 +149,7 @@* h3600_flite_power: enables or disables power to frontlight, using last bright */ unsigned int h3600_flite_power (struct input_dev *dev,enum flite_pwr pwr) { -unsigned char brightness = ((pwr==FLITE_PWR_OFF ) ?0 :flite_brightness); +unsigned char brightness = (pwr ==FLITE_PWR_OFF ) ?0 : flite_brightness;struct h3600_dev *ts = dev->private;/* Must be in this order */
@@ -317,8 +325,8 @@#define STATE_DATA 2/* state where we decode data */ #define STATE_EOF 3/* state where we decode checksum or EOF */ -static void h3600ts_interrupt (struct serio *serio,unsigned char data, -unsigned int flags) +static irqreturn_t h3600ts_interrupt (struct serio *serio,unsigned char data, +unsigned int flags,struct pt_regs *regs) {struct h3600_dev *ts = serio->private;
@@ -329,7 +337,7 @@case STATE_SOF :if (data ==CHAR_SOF ) state =STATE_ID ; -return ; +break ;case STATE_ID : ts->event = (data &0xf0 ) >>4 ; ts->len = (data &0xf );
@@ -339,7 +347,7 @@break ; } ts->chksum = data; - state=(ts->len >0 ) ?STATE_DATA :STATE_EOF ; + state = (ts->len >0 ) ?STATE_DATA :STATE_EOF ;break ;case STATE_DATA : ts->chksum += data;
@@ -349,13 +357,15 @@break ;case STATE_EOF : state =STATE_SOF ; -if (data ==CHAR_EOF || data == ts->chksum ) -h3600ts_process_packet (ts); +if (data ==CHAR_EOF || data == ts->chksum) +h3600ts_process_packet (ts, regs);break ;default :printk ("Error3\n" );break ; } + +return IRQ_HANDLED ; }/*
@@ -378,8 +388,8 @@init_input_dev (&ts->dev);/* Device specific stuff */ -set_GPIO_IRQ_edge (GPIO_BITSY_ACTION_BUTTON ,GPIO_BOTH_EDGES ); -set_GPIO_IRQ_edge (GPIO_BITSY_NPOWER_BUTTON ,GPIO_RISING_EDGE ); +set_GPIO_IRQ_edge (GPIO_BITSY_ACTION_BUTTON ,GPIO_BOTH_EDGES ); +set_GPIO_IRQ_edge (GPIO_BITSY_NPOWER_BUTTON ,GPIO_RISING_EDGE ); if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
PATCH 4/9 New set of input patches - 05-twidjoy-fixes.patch
===================================================================
[email protected], 2004-05-10 01:30:08-05:00, [email protected]
Input: twidjoy module
- twidjoy_interrupt should return irqreturn_t
- add MODULE_DESCRIPTION and MODULE_LICENSE
twidjoy.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)
===================================================================
drivers/input/joystick/twidjoy.c +6 -3
@@ -58,6 +58,9 @@#include <linux/serio.h> #include <linux/init.h> +MODULE_DESCRIPTION ("Handykey Twiddler keyboard as a joystick driver" ); +MODULE_LICENSE ("GPL" ); +/* * Constants. */
@@ -142,7 +145,7 @@* packet processing routine. */ -static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struc pt_regs *regs) +static irqreturn_t twidjoy_interrupt (struct serio *serio,unsigned char data,unsigned int flags,struct pt_regs *regs) {struct twidjoy *twidjoy = serio->private;
@@ -153,7 +156,7 @@if ((data &0x80 ) ==0 ) twidjoy->idx =0 ;/* this byte starts a new packet */ else if (twidjoy->idx ==0 ) -return ;/* wrong MSB -- ignore this byte */ +return IRQ_HANDLED ;/* wrong MSB -- ignore this byte */ if (twidjoy->idx <TWIDJOY_MAX_LENGTH ) twidjoy->data[twidjoy->idx++] = data;
@@ -163,7 +166,7 @@ twidjoy->idx =0 ; } -return ; +return IRQ_HANDLED ; }/*
PATCH 5/9 New set of input patches - 07-power-license.patch
===================================================================
[email protected], 2004-05-10 01:32:39-05:00, [email protected]
Input: power - add MODULE_LICENSE
power.c | 1 + 1 files changed, 1 insertion(+)
===================================================================
drivers/input/power.c +1 -0
@@ -172,3 +172,4 @@MODULE_AUTHOR ("James Simmons <[email protected]>" );MODULE_DESCRIPTION ("Input Power Management driver" ); +MODULE_LICENSE ("GPL" );
PATCH 6/9 New set of input patches - 11-synaptics-reconnect.patch
===================================================================
[email protected], 2004-05-10 01:37:47-05:00, [email protected]
Input: do not call synaptics_init unless we are ready to do full
mouse setup
psmouse-base.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
===================================================================
drivers/input/mouse/psmouse-base.c +1 -1
@@ -427,7 +427,7 @@ }if (max_proto >PSMOUSE_IMEX ) { -if (synaptics_init (psmouse) ==0 ) +if (!set_properties ||synaptics_init (psmouse) ==0 )return PSMOUSE_SYNAPTICS ;/* * Some Synaptics touchpads can emulate extended protocols (like IMPS/2).
PATCH 7/9 New set of input patches - 12-i8042-interrupt.patch
===================================================================
[email protected], 2004-05-10 01:39:35-05:00, [email protected]
Input: split i8042 interrupt handling into an IRQ handler and a tasklet
i8042.c | 141 +++++++++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 92 insertions(+), 49 deletions(-)
===================================================================
drivers/input/serio/i8042.c +92 -49
@@ -2,6 +2,7 @@* i8042 keyboard and mouse controller driver for Linux * * Copyright (c) 1999-2002 Vojtech Pavlik +* Copyright (c) 2004 Dmitry Torokhov */ /*
@@ -74,6 +75,14 @@unsigned char *phys; }; +#define I8042_QUEUE_LEN 64 +struct { +unsigned char str[I8042_QUEUE_LEN ]; +unsigned char data[I8042_QUEUE_LEN ]; +unsigned int read_pos; +unsigned int write_pos; +} i8042_buf; +static struct serio i8042_kbd_port;static struct serio i8042_aux_port;static unsigned char i8042_initial_ctr;
@@ -82,7 +91,7 @@static unsigned char i8042_mux_present;static unsigned char i8042_sysdev_initialized;static struct pm_dev *i8042_pm_dev; -struct timer_list i8042_timer; +static struct timer_list i8042_timer;/* * Shared IRQ's require a device pointer, but this driver doesn't support
@@ -374,77 +383,109 @@static char i8042_mux_phys[4 ][32 ];/* -* i8042_interrupt() is the most important function in this driver - -* it handles the interrupts from the i8042, and sends incoming bytes -* to the upper layers. +* i8042_handle_data() is the most important function in this driver - +* it processes data received by i8042_interrupt and sends it to the +* upper layers. */ -static irqreturn_t i8042_interrupt (int irq,void *dev_id,struct pt_regs *regs) +static void i8042_handle_data (unsigned long notused) { -unsigned long flags;unsigned char str, data =0 ;unsigned int dfl; -int ret; -mod_timer (&i8042_timer, jiffies +I8042_POLL_PERIOD ); +/* +* No locking it required on i8042_buf as the tasklet is guaranteed +* to be serialized and if write_pos changes while comparing it with +* read_pos another run will be scheduled by i8042_interrupt. +*/ +while (i8042_buf.read_pos != i8042_buf.write_pos) { -spin_lock_irqsave (&i8042_lock, flags); - str =i8042_read_status (); -if (str &I8042_STR_OBF ) - data =i8042_read_data (); -spin_unlock_irqrestore (&i8042_lock, flags); + str = i8042_buf.str[i8042_buf.read_pos]; + data = i8042_buf.data[i8042_buf.read_pos]; -if (~str &I8042_STR_OBF ) { -if (irq)dbg ("Interrupt %d, without any data" , irq); - ret =0 ; - goto out; + i8042_buf.read_pos++; + i8042_buf.read_pos %=I8042_QUEUE_LEN ; + + dfl = ((str &I8042_STR_PARITY ) ?SERIO_PARITY :0 ) | + ((str &I8042_STR_TIMEOUT ) ?SERIO_TIMEOUT :0 ); + +if (i8042_mux_values[0 ].exists && (str &I8042_STR_AUXDATA )) { + +if (str &I8042_STR_MUXERR ) { +switch (data) { +case 0xfd : +case 0xfe : dfl =SERIO_TIMEOUT ;break ; +case 0xff : dfl =SERIO_PARITY ;break ; + } + data =0xfe ; + }else dfl =0 ; + +dbg ("%02x <- i8042 (interrupt, aux%d, %d%s%s)" , + data, (str >>6 ), irq, + dfl &SERIO_PARITY ?", bad parity" :"" , + dfl &SERIO_TIMEOUT ?", timeout" :"" ); + +serio_interrupt (i8042_mux_port + ((str >>6 ) &3 ), data, dfl,NULL ); + }else { + +dbg ("%02x <- i8042 (interrupt, %s, %d%s%s)" , + data, (str &I8042_STR_AUXDATA ) ?"aux" :"kbd" , irq, + dfl &SERIO_PARITY ?", bad parity" :"" , + dfl &SERIO_TIMEOUT ?", timeout" :"" ); + +if (i8042_aux_values.exists && (str &I8042_STR_AUXDATA )) +serio_interrupt (&i8042_aux_port, data, dfl,NULL ); +else if (i8042_kbd_values.exists) +serio_interrupt (&i8042_kbd_port, data, dfl,NULL ); + } } +} + +DECLARE_TASKLET (i8042_tasklet, i8042_handle_data,0 ); + +/* +* i8042_interrupt() handles the interrupts from i8042 and schedules +* i8042_handle_data to process and pass received bytes to the upper +* layers. +*/ - dfl = ((str &I8042_STR_PARITY ) ?SERIO_PARITY :0 ) | - ((str &I8042_STR_TIMEOUT ) ?SERIO_TIMEOUT :0 ); +static irqreturn_t i8042_interrupt (int irq,void *dev_id,struct pt_regs *regs) +{ +unsigned long flags; +unsigned char str; +unsigned int n_bytes =0 ; -if (i8042_mux_values[0 ].exists && (str &I8042_STR_AUXDATA )) { +mod_timer (&i8042_timer, jiffies +I8042_POLL_PERIOD ); -if (str &I8042_STR_MUXERR ) { -switch (data) { -case 0xfd : -case 0xfe : dfl =SERIO_TIMEOUT ;break ; -case 0xff : dfl =SERIO_PARITY ;break ; - } - data =0xfe ; - }else dfl =0 ; +spin_lock_irqsave (&i8042_lock, flags); -dbg ("%02x <- i8042 (interrupt, aux%d, %d%s%s)" , - data, (str >>6 ), irq, - dfl &SERIO_PARITY ?", bad parity" :"" , - dfl &SERIO_TIMEOUT ?", timeout" :"" ); +while ((str =i8042_read_status ()) &I8042_STR_OBF ) { -serio_interrupt (i8042_mux_port + ((str >>6 ) &3 ), data, dfl, regs); + n_bytes++; - goto irq_ret; - } + i8042_buf.str[i8042_buf.write_pos] = str; + i8042_buf.data[i8042_buf.write_pos] =i8042_read_data (); -dbg ("%02x <- i8042 (interrupt, %s, %d%s%s)" , - data, (str &I8042_STR_AUXDATA ) ?"aux" :"kbd" , irq, - dfl &SERIO_PARITY ?", bad parity" :"" , - dfl &SERIO_TIMEOUT ?", timeout" :"" ); + i8042_buf.write_pos++; + i8042_buf.write_pos %=I8042_QUEUE_LEN ; -if (i8042_aux_values.exists && (str &I8042_STR_AUXDATA )) { -serio_interrupt (&i8042_aux_port, data, dfl, regs); - goto irq_ret; +if (unlikely (i8042_buf.write_pos == i8042_buf.read_pos)) +printk (KERN_WARNING "i8042.c: ring buffer full\n" ); } -if (!i8042_kbd_values.exists) - goto irq_ret; +spin_unlock_irqrestore (&i8042_lock, flags); -serio_interrupt (&i8042_kbd_port, data, dfl, regs); +if (unlikely (n_bytes ==0 )) { +if (irq)dbg ("Interrupt %d, without any data" , irq); +return IRQ_NONE ; + } -irq_ret: - ret =1 ; -out: -return IRQ_RETVAL (ret); +tasklet_schedule (&i8042_tasklet); + +return IRQ_HANDLED ; } +/* * i8042_enable_mux_mode checks whether the controller has an active * multiplexor and puts the chip into Multiplexed (as opposed to
@@ -1019,6 +1060,8 @@for (i =0 ; i <4 ; i++)if (i8042_mux_values[i].exists)serio_unregister_port (i8042_mux_port + i); + +tasklet_kill (&i8042_tasklet);i8042_platform_exit (); }
PATCH 8/9 New set of input patches - 13-i8042-unload.patch
===================================================================
[email protected], 2004-05-10 01:40:59-05:00, [email protected]
Patch from Sau Dan Lee
Input: i8042 - kill the timer only after removing interrupt handler,
otherwise there is a chance that interrupt handler will install the timer again and it will trigger after module is unloaded.
i8042.c | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-)
===================================================================
drivers/input/serio/i8042.c +1 -2
@@ -1047,8 +1047,6 @@sysdev_class_unregister (&kbc_sysclass); } -del_timer_sync (&i8042_timer); -i8042_controller_cleanup ();if (i8042_kbd_values.exists)
@@ -1061,6 +1059,7 @@if (i8042_mux_values[i].exists)serio_unregister_port (i8042_mux_port + i); +del_timer_sync (&i8042_timer);tasklet_kill (&i8042_tasklet);i8042_platform_exit ();
PATCH 9/9 New set of input patches - 14-mousedev-multiplexing.patch
===================================================================
[email protected], 2004-05-10 01:44:03-05:00, [email protected]
Input: mousedev - better multiplex absolute and relative devices;
cleanups
mousedev.c | 260 ++++++++++++++++++++++++++++++++++--------------------------- 1 files changed, 146 insertions(+), 114 deletions(-)
===================================================================
drivers/input/mousedev.c +146 -114
@@ -2,6 +2,7 @@* Input driver to ExplorerPS/2 device driver module. * * Copyright (c) 1999-2002 Vojtech Pavlik +* Copyright (c) 2004 Dmitry Torokhov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published by
@@ -47,15 +48,24 @@module_param (yres, uint,0 );MODULE_PARM_DESC (yres,"Vertical screen resolution" ); +struct mousedev_motion { +int dx, dy, dz; +}; +struct mousedev {int exist;int open;int minor; -int misc;char name[16 ];wait_queue_head_t wait;struct list_head list;struct input_handle handle; + +struct mousedev_motion packet; +unsigned long buttons; +unsigned int pkt_count; +int old_x[4 ], old_y[4 ]; +unsigned int touch; };struct mousedev_list {
@@ -63,13 +73,10 @@struct mousedev *mousedev;struct list_head node;int dx, dy, dz; -int old_x[4 ], old_y[4 ];unsigned long buttons;signed char ps2[6 ];unsigned char ready, buffer, bufsiz;unsigned char mode, imexseq, impsseq; -unsigned int pkt_count; -unsigned char touch; };#define MOUSEDEV_SEQ_LEN 6
@@ -82,135 +89,157 @@static struct mousedev *mousedev_table[MOUSEDEV_MINORS ];static struct mousedev mousedev_mix; -#define fx (i) (list->old_x[(list->pkt_count - (i)) & 03]) -#define fy (i) (list->old_y[(list->pkt_count - (i)) & 03]) +#define fx (i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) +#define fy (i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) -static void mousedev_abs_event (struct input_handle *handle,struct mousedev_list *list,unsigned int code,int value) +static void mousedev_touchpad_event (struct mousedev *mousedev,unsigned int code,int value) { -int size; -int touchpad; +if (mousedev->touch) { +switch (code) { +case ABS_X : +fx (0 ) = value; +if (mousedev->pkt_count >=2 ) + mousedev->packet.dx = ((fx (0 ) -fx (1 )) /2 + (fx (1 ) -fx (2 )) /2 ) /8 ; +break ; -/* Ignore joysticks */ -if (test_bit (BTN_TRIGGER , handle->dev->keybit)) -return ; +case ABS_Y : +fy (0 ) = value; +if (mousedev->pkt_count >=2 ) + mousedev->packet.dy = -((fy (0 ) -fy (1 )) /2 + (fy (1 ) -fy (2 )) /2 ) /8 ; +break ; + } + } +} - touchpad =test_bit (BTN_TOOL_FINGER , handle->dev->keybit); +static void mousedev_abs_event (struct input_dev *dev,struct mousedev *mousedev,unsigned int code,int value) +{ +int size;switch (code) {case ABS_X : -if (touchpad) { -if (list->touch) { -fx (0 ) = value; -if (list->pkt_count >=2 ) - list->dx = ((fx (0 ) -fx (1 )) /2 + (fx (1 ) -fx (2 )) /2 ) /8 ; - } - }else { - size = handle->dev->absmax[ABS_X ] - handle->dev->absmin[ABS_X ]; -if (size ==0 ) size = xres; - list->dx += (value * xres - list->old_x[0 ]) / size; - list->old_x[0 ] += list->dx * size; - } + size = dev->absmax[ABS_X ] - dev->absmin[ABS_X ]; +if (size ==0 ) size = xres; + mousedev->packet.dx = (value * xres - mousedev->old_x[0 ]) / size; + mousedev->old_x[0 ] = mousedev->packet.dx * size;break ; +case ABS_Y : -if (touchpad) { -if (list->touch) { -fy (0 ) = value; -if (list->pkt_count >=2 ) - list->dy = -((fy (0 ) -fy (1 )) /2 + (fy (1 ) -fy (2 )) /2 ) /8 ; - } - }else { - size = handle->dev->absmax[ABS_Y ] - handle->dev->absmin[ABS_Y ]; -if (size ==0 ) size = yres; - list->dy -= (value * yres - list->old_y[0 ]) / size; - list->old_y[0 ] -= list->dy * size; - } + size = dev->absmax[ABS_Y ] - dev->absmin[ABS_Y ]; +if (size ==0 ) size = yres; + mousedev->packet.dy = (value * yres - mousedev->old_y[0 ]) / size; + mousedev->old_y[0 ] = mousedev->packet.dy * size;break ; } } -static void mousedev_event (struct input_handle *handle,unsigned int type,unsigned int code,int value) +static void mousedev_rel_event (struct mousedev *mousedev,unsigned int code,int value) +{ +switch (code) { +case REL_X : mousedev->packet.dx += value;break ; +case REL_Y : mousedev->packet.dy -= value;break ; +case REL_WHEEL : mousedev->packet.dz -= value;break ; + } +} + +static void mousedev_key_event (struct mousedev *mousedev,unsigned int code,int value) +{ +int index; + +switch (code) { +case BTN_TOUCH : +case BTN_0 : +case BTN_FORWARD : +case BTN_LEFT : index =0 ;break ; +case BTN_STYLUS : +case BTN_1 : +case BTN_RIGHT : index =1 ;break ; +case BTN_2 : +case BTN_STYLUS2 : +case BTN_MIDDLE : index =2 ;break ; +case BTN_3 : +case BTN_BACK : +case BTN_SIDE : index =3 ;break ; +case BTN_4 : +case BTN_EXTRA : index =4 ;break ; +default :return ; + } + +if (value) { +set_bit (index, &mousedev->buttons); +set_bit (index, &mousedev_mix.buttons); + }else { +clear_bit (index, &mousedev->buttons); +clear_bit (index, &mousedev_mix.buttons); + } +} + +static void mousedev_notify_readers (struct mousedev *mousedev,struct mousedev_motion *packet) { -struct mousedev *mousedevs[3 ] = { handle->private, &mousedev_mix,NULL }; -struct mousedev **mousedev = mousedevs;struct mousedev_list *list; -int index, wake; -while (*mousedev) { +list_for_each_entry (list, &mousedev->list, node) { + list->dx += packet->dx; + list->dy += packet->dy; + list->dz += packet->dz; + list->buttons = mousedev->buttons; + list->ready =1 ; +kill_fasync (&list->fasync,SIGIO ,POLL_IN ); + } + +wake_up_interruptible (&mousedev->wait); +} + +static void mousedev_event (struct input_handle *handle,unsigned int type,unsigned int code,int value) +{ +struct mousedev *mousedev = handle->private; + +switch (type) { +case EV_ABS : +/* Ignore joysticks */ +if (test_bit (BTN_TRIGGER , handle->dev->keybit)) +return ; + +if (test_bit (BTN_TOOL_FINGER , handle->dev->keybit)) +mousedev_touchpad_event (mousedev, code, value); +else +mousedev_abs_event (handle->dev, mousedev, code, value); - wake =0 ; +break ; + +case EV_REL : +mousedev_rel_event (mousedev, code, value); +break ; -list_for_each_entry (list, &(*mousedev)->list, node) -switch (type) { -case EV_ABS : -mousedev_abs_event (handle, list, code, value); -break ; - -case EV_REL : -switch (code) { -case REL_X : list->dx += value;break ; -case REL_Y : list->dy -= value;break ; -case REL_WHEEL :if (list->mode) list->dz -= value;break ; - } -break ; - -case EV_KEY : -if (code ==BTN_TOUCH &&test_bit (BTN_TOOL_FINGER , handle->dev->keybit)) { -/* Handle touchpad data */ - list->touch = value; -if (!list->touch) - list->pkt_count =0 ; -break ; - } - -switch (code) { -case BTN_TOUCH : -case BTN_0 : -case BTN_FORWARD : -case BTN_LEFT : index =0 ;break ; -case BTN_4 : -case BTN_EXTRA :if (list->mode ==2 ) { index =4 ;break ; } -case BTN_STYLUS : -case BTN_1 : -case BTN_RIGHT : index =1 ;break ; -case BTN_3 : -case BTN_BACK : -case BTN_SIDE :if (list->mode ==2 ) { index =3 ;break ; } -case BTN_2 : -case BTN_STYLUS2 : -case BTN_MIDDLE : index =2 ;break ; -default :return ; - } -switch (value) { -case 0 :clear_bit (index, &list->buttons);break ; -case 1 :set_bit (index, &list->buttons);break ; -case 2 :return ; - } -break ; - -case EV_SYN : -switch (code) { -case SYN_REPORT : -if (list->touch) { - list->pkt_count++; -/* Input system eats duplicate events, -* but we need all of them to do correct -* averaging so apply present one forward -*/ -fx (0 ) =fx (1 ); -fy (0 ) =fy (1 ); - } - - list->ready =1 ; -kill_fasync (&list->fasync,SIGIO ,POLL_IN ); - wake =1 ; -break ; - } +case EV_KEY : +if (value !=2 ) { +if (code ==BTN_TOUCH &&test_bit (BTN_TOOL_FINGER , handle->dev->keybit)) { +/* Handle touchpad data */ + mousedev->touch = value; +if (!mousedev->touch) + mousedev->pkt_count =0 ; + } +else +mousedev_key_event (mousedev, code, value); } +break ; + +case EV_SYN : +if (code ==SYN_REPORT ) { +if (mousedev->touch) { + mousedev->pkt_count++; +/* Input system eats duplicate events, but we need all of them +* to do correct averaging so apply present one forward +*/ +fx (0 ) =fx (1 ); +fy (0 ) =fy (1 ); + } -if (wake) -wake_up_interruptible (&((*mousedev)->wait)); +mousedev_notify_readers (mousedev, &mousedev->packet); +mousedev_notify_readers (&mousedev_mix, &mousedev->packet); - mousedev++; +memset (&mousedev->packet,0 ,sizeof (struct mousedev_motion )); + } +break ; } }
@@ -326,6 +355,8 @@ list->dz -= list->ps2[off +3 ]; list->ps2[off +3 ] = (list->ps2[off +3 ] &0x0f ) | ((list->buttons &0x18 ) <<1 ); list->bufsiz++; + }else { + list->ps2[off] |= ((list->buttons &0x10 ) >>3 ) | ((list->buttons &0x08 ) >>1 ); }if (list->mode ==1 ) {
@@ -553,6 +584,7 @@static struct miscdevice psaux_mouse = {PSMOUSE_MINOR ,"psaux" , &mousedev_fops }; +static int psaux_registered;#endif static int __init mousedev_init (void )
@@ -572,7 +604,7 @@ NULL, "mice");#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX -if (!(mousedev_mix.misc = !misc_register (&psaux_mouse))) +if (!(psaux_registered = !misc_register (&psaux_mouse)))printk (KERN_WARNING "mice: could not misc_register the device\n" );#endif
@@ -584,7 +616,7 @@ static void __exit mousedev_exit(void) {#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX -if (mousedev_mix.misc) +if (psaux_registered)misc_deregister (&psaux_mouse);#endif devfs_remove ("input/mice" );