bk://kernel.bkbits.net/vojtech/input vojtech@suse.cz|ChangeSet|20040430152000|40922 vojtech # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/04/30 10:59:00-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/vojtech/input # into bix.(none):/usr/src/bk-input # # Documentation/kernel-parameters.txt # 2004/04/30 10:58:57-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/30 17:20:00+02:00 vojtech@suse.cz # Merge bk://dtor.bkbits.net/input into suse.cz:/home/vojtech/bk/input-dt # # Documentation/kernel-parameters.txt # 2004/04/30 17:19:57+02:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/04/27 01:12:57-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # Documentation/kernel-parameters.txt # 2004/04/27 01:12:54-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/23 12:45:46-07:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/vojtech/input # into bix.(none):/usr/src/bk-input # # drivers/input/serio/i8042.c # 2004/04/23 12:45:44-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/23 02:51:39-05:00 dtor_core@ameritech.net # Input: - move set_abs_params from synaptics driver to input and # rename to input_set_abs_params # - convert input_report_* macros into inline functions # - make use of set_abs_params in touchscreen drivers # # include/linux/input.h # 2004/04/22 21:51:18-05:00 dtor_core@ameritech.net +50 -9 # Move set_abs_params from synaptics; convert input_report* macros # into inline fucntions # # drivers/input/touchscreen/h3600_ts_input.c # 2004/04/22 21:51:18-05:00 dtor_core@ameritech.net +6 -8 # Use input_set_abs_params to set device properties # # drivers/input/touchscreen/gunze.c # 2004/04/22 21:51:18-05:00 dtor_core@ameritech.net +2 -4 # Use input_set_abs_params to set device properties # # drivers/input/mouse/synaptics.c # 2004/04/22 21:51:18-05:00 dtor_core@ameritech.net +3 -14 # Remove set_abs_params; use input_set_abs_params instead # # ChangeSet # 2004/04/23 02:50:49-05:00 dtor_core@ameritech.net # Input: trailing whitespace fixes # # include/linux/input.h # 2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +1 -1 # Trailing whitespace fixes # # drivers/input/touchscreen/h3600_ts_input.c # 2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +33 -33 # Trailing whitespace fixes # # drivers/input/touchscreen/gunze.c # 2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +1 -1 # Trailing whitespace fixes # # drivers/input/misc/uinput.c # 2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +25 -25 # Trailing whitespace fixes # # drivers/input/misc/sparcspkr.c # 2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +4 -4 # Trailing whitespace fixes # # drivers/input/misc/pcspkr.c # 2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +2 -2 # Trailing whitespace fixes # # drivers/input/misc/98spkr.c # 2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +2 -2 # Trailing whitespace fixes # # drivers/input/input.c # 2004/04/22 21:50:37-05:00 dtor_core@ameritech.net +20 -20 # Trailing whitespace fixes # # ChangeSet # 2004/04/23 02:50:09-05:00 dtor_core@ameritech.net # Input: make serio open and close methods optional # # drivers/input/serio/serport.c # 2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +2 -8 # Remove serio open method as it is not needed anymore. # # drivers/input/serio/serio.c # 2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +3 -2 # Make serio open and close methods optional. # # drivers/input/serio/q40kbd.c # 2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +0 -11 # Remove serio open and close methods as they are not needed anymore. # # drivers/input/serio/parkbd.c # 2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +0 -11 # Remove serio open and close methods as they are not needed anymore. # # drivers/input/mouse/synaptics.c # 2004/04/22 21:49:43-05:00 dtor_core@ameritech.net +0 -11 # Remove pass-through open and close methods as they are not needed anymore. # # ChangeSet # 2004/04/23 02:48:40-05:00 dtor_core@ameritech.net # Input: serio trailing whitespace fixes # # drivers/input/serio/serio.c # 2004/04/22 21:48:17-05:00 dtor_core@ameritech.net +6 -6 # Trailing whitespace fixes # # ChangeSet # 2004/04/23 02:46:06-05:00 dtor_core@ameritech.net # Input: allow disabling legacy psaux device even for non-embedded systems # # drivers/input/Kconfig # 2004/04/22 21:45:47-05:00 dtor_core@ameritech.net +8 -1 # Allow disabling legacy psaux device even for non-embedded systems # # ChangeSet # 2004/04/23 02:45:14-05:00 dtor_core@ameritech.net # Input: do not modify device's properties when probing for protocol # extensions on reconnect as it may interfere with reconnect # process # # drivers/input/mouse/psmouse-base.c # 2004/04/22 21:44:58-05:00 dtor_core@ameritech.net +43 -35 # Do not alter device's properties on reconnect # # drivers/input/mouse/logips2pp.h # 2004/04/22 21:44:58-05:00 dtor_core@ameritech.net +3 -2 # Allow t specify whether the init routine should set device's # properties. # # drivers/input/mouse/logips2pp.c # 2004/04/22 21:44:58-05:00 dtor_core@ameritech.net +91 -77 # Split protocol probing from setting device's properties # # ChangeSet # 2004/04/23 02:44:24-05:00 dtor_core@ameritech.net # Input: add psmouse_sliced_command (passes extended commands encoded # with 0xE8 to the mouse) and use it in Synaptics and Logitech # drivers # # drivers/input/mouse/synaptics.c # 2004/04/22 21:44:08-05:00 dtor_core@ameritech.net +3 -25 # Use psmouse_sliced_command instead of local implementation # # drivers/input/mouse/psmouse.h # 2004/04/22 21:44:08-05:00 dtor_core@ameritech.net +1 -0 # Add psmouse_sliced_command # # drivers/input/mouse/psmouse-base.c # 2004/04/22 21:44:08-05:00 dtor_core@ameritech.net +24 -0 # Add psmouse_sliced_command # # drivers/input/mouse/logips2pp.c # 2004/04/22 21:44:08-05:00 dtor_core@ameritech.net +1 -11 # Use psmouse_sliced_command instead of local implementation # # ChangeSet # 2004/04/23 02:43:45-05:00 dtor_core@ameritech.net # Input: add protocol_handler to psmouse structure to ease adding # new protocols to psmouse module # # drivers/input/mouse/synaptics.h # 2004/04/22 21:43:19-05:00 dtor_core@ameritech.net +0 -1 # Add protocol_handler to psmouse structure # # drivers/input/mouse/synaptics.c # 2004/04/22 21:43:19-05:00 dtor_core@ameritech.net +144 -141 # Add protocol_handler to psmouse structure # # drivers/input/mouse/psmouse.h # 2004/04/22 21:43:19-05:00 dtor_core@ameritech.net +1 -0 # Add protocol_handler to psmouse structure # # drivers/input/mouse/psmouse-base.c # 2004/04/22 21:43:19-05:00 dtor_core@ameritech.net +2 -2 # Add protocol handler to psmouse structure # # ChangeSet # 2004/04/23 02:42:57-05:00 dtor_core@ameritech.net # Input: move "reconnect after so many errors" handling from synaptics driver # to psmouse so it can be used by other PS/2 protcol drivers (but so far # only synaptics knows how to validate incoming data) # # drivers/input/mouse/synaptics.h # 2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +1 -2 # out_of_sync field moved to psmouse structure. # # drivers/input/mouse/synaptics.c # 2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +8 -16 # Do not issue reconnect request after errors, just let caller # know whether the byte was good or bad and let it decide what # to do. # # drivers/input/mouse/psmouse.h # 2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +8 -1 # Add out_of_sync to psmouse, define psmouse_ret_t describing # received data. # # drivers/input/mouse/psmouse-base.c # 2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +43 -18 # If protocol handler returns that data is bad too many times issue reconnect # request for the device in question. # # Documentation/kernel-parameters.txt # 2004/04/22 21:42:44-05:00 dtor_core@ameritech.net +2 -2 # Clarify psmouse.resetafter comment # # ChangeSet # 2004/04/23 02:41:59-05:00 dtor_core@ameritech.net # Input: when getting a new device announce (0xAA 0x00) in psmouse # try reconnecting instead of rescanning to preserve (if possible) # the same input device. # # drivers/input/mouse/psmouse-base.c # 2004/04/22 21:41:43-05:00 dtor_core@ameritech.net +1 -1 # When getting 0xAA 0x00 try reconnecting instead of rescanning to # preserve (if possible) the same input device. # # ChangeSet # 2004/04/23 02:40:48-05:00 dtor_core@ameritech.net # Input: Do not generate events from atkbd until keyboard is completely # initialized. It should suppress messages about suprious NAKs # when controller's timeout is longer than one in atkbd # # drivers/input/keyboard/atkbd.c # 2004/04/22 21:40:33-05:00 dtor_core@ameritech.net +6 -0 # Do not generate events until keyboard is completely initialized # # ChangeSet # 2004/04/23 02:40:08-05:00 dtor_core@ameritech.net # Input: remove unneeded fields in atkbd structure, convert to bitfields # # drivers/input/keyboard/atkbd.c # 2004/04/22 21:39:42-05:00 dtor_core@ameritech.net +11 -11 # Remove unneeded fields in atkbd structure, convert to bitfields # # ChangeSet # 2004/04/23 02:39:09-05:00 dtor_core@ameritech.net # Input: fix trailing whitespace in atkbd # # drivers/input/keyboard/atkbd.c # 2004/04/22 21:38:31-05:00 dtor_core@ameritech.net +2 -2 # Fix trailing whotespace # # ChangeSet # 2004/04/23 02:37:43-05:00 dtor_core@ameritech.net # Input: Change spurious ACK warning in atkbd to soften accusation # against XFree86 # # drivers/input/keyboard/atkbd.c # 2004/04/22 21:37:01-05:00 dtor_core@ameritech.net +14 -9 # Change spurious ACK warning so we don't accuse XFree86 that strongly # # ChangeSet # 2004/04/23 02:33:04-05:00 dtor_core@ameritech.net # Input: pass maximum allowed protocol to psmouse_extensions instead of # accessing psmouse_max_proto directly allowing to avoid changing # the global parameter when synaptics initialization fails # # drivers/input/mouse/psmouse-base.c # 2004/04/22 21:32:48-05:00 dtor_core@ameritech.net +9 -10 # Pass maximum allowed protocol to psmouse_extensions instead of # accessing psmouse_max_proto directly allowing to avoid changing # the global parameter when synaptics initialization fails # # ChangeSet # 2004/04/23 02:32:22-05:00 dtor_core@ameritech.net # Input: support Synaptics touchpads that have separate middle button # # drivers/input/mouse/synaptics.h # 2004/04/22 21:31:47-05:00 dtor_core@ameritech.net +2 -0 # Add middle button data # # drivers/input/mouse/synaptics.c # 2004/04/22 21:31:47-05:00 dtor_core@ameritech.net +11 -0 # Support touchpads that have separate middle pbutton # # ChangeSet # 2004/04/23 02:28:25-05:00 dtor_core@ameritech.net # Input: synaptics driver cleanup # - pack all button data in 2 bytes instead of 48 # - adjust the way we extract button data # - query extended capabilities if SYN_EXT_CAP_REQUESTS >= 1 # (was == 1) according to Synaptics' addendum to the interfacing # guide # - do not announce or report BTN_BACK/BTN_FORWARD unless touchpad # has SYN_CAP_FOUR_BUTTON in its capability flags # # drivers/input/mouse/synaptics.h # 2004/04/22 21:17:06-05:00 dtor_core@ameritech.net +6 -13 # Pack all button data in 2 bytes instead of 48 # # drivers/input/mouse/synaptics.c # 2004/04/22 21:17:06-05:00 dtor_core@ameritech.net +59 -78 # - adjust the way we extract button data # - query extended capabilities if SYN_EXT_CAP_REQUESTS >= 1 # (was == 1) according to Synaptics' addendum to the interfacing # guide # - do not announce or report BTN_BACK/BTN_FORWARD unless touchpad # has SYN_CAP_FOUR_BUTTON in its capability flags # # ChangeSet # 2004/04/21 21:59:48-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # init/main.c # 2004/04/21 21:59:45-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/19 19:33:52-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # init/main.c # 2004/04/19 19:33:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/char/Kconfig # 2004/04/19 19:33:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/05 17:39:48+02:00 vojtech@suse.cz # input: Fix emulation of mouse reset (0xff) command. # # drivers/input/mousedev.c # 2004/04/05 17:39:39+02:00 vojtech@suse.cz +3 -3 # input: Fix emulation of mouse reset (0xff) command. # # ChangeSet # 2004/04/01 15:09:02-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # init/main.c # 2004/04/01 15:08:59-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/26 16:27:05+01:00 vojtech@suse.cz # input: Profusion/ServerWorks chipset workaround in i8042.c for Ingo Molnar. # # drivers/input/serio/i8042.c # 2004/03/26 16:27:00+01:00 vojtech@suse.cz +10 -1 # input: Profusion/ServerWorks chipset workaround in i8042.c for Ingo Molnar. # # ChangeSet # 2004/03/24 12:34:31+01:00 vojtech@suse.cz # Merge suse.cz:/data/bk/linus into suse.cz:/data/bk/input # # drivers/input/serio/i8042.c # 2004/03/24 12:34:28+01:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/03/24 02:40:26-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # Documentation/kernel-parameters.txt # 2004/03/24 02:40:23-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/23 03:06:16-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # drivers/input/serio/i8042.c # 2004/03/23 03:06:13-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/22 13:30:28-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/vojtech/input # into bix.(none):/usr/src/bk-input # # drivers/input/serio/i8042.c # 2004/03/22 13:30:25-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/19 14:56:45+01:00 vojtech@suse.cz # input: Chips passing MUX detection incorrectly due to USB Legacy support # report MUX version 10.12, not 12.10. Fixed. # # drivers/input/serio/i8042.c # 2004/03/19 14:56:40+01:00 vojtech@suse.cz +2 -2 # input: Chips passing MUX detection incorrectly due to USB Legacy support # report MUX version 10.12, not 12.10. Fixed. # # ChangeSet # 2004/03/16 12:44:52-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # init/main.c # 2004/03/16 12:44:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/char/Kconfig # 2004/03/16 12:44:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/03/16 12:44:36-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/14 10:50:14-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # init/main.c # 2004/03/14 10:50:00-08:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/03/14 10:50:00-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/12 10:44:04-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # drivers/char/Kconfig # 2004/03/12 10:43:50-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/12 00:49:27-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/vojtech/input # into bix.(none):/usr/src/bk-input # # init/main.c # 2004/03/12 00:49:07-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/10 10:36:24-08:00 akpm@mnm.(none) # Merge mnm.(none):/usr/src/bk25 into mnm.(none):/usr/src/bk-input # # init/main.c # 2004/03/10 10:36:17-08:00 akpm@mnm.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/08 22:31:40-08:00 akpm@mnm.(none) # Merge bk://kernel.bkbits.net/vojtech/input # into mnm.(none):/usr/src/bk-input # # Documentation/kernel-parameters.txt # 2004/03/08 22:31:33-08:00 akpm@mnm.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/06 12:55:28-08:00 akpm@mnm.(none) # Merge mnm.(none):/usr/src/bk25 into mnm.(none):/usr/src/bk-input # # Documentation/kernel-parameters.txt # 2004/03/06 12:55:22-08:00 akpm@mnm.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/03 14:17:29-08:00 akpm@mnm.(none) # Merge bk://kernel.bkbits.net/vojtech/input # into mnm.(none):/usr/src/bk-input # # drivers/input/serio/i8042.c # 2004/03/03 14:17:23-08:00 akpm@mnm.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/03 02:22:06-08:00 akpm@mnm.(none) # Merge bk://kernel.bkbits.net/vojtech/input # into mnm.(none):/usr/src/bk-input # # drivers/input/serio/i8042.c # 2004/03/03 02:22:00-08:00 akpm@mnm.(none) +0 -0 # Auto merged # # ChangeSet # 2004/03/02 22:13:49-08:00 akpm@mnm.(none) # Merge mnm.(none):/usr/src/bk25 into mnm.(none):/usr/src/bk-input # # drivers/input/serio/i8042.c # 2004/03/02 22:13:42-08:00 akpm@mnm.(none) +0 -0 # Auto merged # diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt Tue May 4 22:10:38 2004 +++ b/Documentation/kernel-parameters.txt Tue May 4 22:10:38 2004 @@ -890,8 +890,8 @@ psmouse.rate= [HW,MOUSE] Set desired mouse report rate, in reports per second. psmouse.resetafter= - [HW,MOUSE] Try to reset Synaptics Touchpad after so many - bad packets (0 = never). + [HW,MOUSE] Try to reset the device after so many bad packets + (0 = never). psmouse.resolution= [HW,MOUSE] Set desired mouse resolution, in dpi. psmouse.smartscroll= diff -Nru a/drivers/input/Kconfig b/drivers/input/Kconfig --- a/drivers/input/Kconfig Tue May 4 22:10:38 2004 +++ b/drivers/input/Kconfig Tue May 4 22:10:38 2004 @@ -41,9 +41,16 @@ module will be called mousedev. config INPUT_MOUSEDEV_PSAUX - bool "Provide legacy /dev/psaux device" if EMBEDDED + bool "Provide legacy /dev/psaux device" default y depends on INPUT_MOUSEDEV + ---help--- + Say Y here if you want your mouse also be accessible as char device + 10:1 - /dev/psaux. The data available through /dev/psaux is exactly + the same as the data from /dev/input/mice. + + If unsure, say Y. + config INPUT_MOUSEDEV_SCREEN_X int "Horizontal screen resolution" diff -Nru a/drivers/input/input.c b/drivers/input/input.c --- a/drivers/input/input.c Tue May 4 22:10:38 2004 +++ b/drivers/input/input.c Tue May 4 22:10:38 2004 @@ -106,7 +106,7 @@ } break; - + case EV_ABS: if (code > ABS_MAX || !test_bit(code, dev->absbit)) @@ -144,27 +144,27 @@ if (code > MSC_MAX || !test_bit(code, dev->mscbit)) return; - if (dev->event) dev->event(dev, type, code, value); - + if (dev->event) dev->event(dev, type, code, value); + break; case EV_LED: - + if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value) return; change_bit(code, dev->led); - if (dev->event) dev->event(dev, type, code, value); - + if (dev->event) dev->event(dev, type, code, value); + break; case EV_SND: - + if (code > SND_MAX || !test_bit(code, dev->sndbit)) return; - if (dev->event) dev->event(dev, type, code, value); - + if (dev->event) dev->event(dev, type, code, value); + break; case EV_REP: @@ -181,7 +181,7 @@ break; } - if (type != EV_SYN) + if (type != EV_SYN) dev->sync = 0; if (dev->grab) @@ -282,11 +282,11 @@ if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) if (id->id.vendor != dev->id.vendor) continue; - + if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) if (id->id.product != dev->id.product) continue; - + if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) if (id->id.version != dev->id.version) continue; @@ -351,11 +351,11 @@ } if (in_interrupt()) { printk(KERN_ERR "input.c: calling hotplug from interrupt\n"); - return; + return; } if (!current->fs->root) { printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n"); - return; + return; } if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) { printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n"); @@ -381,17 +381,17 @@ envp[i++] = scratch; scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x", - dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1; - + dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1; + if (dev->name) { envp[i++] = scratch; - scratch += sprintf(scratch, "NAME=%s", dev->name) + 1; + scratch += sprintf(scratch, "NAME=%s", dev->name) + 1; } if (dev->phys) { envp[i++] = scratch; - scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1; - } + scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1; + } SPRINTF_BIT_A(evbit, "EV=", EV_MAX); SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY); @@ -506,7 +506,7 @@ input_table[handler->minor >> 5] = handler; list_add_tail(&handler->node, &input_handler_list); - + list_for_each_entry(dev, &input_dev_list, node) if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) if ((id = input_match_device(handler->id_table, dev))) diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c --- a/drivers/input/keyboard/atkbd.c Tue May 4 22:10:38 2004 +++ b/drivers/input/keyboard/atkbd.c Tue May 4 22:10:38 2004 @@ -26,7 +26,6 @@ #include #include #include -#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("AT and PS/2 keyboard driver"); @@ -173,22 +172,24 @@ unsigned char keycode[512]; struct input_dev dev; struct serio *serio; - struct timer_list timer; + char name[64]; char phys[32]; + unsigned short id; + unsigned char set; + unsigned int translated:1; + unsigned int extra:1; + unsigned int write:1; + unsigned char cmdbuf[4]; unsigned char cmdcnt; - unsigned char set; - unsigned char extra; - unsigned char release; - int lastkey; volatile signed char ack; unsigned char emul; - unsigned short id; - unsigned char write; - unsigned char translated; - unsigned char resend; - unsigned char bat_xl; + unsigned int resend:1; + unsigned int release:1; + unsigned int bat_xl:1; + unsigned int enabled:1; + unsigned int last; unsigned long time; }; @@ -248,6 +249,9 @@ goto out; } + if (!atkbd->enabled) + goto out; + if (atkbd->translated) { if (atkbd->emul || @@ -300,15 +304,20 @@ case ATKBD_KEY_NULL: break; case ATKBD_KEY_UNKNOWN: - printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", - atkbd->release ? "released" : "pressed", - atkbd->translated ? "translated" : "raw", - atkbd->set, code, serio->phys); - if (atkbd->translated && atkbd->set == 2 && code == 0x7a) - printk(KERN_WARNING "atkbd.c: This is an XFree86 bug. It shouldn't access" - " hardware directly.\n"); - else - printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x ' to make it known.\n", code & 0x80 ? "e0" : "", code & 0x7f); + if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) { + printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, " + "like XFree86, might be trying access hardware directly.\n", + data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); + } else { + printk(KERN_WARNING "atkbd.c: Unknown key %s " + "(%s set %d, code %#x on %s).\n", + atkbd->release ? "released" : "pressed", + atkbd->translated ? "translated" : "raw", + atkbd->set, code, serio->phys); + printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x ' " + "to make it known.\n", + code & 0x80 ? "e0" : "", code & 0x7f); + } break; case ATKBD_SCR_1: scroll = 1 - atkbd->release * 2; @@ -745,6 +754,8 @@ atkbd->id = 0xab00; } + atkbd->enabled = 1; + if (atkbd->extra) { atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC); sprintf(atkbd->name, "AT Set 2 Extra keyboard"); @@ -809,12 +820,12 @@ param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0) | (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0) | (test_bit(LED_CAPSL, atkbd->dev.led) ? 4 : 0); - + if (atkbd_probe(atkbd)) return -1; if (atkbd->set != atkbd_set_3(atkbd)) return -1; - + atkbd_enable(atkbd); if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS)) diff -Nru a/drivers/input/misc/98spkr.c b/drivers/input/misc/98spkr.c --- a/drivers/input/misc/98spkr.c Tue May 4 22:10:38 2004 +++ b/drivers/input/misc/98spkr.c Tue May 4 22:10:38 2004 @@ -41,11 +41,11 @@ case SND_BELL: if (value) value = 1000; case SND_TONE: break; default: return -1; - } + } if (value > 20 && value < 32767) count = CLOCK_TICK_RATE / value; - + spin_lock_irqsave(&i8253_beep_lock, flags); if (count) { diff -Nru a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c --- a/drivers/input/misc/pcspkr.c Tue May 4 22:10:38 2004 +++ b/drivers/input/misc/pcspkr.c Tue May 4 22:10:38 2004 @@ -40,11 +40,11 @@ case SND_BELL: if (value) value = 1000; case SND_TONE: break; default: return -1; - } + } if (value > 20 && value < 32767) count = CLOCK_TICK_RATE / value; - + spin_lock_irqsave(&i8253_beep_lock, flags); if (count) { diff -Nru a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c --- a/drivers/input/misc/sparcspkr.c Tue May 4 22:10:38 2004 +++ b/drivers/input/misc/sparcspkr.c Tue May 4 22:10:38 2004 @@ -53,11 +53,11 @@ case SND_BELL: if (value) value = 1000; case SND_TONE: break; default: return -1; - } + } if (value > 20 && value < 32767) count = 1193182 / value; - + spin_lock_irqsave(&beep_lock, flags); /* EBUS speaker only has on/off state, the frequency does not @@ -108,11 +108,11 @@ case SND_BELL: if (value) value = 1000; case SND_TONE: break; default: return -1; - } + } if (value > 20 && value < 32767) count = 1193182 / value; - + spin_lock_irqsave(&beep_lock, flags); if (count) { diff -Nru a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c --- a/drivers/input/misc/uinput.c Tue May 4 22:10:38 2004 +++ b/drivers/input/misc/uinput.c Tue May 4 22:10:38 2004 @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Aristeu Sergio Rozanski Filho - * + * * Changes/Revisions: * 0.1 20/06/2002 * - first public version @@ -68,7 +68,7 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) { return 0; -} +} static int uinput_create_device(struct uinput_device *udev) { @@ -123,7 +123,7 @@ memset(newinput, 0, sizeof(struct input_dev)); newdev->dev = newinput; - + file->private_data = newdev; return 0; @@ -137,16 +137,16 @@ { unsigned int cnt; int retval = 0; - + for (cnt = 0; cnt < ABS_MAX; cnt++) { - if (!test_bit(cnt, dev->absbit)) + if (!test_bit(cnt, dev->absbit)) continue; - + if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */ (dev->absmax[cnt] <= dev->absmin[cnt])) { - printk(KERN_DEBUG + printk(KERN_DEBUG "%s: invalid abs[%02x] min:%d max:%d\n", - UINPUT_NAME, cnt, + UINPUT_NAME, cnt, dev->absmin[cnt], dev->absmax[cnt]); retval = -EINVAL; break; @@ -154,7 +154,7 @@ if ((dev->absflat[cnt] < dev->absmin[cnt]) || (dev->absflat[cnt] > dev->absmax[cnt])) { - printk(KERN_DEBUG + printk(KERN_DEBUG "%s: absflat[%02x] out of range: %d " "(min:%d/max:%d)\n", UINPUT_NAME, cnt, dev->absflat[cnt], @@ -190,7 +190,7 @@ goto exit; } - if (NULL != dev->name) + if (NULL != dev->name) kfree(dev->name); size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; @@ -229,7 +229,7 @@ static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct uinput_device *udev = file->private_data; - + if (test_bit(UIST_CREATED, &(udev->state))) { struct input_event ev; @@ -247,7 +247,7 @@ { struct uinput_device *udev = file->private_data; int retval = 0; - + if (!test_bit(UIST_CREATED, &(udev->state))) return -ENODEV; @@ -255,16 +255,16 @@ return -EAGAIN; retval = wait_event_interruptible(udev->waitq, - (udev->head != udev->tail) || + (udev->head != udev->tail) || !test_bit(UIST_CREATED, &(udev->state))); - + if (retval) return retval; if (!test_bit(UIST_CREATED, &(udev->state))) return -ENODEV; - while ((udev->head != udev->tail) && + while ((udev->head != udev->tail) && (retval + sizeof(struct input_event) <= count)) { if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]), sizeof(struct input_event))) return -EFAULT; @@ -284,7 +284,7 @@ if (udev->head != udev->tail) return POLLIN | POLLRDNORM; - return 0; + return 0; } static int uinput_burn_device(struct uinput_device *udev) @@ -318,7 +318,7 @@ case UI_DEV_CREATE: retval = uinput_create_device(udev); break; - + case UI_DEV_DESTROY: retval = uinput_destroy_device(udev); break; @@ -330,7 +330,7 @@ } set_bit(arg, udev->dev->evbit); break; - + case UI_SET_KEYBIT: if (arg > KEY_MAX) { retval = -EINVAL; @@ -338,7 +338,7 @@ } set_bit(arg, udev->dev->keybit); break; - + case UI_SET_RELBIT: if (arg > REL_MAX) { retval = -EINVAL; @@ -346,7 +346,7 @@ } set_bit(arg, udev->dev->relbit); break; - + case UI_SET_ABSBIT: if (arg > ABS_MAX) { retval = -EINVAL; @@ -354,7 +354,7 @@ } set_bit(arg, udev->dev->absbit); break; - + case UI_SET_MSCBIT: if (arg > MSC_MAX) { retval = -EINVAL; @@ -362,7 +362,7 @@ } set_bit(arg, udev->dev->mscbit); break; - + case UI_SET_LEDBIT: if (arg > LED_MAX) { retval = -EINVAL; @@ -370,7 +370,7 @@ } set_bit(arg, udev->dev->ledbit); break; - + case UI_SET_SNDBIT: if (arg > SND_MAX) { retval = -EINVAL; @@ -378,7 +378,7 @@ } set_bit(arg, udev->dev->sndbit); break; - + case UI_SET_FFBIT: if (arg > FF_MAX) { retval = -EINVAL; @@ -386,7 +386,7 @@ } set_bit(arg, udev->dev->ffbit); break; - + default: retval = -EFAULT; } diff -Nru a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c --- a/drivers/input/mouse/logips2pp.c Tue May 4 22:10:38 2004 +++ b/drivers/input/mouse/logips2pp.c Tue May 4 22:10:38 2004 @@ -63,7 +63,6 @@ packet[0] &= 0x0f; packet[1] = 0; packet[2] = 0; - } } @@ -76,18 +75,9 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command) { - unsigned char d; - int i; - - if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) + if (psmouse_sliced_command(psmouse, command)) return -1; - for (i = 6; i >= 0; i -= 2) { - d = (command >> i) & 3; - if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES)) - return -1; - } - if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL)) return -1; @@ -99,7 +89,7 @@ * enabled if we do nothing to it. Of course I put this in because I want it * disabled :P * 1 - enabled (if previously disabled, also default) - * 0/2 - disabled + * 0/2 - disabled */ static void ps2pp_set_smartscroll(struct psmouse *psmouse) @@ -113,14 +103,11 @@ psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - if (psmouse_smartscroll == 1) - param[0] = 1; - else - if (psmouse_smartscroll > 2) - return; - - /* else leave param[0] == 0 to disable */ - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + if (psmouse_smartscroll < 2) { + /* 0 - disabled, 1 - enabled */ + param[0] = psmouse_smartscroll; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + } } /* @@ -138,111 +125,128 @@ psmouse_command(psmouse, ¶m, PSMOUSE_CMD_SETRES); } + +static int is_model_in_list(unsigned char model, int *model_list) +{ + int i; + + for (i = 0; model_list[i] != -1; i++) + if (model == model_list[i]) + return 1; + return 0; +} + /* - * Detect the exact model and features of a PS2++ or PS2T++ Logitech mouse or - * touchpad. + * Set up input device's properties based on the detected mouse model. */ -static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param) +static void ps2pp_set_properties(struct psmouse *psmouse, unsigned char protocol, + unsigned char model, unsigned char buttons) { - int i; static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 }; static int logitech_wheel[] = { 52, 53, 75, 76, 80, 81, 83, 88, 112, -1 }; - static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75, - 76, 80, 81, 83, 88, 96, 97, 112, -1 }; static int logitech_mx[] = { 61, 112, -1 }; psmouse->vendor = "Logitech"; - psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); + psmouse->model = model; - if (param[1] < 3) + if (buttons < 3) clear_bit(BTN_MIDDLE, psmouse->dev.keybit); - if (param[1] < 2) + if (buttons < 2) clear_bit(BTN_RIGHT, psmouse->dev.keybit); - psmouse->type = PSMOUSE_PS2; + if (protocol == PSMOUSE_PS2PP) { - for (i = 0; logitech_ps2pp[i] != -1; i++) - if (logitech_ps2pp[i] == psmouse->model) - psmouse->type = PSMOUSE_PS2PP; - - if (psmouse->type == PSMOUSE_PS2PP) { - - for (i = 0; logitech_4btn[i] != -1; i++) - if (logitech_4btn[i] == psmouse->model) - set_bit(BTN_SIDE, psmouse->dev.keybit); - - for (i = 0; logitech_wheel[i] != -1; i++) - if (logitech_wheel[i] == psmouse->model) { - set_bit(REL_WHEEL, psmouse->dev.relbit); - psmouse->name = "Wheel Mouse"; - } + if (is_model_in_list(model, logitech_4btn)) + set_bit(BTN_SIDE, psmouse->dev.keybit); + + if (is_model_in_list(model, logitech_wheel)) { + set_bit(REL_WHEEL, psmouse->dev.relbit); + psmouse->name = "Wheel Mouse"; + } + + if (is_model_in_list(model, logitech_mx)) { + set_bit(BTN_SIDE, psmouse->dev.keybit); + set_bit(BTN_EXTRA, psmouse->dev.keybit); + set_bit(BTN_BACK, psmouse->dev.keybit); + set_bit(BTN_FORWARD, psmouse->dev.keybit); + set_bit(BTN_TASK, psmouse->dev.keybit); + psmouse->name = "MX Mouse"; + } + } + + if (protocol == PSMOUSE_PS2TPP) { + set_bit(REL_WHEEL, psmouse->dev.relbit); + set_bit(REL_HWHEEL, psmouse->dev.relbit); + psmouse->name = "TouchPad 3"; + } +} - for (i = 0; logitech_mx[i] != -1; i++) - if (logitech_mx[i] == psmouse->model) { - set_bit(BTN_SIDE, psmouse->dev.keybit); - set_bit(BTN_EXTRA, psmouse->dev.keybit); - set_bit(BTN_BACK, psmouse->dev.keybit); - set_bit(BTN_FORWARD, psmouse->dev.keybit); - set_bit(BTN_TASK, psmouse->dev.keybit); - psmouse->name = "MX Mouse"; - } /* - * Do Logitech PS2++ / PS2T++ magic init. + * Logitech magic init. Detect whether the mouse is a Logitech one + * and its exact model and try turning on extended protocol for ones + * that support it. */ - if (psmouse->model == 97) { /* TouchPad 3 */ +int ps2pp_init(struct psmouse *psmouse, int set_properties) +{ + static int logitech_ps2pp[] = { 12, 13, 40, 41, 42, 43, 50, 51, 52, 53, 73, 75, + 76, 80, 81, 83, 88, 96, 97, 112, -1 }; + unsigned char param[4]; + unsigned char protocol = PSMOUSE_PS2; + unsigned char model, buttons; - set_bit(REL_WHEEL, psmouse->dev.relbit); - set_bit(REL_HWHEEL, psmouse->dev.relbit); + param[0] = 0; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); + psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); + psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); + param[1] = 0; + psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); - param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */ + if (param[1] != 0) { + model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); + buttons = param[1]; +/* + * Do Logitech PS2++ / PS2T++ magic init. + */ + if (model == 97) { /* Touch Pad 3 */ + + /* Unprotect RAM */ + param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; psmouse_command(psmouse, param, 0x30d1); - param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */ + /* Enable features */ + param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; psmouse_command(psmouse, param, 0x30d1); - param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */ + /* Enable PS2++ */ + param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; psmouse_command(psmouse, param, 0x30d1); param[0] = 0; if (!psmouse_command(psmouse, param, 0x13d1) && - param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { - psmouse->name = "TouchPad 3"; - return PSMOUSE_PS2TPP; + param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { + protocol = PSMOUSE_PS2TPP; } - } else { + } else if (is_model_in_list(model, logitech_ps2pp)) { param[0] = param[1] = param[2] = 0; ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */ ps2pp_cmd(psmouse, param, 0xDB); - if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 && - (param[2] & 3) == ((param[1] >> 2) & 3)) { - ps2pp_set_smartscroll(psmouse); - return PSMOUSE_PS2PP; + if ((param[0] & 0x78) == 0x48 && + (param[1] & 0xf3) == 0xc2 && + (param[2] & 0x03) == ((param[1] >> 2) & 3)) { + ps2pp_set_smartscroll(psmouse); + protocol = PSMOUSE_PS2PP; } } - } - - return 0; -} - -/* - * Logitech magic init. - */ -int ps2pp_detect(struct psmouse *psmouse) -{ - unsigned char param[4]; - param[0] = 0; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - param[1] = 0; - psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); + if (set_properties) + ps2pp_set_properties(psmouse, protocol, model, buttons); + } - return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0; + return protocol; } diff -Nru a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h --- a/drivers/input/mouse/logips2pp.h Tue May 4 22:10:38 2004 +++ b/drivers/input/mouse/logips2pp.h Tue May 4 22:10:38 2004 @@ -10,8 +10,9 @@ #ifndef _LOGIPS2PP_H #define _LOGIPS2PP_H -struct psmouse; + void ps2pp_process_packet(struct psmouse *psmouse); void ps2pp_set_800dpi(struct psmouse *psmouse); -int ps2pp_detect(struct psmouse *psmouse); +int ps2pp_init(struct psmouse *psmouse, int set_properties); + #endif diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c --- a/drivers/input/mouse/psmouse-base.c Tue May 4 22:10:38 2004 +++ b/drivers/input/mouse/psmouse-base.c Tue May 4 22:10:38 2004 @@ -43,9 +43,9 @@ module_param_named(smartscroll, psmouse_smartscroll, bool, 0); MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); -unsigned int psmouse_resetafter; +static unsigned int psmouse_resetafter; module_param_named(resetafter, psmouse_resetafter, uint, 0); -MODULE_PARM_DESC(resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never)."); +MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); __obsolete_setup("psmouse_noext"); __obsolete_setup("psmouse_resolution="); @@ -56,15 +56,22 @@ static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"}; /* - * psmouse_process_packet() analyzes the PS/2 mouse packet contents and - * reports relevant events to the input module. + * psmouse_process_byte() analyzes the PS/2 data stream and reports + * relevant events to the input module once full packet has arrived. */ -static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs) +static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { struct input_dev *dev = &psmouse->dev; unsigned char *packet = psmouse->packet; + if (psmouse->pktcnt < 3 + (psmouse->type >= PSMOUSE_GENPS)) + return PSMOUSE_GOOD_DATA; + +/* + * Full packet accumulated, process it + */ + input_regs(dev, regs); /* @@ -112,6 +119,8 @@ input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0); input_sync(dev); + + return PSMOUSE_FULL_PACKET; } /* @@ -123,6 +132,7 @@ unsigned char data, unsigned int flags, struct pt_regs *regs) { struct psmouse *psmouse = serio->private; + psmouse_ret_t rc; if (psmouse->state == PSMOUSE_IGNORE) goto out; @@ -180,7 +190,7 @@ if (psmouse->pktcnt == 2) { if (psmouse->packet[1] == PSMOUSE_RET_ID) { psmouse->state = PSMOUSE_IGNORE; - serio_rescan(serio); + serio_reconnect(serio); goto out; } if (psmouse->type == PSMOUSE_SYNAPTICS) { @@ -193,19 +203,32 @@ } } - if (psmouse->type == PSMOUSE_SYNAPTICS) { - /* - * The synaptics driver has its own resync logic, - * so it needs to receive all bytes one at a time. - */ - synaptics_process_byte(psmouse, regs); - goto out; - } + rc = psmouse->protocol_handler(psmouse, regs); - if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) { - psmouse_process_packet(psmouse, regs); - psmouse->pktcnt = 0; - goto out; + switch (rc) { + case PSMOUSE_BAD_DATA: + printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", + psmouse->name, psmouse->phys, psmouse->pktcnt); + psmouse->pktcnt = 0; + + if (++psmouse->out_of_sync == psmouse_resetafter) { + psmouse->state = PSMOUSE_IGNORE; + printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); + serio_reconnect(psmouse->serio); + } + break; + + case PSMOUSE_FULL_PACKET: + psmouse->pktcnt = 0; + if (psmouse->out_of_sync) { + psmouse->out_of_sync = 0; + printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", + psmouse->name, psmouse->phys); + } + break; + + case PSMOUSE_GOOD_DATA: + break; } out: return IRQ_HANDLED; @@ -289,6 +312,30 @@ /* + * psmouse_sliced_command() sends an extended PS/2 command to the mouse + * using sliced syntax, understood by advanced devices, such as Logitech + * or Synaptics touchpads. The command is encoded as: + * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu + * is the command. + */ +int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command) +{ + int i; + + if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) + return -1; + + for (i = 6; i >= 0; i -= 2) { + unsigned char d = (command >> i) & 3; + if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES)) + return -1; + } + + return 0; +} + + +/* * psmouse_reset() resets the mouse into power-on state. */ int psmouse_reset(struct psmouse *psmouse) @@ -363,23 +410,23 @@ * the mouse may have. */ -static int psmouse_extensions(struct psmouse *psmouse) +static int psmouse_extensions(struct psmouse *psmouse, + unsigned int max_proto, int set_properties) { int synaptics_hardware = 0; - psmouse->vendor = "Generic"; - psmouse->name = "Mouse"; - psmouse->model = 0; - /* * Try Synaptics TouchPad */ - if (psmouse_max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) { + if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) { synaptics_hardware = 1; - psmouse->vendor = "Synaptics"; - psmouse->name = "TouchPad"; - if (psmouse_max_proto > PSMOUSE_IMEX) { + if (set_properties) { + psmouse->vendor = "Synaptics"; + psmouse->name = "TouchPad"; + } + + if (max_proto > PSMOUSE_IMEX) { if (synaptics_init(psmouse) == 0) return PSMOUSE_SYNAPTICS; /* @@ -387,7 +434,7 @@ * Unfortunately Logitech/Genius probes confuse some firmware versions so * we'll have to skip them. */ - psmouse_max_proto = PSMOUSE_IMEX; + max_proto = PSMOUSE_IMEX; } /* * Make sure that touchpad is in relative mode, gestures (taps) are enabled @@ -395,35 +442,45 @@ synaptics_reset(psmouse); } - if (psmouse_max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) { - set_bit(BTN_EXTRA, psmouse->dev.keybit); - set_bit(BTN_SIDE, psmouse->dev.keybit); - set_bit(REL_WHEEL, psmouse->dev.relbit); + if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) { + + if (set_properties) { + set_bit(BTN_EXTRA, psmouse->dev.keybit); + set_bit(BTN_SIDE, psmouse->dev.keybit); + set_bit(REL_WHEEL, psmouse->dev.relbit); + psmouse->vendor = "Genius"; + psmouse->name = "Wheel Mouse"; + } - psmouse->vendor = "Genius"; - psmouse->name = "Wheel Mouse"; return PSMOUSE_GENPS; } - if (psmouse_max_proto > PSMOUSE_IMEX) { - int type = ps2pp_detect(psmouse); - if (type) + if (max_proto > PSMOUSE_IMEX) { + int type = ps2pp_init(psmouse, set_properties); + if (type > PSMOUSE_PS2) return type; } - if (psmouse_max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) { - set_bit(REL_WHEEL, psmouse->dev.relbit); + if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) { - if (psmouse_max_proto >= PSMOUSE_IMEX && - im_explorer_detect(psmouse)) { - set_bit(BTN_SIDE, psmouse->dev.keybit); - set_bit(BTN_EXTRA, psmouse->dev.keybit); + if (set_properties) { + set_bit(REL_WHEEL, psmouse->dev.relbit); + if (!psmouse->name) + psmouse->name = "Wheel Mouse"; + } + + if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) { + + if (!set_properties) { + set_bit(BTN_SIDE, psmouse->dev.keybit); + set_bit(BTN_EXTRA, psmouse->dev.keybit); + if (!psmouse->name) + psmouse->name = "Explorer Mouse"; + } - psmouse->name = "Explorer Mouse"; return PSMOUSE_IMEX; } - psmouse->name = "Wheel Mouse"; return PSMOUSE_IMPS; } @@ -473,12 +530,7 @@ if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS)) printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys); -/* - * And here we try to determine if it has any extensions over the - * basic PS/2 3-button mouse. - */ - - return psmouse->type = psmouse_extensions(psmouse); + return 0; } /* @@ -616,7 +668,6 @@ psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); - psmouse->state = PSMOUSE_CMD_MODE; psmouse->serio = serio; psmouse->dev.private = psmouse; @@ -628,13 +679,21 @@ return; } - if (psmouse_probe(psmouse) <= 0) { + if (psmouse_probe(psmouse) < 0) { serio_close(serio); kfree(psmouse); serio->private = NULL; return; } + psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); + if (!psmouse->vendor) + psmouse->vendor = "Generic"; + if (!psmouse->name) + psmouse->name = "Mouse"; + if (!psmouse->protocol_handler) + psmouse->protocol_handler = psmouse_process_byte; + sprintf(psmouse->devname, "%s %s %s", psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name); sprintf(psmouse->phys, "%s/input0", @@ -668,27 +727,24 @@ { struct psmouse *psmouse = serio->private; struct serio_dev *dev = serio->dev; - int old_type; if (!dev || !psmouse) { printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n"); return -1; } - old_type = psmouse->type; - psmouse->state = PSMOUSE_CMD_MODE; - psmouse->type = psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = 0; + psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0; if (psmouse->reconnect) { if (psmouse->reconnect(psmouse)) return -1; - } else if (psmouse_probe(psmouse) != old_type) + } else if (psmouse_probe(psmouse) < 0 || + psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0)) return -1; /* ok, the device type (and capabilities) match the old one, * we can continue using it, complete intialization */ - psmouse->type = old_type; psmouse_initialize(psmouse); if (psmouse->ptport) { diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h --- a/drivers/input/mouse/psmouse.h Tue May 4 22:10:38 2004 +++ b/drivers/input/mouse/psmouse.h Tue May 4 22:10:38 2004 @@ -22,6 +22,13 @@ #define PSMOUSE_ACTIVATED 1 #define PSMOUSE_IGNORE 2 +/* psmouse protocol handler return codes */ +typedef enum { + PSMOUSE_BAD_DATA, + PSMOUSE_GOOD_DATA, + PSMOUSE_FULL_PACKET +} psmouse_ret_t; + struct psmouse; struct psmouse_ptport { @@ -45,6 +52,7 @@ unsigned char type; unsigned char model; unsigned long last; + unsigned long out_of_sync; unsigned char state; char acking; volatile char ack; @@ -52,6 +60,7 @@ char devname[64]; char phys[32]; + psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); int (*reconnect)(struct psmouse *psmouse); void (*disconnect)(struct psmouse *psmouse); }; @@ -65,10 +74,10 @@ #define PSMOUSE_SYNAPTICS 7 int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command); +int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command); int psmouse_reset(struct psmouse *psmouse); extern int psmouse_smartscroll; extern unsigned int psmouse_rate; -extern unsigned int psmouse_resetafter; #endif /* _PSMOUSE_H */ diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c --- a/drivers/input/mouse/synaptics.c Tue May 4 22:10:38 2004 +++ b/drivers/input/mouse/synaptics.c Tue May 4 22:10:38 2004 @@ -44,33 +44,11 @@ ****************************************************************************/ /* - * Use the Synaptics extended ps/2 syntax to write a special command byte. - * special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu - * is the command. A 0xF3 or 0xE9 must follow (see synaptics_send_cmd - * and synaptics_mode_cmd) - */ -static int synaptics_special_cmd(struct psmouse *psmouse, unsigned char command) -{ - int i; - - if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) - return -1; - - for (i = 6; i >= 0; i -= 2) { - unsigned char d = (command >> i) & 3; - if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES)) - return -1; - } - - return 0; -} - -/* * Send a command to the synpatics touchpad by special commands */ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) { - if (synaptics_special_cmd(psmouse, c)) + if (psmouse_sliced_command(psmouse, c)) return -1; if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO)) return -1; @@ -84,7 +62,7 @@ { unsigned char param[1]; - if (synaptics_special_cmd(psmouse, mode)) + if (psmouse_sliced_command(psmouse, mode)) return -1; param[0] = SYN_PS_SET_MODE2; if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE)) @@ -118,17 +96,31 @@ if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) return -1; - priv->capabilities = (cap[0]<<16) | (cap[1]<<8) | cap[2]; + priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2]; priv->ext_cap = 0; if (!SYN_CAP_VALID(priv->capabilities)) return -1; - if (SYN_EXT_CAP_REQUESTS(priv->capabilities)) { + /* + * Unless capExtended is set the rest of the flags should be ignored + */ + if (!SYN_CAP_EXTENDED(priv->capabilities)) + priv->capabilities = 0; + + if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { printk(KERN_ERR "Synaptics claims to have extended capabilities," " but I'm not able to read them."); - } else - priv->ext_cap = (cap[0]<<16) | (cap[1]<<8) | cap[2]; + } else { + priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; + + /* + * if nExtBtn is greater than 8 it should be considered + * invalid and treated as 0 + */ + if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 8) + priv->ext_cap &= 0xff0fff; + } } return 0; } @@ -167,11 +159,12 @@ if (SYN_CAP_EXTENDED(priv->capabilities)) { printk(KERN_INFO " Touchpad has extended capability bits\n"); - if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && - SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) <= 8) + if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n", (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))); - else if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) + if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) + printk(KERN_INFO " -> middle button\n"); + if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) printk(KERN_INFO " -> four buttons\n"); if (SYN_CAP_MULTIFINGER(priv->capabilities)) printk(KERN_INFO " -> multifinger detection\n"); @@ -219,21 +212,12 @@ /***************************************************************************** * Synaptics pass-through PS/2 port support ****************************************************************************/ -static int synaptics_pt_open(struct serio *port) -{ - return 0; -} - -static void synaptics_pt_close(struct serio *port) -{ -} - static int synaptics_pt_write(struct serio *port, unsigned char c) { struct psmouse *parent = port->driver; char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */ - if (synaptics_special_cmd(parent, c)) + if (psmouse_sliced_command(parent, c)) return -1; if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE)) return -1; @@ -289,166 +273,12 @@ port->serio.name = "Synaptics pass-through"; port->serio.phys = "synaptics-pt/serio0"; port->serio.write = synaptics_pt_write; - port->serio.open = synaptics_pt_open; - port->serio.close = synaptics_pt_close; port->serio.driver = psmouse; port->activate = synaptics_pt_activate; } /***************************************************************************** - * Driver initialization/cleanup functions - ****************************************************************************/ - -static inline void set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat) -{ - dev->absmin[axis] = min; - dev->absmax[axis] = max; - dev->absfuzz[axis] = fuzz; - dev->absflat[axis] = flat; - - set_bit(axis, dev->absbit); -} - -static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) -{ - set_bit(EV_ABS, dev->evbit); - set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); - set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); - set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); - set_bit(ABS_TOOL_WIDTH, dev->absbit); - - set_bit(EV_KEY, dev->evbit); - set_bit(BTN_TOUCH, dev->keybit); - set_bit(BTN_TOOL_FINGER, dev->keybit); - set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); - set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); - - set_bit(BTN_LEFT, dev->keybit); - set_bit(BTN_RIGHT, dev->keybit); - set_bit(BTN_FORWARD, dev->keybit); - set_bit(BTN_BACK, dev->keybit); - if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) { - switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { - default: - /* - * if nExtBtn is greater than 8 it should be considered - * invalid and treated as 0 - */ - break; - case 8: - set_bit(BTN_7, dev->keybit); - set_bit(BTN_6, dev->keybit); - case 6: - set_bit(BTN_5, dev->keybit); - set_bit(BTN_4, dev->keybit); - case 4: - set_bit(BTN_3, dev->keybit); - set_bit(BTN_2, dev->keybit); - case 2: - set_bit(BTN_1, dev->keybit); - set_bit(BTN_0, dev->keybit); - break; - } - } - - clear_bit(EV_REL, dev->evbit); - clear_bit(REL_X, dev->relbit); - clear_bit(REL_Y, dev->relbit); -} - -void synaptics_reset(struct psmouse *psmouse) -{ - /* reset touchpad back to relative mode, gestures enabled */ - synaptics_mode_cmd(psmouse, 0); -} - -static void synaptics_disconnect(struct psmouse *psmouse) -{ - synaptics_reset(psmouse); - kfree(psmouse->private); -} - -static int synaptics_reconnect(struct psmouse *psmouse) -{ - struct synaptics_data *priv = psmouse->private; - struct synaptics_data old_priv = *priv; - - if (!synaptics_detect(psmouse)) - return -1; - - if (synaptics_query_hardware(psmouse)) { - printk(KERN_ERR "Unable to query Synaptics hardware.\n"); - return -1; - } - - if (old_priv.identity != priv->identity || - old_priv.model_id != priv->model_id || - old_priv.capabilities != priv->capabilities || - old_priv.ext_cap != priv->ext_cap) - return -1; - - if (synaptics_set_mode(psmouse, 0)) { - printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); - return -1; - } - - return 0; -} - -int synaptics_detect(struct psmouse *psmouse) -{ - unsigned char param[4]; - - param[0] = 0; - - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); - - return param[1] == 0x47; -} - -int synaptics_init(struct psmouse *psmouse) -{ - struct synaptics_data *priv; - - psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL); - if (!priv) - return -1; - memset(priv, 0, sizeof(struct synaptics_data)); - - if (synaptics_query_hardware(psmouse)) { - printk(KERN_ERR "Unable to query Synaptics hardware.\n"); - goto init_fail; - } - - if (synaptics_set_mode(psmouse, 0)) { - printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); - goto init_fail; - } - - priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; - - if (SYN_CAP_EXTENDED(priv->capabilities) && SYN_CAP_PASS_THROUGH(priv->capabilities)) - synaptics_pt_create(psmouse); - - print_ident(priv); - set_input_params(&psmouse->dev, priv); - - psmouse->disconnect = synaptics_disconnect; - psmouse->reconnect = synaptics_reconnect; - - return 0; - - init_fail: - kfree(priv); - return -1; -} - -/***************************************************************************** * Functions to interpret the absolute mode packets ****************************************************************************/ @@ -471,17 +301,17 @@ hw->left = (buf[0] & 0x01) ? 1 : 0; hw->right = (buf[0] & 0x02) ? 1 : 0; - if (SYN_CAP_EXTENDED(priv->capabilities) && - (SYN_CAP_FOUR_BUTTON(priv->capabilities))) { - hw->up = ((buf[3] & 0x01)) ? 1 : 0; - if (hw->left) - hw->up = !hw->up; - hw->down = ((buf[3] & 0x02)) ? 1 : 0; - if (hw->right) - hw->down = !hw->down; + + if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) + hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; + + if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { + hw->up = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0; + hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; } + if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && - ((buf[3] & 2) ? !hw->right : hw->right)) { + ((buf[0] ^ buf[3]) & 0x02)) { switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { default: /* @@ -490,17 +320,17 @@ */ break; case 8: - hw->b7 = ((buf[5] & 0x08)) ? 1 : 0; - hw->b6 = ((buf[4] & 0x08)) ? 1 : 0; + hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0; + hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0; case 6: - hw->b5 = ((buf[5] & 0x04)) ? 1 : 0; - hw->b4 = ((buf[4] & 0x04)) ? 1 : 0; + hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0; + hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0; case 4: - hw->b3 = ((buf[5] & 0x02)) ? 1 : 0; - hw->b2 = ((buf[4] & 0x02)) ? 1 : 0; + hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0; + hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0; case 2: - hw->b1 = ((buf[5] & 0x01)) ? 1 : 0; - hw->b0 = ((buf[4] & 0x01)) ? 1 : 0; + hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0; + hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0; } } } else { @@ -525,6 +355,7 @@ struct synaptics_hw_state hw; int num_fingers; int finger_width; + int i; synaptics_parse_hw_state(psmouse->packet, priv, &hw); @@ -570,32 +401,20 @@ input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); - input_report_key(dev, BTN_LEFT, hw.left); - input_report_key(dev, BTN_RIGHT, hw.right); - input_report_key(dev, BTN_FORWARD, hw.up); - input_report_key(dev, BTN_BACK, hw.down); - if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) - switch(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { - default: - /* - * if nExtBtn is greater than 8 it should be considered - * invalid and treated as 0 - */ - break; - case 8: - input_report_key(dev, BTN_7, hw.b7); - input_report_key(dev, BTN_6, hw.b6); - case 6: - input_report_key(dev, BTN_5, hw.b5); - input_report_key(dev, BTN_4, hw.b4); - case 4: - input_report_key(dev, BTN_3, hw.b3); - input_report_key(dev, BTN_2, hw.b2); - case 2: - input_report_key(dev, BTN_1, hw.b1); - input_report_key(dev, BTN_0, hw.b0); - break; - } + input_report_key(dev, BTN_LEFT, hw.left); + input_report_key(dev, BTN_RIGHT, hw.right); + + if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) + input_report_key(dev, BTN_MIDDLE, hw.middle); + + if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { + input_report_key(dev, BTN_FORWARD, hw.up); + input_report_key(dev, BTN_BACK, hw.down); + } + + for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) + input_report_key(dev, BTN_0 + i, hw.ext_buttons & (1 << i)); + input_sync(dev); } @@ -607,6 +426,9 @@ static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 }; static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 }; + if (idx < 0 || idx > 4) + return 0; + switch (pkt_type) { case SYN_NEWABS: case SYN_NEWABS_RELAXED: @@ -637,7 +459,7 @@ return SYN_NEWABS_STRICT; } -void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) +static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { struct input_dev *dev = &psmouse->dev; struct synaptics_data *priv = psmouse->private; @@ -645,11 +467,6 @@ input_regs(dev, regs); if (psmouse->pktcnt >= 6) { /* Full packet received */ - if (priv->out_of_sync) { - priv->out_of_sync = 0; - printk(KERN_NOTICE "Synaptics driver resynced.\n"); - } - if (unlikely(priv->pkt_type == SYN_NEWABS)) priv->pkt_type = synaptics_detect_pkt_type(psmouse); @@ -657,16 +474,142 @@ synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet); else synaptics_process_packet(psmouse); - psmouse->pktcnt = 0; - } else if (psmouse->pktcnt && - !synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type)) { - printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt); - psmouse->pktcnt = 0; - if (++priv->out_of_sync == psmouse_resetafter) { - psmouse->state = PSMOUSE_IGNORE; - printk(KERN_NOTICE "synaptics: issuing reconnect request\n"); - serio_reconnect(psmouse->serio); - } + return PSMOUSE_FULL_PACKET; + } + + return synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type) ? + PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; +} + +/***************************************************************************** + * Driver initialization/cleanup functions + ****************************************************************************/ +static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) +{ + int i; + + set_bit(EV_ABS, dev->evbit); + input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); + input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); + input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); + set_bit(ABS_TOOL_WIDTH, dev->absbit); + + set_bit(EV_KEY, dev->evbit); + set_bit(BTN_TOUCH, dev->keybit); + set_bit(BTN_TOOL_FINGER, dev->keybit); + set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); + set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); + + set_bit(BTN_LEFT, dev->keybit); + set_bit(BTN_RIGHT, dev->keybit); + + if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) + set_bit(BTN_MIDDLE, dev->keybit); + + if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { + set_bit(BTN_FORWARD, dev->keybit); + set_bit(BTN_BACK, dev->keybit); + } + + for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) + set_bit(BTN_0 + i, dev->keybit); + + clear_bit(EV_REL, dev->evbit); + clear_bit(REL_X, dev->relbit); + clear_bit(REL_Y, dev->relbit); +} + +void synaptics_reset(struct psmouse *psmouse) +{ + /* reset touchpad back to relative mode, gestures enabled */ + synaptics_mode_cmd(psmouse, 0); +} + +static void synaptics_disconnect(struct psmouse *psmouse) +{ + synaptics_reset(psmouse); + kfree(psmouse->private); +} + +static int synaptics_reconnect(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + struct synaptics_data old_priv = *priv; + + if (!synaptics_detect(psmouse)) + return -1; + + if (synaptics_query_hardware(psmouse)) { + printk(KERN_ERR "Unable to query Synaptics hardware.\n"); + return -1; + } + + if (old_priv.identity != priv->identity || + old_priv.model_id != priv->model_id || + old_priv.capabilities != priv->capabilities || + old_priv.ext_cap != priv->ext_cap) + return -1; + + if (synaptics_set_mode(psmouse, 0)) { + printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); + return -1; + } + + return 0; +} + +int synaptics_detect(struct psmouse *psmouse) +{ + unsigned char param[4]; + + param[0] = 0; + + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); + + return param[1] == 0x47; +} + +int synaptics_init(struct psmouse *psmouse) +{ + struct synaptics_data *priv; + + psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL); + if (!priv) + return -1; + memset(priv, 0, sizeof(struct synaptics_data)); + + if (synaptics_query_hardware(psmouse)) { + printk(KERN_ERR "Unable to query Synaptics hardware.\n"); + goto init_fail; + } + + if (synaptics_set_mode(psmouse, 0)) { + printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); + goto init_fail; } + + priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; + + if (SYN_CAP_PASS_THROUGH(priv->capabilities)) + synaptics_pt_create(psmouse); + + print_ident(priv); + set_input_params(&psmouse->dev, priv); + + psmouse->protocol_handler = synaptics_process_byte; + psmouse->disconnect = synaptics_disconnect; + psmouse->reconnect = synaptics_reconnect; + + return 0; + + init_fail: + kfree(priv); + return -1; } + + diff -Nru a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h --- a/drivers/input/mouse/synaptics.h Tue May 4 22:10:38 2004 +++ b/drivers/input/mouse/synaptics.h Tue May 4 22:10:38 2004 @@ -9,7 +9,6 @@ #ifndef _SYNAPTICS_H #define _SYNAPTICS_H -extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs); extern int synaptics_detect(struct psmouse *psmouse); extern int synaptics_init(struct psmouse *psmouse); extern void synaptics_reset(struct psmouse *psmouse); @@ -44,13 +43,14 @@ /* synaptics capability bits */ #define SYN_CAP_EXTENDED(c) ((c) & (1 << 23)) +#define SYN_CAP_MIDDLE_BUTTON(c) ((c) & (1 << 18)) #define SYN_CAP_PASS_THROUGH(c) ((c) & (1 << 7)) #define SYN_CAP_SLEEP(c) ((c) & (1 << 4)) #define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3)) #define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1)) #define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0)) #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) -#define SYN_EXT_CAP_REQUESTS(c) ((((c) & 0x700000) >> 20) == 1) +#define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) /* synaptics modes query bits */ @@ -86,18 +86,12 @@ int y; int z; int w; - int left; - int right; - int up; - int down; - int b0; - int b1; - int b2; - int b3; - int b4; - int b5; - int b6; - int b7; + unsigned int left:1; + unsigned int right:1; + unsigned int middle:1; + unsigned int up:1; + unsigned int down:1; + unsigned char ext_buttons; }; struct synaptics_data { @@ -108,7 +102,6 @@ unsigned long int identity; /* Identification */ /* Data for normal processing */ - unsigned int out_of_sync; /* # of packets out of sync */ int old_w; /* Previous w value */ unsigned char pkt_type; /* packet type - old, new, etc */ }; diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c --- a/drivers/input/mousedev.c Tue May 4 22:10:38 2004 +++ b/drivers/input/mousedev.c Tue May 4 22:10:38 2004 @@ -391,9 +391,9 @@ list->impsseq = 0; list->imexseq = 0; list->mode = 0; - list->ps2[0] = 0xaa; - list->ps2[1] = 0x00; - list->bufsiz = 2; + list->ps2[1] = 0xaa; + list->ps2[2] = 0x00; + list->bufsiz = 3; break; } diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c --- a/drivers/input/serio/i8042.c Tue May 4 22:10:38 2004 +++ b/drivers/input/serio/i8042.c Tue May 4 22:10:38 2004 @@ -474,8 +474,17 @@ if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xa9) return -1; param = 0xa4; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == 0x5b) + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == 0x5b) { + +/* + * Do another loop test with the 0x5a value. Doing anything else upsets + * Profusion/ServerWorks OSB4 chipsets. + */ + + param = 0x5a; + i8042_command(¶m, I8042_CMD_AUX_LOOP); return -1; + } if (mux_version) *mux_version = ~param; @@ -532,8 +541,8 @@ return -1; /* Workaround for broken chips which seem to support MUX, but in reality don't. */ - /* They all report version 12.10 */ - if (mux_version == 0xCA) + /* They all report version 10.12 */ + if (mux_version == 0xAC) return -1; printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n", diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c --- a/drivers/input/serio/parkbd.c Tue May 4 22:10:38 2004 +++ b/drivers/input/serio/parkbd.c Tue May 4 22:10:38 2004 @@ -86,20 +86,9 @@ return 0; } -static int parkbd_open(struct serio *port) -{ - return 0; -} - -static void parkbd_close(struct serio *port) -{ -} - static struct serio parkbd_port = { .write = parkbd_write, - .open = parkbd_open, - .close = parkbd_close, .name = parkbd_name, .phys = parkbd_phys, }; diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c --- a/drivers/input/serio/q40kbd.c Tue May 4 22:10:38 2004 +++ b/drivers/input/serio/q40kbd.c Tue May 4 22:10:38 2004 @@ -47,23 +47,12 @@ MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver"); MODULE_LICENSE("GPL"); - -static int q40kbd_open(struct serio *port) -{ - return 0; -} -static void q40kbd_close(struct serio *port) -{ -} - static struct serio q40kbd_port = { .type = SERIO_8042, .name = "Q40 kbd port", .phys = "Q40", .write = NULL, - .open = q40kbd_open, - .close = q40kbd_close, }; static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c --- a/drivers/input/serio/serio.c Tue May 4 22:10:38 2004 +++ b/drivers/input/serio/serio.c Tue May 4 22:10:38 2004 @@ -11,18 +11,18 @@ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to , or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic @@ -108,7 +108,7 @@ struct serio_event *event; list_for_each_safe(node, next, &serio_event_list) { - event = container_of(node, struct serio_event, node); + event = container_of(node, struct serio_event, node); down(&serio_sem); if (event->serio == NULL) @@ -152,7 +152,7 @@ do { serio_handle_events(); - wait_event_interruptible(serio_wait, !list_empty(&serio_event_list)); + wait_event_interruptible(serio_wait, !list_empty(&serio_event_list)); if (current->flags & PF_FREEZE) refrigerator(PF_FREEZE); } while (!signal_pending(current)); @@ -293,7 +293,7 @@ int serio_open(struct serio *serio, struct serio_dev *dev) { serio->dev = dev; - if (serio->open(serio)) { + if (serio->open && serio->open(serio)) { serio->dev = NULL; return -1; } @@ -303,7 +303,8 @@ /* called from serio_dev->connect/disconnect methods under serio_sem */ void serio_close(struct serio *serio) { - serio->close(serio); + if (serio->close) + serio->close(serio); serio->dev = NULL; } diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c --- a/drivers/input/serio/serport.c Tue May 4 22:10:38 2004 +++ b/drivers/input/serio/serport.c Tue May 4 22:10:38 2004 @@ -48,11 +48,6 @@ return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1); } -static int serport_serio_open(struct serio *serio) -{ - return 0; -} - static void serport_serio_close(struct serio *serio) { struct serport *serport = serio->driver; @@ -87,7 +82,6 @@ serport->serio.type = SERIO_RS232; serport->serio.write = serport_serio_write; - serport->serio.open = serport_serio_open; serport->serio.close = serport_serio_close; serport->serio.driver = serport; @@ -135,7 +129,7 @@ } /* - * serport_ldisc_read() just waits indefinitely if everything goes well. + * serport_ldisc_read() just waits indefinitely if everything goes well. * However, when the serio driver closes the serio port, it finishes, * returning 0 characters. */ @@ -165,7 +159,7 @@ static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) { struct serport *serport = (struct serport*) tty->disc_data; - + if (cmd == SPIOCSTYPE) return get_user(serport->serio.type, (unsigned long *) arg); diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c --- a/drivers/input/touchscreen/gunze.c Tue May 4 22:10:38 2004 +++ b/drivers/input/touchscreen/gunze.c Tue May 4 22:10:38 2004 @@ -124,12 +124,10 @@ memset(gunze, 0, sizeof(struct gunze)); init_input_dev(&gunze->dev); - gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - gunze->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); + gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - - gunze->dev.absmin[ABS_X] = 96; gunze->dev.absmin[ABS_Y] = 72; - gunze->dev.absmax[ABS_X] = 4000; gunze->dev.absmax[ABS_Y] = 3000; + input_set_abs_params(&gunze->dev, ABS_X, 96, 4000, 0, 0); + input_set_abs_params(&gunze->dev, ABS_Y, 72, 3000, 0, 0); gunze->serio = serio; serio->private = gunze; diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c --- a/drivers/input/touchscreen/h3600_ts_input.c Tue May 4 22:10:38 2004 +++ b/drivers/input/touchscreen/h3600_ts_input.c Tue May 4 22:10:38 2004 @@ -1,11 +1,11 @@ /* * $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $ * - * Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com + * Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com * - * Sponsored by Transvirtual Technology. - * - * Derived from the code in h3600_ts.[ch] by Charles Flynn + * Sponsored by Transvirtual Technology. + * + * Derived from the code in h3600_ts.[ch] by Charles Flynn */ /* @@ -75,7 +75,7 @@ #define MAX_ID 14 #define H3600_MAX_LENGTH 16 -#define H3600_KEY 0xf +#define H3600_KEY 0xf #define H3600_SCANCODE_RECORD 1 /* 1 -> record button */ #define H3600_SCANCODE_CALENDAR 2 /* 2 -> calendar */ @@ -118,13 +118,13 @@ int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1; struct input_dev *dev = (struct input_dev *) dev_id; - /* - * This interrupt is only called when we release the key. So we have + /* + * This interrupt is only called when we release the key. So we have * to fake a key press. - */ + */ input_regs(dev, regs); input_report_key(dev, KEY_SUSPEND, 1); - input_report_key(dev, KEY_SUSPEND, down); + input_report_key(dev, KEY_SUSPEND, down); input_sync(dev); } @@ -144,18 +144,18 @@ unsigned char brightness = ((pwr==FLITE_PWR_OFF) ? 0:flite_brightness); struct h3600_dev *ts = dev->private; - /* Must be in this order */ + /* Must be in this order */ ts->serio->write(ts->serio, 1); ts->serio->write(ts->serio, pwr); - ts->serio->write(ts->serio, brightness); + ts->serio->write(ts->serio, brightness); return 0; } static int suspended = 0; -static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, +static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) { - struct input_dev *dev = (struct input_dev *) data; + struct input_dev *dev = (struct input_dev *) data; switch (req) { case PM_SUSPEND: /* enter D1-D3 */ @@ -183,7 +183,7 @@ /* * This function translates the native event packets to linux input event * packets. Some packets coming from serial are not touchscreen related. In - * this case we send them off to be processed elsewhere. + * this case we send them off to be processed elsewhere. */ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) { @@ -206,7 +206,7 @@ Note: This is true for non interrupt generated key events. */ case KEYBD_ID: - down = (ts->buf[0] & 0x80) ? 0 : 1; + down = (ts->buf[0] & 0x80) ? 0 : 1; switch (ts->buf[0] & 0x7f) { case H3600_SCANCODE_RECORD: @@ -218,7 +218,7 @@ case H3600_SCANCODE_CONTACTS: key = KEY_PROG2; break; - case H3600_SCANCODE_Q: + case H3600_SCANCODE_Q: key = KEY_Q; break; case H3600_SCANCODE_START: @@ -237,9 +237,9 @@ key = KEY_DOWN; break; default: - key = 0; - } - if (key) + key = 0; + } + if (key) input_report_key(dev, key, down); break; /* @@ -251,13 +251,13 @@ * byte 0 1 2 3 */ case TOUCHS_ID: - if (!touched) { + if (!touched) { input_report_key(dev, BTN_TOUCH, 1); touched = 1; - } + } if (ts->len) { - unsigned short x, y; + unsigned short x, y; x = ts->buf[0]; x <<= 8; x += ts->buf[1]; y = ts->buf[2]; y <<= 8; y += ts->buf[3]; @@ -267,7 +267,7 @@ } else { input_report_key(dev, BTN_TOUCH, 0); touched = 0; - } + } break; default: /* Send a non input event elsewhere */ @@ -280,7 +280,7 @@ /* * h3600ts_event() handles events from the input module. */ -static int h3600ts_event(struct input_dev *dev, unsigned int type, +static int h3600ts_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct h3600_dev *ts = dev->private; @@ -290,7 +290,7 @@ // ts->serio->write(ts->serio, SOME_CMD); return 0; } - } + } return -1; } @@ -323,12 +323,12 @@ struct h3600_dev *ts = serio->private; /* - * We have a new frame coming in. + * We have a new frame coming in. */ switch (state) { case STATE_SOF: if (data == CHAR_SOF) - state = STATE_ID; + state = STATE_ID; return; case STATE_ID: ts->event = (data & 0xf0) >> 4; @@ -344,7 +344,7 @@ case STATE_DATA: ts->chksum += data; ts->buf[ts->idx]= data; - if(++ts->idx == ts->len) + if(++ts->idx == ts->len) state = STATE_EOF; break; case STATE_EOF: @@ -382,7 +382,7 @@ 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, + SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, "h3600_action", &ts->dev)) { printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); kfree(ts); @@ -390,24 +390,19 @@ } if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, - SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, + SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, "h3600_suspend", &ts->dev)) { free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); kfree(ts); return; } + /* Now we have things going we setup our input device */ ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR); - ts->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); - ts->dev.ledbit[0] = BIT(LED_SLEEP); - - ts->dev.absmin[ABS_X] = 60; ts->dev.absmin[ABS_Y] = 35; - ts->dev.absmax[ABS_X] = 985; ts->dev.absmax[ABS_Y] = 1024; - ts->dev.absfuzz[ABS_X] = 0; ts->dev.absfuzz[ABS_Y] = 0; - - ts->serio = serio; - serio->private = ts; + ts->dev.ledbit[0] = BIT(LED_SLEEP); + input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0); + input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0); set_bit(KEY_RECORD, ts->dev.keybit); set_bit(KEY_Q, ts->dev.keybit); @@ -422,6 +417,9 @@ ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH); ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND); + ts->serio = serio; + serio->private = ts; + sprintf(ts->phys, "%s/input0", serio->phys); ts->dev.event = h3600ts_event; @@ -442,7 +440,7 @@ //h3600_flite_control(1, 25); /* default brightness */ #ifdef CONFIG_PM - ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT, + ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT, h3600ts_pm_callback); printk("registered pm callback\n"); #endif @@ -458,7 +456,7 @@ static void h3600ts_disconnect(struct serio *serio) { struct h3600_dev *ts = serio->private; - + free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev); input_unregister_device(&ts->dev); diff -Nru a/include/linux/input.h b/include/linux/input.h --- a/include/linux/input.h Tue May 4 22:10:38 2004 +++ b/include/linux/input.h Tue May 4 22:10:38 2004 @@ -655,7 +655,7 @@ struct ff_envelope envelope; /* Only used if waveform == FF_CUSTOM */ - __u32 custom_len; /* Number of samples */ + __u32 custom_len; /* Number of samples */ __s16 *custom_data; /* Buffer of samples */ /* Note: the data pointed by custom_data is copied by the driver. You can * therefore dispose of the memory after the upload/update */ @@ -749,8 +749,6 @@ #define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \ ((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode]))) -#define init_input_dev(dev) do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0) - #define SET_INPUT_KEYCODE(dev, scancode, val) \ ({ unsigned __old; \ switch (dev->keycodesize) { \ @@ -915,6 +913,12 @@ #define to_handle(n) container_of(n,struct input_handle,d_node) #define to_handle_h(n) container_of(n,struct input_handle,h_node) +static inline void init_input_dev(struct input_dev *dev) +{ + INIT_LIST_HEAD(&dev->h_list); + INIT_LIST_HEAD(&dev->node); +} + void input_register_device(struct input_dev *); void input_unregister_device(struct input_dev *); @@ -932,14 +936,51 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); -#define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c)) -#define input_report_rel(a,b,c) input_event(a, EV_REL, b, c) -#define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c) -#define input_report_ff(a,b,c) input_event(a, EV_FF, b, c) -#define input_report_ff_status(a,b,c) input_event(a, EV_FF_STATUS, b, c) +static inline void input_report_key(struct input_dev *dev, unsigned int code, int value) +{ + input_event(dev, EV_KEY, code, !!value); +} + +static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value) +{ + input_event(dev, EV_REL, code, value); +} + +static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value) +{ + input_event(dev, EV_ABS, code, value); +} + +static inline void input_report_ff(struct input_dev *dev, unsigned int code, int value) +{ + input_event(dev, EV_FF, code, value); +} + +static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value) +{ + input_event(dev, EV_FF_STATUS, code, value); +} + +static inline void input_regs(struct input_dev *dev, struct pt_regs *regs) +{ + dev->regs = regs; +} + +static inline void input_sync(struct input_dev *dev) +{ + input_event(dev, EV_SYN, SYN_REPORT, 0); + dev->regs = NULL; +} + +static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat) +{ + dev->absmin[axis] = min; + dev->absmax[axis] = max; + dev->absfuzz[axis] = fuzz; + dev->absflat[axis] = flat; -#define input_regs(a,b) do { (a)->regs = (b); } while (0) -#define input_sync(a) do { input_event(a, EV_SYN, SYN_REPORT, 0); (a)->regs = NULL; } while (0) + dev->absbit[LONG(axis)] |= BIT(axis); +} extern struct class_simple *input_class;