bk://kernel.bkbits.net/vojtech/input vojtech@suse.cz|ChangeSet|20041227092115|17133 vojtech # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/12/29 18:24:03-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # Documentation/kernel-parameters.txt # 2004/12/29 18:23:57-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/12/28 20:48:26-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/vojtech/input # into bix.(none):/usr/src/bk-input # # drivers/usb/input/hid-core.c # 2004/12/28 20:48:22-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/input/tsdev.c # 2004/12/28 20:48:22-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/input/mousedev.c # 2004/12/28 20:48:22-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/input/joydev.c # 2004/12/28 20:48:22-08:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/input/evdev.c # 2004/12/28 20:48:22-08:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/12/28 20:48:22-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/12/27 10:21:15+01:00 vojtech@suse.cz # Merge suse.cz:/home/vojtech/bk/linus into suse.cz:/home/vojtech/bk/input # # drivers/usb/input/hid-core.c # 2004/12/27 10:21:12+01:00 vojtech@suse.cz +0 -0 # Auto merged # # drivers/input/tsdev.c # 2004/12/27 10:21:12+01:00 vojtech@suse.cz +0 -5 # Auto merged # # drivers/input/mousedev.c # 2004/12/27 10:21:12+01:00 vojtech@suse.cz +0 -2 # Auto merged # # drivers/input/joydev.c # 2004/12/27 10:21:12+01:00 vojtech@suse.cz +0 -2 # Auto merged # # drivers/input/evdev.c # 2004/12/27 10:21:12+01:00 vojtech@suse.cz +0 -2 # Auto merged # # Documentation/kernel-parameters.txt # 2004/12/27 10:21:12+01:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/12/25 08:59:48-08:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-input # # drivers/input/tsdev.c # 2004/12/25 08:59:44-08:00 akpm@bix.(none) +0 -5 # Auto merged # # drivers/input/mousedev.c # 2004/12/25 08:59:44-08:00 akpm@bix.(none) +0 -2 # Auto merged # # drivers/input/joydev.c # 2004/12/25 08:59:44-08:00 akpm@bix.(none) +0 -2 # Auto merged # # drivers/input/evdev.c # 2004/12/25 08:59:44-08:00 akpm@bix.(none) +0 -2 # Auto merged # # ChangeSet # 2004/12/16 13:33:00-08:00 akpm@bix.(none) # Merge bk://kernel.bkbits.net/vojtech/input # into bix.(none):/usr/src/bk-input # # drivers/usb/input/hid-core.c # 2004/12/16 13:32:57-08:00 akpm@bix.(none) +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/12/16 13:32:57-08:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/11/18 12:06:01+01:00 vojtech@suse.cz # Manual merge # # drivers/usb/input/hid-core.c # 2004/11/18 12:05:54+01:00 vojtech@suse.cz +5 -4 # Manual merge # # drivers/input/serio/serio.c # 2004/11/18 11:50:15+01:00 vojtech@suse.cz +0 -0 # Auto merged # # drivers/input/serio/i8042.c # 2004/11/18 11:50:15+01:00 vojtech@suse.cz +0 -0 # Auto merged # # drivers/input/input.c # 2004/11/18 11:50:15+01:00 vojtech@suse.cz +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/11/18 11:50:15+01:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/11/10 16:28:17-08:00 torvalds@ppc970.osdl.org # Fix the fix. # # Silly #endif placement problem. # # arch/i386/kernel/io_apic.c # 2004/11/10 16:28:10-08:00 torvalds@ppc970.osdl.org +1 -1 # Fix the fix. # # Silly #endif placement problem. # # ChangeSet # 2004/11/10 16:25:01-08:00 acme@conectiva.com.br # [PATCH] fix platform_rename_gsi related ia32 build breakage # # "platform_rename_gsi" does not exist unless CONFIG_ACPI_BOOT is defined. # # arch/i386/kernel/io_apic.c # 2004/11/10 15:58:57-08:00 acme@conectiva.com.br +2 -0 # fix platform_rename_gsi related ia32 build breakage # # ChangeSet # 2004/11/01 20:44:28+01:00 vojtech@suse.cz # Merge suse.cz:/home/vojtech/bk/linus into suse.cz:/home/vojtech/bk/input # # include/linux/input.h # 2004/11/01 20:44:12+01:00 vojtech@suse.cz +0 -0 # Auto merged # # drivers/input/serio/Kconfig # 2004/11/01 20:44:12+01:00 vojtech@suse.cz +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/11/01 20:44:12+01:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/10/27 12:09:04+02:00 vojtech@suse.cz # Manual merge # # drivers/input/serio/i8042-io.h # 2004/10/27 12:08:57+02:00 vojtech@suse.cz +2 -4 # Manual merge # # ChangeSet # 2004/10/27 01:11:44-05:00 dtor_core@ameritech.net # Input: parkbd - switch to using module_param. Parameter names are # parkbd.port and parkbd.mode # # Signed-off-by: Dmitry Torokhov # # drivers/input/serio/parkbd.c # 2004/10/27 01:10:52-05:00 dtor_core@ameritech.net +8 -11 # Switch to using module_param() # # Documentation/kernel-parameters.txt # 2004/10/27 01:10:52-05:00 dtor_core@ameritech.net +7 -0 # Document parkbd options. # # ChangeSet # 2004/10/24 21:02:03+02:00 vojtech@suse.cz # Merge bk://dtor.bkbits.net/input/ into suse.cz:/home/vojtech/bk/input # # drivers/input/keyboard/lkkbd.c # 2004/10/24 21:01:51+02:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/10/24 20:59:23+02:00 vojtech@suse.cz # Merge suse.cz:/home/vojtech/bk/linus into suse.cz:/home/vojtech/bk/input # # drivers/usb/input/hid-core.c # 2004/10/24 20:59:06+02:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/10/21 23:57:49-05:00 dtor_core@ameritech.net # Input: gscps2 - remove unused statically allocated gscps2_serio_port # variable as the port is allocated dynamically. # # Signed-off-by: Dmitry Torokhov # # drivers/input/serio/gscps2.c # 2004/10/21 23:57:31-05:00 dtor_core@ameritech.net +0 -13 # Remove unused statically allocated gscps2_serio_port as the port is # allocated dynamically. # # ChangeSet # 2004/10/21 23:56:41-05:00 dtor_core@ameritech.net # Input: get rid of pm_dev in input core as it is deprecated and # nothing uses it anyway. # # Signed-off-by: Dmitry Torokhov # # include/linux/input.h # 2004/10/21 23:56:15-05:00 dtor_core@ameritech.net +0 -1 # Get rid of pm_dev in input core as it is deprecated and nothing # uses it anyway. # # drivers/input/touchscreen/h3600_ts_input.c # 2004/10/21 23:56:15-05:00 dtor_core@ameritech.net +3 -2 # Move pm_dev into h3600_dev structure (not that it works anyway). # # drivers/input/input.c # 2004/10/21 23:56:15-05:00 dtor_core@ameritech.net +0 -4 # Get rid of pm_dev in input core as it is deprecated and nothing # uses it anyway. # # ChangeSet # 2004/10/21 23:55:41-05:00 dtor_core@ameritech.net # Input: i8042 - get rid of reboot notifier as suspend method # should do the job. # # Signed-off-by: Dmitry Torokhov # # drivers/input/serio/i8042.c # 2004/10/21 23:55:20-05:00 dtor_core@ameritech.net +5 -28 # Get rid of reboot notifier as suspend method shoudl do the job. # # ChangeSet # 2004/10/21 23:53:52-05:00 dtor_core@ameritech.net # Input: i8042 - get rid of old style power management handler since # APM calls both pm_send and device_suspend. # # Signed-off-by: Dmitry Torokhov # # drivers/input/serio/i8042.c # 2004/10/21 23:53:26-05:00 dtor_core@ameritech.net +30 -59 # Get rid of old style power management handler since APM calls both # pm_send and device_suspend so in fact we were resuming everything # twice. # # ChangeSet # 2004/10/21 23:52:36-05:00 dtor_core@ameritech.net # Input: i8042 - allow turning debugging on and off "on-fly" # so people do not have to recompile their kernels to # provide debug info. # # Adds new parameter i8042.debug also accessible through # sysfs. # # Signed-off-by: Dmitry Torokhov # # drivers/input/serio/i8042.h # 2004/10/21 23:52:18-05:00 dtor_core@ameritech.net +6 -2 # Allow debugging to be turned on and off "on-fly" # # drivers/input/serio/i8042.c # 2004/10/21 23:52:18-05:00 dtor_core@ameritech.net +7 -1 # Allow debugging to be turned on and off "on-fly" # # ChangeSet # 2004/10/21 23:51:43-05:00 dtor_core@ameritech.net # Input: when creating input devices for hardware attached to # a serio port properly set input_device->dev pointer # so when corresponding class device is created it will # show proper links to parent device and driver in sysfs # hierarchy. # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/vsxxxaa.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/mouse/sermouse.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/mouse/psmouse-base.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/keyboard/xtkbd.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/keyboard/sunkbd.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/keyboard/newtonkbd.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/keyboard/lkkbd.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/keyboard/atkbd.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/joystick/warrior.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/joystick/twidjoy.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/joystick/stinger.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/joystick/spaceorb.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/joystick/spaceball.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/joystick/magellan.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +1 -0 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # drivers/input/joystick/iforce/iforce-main.c # 2004/10/21 23:51:23-05:00 dtor_core@ameritech.net +15 -1 # Link input device with serio's device so when class device is # registered appropriate links to device and driver are created. # # ChangeSet # 2004/10/21 23:50:25-05:00 dtor_core@ameritech.net # Input: evdev, joydev, mousedev, tsdev - remove class device and devfs # entry when hardware driver disconnects instead of waiting for # the last user to drop off. This way hardware drivers can be # unloaded at any time. # # Signed-off-by: Dmitry Torokhov # # drivers/input/tsdev.c # 2004/10/21 23:49:57-05:00 dtor_core@ameritech.net +5 -5 # Remove class device and devfs entry when hardware is disconncted; # do not wait till the last user drops off. # # drivers/input/mousedev.c # 2004/10/21 23:49:57-05:00 dtor_core@ameritech.net +2 -2 # Remove class device and devfs entry when hardware is disconncted; # do not wait till the last user drops off. # # drivers/input/joydev.c # 2004/10/21 23:49:57-05:00 dtor_core@ameritech.net +2 -2 # Remove class device and devfs entry when hardware is disconncted; # do not wait till the last user drops off. # # drivers/input/evdev.c # 2004/10/21 23:49:57-05:00 dtor_core@ameritech.net +2 -2 # Remove class device and devfs entry when hardware is disconncted; # do not wait till the last user drops off. # # ChangeSet # 2004/10/21 23:49:17-05:00 dtor_core@ameritech.net # Input: couple of whitespace fixes. # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/vsxxxaa.c # 2004/10/21 23:48:57-05:00 dtor_core@ameritech.net +1 -1 # Whitespace fixes # # drivers/input/mouse/sermouse.c # 2004/10/21 23:48:57-05:00 dtor_core@ameritech.net +12 -12 # Whitespace fixes # # ChangeSet # 2004/10/21 11:59:13+02:00 vojtech@suse.cz # Merge suse.cz:/data2/bk/linus into suse.cz:/data2/bk/input # # drivers/input/mouse/Kconfig # 2004/10/21 11:59:08+02:00 vojtech@suse.cz +0 -0 # Auto merged # # drivers/input/joystick/gamecon.c # 2004/10/21 11:59:08+02:00 vojtech@suse.cz +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/21 11:59:08+02:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/10/20 14:54:11+02:00 vojtech@suse.cz # Manual merge # # drivers/usb/input/hid-core.c # 2004/10/20 14:54:04+02:00 vojtech@suse.cz +5 -6 # Manual merge # # Documentation/kernel-parameters.txt # 2004/10/20 14:49:34+02:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/10/20 10:13:15+02:00 vojtech@suse.cz # input: Increase ACK timeouts in libps2 in case the RESET_BAT command is used. # This should fix most Synaptics "reset failed" cases. Thanks to Keith # Packard for the report. # Also add some more keyboard IDs, so that unusual keyboards are accepted # by libps2 and atkbd. # # Signed-off-by: Vojtech Pavlik # # include/linux/libps2.h # 2004/10/20 10:13:08+02:00 vojtech@suse.cz +1 -1 # input: Increase ACK timeouts in libps2 in case the RESET_BAT command is used. # This should fix most Synaptics "reset failed" cases. Thanks to Keith # Packard for the report. # Also add some more keyboard IDs, so that unusual keyboards are accepted # by libps2 and atkbd. # # drivers/input/serio/libps2.c # 2004/10/20 10:13:08+02:00 vojtech@suse.cz +32 -10 # input: Increase ACK timeouts in libps2 in case the RESET_BAT command is used. # This should fix most Synaptics "reset failed" cases. Thanks to Keith # Packard for the report. # Also add some more keyboard IDs, so that unusual keyboards are accepted # by libps2 and atkbd. # # drivers/input/keyboard/atkbd.c # 2004/10/20 10:13:08+02:00 vojtech@suse.cz +4 -1 # input: Increase ACK timeouts in libps2 in case the RESET_BAT command is used. # This should fix most Synaptics "reset failed" cases. Thanks to Keith # Packard for the report. # Also add some more keyboard IDs, so that unusual keyboards are accepted # by libps2 and atkbd. # # ChangeSet # 2004/10/19 12:58:36+02:00 vojtech@suse.cz # Input: i8042 ACPI enumeration - add PNP IDs found in AMD64 laptops. # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Andrew Morton # Signed-off-by: Vojtech Pavlik # # drivers/input/serio/i8042-x86ia64io.h # 2004/10/19 12:58:22+02:00 vojtech@suse.cz +2 -2 # Input: i8042 ACPI enumeration - add PNP IDs found in AMD64 laptops. # # Signed-off-by: Dmitry Torokhov # Signed-off-by: Andrew Morton # Signed-off-by: Vojtech Pavlik # # ChangeSet # 2004/10/19 10:02:20+02:00 vojtech@suse.cz # Merge suse.cz:/data2/bk/linus into suse.cz:/data2/bk/input # # drivers/usb/input/hid-core.c # 2004/10/19 10:02:15+02:00 vojtech@suse.cz +0 -0 # Auto merged # # drivers/input/joystick/Kconfig # 2004/10/19 10:02:15+02:00 vojtech@suse.cz +0 -1 # Auto merged # # ChangeSet # 2004/10/16 13:15:38+02:00 vojtech@suse.cz # input: Fix ssize_t prototype mismatch in psmouse and atkbd. # # Signed-off-by: Vojtech Pavlik # # drivers/input/mouse/psmouse.h # 2004/10/16 13:15:31+02:00 vojtech@suse.cz +1 -1 # input: Fix ssize_t prototype mismatch in psmouse and atkbd. # # drivers/input/keyboard/atkbd.c # 2004/10/16 13:15:31+02:00 vojtech@suse.cz +2 -2 # input: Fix ssize_t prototype mismatch in psmouse and atkbd. # # ChangeSet # 2004/10/13 15:54:28+02:00 vojtech@suse.cz # Merge suse.cz:/data2/bk/linus into suse.cz:/data2/bk/input # # drivers/usb/input/hid-core.c # 2004/10/13 15:54:24+02:00 vojtech@suse.cz +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/10/13 15:54:24+02:00 vojtech@suse.cz +0 -0 # Auto merged # # ChangeSet # 2004/09/30 01:31:12-05:00 dtor_core@ameritech.net # Input: psmouse - explicitely specify packet size instead of relying # on protocol numbering scheme. Make protocol detection routines # return -1 on failure to keep them consistent with ther rest # of the code. Set mouse parameters right in detection routines # instead of doing it in psmouse_extensions. # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/synaptics.h # 2004/09/30 01:30:53-05:00 dtor_core@ameritech.net +1 -1 # Adjust synaptics_detect prototype. # # drivers/input/mouse/synaptics.c # 2004/09/30 01:30:53-05:00 dtor_core@ameritech.net +12 -3 # Explicitely set up packet size and vendor/name, adjust detect # routine to return -1 on failure. # # drivers/input/mouse/psmouse.h # 2004/09/30 01:30:53-05:00 dtor_core@ameritech.net +1 -0 # Add packet size to psmouse structure. # # drivers/input/mouse/psmouse-base.c # 2004/09/30 01:30:53-05:00 dtor_core@ameritech.net +82 -74 # Explicitely set and check packet size and not rely on protocol # numbering scheme; rearrange detect methods to return -1 when # hardware is not detceted and also set psmouse properties instead # of duing it in psmouse_extensions. # # drivers/input/mouse/logips2pp.c # 2004/09/30 01:30:53-05:00 dtor_core@ameritech.net +3 -2 # Explicitely set up packet size, adjust ps2pp_init to return -1 # on failure. # # drivers/input/mouse/alps.h # 2004/09/30 01:30:53-05:00 dtor_core@ameritech.net +1 -1 # Adjust alps_detect prototype. # # drivers/input/mouse/alps.c # 2004/09/30 01:30:53-05:00 dtor_core@ameritech.net +10 -2 # Explicitely set up packet size and vendor/name, adjust alps_detect # to retrun -1 on failure. # # ChangeSet # 2004/09/30 01:30:25-05:00 dtor_core@ameritech.net # Input: psmouse - make logips2pp fully decode its protocol packets # and not rely on generic handler to finish job. # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/psmouse-base.c # 2004/09/30 01:30:04-05:00 dtor_core@ameritech.net +0 -7 # Make logips2pp fully decode its protocol packets and not rely # on generic handler to finish job. # # drivers/input/mouse/logips2pp.h # 2004/09/30 01:30:04-05:00 dtor_core@ameritech.net +0 -1 # Make logips2pp fully decode its protocol packets and not rely # on generic handler to finish job. # # drivers/input/mouse/logips2pp.c # 2004/09/30 01:30:04-05:00 dtor_core@ameritech.net +33 -10 # Make logips2pp fully decode its protocol packets and not rely # on generic handler to finish job. # # ChangeSet # 2004/09/30 01:28:49-05:00 dtor_core@ameritech.net # Input: psmouse - drop PS2TPP protocol (it is handled exactly like # PS2PP) to free spot for THINKPS protocol and keep old protocol # numbers for binary compatibility with Synaptics/ALPS touchpad # driver for X. # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/psmouse.h # 2004/09/30 01:28:32-05:00 dtor_core@ameritech.net +0 -1 # Remove PS2TPP protocol as it is handled exactly like PS2PP # # drivers/input/mouse/psmouse-base.c # 2004/09/30 01:28:32-05:00 dtor_core@ameritech.net +4 -7 # Remove PS2TPP protocol as it is handled exactly like PS2PP # # drivers/input/mouse/logips2pp.c # 2004/09/30 01:28:32-05:00 dtor_core@ameritech.net +28 -24 # Convert ps2pp_init to signal caller whether it supports # PS2PP protocol or not like other detection functions do. # # ChangeSet # 2004/09/30 01:28:03-05:00 dtor_core@ameritech.net # Input: psmouse - export rate, resolution, resetafter and smartscroll # (Logitech only) as individual mouse attributes (sysfs) and allow # them to be set/changed independently for each mouse: # # echo -n "100" > /sys/bus/serio/devices/serio0/rate # echo -n "200" > /sys/bus/serio/devices/serio0/resolution # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/psmouse.h # 2004/09/30 01:27:48-05:00 dtor_core@ameritech.net +21 -1 # Add PSMOUSE_DEFINE_ATTR to help define psmouse sysfs attributes # # drivers/input/mouse/psmouse-base.c # 2004/09/30 01:27:48-05:00 dtor_core@ameritech.net +125 -2 # Export rate, resolution and resetafter as sysfs attributes. # # drivers/input/mouse/logips2pp.c # 2004/09/30 01:27:48-05:00 dtor_core@ameritech.net +39 -9 # Export smartscroll as a sysfs attribute. # # ChangeSet # 2004/09/30 01:27:24-05:00 dtor_core@ameritech.net # Input: psmouse - reset mouse before doing intellimouse/explorer # probes in case it got confused by earlier probes; switch # to streaming mode before setting scale and resolution, # otherwise some KVMs get confused. # # Patch-by: Marko Macek # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/psmouse-base.c # 2004/09/30 01:27:07-05:00 dtor_core@ameritech.net +11 -7 # Reset mouse before doing intellimouse/explorer probes in case it # got confused by earlier probes; switch to streaming mode before # setting scale and resolution, otherwise some KVMs may get confused. # # ChangeSet # 2004/09/30 01:26:43-05:00 dtor_core@ameritech.net # Input: synaptics - not only switch to 4-byte client protocol # but also revert to 3-byte mode if client selected lower # protocol. # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/synaptics.c # 2004/09/30 01:26:27-05:00 dtor_core@ameritech.net +7 -3 # Not only switch to 4-byte client protocol but also disable it # if client switched to 3-byte protocol. # # ChangeSet # 2004/09/30 01:25:47-05:00 dtor_core@ameritech.net # Input: psmouse - add set_rate and set_resolution handlers to make # adding new protocols easier and remove special knowledge # from psmouse-base.c # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/synaptics.h # 2004/09/30 01:25:30-05:00 dtor_core@ameritech.net +1 -0 # Add current mode byte to synaptics structure. # # drivers/input/mouse/synaptics.c # 2004/09/30 01:25:30-05:00 dtor_core@ameritech.net +27 -10 # Move rate switching code into separate synaptics_set_rate handler. # # drivers/input/mouse/psmouse.h # 2004/09/30 01:25:30-05:00 dtor_core@ameritech.net +7 -1 # Add set_rate and set_resolution handlers to make adding new # protocols easier and remove special knowledge from psmouse-base.c # # drivers/input/mouse/psmouse-base.c # 2004/09/30 01:25:30-05:00 dtor_core@ameritech.net +20 -23 # Add set_rate and set_resolution handlers to make adding new # protocols easier and remove special knowledge from psmouse-base.c # # drivers/input/mouse/logips2pp.h # 2004/09/30 01:25:30-05:00 dtor_core@ameritech.net +0 -1 # Remove ps2pp_set_800dpi from list of exported functions. # # drivers/input/mouse/logips2pp.c # 2004/09/30 01:25:30-05:00 dtor_core@ameritech.net +14 -8 # Add set_resultion handler. # # ChangeSet # 2004/09/30 01:24:59-05:00 dtor_core@ameritech.net # Input: add a new signature for ALPS DualPoint found in # Dell Inspiron 8500 # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/alps.c # 2004/09/30 01:24:37-05:00 dtor_core@ameritech.net +1 -0 # Add a new signature for DualPoint found in Dell Inspiron 8500 # # ChangeSet # 2004/09/24 12:26:54+02:00 jbglaw@lug-owl.de # input: More comment fixes in lkkbd.c # # Signed-off-by: Jan-Benedict Glaw # Signed-off-by: Vojtech Pavlik # # drivers/input/keyboard/lkkbd.c # 2004/09/24 12:26:43+02:00 jbglaw@lug-owl.de +3 -3 # input: More comment fixes in lkkbd.c # # Signed-off-by: Jan-Benedict Glaw # Signed-off-by: Vojtech Pavlik # # ChangeSet # 2004/09/24 11:40:14+02:00 bjorn.helgaas@hp.com # Input: Add ACPI-based i8042 keyboard and aux controller enumeration; can be # disabled by passing i8042.noacpi as a boot parameter. # # Original code by Bjorn Helgaas , reworked by # Dmitry Torokhov , FixedIO support from Hans-Frieder Vogt # # # Signed-off-by: Bjorn Helgaas # Signed-off-by: Dmitry Torokhov # Signed-off-by: Andrew Morton # Signed-off-by: Vojtech Pavlik # # drivers/input/serio/i8042-x86ia64io.h # 2004/09/24 11:40:02+02:00 bjorn.helgaas@hp.com +308 -0 # # drivers/input/serio/i8042.h # 2004/09/24 11:40:02+02:00 bjorn.helgaas@hp.com +2 -0 # Input: Add ACPI-based i8042 keyboard and aux controller enumeration; can be # disabled by passing i8042.noacpi as a boot parameter. # # Original code by Bjorn Helgaas , reworked by # Dmitry Torokhov , FixedIO support from Hans-Frieder Vogt # # # Signed-off-by: Bjorn Helgaas # Signed-off-by: Dmitry Torokhov # Signed-off-by: Andrew Morton # Signed-off-by: Vojtech Pavlik # # drivers/input/serio/i8042.c # 2004/09/24 11:40:02+02:00 bjorn.helgaas@hp.com +6 -0 # Input: Add ACPI-based i8042 keyboard and aux controller enumeration; can be # disabled by passing i8042.noacpi as a boot parameter. # # Original code by Bjorn Helgaas , reworked by # Dmitry Torokhov , FixedIO support from Hans-Frieder Vogt # # # Signed-off-by: Bjorn Helgaas # Signed-off-by: Dmitry Torokhov # Signed-off-by: Andrew Morton # Signed-off-by: Vojtech Pavlik # # drivers/input/serio/i8042-x86ia64io.h # 2004/09/24 11:40:02+02:00 bjorn.helgaas@hp.com +0 -0 # BitKeeper file /home/vojtech/bk/input/drivers/input/serio/i8042-x86ia64io.h # # drivers/input/serio/i8042-io.h # 2004/09/24 11:40:02+02:00 bjorn.helgaas@hp.com +7 -44 # Input: Add ACPI-based i8042 keyboard and aux controller enumeration; can be # disabled by passing i8042.noacpi as a boot parameter. # # Original code by Bjorn Helgaas , reworked by # Dmitry Torokhov , FixedIO support from Hans-Frieder Vogt # # # Signed-off-by: Bjorn Helgaas # Signed-off-by: Dmitry Torokhov # Signed-off-by: Andrew Morton # Signed-off-by: Vojtech Pavlik # # Documentation/kernel-parameters.txt # 2004/09/24 11:40:00+02:00 bjorn.helgaas@hp.com +2 -0 # Input: Add ACPI-based i8042 keyboard and aux controller enumeration; can be # disabled by passing i8042.noacpi as a boot parameter. # # Original code by Bjorn Helgaas , reworked by # Dmitry Torokhov , FixedIO support from Hans-Frieder Vogt # # # Signed-off-by: Bjorn Helgaas # Signed-off-by: Dmitry Torokhov # Signed-off-by: Andrew Morton # Signed-off-by: Vojtech Pavlik # # ChangeSet # 2004/09/24 11:36:34+02:00 jbglaw@lug-owl.de # Input: correct the the wrong use of "DB9" to the correct name, "DE9". # Also, some comments/debugging output is fixed up. # # Signed-off-by: Jan-Benedict Glaw # Signed-off-by: Andrew Morton # Signed-off-by: Vojtech Pavlik # # drivers/input/mouse/vsxxxaa.c # 2004/09/24 11:36:22+02:00 jbglaw@lug-owl.de +29 -24 # Input: correct the the wrong use of "DB9" to the correct name, "DE9". # Also, some comments/debugging output is fixed up. # # Signed-off-by: Jan-Benedict Glaw # Signed-off-by: Andrew Morton # Signed-off-by: Vojtech Pavlik # # ChangeSet # 2004/09/24 10:30:25+02:00 lenz@cs.wisc.edu # input: Add LED definitions for PDAs. # # Signed-off-by: Vojtech Pavlik # Signed-off-by: John Lenz # # include/linux/input.h # 2004/09/24 10:30:14+02:00 lenz@cs.wisc.edu +2 -0 # input: Add LED definitions for PDAs. # # Signed-off-by: Vojtech Pavlik # Signed-off-by: John Lenz # # ChangeSet # 2004/09/23 13:01:47+02:00 mochel@digitalimplant.org # input: Remove calls to pm_access() and pm_dev_idle() from input.c, as # they're empty functions anyway. # # Signed-off-by: Vojtech Pavlik # Patch-by: Patrick Mochel # # drivers/input/input.c # 2004/09/23 13:01:41+02:00 mochel@digitalimplant.org +0 -7 # input: Remove calls to pm_access() and pm_dev_idle() from input.c, as # they're empty functions anyway. # # Signed-off-by: Vojtech Pavlik # Patch-by: Patrick Mochel # # ChangeSet # 2004/09/23 12:59:31+02:00 vojtech@suse.cz # input: Tidy up & fix the hid-input.c driver. Dual-wheel A4 mice don't report the phantom # button anymore, D-Pads are mapped to Hat-switches, debug can print HID->Input # mappings, more mappings added, devices with reports larger than MaxPacketSize # work again. # # Signed-off-by: Vojtech Pavlik # # include/linux/input.h # 2004/09/23 12:59:24+02:00 vojtech@suse.cz +3 -0 # input: Tidy up & fix the hid-input.c driver. Dual-wheel A4 mice don't report the phantom # button anymore, D-Pads are mapped to Hat-switches, debug can print HID->Input # mappings, more mappings added, devices with reports larger than MaxPacketSize # work again. # # Signed-off-by: Vojtech Pavlik # # drivers/usb/input/hid.h # 2004/09/23 12:59:24+02:00 vojtech@suse.cz +41 -3 # input: Tidy up & fix the hid-input.c driver. Dual-wheel A4 mice don't report the phantom # button anymore, D-Pads are mapped to Hat-switches, debug can print HID->Input # mappings, more mappings added, devices with reports larger than MaxPacketSize # work again. # # Signed-off-by: Vojtech Pavlik # # drivers/usb/input/hid-input.c # 2004/09/23 12:59:24+02:00 vojtech@suse.cz +217 -246 # input: Tidy up & fix the hid-input.c driver. Dual-wheel A4 mice don't report the phantom # button anymore, D-Pads are mapped to Hat-switches, debug can print HID->Input # mappings, more mappings added, devices with reports larger than MaxPacketSize # work again. # # Signed-off-by: Vojtech Pavlik # # drivers/usb/input/hid-debug.h # 2004/09/23 12:59:24+02:00 vojtech@suse.cz +263 -1 # input: Tidy up & fix the hid-input.c driver. Dual-wheel A4 mice don't report the phantom # button anymore, D-Pads are mapped to Hat-switches, debug can print HID->Input # mappings, more mappings added, devices with reports larger than MaxPacketSize # work again. # # Signed-off-by: Vojtech Pavlik # # drivers/usb/input/hid-core.c # 2004/09/23 12:59:24+02:00 vojtech@suse.cz +8 -9 # input: Tidy up & fix the hid-input.c driver. Dual-wheel A4 mice don't report the phantom # button anymore, D-Pads are mapped to Hat-switches, debug can print HID->Input # mappings, more mappings added, devices with reports larger than MaxPacketSize # work again. # # Signed-off-by: Vojtech Pavlik # # ChangeSet # 2004/09/22 22:35:49-05:00 dtor_core@ameritech.net # Input: clean up ALPS DualPoint logic # # Signed-off-by: Dmitry Torokhov # # drivers/input/mouse/alps.c # 2004/09/22 22:35:28-05:00 dtor_core@ameritech.net +22 -37 # Clean up DualPoint logic # # ChangeSet # 2004/09/22 10:46:32+02:00 vojtech@suse.cz # input: More IOWarrior blacklist entries in hid.c, rearranging the # blacklist back to alphabetic order. # # Signed-off-by: Vojtech Pavlik # # drivers/usb/input/hid-core.c # 2004/09/22 10:46:25+02:00 vojtech@suse.cz +9 -7 # input: More IOWarrior blacklist entries in hid.c, rearranging the # blacklist back to alphabetic order. # # Signed-off-by: Vojtech Pavlik # # ChangeSet # 2004/09/22 01:50:38-05:00 dtor_core@ameritech.net # Input: atkbd - export extra, scroll, set, softrepeat and softraw as individual # keyboard attributes (sysfs) and allow them to be set/changed independently # for each keyboard: # # echo -n "2" > /sys/bus/serio/devices/serio1/set # echo -n "1" > /sys/bus/serio/devices/serio1/softrepeat # # Signed-off-by: Dmitry Torokhov # # drivers/input/keyboard/atkbd.c # 2004/09/22 01:50:23-05:00 dtor_core@ameritech.net +365 -76 # Export extra, scroll, set, softrepeat and softraw as individual # sysfs keyboard attributes. # # ChangeSet # 2004/09/22 01:49:31-05:00 dtor_core@ameritech.net # Input: add serio_[un]pin_driver() functions so attribute handlers # can safely access driver bound to a serio port. # # Signed-off-by: Dmitry Torokhov # # include/linux/serio.h # 2004/09/22 01:49:13-05:00 dtor_core@ameritech.net +15 -1 # Add drv_sem to serio structure and serio_[un]pin_driver() so attribute # handlers can safely access driver bound to a serio port # # drivers/input/serio/serio.c # 2004/09/22 01:49:13-05:00 dtor_core@ameritech.net +12 -8 # Take drv_sem when binding/unbinding driver to a serio port # # ChangeSet # 2004/09/22 01:48:40-05:00 dtor_core@ameritech.net # Input: pull common code from psmouse and atkbd into libps2 module # # Signed-off-by: Dmitry Torokhov # # include/linux/libps2.h # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +50 -0 # BitKeeper file /misc/arc/dtor/include/linux/libps2.h # # drivers/input/serio/Makefile # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +1 -0 # Add libps2 # # drivers/input/serio/Kconfig # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +10 -0 # Add libps2 # # drivers/input/mouse/synaptics.c # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +15 -13 # Rename psmouse_coommand -> ps2_command # # drivers/input/mouse/psmouse.h # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +1 -15 # Embed ps2dev into psmouse structure # # drivers/input/mouse/psmouse-base.c # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +52 -187 # Switch to using libps2 to communicate with PS/2 port # # drivers/input/mouse/logips2pp.c # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +23 -18 # Rename psmouse_coommand -> ps2_command # # drivers/input/mouse/alps.c # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +38 -30 # Rename psmouse_coommand -> ps2_command # # drivers/input/mouse/Kconfig # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +1 -0 # Automatically select libps2 when selecting psmouse # # include/linux/libps2.h # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +0 -0 # BitKeeper file /usr/src/export/input/include/linux/libps2.h # # drivers/input/serio/libps2.c # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +273 -0 # BitKeeper file /misc/arc/dtor/drivers/input/serio/libps2.c # # drivers/input/keyboard/atkbd.c # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +52 -238 # Switch to using libps2 to communicate with PS/2 port # # drivers/input/keyboard/Kconfig # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +1 -0 # Automatically select libps2 when selecting atkbd # # drivers/input/serio/libps2.c # 2004/09/22 01:48:17-05:00 dtor_core@ameritech.net +0 -0 # BitKeeper file /usr/src/export/input/drivers/input/serio/libps2.c # # ChangeSet # 2004/09/21 16:12:18+02:00 vojtech@suse.cz # input: Add AT-compatible rawmode generation for ARM. # # Signed-off-by: Vojtech Pavlik # Patch-by: Woody Suwalski # # drivers/char/keyboard.c # 2004/09/21 16:12:11+02:00 vojtech@suse.cz +4 -1 # input: Add AT-compatible rawmode generation for ARM. # # Signed-off-by: Vojtech Pavlik # Patch-by: Woody Suwalski # # ChangeSet # 2004/09/21 15:48:50+02:00 petero2@telia.com # input: Add ALPS touchpad driver, driver by Neil Brown, Peter Osterlund # and Dmitry Torokhov, some fixes by Vojtech Pavlik. # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Osterlund # # drivers/input/mouse/alps.h # 2004/09/21 15:48:43+02:00 petero2@telia.com +17 -0 # # drivers/input/mouse/alps.h # 2004/09/21 15:48:43+02:00 petero2@telia.com +0 -0 # BitKeeper file /data2/bk/input/drivers/input/mouse/alps.h # # drivers/input/mouse/alps.c # 2004/09/21 15:48:42+02:00 petero2@telia.com +422 -0 # # drivers/input/mousedev.c # 2004/09/21 15:48:42+02:00 petero2@telia.com +10 -4 # input: Add ALPS touchpad driver, driver by Neil Brown, Peter Osterlund # and Dmitry Torokhov, some fixes by Vojtech Pavlik. # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Osterlund # # drivers/input/mouse/psmouse.h # 2004/09/21 15:48:42+02:00 petero2@telia.com +3 -0 # input: Add ALPS touchpad driver, driver by Neil Brown, Peter Osterlund # and Dmitry Torokhov, some fixes by Vojtech Pavlik. # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Osterlund # # drivers/input/mouse/psmouse-base.c # 2004/09/21 15:48:42+02:00 petero2@telia.com +22 -1 # input: Add ALPS touchpad driver, driver by Neil Brown, Peter Osterlund # and Dmitry Torokhov, some fixes by Vojtech Pavlik. # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Osterlund # # drivers/input/mouse/alps.c # 2004/09/21 15:48:42+02:00 petero2@telia.com +0 -0 # BitKeeper file /data2/bk/input/drivers/input/mouse/alps.c # # drivers/input/mouse/Makefile # 2004/09/21 15:48:42+02:00 petero2@telia.com +1 -1 # input: Add ALPS touchpad driver, driver by Neil Brown, Peter Osterlund # and Dmitry Torokhov, some fixes by Vojtech Pavlik. # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Osterlund # # ChangeSet # 2004/09/21 15:27:54+02:00 pmaydell@chiark.greenend.org.uk # input: Add support for Kensington ThinkingMouse PS/2 protocol. # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Maydell # # drivers/input/mouse/psmouse.h # 2004/09/21 15:27:48+02:00 pmaydell@chiark.greenend.org.uk +11 -7 # input: Add support for Kensington ThinkingMouse PS/2 protocol. # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Maydell # # drivers/input/mouse/psmouse-base.c # 2004/09/21 15:27:48+02:00 pmaydell@chiark.greenend.org.uk +50 -5 # input: Add support for Kensington ThinkingMouse PS/2 protocol. # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Maydell # # ChangeSet # 2004/09/21 10:04:06+02:00 vojtech@suse.cz # input: Some HID devices have problems returning the HID class descriptor. # Try a few times before giving up. # # Signed-off-by: Vojtech Pavlik # # drivers/usb/input/hid-core.c # 2004/09/21 10:04:00+02:00 vojtech@suse.cz +8 -3 # input: Some HID devices have problems returning the HID class descriptor. # Try a few times before giving up. # # Signed-off-by: Vojtech Pavlik # # ChangeSet # 2004/09/21 09:24:21+02:00 pnelson@suse.cz # input: Fix oops in gamecon # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Nelson # # drivers/input/joystick/gamecon.c # 2004/09/21 09:24:14+02:00 pnelson@suse.cz +3 -3 # input: Fix oops in gamecon # # Signed-off-by: Vojtech Pavlik # Patch-by: Peter Nelson # # ChangeSet # 2004/09/19 13:46:50+02:00 olh@suse.de # input: Joydump depends on gameport # # Signed-off-by: Vojtech Pavlik # Patch-by: Olaf Hering # # drivers/input/joystick/Kconfig # 2004/09/19 13:46:33+02:00 olh@suse.de +1 -1 # input: Joydump depends on gameport # # Signed-off-by: Vojtech Pavlik # Patch-by: Olaf Hering # diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt 2005-01-02 23:11:39 -08:00 +++ b/Documentation/kernel-parameters.txt 2005-01-02 23:11:39 -08:00 @@ -500,6 +500,8 @@ i8042.dumbkbd [HW] Pretend that controlled can only read data from keyboard and can not control its state (Don't attempt to blink the leds) + i8042.noacpi [HW] Don't use ACPI to discover KBD/AUX controller + settings i8042.noaux [HW] Don't check for auxiliary (== mouse) port i8042.nomux [HW] Don't check presence of an active multiplexing controller @@ -873,6 +875,13 @@ panic= [KNL] Kernel behaviour on panic Format: + + parkbd.port= [HW] Parallel port number the keyboard adapter is + connected to, default is 0. + Format: + parkbd.mode= [HW] Parallel port keyboard adapter mode of operation, + 0 for XT, 1 for AT (default is AT). + Format: parport=0 [HW,PPT] Specify parallel ports. 0 disables. parport=auto Use 'auto' to force the driver to use diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c --- a/drivers/char/keyboard.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/char/keyboard.c 2005-01-02 23:11:39 -08:00 @@ -939,7 +939,10 @@ tasklet_enable(&keyboard_tasklet); } -#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) +#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ + defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) ||\ + defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ + (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_RPC)) #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\ ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001)) diff -Nru a/drivers/input/input.c b/drivers/input/input.c --- a/drivers/input/input.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/input.c 2005-01-02 23:11:39 -08:00 @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -67,9 +66,6 @@ { struct input_handle *handle; - if (dev->pm_dev) - pm_access(dev->pm_dev); - if (type > EV_MAX || !test_bit(type, dev->evbit)) return; @@ -230,8 +226,6 @@ int input_open_device(struct input_handle *handle) { - if (handle->dev->pm_dev) - pm_access(handle->dev->pm_dev); handle->open++; if (handle->dev->open) return handle->dev->open(handle->dev); @@ -249,8 +243,6 @@ void input_close_device(struct input_handle *handle) { input_release_device(handle); - if (handle->dev->pm_dev) - pm_dev_idle(handle->dev->pm_dev); if (handle->dev->close) handle->dev->close(handle->dev); handle->open--; @@ -467,9 +459,6 @@ struct list_head * node, * next; if (!dev) return; - - if (dev->pm_dev) - pm_unregister(dev->pm_dev); del_timer_sync(&dev->timer); diff -Nru a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c --- a/drivers/input/joystick/gamecon.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/joystick/gamecon.c 2005-01-02 23:11:39 -08:00 @@ -89,7 +89,7 @@ static int gc_status_bit[] = { 0x40, 0x80, 0x20, 0x10, 0x08 }; static char *gc_names[] = { NULL, "SNES pad", "NES pad", "NES FourPort", "Multisystem joystick", - "Multisystem 2-button joystick", "N64 controller", "PSX controller" + "Multisystem 2-button joystick", "N64 controller", "PSX controller", "PSX DDR controller" }; /* * N64 support. @@ -271,7 +271,7 @@ udelay(gc_psx_delay); read = parport_read_status(gc->pd->port) ^ 0x80; for (j = 0; j < 5; j++) - data[j] |= (read & gc_status_bit[j] & gc->pads[GC_PSX]) ? (1 << i) : 0; + data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0; parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); udelay(gc_psx_delay); } @@ -300,7 +300,7 @@ gc_psx_command(gc, 0, data2); /* Dump status */ for (i =0; i < 5; i++) /* Find the longest pad */ - if((gc_status_bit[i] & gc->pads[GC_PSX]) && (GC_PSX_LEN(id[i]) > max_len)) + if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) && (GC_PSX_LEN(id[i]) > max_len)) max_len = GC_PSX_LEN(id[i]); for (i = 0; i < max_len * 2; i++) { /* Read in all the data */ diff -Nru a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c --- a/drivers/input/joystick/iforce/iforce-main.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/joystick/iforce/iforce-main.c 2005-01-02 23:11:39 -08:00 @@ -352,7 +352,21 @@ * Input device fields. */ - iforce->dev.id.bustype = BUS_USB; + switch (iforce->bus) { +#ifdef CONFIG_JOYSTICK_IFORCE_USB + case IFORCE_USB: + iforce->dev.id.bustype = BUS_USB; + iforce->dev.dev = &iforce->usbdev->dev; + break; +#endif +#ifdef CONFIG_JOYSTICK_IFORCE_232 + case IFORCE_232: + iforce->dev.id.bustype = BUS_RS232; + iforce->dev.dev = &iforce->serio->dev; + break; +#endif + } + iforce->dev.private = iforce; iforce->dev.name = "Unknown I-Force device"; iforce->dev.open = iforce_open; diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c --- a/drivers/input/joystick/magellan.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/joystick/magellan.c 2005-01-02 23:11:39 -08:00 @@ -183,6 +183,7 @@ magellan->dev.id.vendor = SERIO_MAGELLAN; magellan->dev.id.product = 0x0001; magellan->dev.id.version = 0x0100; + magellan->dev.dev = &serio->dev; serio->private = magellan; diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c --- a/drivers/input/joystick/spaceball.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/joystick/spaceball.c 2005-01-02 23:11:39 -08:00 @@ -253,6 +253,7 @@ spaceball->dev.id.vendor = SERIO_SPACEBALL; spaceball->dev.id.product = id; spaceball->dev.id.version = 0x0100; + spaceball->dev.dev = &serio->dev; serio->private = spaceball; diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c --- a/drivers/input/joystick/spaceorb.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/joystick/spaceorb.c 2005-01-02 23:11:39 -08:00 @@ -200,6 +200,7 @@ spaceorb->dev.id.vendor = SERIO_SPACEORB; spaceorb->dev.id.product = 0x0001; spaceorb->dev.id.version = 0x0100; + spaceorb->dev.dev = &serio->dev; serio->private = spaceorb; diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c --- a/drivers/input/joystick/stinger.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/joystick/stinger.c 2005-01-02 23:11:39 -08:00 @@ -164,6 +164,7 @@ stinger->dev.id.vendor = SERIO_STINGER; stinger->dev.id.product = 0x0001; stinger->dev.id.version = 0x0100; + stinger->dev.dev = &serio->dev; for (i = 0; i < 2; i++) { stinger->dev.absmax[ABS_X+i] = 64; diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c --- a/drivers/input/joystick/twidjoy.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/joystick/twidjoy.c 2005-01-02 23:11:39 -08:00 @@ -210,6 +210,7 @@ twidjoy->dev.id.vendor = SERIO_TWIDJOY; twidjoy->dev.id.product = 0x0001; twidjoy->dev.id.version = 0x0100; + twidjoy->dev.dev = &serio->dev; twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c --- a/drivers/input/joystick/warrior.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/joystick/warrior.c 2005-01-02 23:11:39 -08:00 @@ -168,6 +168,7 @@ warrior->dev.id.vendor = SERIO_WARRIOR; warrior->dev.id.product = 0x0001; warrior->dev.id.version = 0x0100; + warrior->dev.dev = &serio->dev; for (i = 0; i < 2; i++) { warrior->dev.absmax[ABS_X+i] = -64; diff -Nru a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig --- a/drivers/input/keyboard/Kconfig 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/keyboard/Kconfig 2005-01-02 23:11:39 -08:00 @@ -16,6 +16,7 @@ default y depends on INPUT && INPUT_KEYBOARD select SERIO + select SERIO_LIBPS2 select SERIO_I8042 if PC select SERIO_GSCPS2 if GSC help diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c --- a/drivers/input/keyboard/atkbd.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/keyboard/atkbd.c 2005-01-02 23:11:39 -08:00 @@ -26,6 +26,7 @@ #include #include #include +#include #define DRIVER_DESC "AT and PS/2 keyboard driver" @@ -170,36 +171,29 @@ { ATKBD_SCR_CLICK, 0x60 }, }; -#define ATKBD_FLAG_ACK 0 /* Waiting for ACK/NAK */ -#define ATKBD_FLAG_CMD 1 /* Waiting for command to finish */ -#define ATKBD_FLAG_CMD1 2 /* First byte of command response */ -#define ATKBD_FLAG_ENABLED 3 /* Waining for init to finish */ - /* * The atkbd control structure */ struct atkbd { + struct ps2dev ps2dev; + /* Written only during init */ char name[64]; char phys[32]; - struct serio *serio; struct input_dev dev; - unsigned char set; unsigned short id; unsigned char keycode[512]; + unsigned char set; unsigned char translated; unsigned char extra; unsigned char write; - - /* Protected by FLAG_ACK */ - unsigned char nak; - - /* Protected by FLAG_CMD */ - unsigned char cmdbuf[4]; - unsigned char cmdcnt; + unsigned char softrepeat; + unsigned char softraw; + unsigned char scroll; + unsigned char enabled; /* Accessed only from interrupt */ unsigned char emul; @@ -208,24 +202,31 @@ unsigned char bat_xl; unsigned int last; unsigned long time; - - /* Ensures that only one command is executing at a time */ - struct semaphore cmd_sem; - - /* Used to signal completion from interrupt handler */ - wait_queue_head_t wait; - - /* Flags */ - unsigned long flags; }; -/* Work structure to schedule execution of a command */ -struct atkbd_work { - struct work_struct work; - struct atkbd *atkbd; - int command; - unsigned char param[0]; -}; +static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, + ssize_t (*handler)(struct atkbd *, char *)); +static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, + ssize_t (*handler)(struct atkbd *, const char *, size_t)); +#define ATKBD_DEFINE_ATTR(_name) \ +static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ +static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \ +static ssize_t atkbd_do_show_##_name(struct device *d, char *b) \ +{ \ + return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ +} \ +static ssize_t atkbd_do_set_##_name(struct device *d, const char *b, size_t s) \ +{ \ + return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \ +} \ +static struct device_attribute atkbd_attr_##_name = \ + __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name); + +ATKBD_DEFINE_ATTR(extra); +ATKBD_DEFINE_ATTR(scroll); +ATKBD_DEFINE_ATTR(set); +ATKBD_DEFINE_ATTR(softrepeat); +ATKBD_DEFINE_ATTR(softraw); static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value) @@ -268,42 +269,15 @@ atkbd->resend = 0; #endif - if (test_bit(ATKBD_FLAG_ACK, &atkbd->flags)) { - switch (code) { - case ATKBD_RET_ACK: - atkbd->nak = 0; - if (atkbd->cmdcnt) { - set_bit(ATKBD_FLAG_CMD, &atkbd->flags); - set_bit(ATKBD_FLAG_CMD1, &atkbd->flags); - } - clear_bit(ATKBD_FLAG_ACK, &atkbd->flags); - wake_up_interruptible(&atkbd->wait); - break; - case ATKBD_RET_NAK: - atkbd->nak = 1; - clear_bit(ATKBD_FLAG_ACK, &atkbd->flags); - wake_up_interruptible(&atkbd->wait); - break; - } - goto out; - } - - if (test_bit(ATKBD_FLAG_CMD, &atkbd->flags)) { - - if (atkbd->cmdcnt) - atkbd->cmdbuf[--atkbd->cmdcnt] = code; - - if (test_and_clear_bit(ATKBD_FLAG_CMD1, &atkbd->flags) && atkbd->cmdcnt) - wake_up_interruptible(&atkbd->wait); + if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_ACK)) + if (ps2_handle_ack(&atkbd->ps2dev, data)) + goto out; - if (!atkbd->cmdcnt) { - clear_bit(ATKBD_FLAG_CMD, &atkbd->flags); - wake_up_interruptible(&atkbd->wait); - } - goto out; - } + if (unlikely(atkbd->ps2dev.flags & PS2_FLAG_CMD)) + if (ps2_handle_response(&atkbd->ps2dev, data)) + goto out; - if (!test_bit(ATKBD_FLAG_ENABLED, &atkbd->flags)) + if (!atkbd->enabled) goto out; input_event(&atkbd->dev, EV_MSC, MSC_RAW, code); @@ -326,8 +300,8 @@ switch (code) { case ATKBD_RET_BAT: - clear_bit(ATKBD_FLAG_ENABLED, &atkbd->flags); - serio_rescan(atkbd->serio); + atkbd->enabled = 0; + serio_rescan(atkbd->ps2dev.serio); goto out; case ATKBD_RET_EMUL0: atkbd->emul = 1; @@ -396,7 +370,7 @@ break; default: value = atkbd->release ? 0 : - (1 + (!atkbd_softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key))); + (1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key))); switch (value) { /* Workaround Toshiba laptop multiple keypress */ case 0: @@ -427,151 +401,6 @@ return IRQ_HANDLED; } -/* - * atkbd_sendbyte() sends a byte to the keyboard, and waits for - * acknowledge. It doesn't handle resends according to the keyboard - * protocol specs, because if these are needed, the keyboard needs - * replacement anyway, and they only make a mess in the protocol. - * - * atkbd_sendbyte() can only be called from a process context - */ - -static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte) -{ -#ifdef ATKBD_DEBUG - printk(KERN_DEBUG "atkbd.c: Sent: %02x\n", byte); -#endif - atkbd->nak = 1; - set_bit(ATKBD_FLAG_ACK, &atkbd->flags); - - if (serio_write(atkbd->serio, byte) == 0) - wait_event_interruptible_timeout(atkbd->wait, - !test_bit(ATKBD_FLAG_ACK, &atkbd->flags), - msecs_to_jiffies(200)); - - clear_bit(ATKBD_FLAG_ACK, &atkbd->flags); - return -atkbd->nak; -} - -/* - * atkbd_command() sends a command, and its parameters to the keyboard, - * then waits for the response and puts it in the param array. - * - * atkbd_command() can only be called from a process context - */ - -static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command) -{ - int timeout; - int send = (command >> 12) & 0xf; - int receive = (command >> 8) & 0xf; - int rc = -1; - int i; - - timeout = msecs_to_jiffies(command == ATKBD_CMD_RESET_BAT ? 4000 : 500); - - down(&atkbd->cmd_sem); - clear_bit(ATKBD_FLAG_CMD, &atkbd->flags); - - if (receive && param) - for (i = 0; i < receive; i++) - atkbd->cmdbuf[(receive - 1) - i] = param[i]; - - atkbd->cmdcnt = receive; - - if (command & 0xff) - if (atkbd_sendbyte(atkbd, command & 0xff)) - goto out; - - for (i = 0; i < send; i++) - if (atkbd_sendbyte(atkbd, param[i])) - goto out; - - timeout = wait_event_interruptible_timeout(atkbd->wait, - !test_bit(ATKBD_FLAG_CMD1, &atkbd->flags), timeout); - - if (atkbd->cmdcnt && timeout > 0) { - if (command == ATKBD_CMD_RESET_BAT && jiffies_to_msecs(timeout) > 100) - timeout = msecs_to_jiffies(100); - - if (command == ATKBD_CMD_GETID && - atkbd->cmdbuf[receive - 1] != 0xab && atkbd->cmdbuf[receive - 1] != 0xac) { - /* - * Device behind the port is not a keyboard - * so we don't need to wait for the 2nd byte - * of ID response. - */ - clear_bit(ATKBD_FLAG_CMD, &atkbd->flags); - atkbd->cmdcnt = 0; - } - - wait_event_interruptible_timeout(atkbd->wait, - !test_bit(ATKBD_FLAG_CMD, &atkbd->flags), timeout); - } - - if (param) - for (i = 0; i < receive; i++) - param[i] = atkbd->cmdbuf[(receive - 1) - i]; - - if (atkbd->cmdcnt && (command != ATKBD_CMD_RESET_BAT || atkbd->cmdcnt != 1)) - goto out; - - rc = 0; - -out: - clear_bit(ATKBD_FLAG_CMD, &atkbd->flags); - clear_bit(ATKBD_FLAG_CMD1, &atkbd->flags); - up(&atkbd->cmd_sem); - - return rc; -} - -/* - * atkbd_execute_scheduled_command() sends a command, previously scheduled by - * atkbd_schedule_command(), to the keyboard. - */ - -static void atkbd_execute_scheduled_command(void *data) -{ - struct atkbd_work *atkbd_work = data; - - atkbd_command(atkbd_work->atkbd, atkbd_work->param, atkbd_work->command); - - kfree(atkbd_work); -} - -/* - * atkbd_schedule_command() allows to schedule delayed execution of a keyboard - * command and can be used to issue a command from an interrupt or softirq - * context. - */ - -static int atkbd_schedule_command(struct atkbd *atkbd, unsigned char *param, int command) -{ - struct atkbd_work *atkbd_work; - int send = (command >> 12) & 0xf; - int receive = (command >> 8) & 0xf; - - if (!test_bit(ATKBD_FLAG_ENABLED, &atkbd->flags)) - return -1; - - if (!(atkbd_work = kmalloc(sizeof(struct atkbd_work) + max(send, receive), GFP_ATOMIC))) - return -1; - - memset(atkbd_work, 0, sizeof(struct atkbd_work)); - atkbd_work->atkbd = atkbd; - atkbd_work->command = command; - memcpy(atkbd_work->param, param, send); - INIT_WORK(&atkbd_work->work, atkbd_execute_scheduled_command, atkbd_work); - - if (!schedule_work(&atkbd_work->work)) { - kfree(atkbd_work); - return -1; - } - - return 0; -} - /* * Event callback from the input module. Events that change the state of @@ -599,7 +428,7 @@ param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) | (test_bit(LED_NUML, dev->led) ? 2 : 0) | (test_bit(LED_CAPSL, dev->led) ? 4 : 0); - atkbd_schedule_command(atkbd, param, ATKBD_CMD_SETLEDS); + ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS); if (atkbd->extra) { param[0] = 0; @@ -608,7 +437,7 @@ | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0) | (test_bit(LED_MISC, dev->led) ? 0x10 : 0) | (test_bit(LED_MUTE, dev->led) ? 0x20 : 0); - atkbd_schedule_command(atkbd, param, ATKBD_CMD_EX_SETLEDS); + ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS); } return 0; @@ -616,7 +445,7 @@ case EV_REP: - if (atkbd_softrepeat) return 0; + if (atkbd->softrepeat) return 0; i = j = 0; while (i < 32 && period[i] < dev->rep[REP_PERIOD]) i++; @@ -624,7 +453,7 @@ dev->rep[REP_PERIOD] = period[i]; dev->rep[REP_DELAY] = delay[j]; param[0] = i | (j << 5); - atkbd_schedule_command(atkbd, param, ATKBD_CMD_SETREP); + ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP); return 0; } @@ -633,11 +462,36 @@ } /* + * atkbd_enable() signals that interrupt handler is allowed to + * generate input events. + */ + +static inline void atkbd_enable(struct atkbd *atkbd) +{ + serio_pause_rx(atkbd->ps2dev.serio); + atkbd->enabled = 1; + serio_continue_rx(atkbd->ps2dev.serio); +} + +/* + * atkbd_disable() tells input handler that all incoming data except + * for ACKs and command response should be dropped. + */ + +static inline void atkbd_disable(struct atkbd *atkbd) +{ + serio_pause_rx(atkbd->ps2dev.serio); + atkbd->enabled = 0; + serio_continue_rx(atkbd->ps2dev.serio); +} + +/* * atkbd_probe() probes for an AT keyboard on a serio port. */ static int atkbd_probe(struct atkbd *atkbd) { + struct ps2dev *ps2dev = &atkbd->ps2dev; unsigned char param[2]; /* @@ -647,8 +501,8 @@ */ if (atkbd_reset) - if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) - printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys); + if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) + printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", ps2dev->serio->phys); /* * Then we check the keyboard ID. We should get 0xab83 under normal conditions. @@ -658,7 +512,7 @@ */ param[0] = param[1] = 0xa5; /* initialize with invalid values */ - if (atkbd_command(atkbd, param, ATKBD_CMD_GETID)) { + if (ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { /* * If the get ID command failed, we check if we can at least set the LEDs on @@ -666,14 +520,17 @@ * the LEDs off, which we want anyway. */ param[0] = 0; - if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS)) + if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) return -1; atkbd->id = 0xabba; return 0; } - if (param[0] != 0xab && param[0] != 0xac) + if (param[0] != 0xab && param[0] != 0xac && /* Regular and NCD Sun keyboards */ + param[0] != 0x2b && param[0] != 0x5d && /* Trust keyboard, raw and translated */ + param[0] != 0x60 && param[0] != 0x47) /* NMB SGI keyboard, raw and translated */ return -1; + atkbd->id = (param[0] << 8) | param[1]; if (atkbd->id == 0xaca1 && atkbd->translated) { @@ -686,15 +543,17 @@ } /* - * atkbd_set_3 checks if a keyboard has a working Set 3 support, and + * atkbd_select_set checks if a keyboard has a working Set 3 support, and * sets it into that. Unfortunately there are keyboards that can be switched * to Set 3, but don't work well in that (BTC Multimedia ...) */ -static int atkbd_set_3(struct atkbd *atkbd) +static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra) { + struct ps2dev *ps2dev = &atkbd->ps2dev; unsigned char param[2]; + atkbd->extra = 0; /* * For known special keyboards we can go ahead and set the correct set. * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and @@ -706,47 +565,48 @@ if (atkbd->id == 0xaca1) { param[0] = 3; - atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET); + ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET); return 3; } - if (atkbd_extra) { + if (allow_extra) { param[0] = 0x71; - if (!atkbd_command(atkbd, param, ATKBD_CMD_EX_ENABLE)) { + if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { atkbd->extra = 1; return 2; } } - if (atkbd_set != 3) + if (target_set != 3) return 2; - if (!atkbd_command(atkbd, param, ATKBD_CMD_OK_GETID)) { + if (!ps2_command(ps2dev, param, ATKBD_CMD_OK_GETID)) { atkbd->id = param[0] << 8 | param[1]; return 2; } param[0] = 3; - if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET)) + if (ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET)) return 2; param[0] = 0; - if (atkbd_command(atkbd, param, ATKBD_CMD_GSCANSET)) + if (ps2_command(ps2dev, param, ATKBD_CMD_GSCANSET)) return 2; if (param[0] != 3) { param[0] = 2; - if (atkbd_command(atkbd, param, ATKBD_CMD_SSCANSET)) + if (ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET)) return 2; } - atkbd_command(atkbd, param, ATKBD_CMD_SETALL_MBR); + ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MBR); return 3; } -static int atkbd_enable(struct atkbd *atkbd) +static int atkbd_activate(struct atkbd *atkbd) { + struct ps2dev *ps2dev = &atkbd->ps2dev; unsigned char param[1]; /* @@ -754,7 +614,7 @@ */ param[0] = 0; - if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS)) + if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) return -1; /* @@ -762,16 +622,16 @@ */ param[0] = 0; - if (atkbd_command(atkbd, param, ATKBD_CMD_SETREP)) + if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP)) return -1; /* * Enable the keyboard to receive keystrokes. */ - if (atkbd_command(atkbd, NULL, ATKBD_CMD_ENABLE)) { + if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { printk(KERN_ERR "atkbd.c: Failed to enable keyboard on %s\n", - atkbd->serio->phys); + ps2dev->serio->phys); return -1; } @@ -786,9 +646,10 @@ static void atkbd_cleanup(struct serio *serio) { struct atkbd *atkbd = serio->private; - atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT); + ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_BAT); } + /* * atkbd_disconnect() closes and frees. */ @@ -797,15 +658,109 @@ { struct atkbd *atkbd = serio->private; - clear_bit(ATKBD_FLAG_ENABLED, &atkbd->flags); + atkbd_disable(atkbd); + + /* make sure we don't have a command in flight */ synchronize_kernel(); flush_scheduled_work(); + device_remove_file(&serio->dev, &atkbd_attr_extra); + device_remove_file(&serio->dev, &atkbd_attr_scroll); + device_remove_file(&serio->dev, &atkbd_attr_set); + device_remove_file(&serio->dev, &atkbd_attr_softrepeat); + device_remove_file(&serio->dev, &atkbd_attr_softraw); + input_unregister_device(&atkbd->dev); serio_close(serio); kfree(atkbd); } + +/* + * atkbd_set_device_attrs() initializes keyboard's keycode table + * according to the selected scancode set + */ + +static void atkbd_set_keycode_table(struct atkbd *atkbd) +{ + int i, j; + + memset(atkbd->keycode, 0, sizeof(atkbd->keycode)); + + if (atkbd->translated) { + for (i = 0; i < 128; i++) { + atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]]; + atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80]; + if (atkbd->scroll) + for (j = 0; i < 5; i++) { + if (atkbd_unxlate_table[i] == atkbd_scroll_keys[j][1]) + atkbd->keycode[i] = atkbd_scroll_keys[j][0]; + if ((atkbd_unxlate_table[i] | 0x80) == atkbd_scroll_keys[j][1]) + atkbd->keycode[i | 0x80] = atkbd_scroll_keys[j][0]; + } + } + } else if (atkbd->set == 3) { + memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode)); + } else { + memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode)); + + if (atkbd->scroll) + for (i = 0; i < 5; i++) + atkbd->keycode[atkbd_scroll_keys[i][1]] = atkbd_scroll_keys[i][0]; + } +} + +/* + * atkbd_set_device_attrs() sets up keyboard's input device structure + */ + +static void atkbd_set_device_attrs(struct atkbd *atkbd) +{ + int i; + + memset(&atkbd->dev, 0, sizeof(struct input_dev)); + + init_input_dev(&atkbd->dev); + + atkbd->dev.name = atkbd->name; + atkbd->dev.phys = atkbd->phys; + atkbd->dev.id.bustype = BUS_I8042; + atkbd->dev.id.vendor = 0x0001; + atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set; + atkbd->dev.id.version = atkbd->id; + atkbd->dev.event = atkbd_event; + atkbd->dev.private = atkbd; + atkbd->dev.dev = &atkbd->ps2dev.serio->dev; + + atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); + + if (atkbd->write) { + atkbd->dev.evbit[0] |= BIT(EV_LED); + atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); + } + + if (atkbd->extra) + atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | + BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC); + + if (!atkbd->softrepeat) { + atkbd->dev.rep[REP_DELAY] = 250; + atkbd->dev.rep[REP_PERIOD] = 33; + } + + atkbd->dev.mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN); + + if (atkbd->scroll) { + atkbd->dev.evbit[0] |= BIT(EV_REL); + atkbd->dev.relbit[0] = BIT(REL_WHEEL); + set_bit(BTN_MIDDLE, atkbd->dev.keybit); + } + + for (i = 0; i < 512; i++) + if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) + set_bit(atkbd->keycode[i], atkbd->dev.keybit); +} + /* * atkbd_connect() is called when the serio module finds and interface * that isn't handled yet by an appropriate device driver. We check if @@ -816,14 +771,12 @@ static void atkbd_connect(struct serio *serio, struct serio_driver *drv) { struct atkbd *atkbd; - int i; if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL))) return; memset(atkbd, 0, sizeof(struct atkbd)); - init_MUTEX(&atkbd->cmd_sem); - init_waitqueue_head(&atkbd->wait); + ps2_init(&atkbd->ps2dev, serio); switch (serio->type & SERIO_TYPE) { @@ -841,31 +794,19 @@ return; } - if (!atkbd->write) - atkbd_softrepeat = 1; - if (atkbd_softrepeat) - atkbd_softraw = 1; - - if (atkbd->write) { - atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP) | BIT(EV_MSC); - atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); - } else atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); - atkbd->dev.mscbit[0] = atkbd_softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN); + atkbd->softraw = atkbd_softraw; + atkbd->softrepeat = atkbd_softrepeat; + atkbd->scroll = atkbd_scroll; - if (!atkbd_softrepeat) { - atkbd->dev.rep[REP_DELAY] = 250; - atkbd->dev.rep[REP_PERIOD] = 33; - } else atkbd_softraw = 1; + if (!atkbd->write) + atkbd->softrepeat = 1; - atkbd->serio = serio; - - init_input_dev(&atkbd->dev); + if (atkbd->softrepeat) + atkbd->softraw = 1; atkbd->dev.keycode = atkbd->keycode; atkbd->dev.keycodesize = sizeof(unsigned char); atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode); - atkbd->dev.event = atkbd_event; - atkbd->dev.private = atkbd; serio->private = atkbd; @@ -883,56 +824,34 @@ return; } - atkbd->set = atkbd_set_3(atkbd); - atkbd_enable(atkbd); + atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra); + atkbd_activate(atkbd); } else { atkbd->set = 2; atkbd->id = 0xab00; } - if (atkbd->extra) { - atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC); + if (atkbd->extra) sprintf(atkbd->name, "AT Set 2 Extra keyboard"); - } else + else sprintf(atkbd->name, "AT %s Set %d keyboard", atkbd->translated ? "Translated" : "Raw", atkbd->set); sprintf(atkbd->phys, "%s/input0", serio->phys); - if (atkbd_scroll) { - for (i = 0; i < 5; i++) - atkbd_set2_keycode[atkbd_scroll_keys[i][1]] = atkbd_scroll_keys[i][0]; - atkbd->dev.evbit[0] |= BIT(EV_REL); - atkbd->dev.relbit[0] = BIT(REL_WHEEL); - set_bit(BTN_MIDDLE, atkbd->dev.keybit); - } - - if (atkbd->translated) { - for (i = 0; i < 128; i++) { - atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]]; - atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80]; - } - } else if (atkbd->set == 3) { - memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode)); - } else { - memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode)); - } - - atkbd->dev.name = atkbd->name; - atkbd->dev.phys = atkbd->phys; - atkbd->dev.id.bustype = BUS_I8042; - atkbd->dev.id.vendor = 0x0001; - atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set; - atkbd->dev.id.version = atkbd->id; - - for (i = 0; i < 512; i++) - if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL) - set_bit(atkbd->keycode[i], atkbd->dev.keybit); + atkbd_set_keycode_table(atkbd); + atkbd_set_device_attrs(atkbd); input_register_device(&atkbd->dev); - set_bit(ATKBD_FLAG_ENABLED, &atkbd->flags); + device_create_file(&serio->dev, &atkbd_attr_extra); + device_create_file(&serio->dev, &atkbd_attr_scroll); + device_create_file(&serio->dev, &atkbd_attr_set); + device_create_file(&serio->dev, &atkbd_attr_softrepeat); + device_create_file(&serio->dev, &atkbd_attr_softraw); + + atkbd_enable(atkbd); printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys); } @@ -948,11 +867,13 @@ struct serio_driver *drv = serio->drv; unsigned char param[1]; - if (!drv) { + if (!atkbd || !drv) { printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); return -1; } + atkbd_disable(atkbd); + if (atkbd->write) { param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0) | (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0) @@ -960,16 +881,16 @@ if (atkbd_probe(atkbd)) return -1; - if (atkbd->set != atkbd_set_3(atkbd)) + if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) return -1; - atkbd_enable(atkbd); + atkbd_activate(atkbd); - if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS)) + if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) return -1; } - set_bit(ATKBD_FLAG_ENABLED, &atkbd->flags); + atkbd_enable(atkbd); return 0; } @@ -985,6 +906,192 @@ .disconnect = atkbd_disconnect, .cleanup = atkbd_cleanup, }; + +static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, + ssize_t (*handler)(struct atkbd *, char *)) +{ + struct serio *serio = to_serio_port(dev); + int retval; + + retval = serio_pin_driver(serio); + if (retval) + return retval; + + if (serio->drv != &atkbd_drv) { + retval = -ENODEV; + goto out; + } + + retval = handler((struct atkbd *)serio->private, buf); + +out: + serio_unpin_driver(serio); + return retval; +} + +static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, + ssize_t (*handler)(struct atkbd *, const char *, size_t)) +{ + struct serio *serio = to_serio_port(dev); + struct atkbd *atkbd; + int retval; + + retval = serio_pin_driver(serio); + if (retval) + return retval; + + if (serio->drv != &atkbd_drv) { + retval = -ENODEV; + goto out; + } + + atkbd = serio->private; + atkbd_disable(atkbd); + retval = handler(atkbd, buf, count); + atkbd_enable(atkbd); + +out: + serio_unpin_driver(serio); + return retval; +} + +static ssize_t atkbd_show_extra(struct atkbd *atkbd, char *buf) +{ + return sprintf(buf, "%d\n", atkbd->extra ? 1 : 0); +} + +static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count) +{ + unsigned long value; + char *rest; + + if (!atkbd->write) + return -EIO; + + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) + return -EINVAL; + + if (atkbd->extra != value) { + /* unregister device as it's properties will change */ + input_unregister_device(&atkbd->dev); + atkbd->set = atkbd_select_set(atkbd, atkbd->set, value); + atkbd_activate(atkbd); + atkbd_set_device_attrs(atkbd); + input_register_device(&atkbd->dev); + } + return count; +} + +static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) +{ + return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0); +} + +static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) +{ + unsigned long value; + char *rest; + + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) + return -EINVAL; + + if (atkbd->scroll != value) { + /* unregister device as it's properties will change */ + input_unregister_device(&atkbd->dev); + atkbd->scroll = value; + atkbd_set_keycode_table(atkbd); + atkbd_set_device_attrs(atkbd); + input_register_device(&atkbd->dev); + } + return count; +} + +static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf) +{ + return sprintf(buf, "%d\n", atkbd->set); +} + +static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) +{ + unsigned long value; + char *rest; + + if (!atkbd->write) + return -EIO; + + value = simple_strtoul(buf, &rest, 10); + if (*rest || (value != 2 && value != 3)) + return -EINVAL; + + if (atkbd->set != value) { + /* unregister device as it's properties will change */ + input_unregister_device(&atkbd->dev); + atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra); + atkbd_activate(atkbd); + atkbd_set_keycode_table(atkbd); + atkbd_set_device_attrs(atkbd); + input_register_device(&atkbd->dev); + } + return count; +} + +static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf) +{ + return sprintf(buf, "%d\n", atkbd->softrepeat ? 1 : 0); +} + +static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) +{ + unsigned long value; + char *rest; + + if (!atkbd->write) + return -EIO; + + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) + return -EINVAL; + + if (atkbd->softrepeat != value) { + /* unregister device as it's properties will change */ + input_unregister_device(&atkbd->dev); + atkbd->softrepeat = value; + if (atkbd->softrepeat) + atkbd->softraw = 1; + atkbd_set_device_attrs(atkbd); + input_register_device(&atkbd->dev); + } + + return count; +} + + +static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf) +{ + return sprintf(buf, "%d\n", atkbd->softraw ? 1 : 0); +} + +static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) +{ + unsigned long value; + char *rest; + + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) + return -EINVAL; + + if (atkbd->softraw != value) { + /* unregister device as it's properties will change */ + input_unregister_device(&atkbd->dev); + atkbd->softraw = value; + atkbd_set_device_attrs(atkbd); + input_register_device(&atkbd->dev); + } + return count; +} + int __init atkbd_init(void) { diff -Nru a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c --- a/drivers/input/keyboard/lkkbd.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/keyboard/lkkbd.c 2005-01-02 23:11:39 -08:00 @@ -14,13 +14,13 @@ * DISCLAIMER: This works for _me_. If you break anything by using the * information given below, I will _not_ be liable! * - * RJ11 pinout: To DB9: Or DB25: + * RJ11 pinout: To DE9: Or DB25: * 1 - RxD <----> Pin 3 (TxD) <-> Pin 2 (TxD) * 2 - GND <----> Pin 5 (GND) <-> Pin 7 (GND) * 4 - TxD <----> Pin 2 (RxD) <-> Pin 3 (RxD) - * 3 - +12V (from HDD drive connector), DON'T connect to DB9 or DB25!!! + * 3 - +12V (from HDD drive connector), DON'T connect to DE9 or DB25!!! * - * Pin numbers for DB9 and DB25 are noted on the plug (quite small:). For + * Pin numbers for DE9 and DB25 are noted on the plug (quite small:). For * RJ11, it's like this: * * __=__ Hold the plug in front of you, cable downwards, @@ -685,6 +685,7 @@ lk->dev.id.vendor = SERIO_LKKBD; lk->dev.id.product = 0; lk->dev.id.version = 0x0100; + lk->dev.dev = &serio->dev; input_register_device (&lk->dev); diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c --- a/drivers/input/keyboard/newtonkbd.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/keyboard/newtonkbd.c 2005-01-02 23:11:39 -08:00 @@ -126,6 +126,7 @@ nkbd->dev.id.vendor = SERIO_NEWTON; nkbd->dev.id.product = 0x0001; nkbd->dev.id.version = 0x0100; + nkbd->dev.dev = &serio->dev; input_register_device(&nkbd->dev); diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c --- a/drivers/input/keyboard/sunkbd.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/keyboard/sunkbd.c 2005-01-02 23:11:39 -08:00 @@ -285,6 +285,7 @@ sunkbd->dev.id.vendor = SERIO_SUNKBD; sunkbd->dev.id.product = sunkbd->type; sunkbd->dev.id.version = 0x0100; + sunkbd->dev.dev = &serio->dev; input_register_device(&sunkbd->dev); diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c --- a/drivers/input/keyboard/xtkbd.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/keyboard/xtkbd.c 2005-01-02 23:11:39 -08:00 @@ -131,6 +131,7 @@ xtkbd->dev.id.vendor = 0x0001; xtkbd->dev.id.product = 0x0001; xtkbd->dev.id.version = 0x0100; + xtkbd->dev.dev = &serio->dev; input_register_device(&xtkbd->dev); diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig --- a/drivers/input/mouse/Kconfig 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/Kconfig 2005-01-02 23:11:39 -08:00 @@ -16,6 +16,7 @@ default y depends on INPUT && INPUT_MOUSE select SERIO + select SERIO_LIBPS2 select SERIO_I8042 if PC select SERIO_GSCPS2 if GSC ---help--- diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile --- a/drivers/input/mouse/Makefile 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/Makefile 2005-01-02 23:11:39 -08:00 @@ -14,4 +14,4 @@ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o -psmouse-objs := psmouse-base.o logips2pp.o synaptics.o +psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o diff -Nru a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/input/mouse/alps.c 2005-01-02 23:11:39 -08:00 @@ -0,0 +1,424 @@ +/* + * ALPS touchpad PS/2 mouse driver + * + * Copyright (c) 2003 Neil Brown + * Copyright (c) 2003 Peter Osterlund + * Copyright (c) 2004 Dmitry Torokhov + * + * ALPS detection, tap switching and status querying info is taken from + * tpconfig utility (by C. Scott Ananian and Bruce Kall). + * + * 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 + * the Free Software Foundation. + */ + +#include +#include +#include + +#include "psmouse.h" +#include "alps.h" + +#undef DEBUG +#ifdef DEBUG +#define dbg(format, arg...) printk(KERN_INFO "alps.c: " format "\n", ## arg) +#else +#define dbg(format, arg...) do {} while (0) +#endif + +#define ALPS_MODEL_GLIDEPOINT 1 +#define ALPS_MODEL_DUALPOINT 2 + +struct alps_model_info { + unsigned char signature[3]; + unsigned char model; +} alps_model_data[] = { + { { 0x33, 0x02, 0x0a }, ALPS_MODEL_GLIDEPOINT }, + { { 0x53, 0x02, 0x0a }, ALPS_MODEL_GLIDEPOINT }, + { { 0x53, 0x02, 0x14 }, ALPS_MODEL_GLIDEPOINT }, + { { 0x63, 0x02, 0x0a }, ALPS_MODEL_GLIDEPOINT }, + { { 0x63, 0x02, 0x14 }, ALPS_MODEL_GLIDEPOINT }, + { { 0x73, 0x02, 0x0a }, ALPS_MODEL_GLIDEPOINT }, + { { 0x73, 0x02, 0x14 }, ALPS_MODEL_GLIDEPOINT }, + { { 0x63, 0x02, 0x28 }, ALPS_MODEL_GLIDEPOINT }, + { { 0x63, 0x02, 0x3c }, ALPS_MODEL_GLIDEPOINT }, + { { 0x63, 0x02, 0x50 }, ALPS_MODEL_GLIDEPOINT }, + { { 0x63, 0x02, 0x64 }, ALPS_MODEL_GLIDEPOINT }, + { { 0x20, 0x02, 0x0e }, ALPS_MODEL_DUALPOINT }, + { { 0x22, 0x02, 0x0a }, ALPS_MODEL_DUALPOINT }, + { { 0x22, 0x02, 0x14 }, ALPS_MODEL_DUALPOINT }, + { { 0x63, 0x03, 0xc8 }, ALPS_MODEL_DUALPOINT }, +}; + +/* + * ALPS abolute Mode + * byte 0: 1 1 1 1 1 mid0 rig0 lef0 + * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 + * byte 2: 0 x10 x9 x8 x7 up1 fin ges + * byte 3: 0 y9 y8 y7 1 mid1 rig1 lef1 + * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 + * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 + * + * On a dualpoint, {mid,rig,lef}0 are the stick, 1 are the pad. + * We just 'or' them together for now. + * + * We used to send 'ges'tures as BTN_TOUCH but this made it impossible + * to disable tap events in the synaptics driver since the driver + * was unable to distinguish a gesture tap from an actual button click. + * A tap gesture now creates an emulated touch that the synaptics + * driver can interpret as a tap event, if MaxTapTime=0 and + * MaxTapMove=0 then the driver will ignore taps. + * + * The touchpad on an 'Acer Aspire' has 4 buttons: + * left,right,up,down. + * This device always sets {mid,rig,lef}0 to 1 and + * reflects left,right,down,up in lef1,rig1,mid1,up1. + */ + +static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs) +{ + unsigned char *packet = psmouse->packet; + struct input_dev *dev = &psmouse->dev; + int x, y, z; + int left = 0, right = 0, middle = 0; + + input_regs(dev, regs); + + if ((packet[0] & 0xc8) == 0x08) { /* 3-byte PS/2 packet */ + x = packet[1]; + if (packet[0] & 0x10) + x = x - 256; + y = packet[2]; + if (packet[0] & 0x20) + y = y - 256; + left = (packet[0] ) & 1; + right = (packet[0] >> 1) & 1; + + input_report_rel(dev, REL_X, x); + input_report_rel(dev, REL_Y, -y); + input_report_key(dev, BTN_A, left); + input_report_key(dev, BTN_B, right); + input_sync(dev); + return; + } + + x = (packet[1] & 0x7f) | ((packet[2] & 0x78)<<(7-3)); + y = (packet[4] & 0x7f) | ((packet[3] & 0x70)<<(7-4)); + z = packet[5]; + + if (z == 127) { /* DualPoint stick is relative, not absolute */ + if (x > 383) + x = x - 768; + if (y > 255) + y = y - 512; + left = packet[3] & 1; + right = (packet[3] >> 1) & 1; + + input_report_rel(dev, REL_X, x); + input_report_rel(dev, REL_Y, -y); + input_report_key(dev, BTN_LEFT, left); + input_report_key(dev, BTN_RIGHT, right); + input_sync(dev); + return; + } + + if (z > 30) input_report_key(dev, BTN_TOUCH, 1); + if (z < 25) input_report_key(dev, BTN_TOUCH, 0); + + if (z > 0) { + input_report_abs(dev, ABS_X, x); + input_report_abs(dev, ABS_Y, y); + } + input_report_abs(dev, ABS_PRESSURE, z); + input_report_key(dev, BTN_TOOL_FINGER, z > 0); + + left |= (packet[2] ) & 1; + left |= (packet[3] ) & 1; + right |= (packet[3] >> 1) & 1; + if (packet[0] == 0xff) { + int back = (packet[3] >> 2) & 1; + int forward = (packet[2] >> 2) & 1; + if (back && forward) { + middle = 1; + back = 0; + forward = 0; + } + input_report_key(dev, BTN_BACK, back); + input_report_key(dev, BTN_FORWARD, forward); + } else { + left |= (packet[0] ) & 1; + right |= (packet[0] >> 1) & 1; + middle |= (packet[0] >> 2) & 1; + middle |= (packet[3] >> 2) & 1; + } + + input_report_key(dev, BTN_LEFT, left); + input_report_key(dev, BTN_RIGHT, right); + input_report_key(dev, BTN_MIDDLE, middle); + + input_sync(dev); +} + +static psmouse_ret_t alps_process_byte(struct psmouse *psmouse, struct pt_regs *regs) +{ + if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */ + if (psmouse->pktcnt == 3) { + alps_process_packet(psmouse, regs); + return PSMOUSE_FULL_PACKET; + } + return PSMOUSE_GOOD_DATA; + } + + /* ALPS absolute mode packets start with 0b11111mrl */ + if ((psmouse->packet[0] & 0xf8) != 0xf8) + return PSMOUSE_BAD_DATA; + + /* Bytes 2 - 6 should have 0 in the highest bit */ + if (psmouse->pktcnt > 1 && psmouse->pktcnt <= 6 && + (psmouse->packet[psmouse->pktcnt] & 0x80)) + return PSMOUSE_BAD_DATA; + + if (psmouse->pktcnt == 6) { + alps_process_packet(psmouse, regs); + return PSMOUSE_FULL_PACKET; + } + + return PSMOUSE_GOOD_DATA; +} + +int alps_get_model(struct psmouse *psmouse) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param[4]; + int i; + + /* + * First try "E6 report". + * ALPS should return 0x00,0x00,0x0a or 0x00,0x00,0x64 + */ + param[0] = 0; + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11)) + return -1; + + param[0] = param[1] = param[2] = 0xff; + if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) + return -1; + + dbg("E6 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); + + if (param[0] != 0x00 || param[1] != 0x00 || (param[2] != 0x0a && param[2] != 0x64)) + return -1; + + /* Now try "E7 report". ALPS should return 0x33 in byte 1 */ + param[0] = 0; + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21)) + return -1; + + param[0] = param[1] = param[2] = 0xff; + if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) + return -1; + + dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); + + for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) + if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature))) + return alps_model_data[i].model; + + return -1; +} + +/* + * For DualPoint devices select the device that should respond to + * subsequent commands. It looks like glidepad is behind stickpointer, + * I'd thought it would be other way around... + */ +static int alps_passthrough_mode(struct psmouse *psmouse, int enable) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param[3]; + int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; + + if (ps2_command(ps2dev, NULL, cmd) || + ps2_command(ps2dev, NULL, cmd) || + ps2_command(ps2dev, NULL, cmd) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE)) + return -1; + + /* we may get 3 more bytes, just ignore them */ + ps2_command(ps2dev, param, 0x0300); + + return 0; +} + +static int alps_absolute_mode(struct psmouse *psmouse) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + + /* Try ALPS magic knock - 4 disable before enable */ + if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) + return -1; + + /* + * Switch mouse to poll (remote) mode so motion data will not + * get in our way + */ + return ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETPOLL); +} + +static int alps_get_status(struct psmouse *psmouse, char *param) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + + /* Get status: 0xF5 0xF5 0xF5 0xE9 */ + if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) + return -1; + + dbg("Status: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); + + return 0; +} + +/* + * Turn touchpad tapping on or off. The sequences are: + * 0xE9 0xF5 0xF5 0xF3 0x0A to enable, + * 0xE9 0xF5 0xF5 0xE8 0x00 to disable. + * My guess that 0xE9 (GetInfo) is here as a sync point. + * For models that also have stickpointer (DualPoints) its tapping + * is controlled separately (0xE6 0xE6 0xE6 0xF3 0x14|0x0A) but + * we don't fiddle with it. + */ +static int alps_tap_mode(struct psmouse *psmouse, int enable) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + int cmd = enable ? PSMOUSE_CMD_SETRATE : PSMOUSE_CMD_SETRES; + unsigned char tap_arg = enable ? 0x0A : 0x00; + unsigned char param[4]; + + if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || + ps2_command(ps2dev, &tap_arg, cmd)) + return -1; + + if (alps_get_status(psmouse, param)) + return -1; + + return 0; +} + +static int alps_reconnect(struct psmouse *psmouse) +{ + int model; + unsigned char param[4]; + + if ((model = alps_get_model(psmouse)) < 0) + return -1; + + if (model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 1)) + return -1; + + if (alps_get_status(psmouse, param)) + return -1; + + if (param[0] & 0x04) + alps_tap_mode(psmouse, 0); + + if (alps_absolute_mode(psmouse)) { + printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); + return -1; + } + + if (model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 0)) + return -1; + + return 0; +} + +static void alps_disconnect(struct psmouse *psmouse) +{ + psmouse_reset(psmouse); +} + +int alps_init(struct psmouse *psmouse) +{ + unsigned char param[4]; + int model; + + if ((model = alps_get_model(psmouse)) < 0) + return -1; + + printk(KERN_INFO "ALPS Touchpad (%s) detected\n", + model == ALPS_MODEL_GLIDEPOINT ? "Glidepoint" : "Dualpoint"); + + if (model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 1)) + return -1; + + if (alps_get_status(psmouse, param)) { + printk(KERN_ERR "alps.c: touchpad status report request failed\n"); + return -1; + } + + if (param[0] & 0x04) { + printk(KERN_INFO " Disabling hardware tapping\n"); + if (alps_tap_mode(psmouse, 0)) + printk(KERN_WARNING "alps.c: Failed to disable hardware tapping\n"); + } + + if (alps_absolute_mode(psmouse)) { + printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); + return -1; + } + + if (model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 0)) + return -1; + + psmouse->dev.evbit[LONG(EV_REL)] |= BIT(EV_REL); + psmouse->dev.relbit[LONG(REL_X)] |= BIT(REL_X); + psmouse->dev.relbit[LONG(REL_Y)] |= BIT(REL_Y); + psmouse->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A); + psmouse->dev.keybit[LONG(BTN_B)] |= BIT(BTN_B); + + psmouse->dev.evbit[LONG(EV_ABS)] |= BIT(EV_ABS); + input_set_abs_params(&psmouse->dev, ABS_X, 0, 1023, 0, 0); + input_set_abs_params(&psmouse->dev, ABS_Y, 0, 1023, 0, 0); + input_set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0); + + psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH); + psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER); + psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD); + psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); + + psmouse->protocol_handler = alps_process_byte; + psmouse->disconnect = alps_disconnect; + psmouse->reconnect = alps_reconnect; + psmouse->pktsize = 6; + + return 0; +} + +int alps_detect(struct psmouse *psmouse, int set_properties) +{ + if (alps_get_model(psmouse) < 0) + return -1; + + if (set_properties) { + psmouse->vendor = "ALPS"; + psmouse->name = "TouchPad"; + } + return 0; +} + diff -Nru a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/input/mouse/alps.h 2005-01-02 23:11:39 -08:00 @@ -0,0 +1,17 @@ +/* + * ALPS touchpad PS/2 mouse driver + * + * Copyright (c) 2003 Peter Osterlund + * + * 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 + * the Free Software Foundation. + */ + +#ifndef _ALPS_H +#define _ALPS_H + +int alps_detect(struct psmouse *psmouse, int set_properties); +int alps_init(struct psmouse *psmouse); + +#endif diff -Nru a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c --- a/drivers/input/mouse/logips2pp.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/logips2pp.c 2005-01-02 23:11:39 -08:00 @@ -11,6 +11,7 @@ #include #include +#include #include "psmouse.h" #include "logips2pp.h" @@ -37,13 +38,23 @@ * Process a PS2++ or PS2T++ packet. */ -void ps2pp_process_packet(struct psmouse *psmouse) +static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse, struct pt_regs *regs) { struct input_dev *dev = &psmouse->dev; - unsigned char *packet = psmouse->packet; + unsigned char *packet = psmouse->packet; + + if (psmouse->pktcnt < 3) + return PSMOUSE_GOOD_DATA; + +/* + * Full packet accumulated, process it + */ + + input_regs(dev, regs); if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02) { + /* Logitech extended packet */ switch ((packet[1] >> 4) | (packet[0] & 0x30)) { case 0x0d: /* Mouse extra info */ @@ -78,11 +89,20 @@ (packet[1] >> 4) | (packet[0] & 0x30)); #endif } - - packet[0] &= 0x0f; - packet[1] = 0; - packet[2] = 0; + } else { + /* Standard PS/2 motion data */ + input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0); + input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0); } + + input_report_key(dev, BTN_LEFT, packet[0] & 1); + input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); + input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); + + input_sync(dev); + + return PSMOUSE_FULL_PACKET; + } /* @@ -97,7 +117,7 @@ if (psmouse_sliced_command(psmouse, command)) return -1; - if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL)) + if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL)) return -1; return 0; @@ -108,40 +128,73 @@ * 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 - disabled */ -static void ps2pp_set_smartscroll(struct psmouse *psmouse) +static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscroll) { + struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[4]; + if (smartscroll > 1) + smartscroll = 1; + ps2pp_cmd(psmouse, param, 0x32); param[0] = 0; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); - 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); - } + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + + param[0] = smartscroll; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); +} + +static ssize_t psmouse_attr_show_smartscroll(struct psmouse *psmouse, char *buf) +{ + return sprintf(buf, "%d\n", psmouse->smartscroll ? 1 : 0); } +static ssize_t psmouse_attr_set_smartscroll(struct psmouse *psmouse, const char *buf, size_t count) +{ + unsigned long value; + char *rest; + + value = simple_strtoul(buf, &rest, 10); + if (*rest || value > 1) + return -EINVAL; + + ps2pp_set_smartscroll(psmouse, value); + psmouse->smartscroll = value; + return count; +} + +PSMOUSE_DEFINE_ATTR(smartscroll); + /* * Support 800 dpi resolution _only_ if the user wants it (there are good * reasons to not use it even if the mouse supports it, and of course there are * also good reasons to use it, let the user decide). */ -void ps2pp_set_800dpi(struct psmouse *psmouse) +static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolution) +{ + if (resolution > 400) { + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param = 3; + + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); + psmouse->resolution = 800; + } else + psmouse_set_resolution(psmouse, resolution); +} + +static void ps2pp_disconnect(struct psmouse *psmouse) { - unsigned char param = 3; - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(psmouse, ¶m, PSMOUSE_CMD_SETRES); + device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll); } static struct ps2pp_info *get_model_info(unsigned char model) @@ -238,23 +291,27 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) { + struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[4]; - unsigned char protocol = PSMOUSE_PS2; unsigned char model, buttons; struct ps2pp_info *model_info; + int use_ps2pp = 0; 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); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); param[1] = 0; - psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); - if (param[1] != 0) { - model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); - buttons = param[1]; - model_info = get_model_info(model); + if (!param[1]) + return -1; + + model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); + buttons = param[1]; + + if ((model_info = get_model_info(model)) != NULL) { /* * Do Logitech PS2++ / PS2T++ magic init. @@ -263,21 +320,21 @@ /* Unprotect RAM */ param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; - psmouse_command(psmouse, param, 0x30d1); + ps2_command(ps2dev, param, 0x30d1); /* Enable features */ param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; - psmouse_command(psmouse, param, 0x30d1); + ps2_command(ps2dev, param, 0x30d1); /* Enable PS2++ */ param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; - psmouse_command(psmouse, param, 0x30d1); + ps2_command(ps2dev, param, 0x30d1); param[0] = 0; - if (!psmouse_command(psmouse, param, 0x13d1) && + if (!ps2_command(ps2dev, param, 0x13d1) && param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { - protocol = PSMOUSE_PS2TPP; + use_ps2pp = 1; } - } else if (model_info != NULL) { + } else { param[0] = param[1] = param[2] = 0; ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */ @@ -286,25 +343,37 @@ if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 && (param[2] & 0x03) == ((param[1] >> 2) & 3)) { - ps2pp_set_smartscroll(psmouse); - protocol = PSMOUSE_PS2PP; + ps2pp_set_smartscroll(psmouse, psmouse->smartscroll); + use_ps2pp = 1; } } + } - if (set_properties) { - psmouse->vendor = "Logitech"; - psmouse->model = model; - - if (buttons < 3) - clear_bit(BTN_MIDDLE, psmouse->dev.keybit); - if (buttons < 2) - clear_bit(BTN_RIGHT, psmouse->dev.keybit); + if (set_properties) { + psmouse->vendor = "Logitech"; + psmouse->model = model; + + if (use_ps2pp) { + psmouse->protocol_handler = ps2pp_process_byte; + psmouse->pktsize = 3; + + if (model_info->kind != PS2PP_KIND_TP3) { + psmouse->set_resolution = ps2pp_set_resolution; + psmouse->disconnect = ps2pp_disconnect; - if (model_info) - ps2pp_set_model_properties(psmouse, model_info); + device_create_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll); + } } + + if (buttons < 3) + clear_bit(BTN_MIDDLE, psmouse->dev.keybit); + if (buttons < 2) + clear_bit(BTN_RIGHT, psmouse->dev.keybit); + + if (model_info) + ps2pp_set_model_properties(psmouse, model_info); } - return protocol; + return use_ps2pp ? 0 : -1; } diff -Nru a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h --- a/drivers/input/mouse/logips2pp.h 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/logips2pp.h 2005-01-02 23:11:39 -08:00 @@ -11,8 +11,6 @@ #ifndef _LOGIPS2PP_H #define _LOGIPS2PP_H -void ps2pp_process_packet(struct psmouse *psmouse); -void ps2pp_set_800dpi(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 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/psmouse-base.c 2005-01-02 23:11:39 -08:00 @@ -2,6 +2,7 @@ * PS/2 mouse driver * * Copyright (c) 1999-2002 Vojtech Pavlik + * Copyright (c) 2003-2004 Dmitry Torokhov */ /* @@ -18,9 +19,11 @@ #include #include #include +#include #include "psmouse.h" #include "synaptics.h" #include "logips2pp.h" +#include "alps.h" #define DRIVER_DESC "PS/2 mouse driver" @@ -33,15 +36,15 @@ module_param_named(proto, psmouse_proto, charp, 0); MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps). Useful for KVM switches."); -int psmouse_resolution = 200; +static unsigned int psmouse_resolution = 200; module_param_named(resolution, psmouse_resolution, uint, 0); MODULE_PARM_DESC(resolution, "Resolution, in dpi."); -unsigned int psmouse_rate = 100; +static unsigned int psmouse_rate = 100; module_param_named(rate, psmouse_rate, uint, 0); MODULE_PARM_DESC(rate, "Report rate, in reports per second."); -int psmouse_smartscroll = 1; +static unsigned int psmouse_smartscroll = 1; module_param_named(smartscroll, psmouse_smartscroll, bool, 0); MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); @@ -49,13 +52,17 @@ module_param_named(resetafter, psmouse_resetafter, uint, 0); MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); +PSMOUSE_DEFINE_ATTR(rate); +PSMOUSE_DEFINE_ATTR(resolution); +PSMOUSE_DEFINE_ATTR(resetafter); + __obsolete_setup("psmouse_noext"); __obsolete_setup("psmouse_resolution="); __obsolete_setup("psmouse_smartscroll="); __obsolete_setup("psmouse_resetafter="); __obsolete_setup("psmouse_rate="); -static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"}; +static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "ThinkPS/2", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2", "AlpsPS/2" }; /* * psmouse_process_byte() analyzes the PS/2 data stream and reports @@ -67,7 +74,7 @@ struct input_dev *dev = &psmouse->dev; unsigned char *packet = psmouse->packet; - if (psmouse->pktcnt < 3 + (psmouse->type >= PSMOUSE_GENPS)) + if (psmouse->pktcnt < psmouse->pktsize) return PSMOUSE_GOOD_DATA; /* @@ -77,13 +84,6 @@ input_regs(dev, regs); /* - * The PS2++ protocol is a little bit complex - */ - - if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) - ps2pp_process_packet(psmouse); - -/* * Scroll wheel on IntelliMice, scroll buttons on NetMice */ @@ -110,6 +110,15 @@ } /* + * Extra button on ThinkingMouse + */ + if (psmouse->type == PSMOUSE_THINKPS) { + input_report_key(dev, BTN_EXTRA, (packet[0] >> 3) & 1); + /* Without this bit of weirdness moving up gives wildly high Y changes. */ + packet[1] |= (packet[0] & 0x40) << 1; + } + +/* * Generic PS/2 Mouse */ @@ -144,63 +153,17 @@ printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", flags & SERIO_TIMEOUT ? " timeout" : "", flags & SERIO_PARITY ? " bad parity" : ""); - psmouse->nak = 1; - clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags); - clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags); - wake_up_interruptible(&psmouse->wait); + ps2_cmd_aborted(&psmouse->ps2dev); goto out; } - if (test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags)) { - switch (data) { - case PSMOUSE_RET_ACK: - psmouse->nak = 0; - break; - - case PSMOUSE_RET_NAK: - psmouse->nak = 1; - break; - - /* - * Workaround for mice which don't ACK the Get ID command. - * These are valid mouse IDs that we recognize. - */ - case 0x00: - case 0x03: - case 0x04: - if (test_bit(PSMOUSE_FLAG_WAITID, &psmouse->flags)) { - psmouse->nak = 0; - break; - } - /* Fall through */ - default: - goto out; - } - - if (!psmouse->nak && psmouse->cmdcnt) { - set_bit(PSMOUSE_FLAG_CMD, &psmouse->flags); - set_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags); - } - clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags); - wake_up_interruptible(&psmouse->wait); - - if (data == PSMOUSE_RET_ACK || data == PSMOUSE_RET_NAK) + if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK)) + if (ps2_handle_ack(&psmouse->ps2dev, data)) goto out; - } - if (test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags)) { - if (psmouse->cmdcnt) - psmouse->cmdbuf[--psmouse->cmdcnt] = data; - - if (test_and_clear_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags) && psmouse->cmdcnt) - wake_up_interruptible(&psmouse->wait); - - if (!psmouse->cmdcnt) { - clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags); - wake_up_interruptible(&psmouse->wait); - } - goto out; - } + if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_CMD)) + if (ps2_handle_response(&psmouse->ps2dev, data)) + goto out; if (psmouse->state == PSMOUSE_INITIALIZING) goto out; @@ -243,10 +206,10 @@ psmouse->name, psmouse->phys, psmouse->pktcnt); psmouse->pktcnt = 0; - if (++psmouse->out_of_sync == psmouse_resetafter) { + if (++psmouse->out_of_sync == psmouse->resetafter) { psmouse->state = PSMOUSE_IGNORE; printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); - serio_reconnect(psmouse->serio); + serio_reconnect(psmouse->ps2dev.serio); } break; @@ -266,100 +229,6 @@ return IRQ_HANDLED; } -/* - * psmouse_sendbyte() sends a byte to the mouse, and waits for acknowledge. - * It doesn't handle retransmission, though it could - because when there would - * be need for retransmissions, the mouse has to be replaced anyway. - * - * psmouse_sendbyte() can only be called from a process context - */ - -static int psmouse_sendbyte(struct psmouse *psmouse, unsigned char byte) -{ - psmouse->nak = 1; - set_bit(PSMOUSE_FLAG_ACK, &psmouse->flags); - - if (serio_write(psmouse->serio, byte) == 0) - wait_event_interruptible_timeout(psmouse->wait, - !test_bit(PSMOUSE_FLAG_ACK, &psmouse->flags), - msecs_to_jiffies(200)); - - clear_bit(PSMOUSE_FLAG_ACK, &psmouse->flags); - return -psmouse->nak; -} - -/* - * psmouse_command() sends a command and its parameters to the mouse, - * then waits for the response and puts it in the param array. - * - * psmouse_command() can only be called from a process context - */ - -int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command) -{ - int timeout; - int send = (command >> 12) & 0xf; - int receive = (command >> 8) & 0xf; - int rc = -1; - int i; - - timeout = msecs_to_jiffies(command == PSMOUSE_CMD_RESET_BAT ? 4000 : 500); - - clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags); - if (command == PSMOUSE_CMD_GETID) - set_bit(PSMOUSE_FLAG_WAITID, &psmouse->flags); - - if (receive && param) - for (i = 0; i < receive; i++) - psmouse->cmdbuf[(receive - 1) - i] = param[i]; - - psmouse->cmdcnt = receive; - - if (command & 0xff) - if (psmouse_sendbyte(psmouse, command & 0xff)) - goto out; - - for (i = 0; i < send; i++) - if (psmouse_sendbyte(psmouse, param[i])) - goto out; - - timeout = wait_event_interruptible_timeout(psmouse->wait, - !test_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags), timeout); - - if (psmouse->cmdcnt && timeout > 0) { - if (command == PSMOUSE_CMD_RESET_BAT && jiffies_to_msecs(timeout) > 100) - timeout = msecs_to_jiffies(100); - - if (command == PSMOUSE_CMD_GETID && - psmouse->cmdbuf[receive - 1] != 0xab && psmouse->cmdbuf[receive - 1] != 0xac) { - /* - * Device behind the port is not a keyboard - * so we don't need to wait for the 2nd byte - * of ID response. - */ - clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags); - psmouse->cmdcnt = 0; - } - - wait_event_interruptible_timeout(psmouse->wait, - !test_bit(PSMOUSE_FLAG_CMD, &psmouse->flags), timeout); - } - - if (param) - for (i = 0; i < receive; i++) - param[i] = psmouse->cmdbuf[(receive - 1) - i]; - - if (psmouse->cmdcnt && (command != PSMOUSE_CMD_RESET_BAT || psmouse->cmdcnt != 1)) - goto out; - - rc = 0; - -out: - clear_bit(PSMOUSE_FLAG_CMD, &psmouse->flags); - clear_bit(PSMOUSE_FLAG_CMD1, &psmouse->flags); - clear_bit(PSMOUSE_FLAG_WAITID, &psmouse->flags); - return rc; -} /* * psmouse_sliced_command() sends an extended PS/2 command to the mouse @@ -372,12 +241,12 @@ { int i; - if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) + if (ps2_command(&psmouse->ps2dev, 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)) + if (ps2_command(&psmouse->ps2dev, &d, PSMOUSE_CMD_SETRES)) return -1; } @@ -392,7 +261,7 @@ { unsigned char param[2]; - if (psmouse_command(psmouse, param, PSMOUSE_CMD_RESET_BAT)) + if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT)) return -1; if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID) @@ -405,56 +274,138 @@ /* * Genius NetMouse magic init. */ -static int genius_detect(struct psmouse *psmouse) +static int genius_detect(struct psmouse *psmouse, int set_properties) { + struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[4]; param[0] = 3; - 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); - psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); + + if (param[0] != 0x00 || param[1] != 0x33 || param[2] != 0x55) + return -1; + + 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->pktsize = 4; + } - return param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55; + return 0; } /* * IntelliMouse magic init. */ -static int intellimouse_detect(struct psmouse *psmouse) +static int intellimouse_detect(struct psmouse *psmouse, int set_properties) { + struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[2]; param[0] = 200; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); param[0] = 100; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); param[0] = 80; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); - psmouse_command(psmouse, param, PSMOUSE_CMD_GETID); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + + if (param[0] != 3) + return -1; + + if (set_properties) { + set_bit(REL_WHEEL, psmouse->dev.relbit); + + if (!psmouse->vendor) psmouse->vendor = "Generic"; + if (!psmouse->name) psmouse->name = "Wheel Mouse"; + psmouse->pktsize = 4; + } - return param[0] == 3; + return 0; } /* * Try IntelliMouse/Explorer magic init. */ -static int im_explorer_detect(struct psmouse *psmouse) +static int im_explorer_detect(struct psmouse *psmouse, int set_properties) { + struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[2]; - intellimouse_detect(psmouse); + intellimouse_detect(psmouse, 0); param[0] = 200; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); param[0] = 200; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); param[0] = 80; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE); - psmouse_command(psmouse, param, PSMOUSE_CMD_GETID); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + + if (param[0] != 4) + return -1; + + if (set_properties) { + set_bit(REL_WHEEL, psmouse->dev.relbit); + set_bit(BTN_SIDE, psmouse->dev.keybit); + set_bit(BTN_EXTRA, psmouse->dev.keybit); + + if (!psmouse->vendor) psmouse->vendor = "Generic"; + if (!psmouse->name) psmouse->name = "Explorer Mouse"; + psmouse->pktsize = 4; + } - return param[0] == 4; + return 0; +} + +/* + * Kensington ThinkingMouse / ExpertMouse magic init. + */ +static int thinking_detect(struct psmouse *psmouse, int set_properties) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param[2]; + unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20, 0 }; + int i; + + param[0] = 10; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + param[0] = 0; + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + for (i = 0; seq[i]; i++) + ps2_command(ps2dev, seq + i, PSMOUSE_CMD_SETRATE); + ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + + if (param[0] != 2) + return -1; + + if (set_properties) { + set_bit(BTN_EXTRA, psmouse->dev.keybit); + + psmouse->vendor = "Kensington"; + psmouse->name = "ThinkingMouse"; + } + + return 0; +} + +/* + * Bare PS/2 protocol "detection". Always succeeds. + */ +static int ps2bare_detect(struct psmouse *psmouse, int set_properties) +{ + if (!psmouse->vendor) psmouse->vendor = "Generic"; + if (!psmouse->name) psmouse->name = "Mouse"; + + return 0; } /* @@ -468,16 +419,19 @@ int synaptics_hardware = 0; /* + * Try Kensington ThinkingMouse (we try first, because synaptics probe + * upsets the thinkingmouse). + */ + + if (max_proto > PSMOUSE_PS2 && thinking_detect(psmouse, set_properties) == 0) + return PSMOUSE_THINKPS; + +/* * Try Synaptics TouchPad */ - if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) { + if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { synaptics_hardware = 1; - if (set_properties) { - psmouse->vendor = "Synaptics"; - psmouse->name = "TouchPad"; - } - if (max_proto > PSMOUSE_IMEX) { if (!set_properties || synaptics_init(psmouse) == 0) return PSMOUSE_SYNAPTICS; @@ -494,53 +448,43 @@ synaptics_reset(psmouse); } - if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) { +/* + * Try ALPS TouchPad + */ + if (max_proto > PSMOUSE_IMEX && alps_detect(psmouse, set_properties) == 0) { + if (!set_properties || alps_init(psmouse) == 0) + return PSMOUSE_ALPS; - 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"; - } +/* + * Init failed, try basic relative protocols + */ + max_proto = PSMOUSE_IMEX; + } + if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse, set_properties) == 0) return PSMOUSE_GENPS; - } - if (max_proto > PSMOUSE_IMEX) { - int type = ps2pp_init(psmouse, set_properties); - if (type > PSMOUSE_PS2) - return type; - } + if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0) + return PSMOUSE_PS2PP; - if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) { - - if (set_properties) { - set_bit(REL_WHEEL, psmouse->dev.relbit); - set_bit(BTN_SIDE, psmouse->dev.keybit); - set_bit(BTN_EXTRA, psmouse->dev.keybit); - if (!psmouse->name) - psmouse->name = "Explorer Mouse"; - } +/* + * Reset to defaults in case the device got confused by extended + * protocol probes. + */ + ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); + if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0) return PSMOUSE_IMEX; - } - - if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) { - - if (set_properties) { - set_bit(REL_WHEEL, psmouse->dev.relbit); - if (!psmouse->name) - psmouse->name = "Wheel Mouse"; - } + if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse, set_properties) == 0) return PSMOUSE_IMPS; - } /* * Okay, all failed, we have a standard mouse here. The number of the buttons * is still a question, though. We assume 3. */ + ps2bare_detect(psmouse, set_properties); + if (synaptics_hardware) { /* * We detected Synaptics hardware but it did not respond to IMPS/2 probes. @@ -549,7 +493,7 @@ * extensions. */ psmouse_reset(psmouse); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS); + ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); } return PSMOUSE_PS2; @@ -561,6 +505,7 @@ static int psmouse_probe(struct psmouse *psmouse) { + struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[2]; /* @@ -569,8 +514,7 @@ */ param[0] = 0xa5; - - if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETID)) + if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) return -1; if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) @@ -580,8 +524,8 @@ * Then we reset and disable the mouse so that it doesn't generate events. */ - if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS)) - printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys); + if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS)) + printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", ps2dev->serio->phys); return 0; } @@ -590,38 +534,29 @@ * Here we set the mouse resolution. */ -static void psmouse_set_resolution(struct psmouse *psmouse) +void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) { - unsigned char param[1]; + unsigned char params[] = { 0, 1, 2, 2, 3 }; - if (psmouse->type == PSMOUSE_PS2PP && psmouse_resolution > 400) { - ps2pp_set_800dpi(psmouse); - return; - } - - if (!psmouse_resolution || psmouse_resolution >= 200) - param[0] = 3; - else if (psmouse_resolution >= 100) - param[0] = 2; - else if (psmouse_resolution >= 50) - param[0] = 1; - else if (psmouse_resolution) - param[0] = 0; + if (resolution == 0 || resolution > 200) + resolution = 200; - psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + ps2_command(&psmouse->ps2dev, ¶ms[resolution / 50], PSMOUSE_CMD_SETRES); + psmouse->resolution = 25 << params[resolution / 50]; } /* * Here we set the mouse report rate. */ -static void psmouse_set_rate(struct psmouse *psmouse) +static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) { unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 }; int i = 0; - while (rates[i] > psmouse_rate) i++; - psmouse_command(psmouse, rates + i, PSMOUSE_CMD_SETRATE); + while (rates[i] > rate) i++; + ps2_command(&psmouse->ps2dev, &rates[i], PSMOUSE_CMD_SETRATE); + psmouse->rate = rates[i]; } /* @@ -630,23 +565,21 @@ static void psmouse_initialize(struct psmouse *psmouse) { - unsigned char param[2]; - /* - * We set the mouse report rate, resolution and scaling. + * We set the mouse into streaming mode. */ - if (psmouse_max_proto != PSMOUSE_PS2) { - psmouse_set_rate(psmouse); - psmouse_set_resolution(psmouse); - psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); - } + ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM); /* - * We set the mouse into streaming mode. + * We set the mouse report rate, resolution and scaling. */ - psmouse_command(psmouse, param, PSMOUSE_CMD_SETSTREAM); + if (psmouse_max_proto != PSMOUSE_PS2) { + psmouse->set_rate(psmouse, psmouse->rate); + psmouse->set_resolution(psmouse, psmouse->resolution); + ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + } } /* @@ -657,11 +590,11 @@ static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) { - serio_pause_rx(psmouse->serio); + serio_pause_rx(psmouse->ps2dev.serio); psmouse->state = new_state; - psmouse->pktcnt = psmouse->cmdcnt = psmouse->out_of_sync = 0; - psmouse->flags = 0; - serio_continue_rx(psmouse->serio); + psmouse->pktcnt = psmouse->out_of_sync = 0; + psmouse->ps2dev.flags = 0; + serio_continue_rx(psmouse->ps2dev.serio); } /* @@ -670,8 +603,9 @@ static void psmouse_activate(struct psmouse *psmouse) { - if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE)) - printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse->serio->phys); + if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) + printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", + psmouse->ps2dev.serio->phys); psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); } @@ -684,8 +618,9 @@ static void psmouse_deactivate(struct psmouse *psmouse) { - if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE)) - printk(KERN_WARNING "psmouse.c: Failed to deactivate mouse on %s\n", psmouse->serio->phys); + if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) + printk(KERN_WARNING "psmouse.c: Failed to deactivate mouse on %s\n", + psmouse->ps2dev.serio->phys); psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); } @@ -710,6 +645,10 @@ { struct psmouse *psmouse, *parent; + device_remove_file(&serio->dev, &psmouse_attr_rate); + device_remove_file(&serio->dev, &psmouse_attr_resolution); + device_remove_file(&serio->dev, &psmouse_attr_resetafter); + psmouse = serio->private; psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); @@ -755,13 +694,12 @@ memset(psmouse, 0, sizeof(struct psmouse)); - init_waitqueue_head(&psmouse->wait); - init_input_dev(&psmouse->dev); + ps2_init(&psmouse->ps2dev, serio); 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->serio = serio; psmouse->dev.private = psmouse; + psmouse->dev.dev = &serio->dev; psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); serio->private = psmouse; @@ -778,13 +716,16 @@ goto out; } + psmouse->rate = psmouse_rate; + psmouse->resolution = psmouse_resolution; + psmouse->resetafter = psmouse_resetafter; + psmouse->smartscroll = psmouse_smartscroll; + psmouse->set_rate = psmouse_set_rate; + psmouse->set_resolution = psmouse_set_resolution; + psmouse->protocol_handler = psmouse_process_byte; + psmouse->pktsize = 3; + 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); @@ -809,6 +750,10 @@ if (parent && parent->pt_activate) parent->pt_activate(parent); + device_create_file(&serio->dev, &psmouse_attr_rate); + device_create_file(&serio->dev, &psmouse_attr_resolution); + device_create_file(&serio->dev, &psmouse_attr_resetafter); + if (serio->child) { /* * Nothing to be done here, serio core will detect that @@ -846,7 +791,7 @@ psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); if (psmouse->reconnect) { - if (psmouse->reconnect(psmouse)) + if (psmouse->reconnect(psmouse)) goto out; } else if (psmouse_probe(psmouse) < 0 || psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0)) @@ -885,6 +830,115 @@ .disconnect = psmouse_disconnect, .cleanup = psmouse_cleanup, }; + +ssize_t psmouse_attr_show_helper(struct device *dev, char *buf, + ssize_t (*handler)(struct psmouse *, char *)) +{ + struct serio *serio = to_serio_port(dev); + int retval; + + retval = serio_pin_driver(serio); + if (retval) + return retval; + + if (serio->drv != &psmouse_drv) { + retval = -ENODEV; + goto out; + } + + retval = handler(serio->private, buf); + +out: + serio_unpin_driver(serio); + return retval; +} + +ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t count, + ssize_t (*handler)(struct psmouse *, const char *, size_t)) +{ + struct serio *serio = to_serio_port(dev); + struct psmouse *psmouse = serio->private, *parent = NULL; + int retval; + + retval = serio_pin_driver(serio); + if (retval) + return retval; + + if (serio->drv != &psmouse_drv) { + retval = -ENODEV; + goto out; + } + + if (serio->parent && (serio->type & SERIO_TYPE) == SERIO_PS_PSTHRU) { + parent = serio->parent->private; + psmouse_deactivate(parent); + } + psmouse_deactivate(psmouse); + + retval = handler(psmouse, buf, count); + + psmouse_activate(psmouse); + if (parent) + psmouse_activate(parent); + +out: + serio_unpin_driver(serio); + return retval; +} + +static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf) +{ + return sprintf(buf, "%d\n", psmouse->rate); +} + +static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, const char *buf, size_t count) +{ + unsigned long value; + char *rest; + + value = simple_strtoul(buf, &rest, 10); + if (*rest) + return -EINVAL; + + psmouse->set_rate(psmouse, value); + return count; +} + +static ssize_t psmouse_attr_show_resolution(struct psmouse *psmouse, char *buf) +{ + return sprintf(buf, "%d\n", psmouse->resolution); +} + +static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, const char *buf, size_t count) +{ + unsigned long value; + char *rest; + + value = simple_strtoul(buf, &rest, 10); + if (*rest) + return -EINVAL; + + psmouse->set_resolution(psmouse, value); + return count; +} + +static ssize_t psmouse_attr_show_resetafter(struct psmouse *psmouse, char *buf) +{ + return sprintf(buf, "%d\n", psmouse->resetafter); +} + +static ssize_t psmouse_attr_set_resetafter(struct psmouse *psmouse, const char *buf, size_t count) +{ + unsigned long value; + char *rest; + + value = simple_strtoul(buf, &rest, 10); + if (*rest) + return -EINVAL; + + psmouse->resetafter = value; + return count; +} static inline void psmouse_parse_proto(void) { diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h --- a/drivers/input/mouse/psmouse.h 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/psmouse.h 2005-01-02 23:11:39 -08:00 @@ -2,9 +2,11 @@ #define _PSMOUSE_H #define PSMOUSE_CMD_SETSCALE11 0x00e6 +#define PSMOUSE_CMD_SETSCALE21 0x00e7 #define PSMOUSE_CMD_SETRES 0x10e8 #define PSMOUSE_CMD_GETINFO 0x03e9 #define PSMOUSE_CMD_SETSTREAM 0x00ea +#define PSMOUSE_CMD_SETPOLL 0x00f0 #define PSMOUSE_CMD_POLL 0x03eb #define PSMOUSE_CMD_GETID 0x02f2 #define PSMOUSE_CMD_SETRATE 0x10f3 @@ -18,11 +20,6 @@ #define PSMOUSE_RET_ACK 0xfa #define PSMOUSE_RET_NAK 0xfe -#define PSMOUSE_FLAG_ACK 0 /* Waiting for ACK/NAK */ -#define PSMOUSE_FLAG_CMD 1 /* Waiting for command to finish */ -#define PSMOUSE_FLAG_CMD1 2 /* Waiting for the first byte of command response */ -#define PSMOUSE_FLAG_WAITID 3 /* Command execiting is GET ID */ - enum psmouse_state { PSMOUSE_IGNORE, PSMOUSE_INITIALIZING, @@ -40,28 +37,29 @@ struct psmouse { void *private; struct input_dev dev; - struct serio *serio; + struct ps2dev ps2dev; char *vendor; char *name; - unsigned char cmdbuf[8]; unsigned char packet[8]; - unsigned char cmdcnt; unsigned char pktcnt; + unsigned char pktsize; unsigned char type; unsigned char model; unsigned long last; unsigned long out_of_sync; enum psmouse_state state; - unsigned char nak; - char error; char devname[64]; char phys[32]; - unsigned long flags; - /* Used to signal completion from interrupt handler */ - wait_queue_head_t wait; + unsigned int rate; + unsigned int resolution; + unsigned int resetafter; + unsigned int smartscroll; /* Logitech only */ psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); + void (*set_rate)(struct psmouse *psmouse, unsigned int rate); + void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution); + int (*reconnect)(struct psmouse *psmouse); void (*disconnect)(struct psmouse *psmouse); @@ -69,19 +67,40 @@ void (*pt_deactivate)(struct psmouse *psmouse); }; -#define PSMOUSE_PS2 1 -#define PSMOUSE_PS2PP 2 -#define PSMOUSE_PS2TPP 3 -#define PSMOUSE_GENPS 4 -#define PSMOUSE_IMPS 5 -#define PSMOUSE_IMEX 6 -#define PSMOUSE_SYNAPTICS 7 +enum psmouse_type { + PSMOUSE_NONE, + PSMOUSE_PS2, + PSMOUSE_PS2PP, + PSMOUSE_THINKPS, + PSMOUSE_GENPS, + PSMOUSE_IMPS, + PSMOUSE_IMEX, + PSMOUSE_SYNAPTICS, + PSMOUSE_ALPS, +}; -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); +void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution); -extern int psmouse_smartscroll; -extern unsigned int psmouse_rate; +ssize_t psmouse_attr_show_helper(struct device *dev, char *buf, + ssize_t (*handler)(struct psmouse *, char *)); +ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t count, + ssize_t (*handler)(struct psmouse *, const char *, size_t)); + +#define PSMOUSE_DEFINE_ATTR(_name) \ +static ssize_t psmouse_attr_show_##_name(struct psmouse *, char *); \ +static ssize_t psmouse_attr_set_##_name(struct psmouse *, const char *, size_t);\ +static ssize_t psmouse_do_show_##_name(struct device *d, char *b) \ +{ \ + return psmouse_attr_show_helper(d, b, psmouse_attr_show_##_name); \ +} \ +static ssize_t psmouse_do_set_##_name(struct device *d, const char *b, size_t s)\ +{ \ + return psmouse_attr_set_helper(d, b, s, psmouse_attr_set_##_name); \ +} \ +static struct device_attribute psmouse_attr_##_name = \ + __ATTR(_name, S_IWUSR | S_IRUGO, \ + psmouse_do_show_##_name, psmouse_do_set_##_name); #endif /* _PSMOUSE_H */ diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c --- a/drivers/input/mouse/sermouse.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/sermouse.c 2005-01-02 23:11:39 -08:00 @@ -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 @@ -73,19 +73,19 @@ case 0: if ((data & 0xf8) != 0x80) return; - input_report_key(dev, BTN_LEFT, !(data & 4)); + input_report_key(dev, BTN_LEFT, !(data & 4)); input_report_key(dev, BTN_RIGHT, !(data & 1)); input_report_key(dev, BTN_MIDDLE, !(data & 2)); break; - case 1: - case 3: + case 1: + case 3: input_report_rel(dev, REL_X, data / 2); input_report_rel(dev, REL_Y, -buf[1]); buf[0] = data - data / 2; break; - case 2: + case 2: case 4: input_report_rel(dev, REL_X, buf[0]); input_report_rel(dev, REL_Y, buf[1] - data); @@ -145,7 +145,7 @@ case 3: switch (sermouse->type) { - + case SERIO_MS: sermouse->type = SERIO_MP; @@ -164,7 +164,7 @@ input_report_rel(dev, REL_WHEEL, (data & 8) - (data & 7)); break; } - + break; case 4: @@ -243,7 +243,7 @@ { struct sermouse *sermouse; unsigned char c; - + if ((serio->type & SERIO_TYPE) != SERIO_RS232) return; @@ -280,6 +280,7 @@ sermouse->dev.id.vendor = sermouse->type; sermouse->dev.id.product = c; sermouse->dev.id.version = 0x0100; + sermouse->dev.dev = &serio->dev; if (serio_open(serio, drv)) { kfree(sermouse); @@ -287,7 +288,7 @@ } input_register_device(&sermouse->dev); - + printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys); } diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c --- a/drivers/input/mouse/synaptics.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/synaptics.c 2005-01-02 23:11:39 -08:00 @@ -26,6 +26,7 @@ #include #include #include +#include #include "psmouse.h" #include "synaptics.h" @@ -50,7 +51,7 @@ { if (psmouse_sliced_command(psmouse, c)) return -1; - if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO)) + if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) return -1; return 0; } @@ -65,7 +66,7 @@ if (psmouse_sliced_command(psmouse, mode)) return -1; param[0] = SYN_PS_SET_MODE2; - if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE)) + if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE)) return -1; return 0; } @@ -192,23 +193,37 @@ return 0; } -static int synaptics_set_mode(struct psmouse *psmouse, int mode) +static int synaptics_set_absolute_mode(struct psmouse *psmouse) { struct synaptics_data *priv = psmouse->private; - mode |= SYN_BIT_ABSOLUTE_MODE; - if (psmouse_rate >= 80) - mode |= SYN_BIT_HIGH_RATE; + priv->mode = SYN_BIT_ABSOLUTE_MODE; if (SYN_ID_MAJOR(priv->identity) >= 4) - mode |= SYN_BIT_DISABLE_GESTURE; + priv->mode |= SYN_BIT_DISABLE_GESTURE; if (SYN_CAP_EXTENDED(priv->capabilities)) - mode |= SYN_BIT_W_MODE; - if (synaptics_mode_cmd(psmouse, mode)) + priv->mode |= SYN_BIT_W_MODE; + + if (synaptics_mode_cmd(psmouse, priv->mode)) return -1; return 0; } +static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate) +{ + struct synaptics_data *priv = psmouse->private; + + if (rate >= 80) { + priv->mode |= SYN_BIT_HIGH_RATE; + psmouse->rate = 80; + } else { + priv->mode &= ~SYN_BIT_HIGH_RATE; + psmouse->rate = 40; + } + + synaptics_mode_cmd(psmouse, priv->mode); +} + /***************************************************************************** * Synaptics pass-through PS/2 port support ****************************************************************************/ @@ -219,7 +234,7 @@ if (psmouse_sliced_command(parent, c)) return -1; - if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE)) + if (ps2_command(&parent->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE)) return -1; return 0; } @@ -245,12 +260,18 @@ static void synaptics_pt_activate(struct psmouse *psmouse) { - struct psmouse *child = psmouse->serio->child->private; + struct psmouse *child = psmouse->ps2dev.serio->child->private; + struct synaptics_data *priv = psmouse->private; /* adjust the touchpad to child's choice of protocol */ - if (child && child->type >= PSMOUSE_GENPS) { - if (synaptics_set_mode(psmouse, SYN_BIT_FOUR_BYTE_CLIENT)) - printk(KERN_INFO "synaptics: failed to enable 4-byte guest protocol\n"); + if (child) { + if (child->type >= PSMOUSE_GENPS) + priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT; + else + priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; + + if (synaptics_mode_cmd(psmouse, priv->mode)) + printk(KERN_INFO "synaptics: failed to switch guest protocol\n"); } } @@ -270,11 +291,11 @@ strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name)); strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name)); serio->write = synaptics_pt_write; - serio->parent = psmouse->serio; + serio->parent = psmouse->ps2dev.serio; psmouse->pt_activate = synaptics_pt_activate; - psmouse->serio->child = serio; + psmouse->ps2dev.serio->child = serio; } /***************************************************************************** @@ -470,8 +491,8 @@ priv->pkt_type = synaptics_detect_pkt_type(psmouse); if (SYN_CAP_PASS_THROUGH(priv->capabilities) && synaptics_is_pt_packet(psmouse->packet)) { - if (psmouse->serio->child) - synaptics_pass_pt_packet(psmouse->serio->child, psmouse->packet); + if (psmouse->ps2dev.serio->child) + synaptics_pass_pt_packet(psmouse->ps2dev.serio->child, psmouse->packet); } else synaptics_process_packet(psmouse); @@ -537,7 +558,7 @@ struct synaptics_data *priv = psmouse->private; struct synaptics_data old_priv = *priv; - if (!synaptics_detect(psmouse)) + if (synaptics_detect(psmouse, 0)) return -1; if (synaptics_query_hardware(psmouse)) { @@ -551,7 +572,7 @@ old_priv.ext_cap != priv->ext_cap) return -1; - if (synaptics_set_mode(psmouse, 0)) { + if (synaptics_set_absolute_mode(psmouse)) { printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); return -1; } @@ -559,19 +580,28 @@ return 0; } -int synaptics_detect(struct psmouse *psmouse) +int synaptics_detect(struct psmouse *psmouse, int set_properties) { + struct ps2dev *ps2dev = &psmouse->ps2dev; 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); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); + + if (param[1] != 0x47) + return -1; + + if (set_properties) { + psmouse->vendor = "Synaptics"; + psmouse->name = "TouchPad"; + } - return param[1] == 0x47; + return 0; } int synaptics_init(struct psmouse *psmouse) @@ -588,7 +618,7 @@ goto init_fail; } - if (synaptics_set_mode(psmouse, 0)) { + if (synaptics_set_absolute_mode(psmouse)) { printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); goto init_fail; } @@ -602,8 +632,10 @@ set_input_params(&psmouse->dev, priv); psmouse->protocol_handler = synaptics_process_byte; + psmouse->set_rate = synaptics_set_rate; psmouse->disconnect = synaptics_disconnect; psmouse->reconnect = synaptics_reconnect; + psmouse->pktsize = 6; return 0; diff -Nru a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h --- a/drivers/input/mouse/synaptics.h 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/synaptics.h 2005-01-02 23:11:39 -08:00 @@ -9,7 +9,7 @@ #ifndef _SYNAPTICS_H #define _SYNAPTICS_H -extern int synaptics_detect(struct psmouse *psmouse); +extern int synaptics_detect(struct psmouse *psmouse, int set_properties); extern int synaptics_init(struct psmouse *psmouse); extern void synaptics_reset(struct psmouse *psmouse); @@ -104,6 +104,7 @@ /* Data for normal processing */ int old_w; /* Previous w value */ unsigned char pkt_type; /* packet type - old, new, etc */ + unsigned char mode; /* current mode byte */ }; #endif /* _SYNAPTICS_H */ diff -Nru a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c --- a/drivers/input/mouse/vsxxxaa.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mouse/vsxxxaa.c 2005-01-02 23:11:39 -08:00 @@ -1,11 +1,14 @@ /* - * DEC VSXXX-AA and VSXXX-GA mouse driver. + * Driver for DEC VSXXX-AA mouse (hockey-puck mouse, ball or two rollers) + * DEC VSXXX-GA mouse (rectangular mouse, with ball) + * DEC VSXXX-AB tablet (digitizer with hair cross or stylus) * * Copyright (C) 2003-2004 by Jan-Benedict Glaw * - * The packet format was taken from a patch to GPM which is (C) 2001 + * The packet format was initially taken from a patch to GPM which is (C) 2001 * by Karsten Merker * and Maciej W. Rozycki + * Later on, I had access to the device's documentation (referenced below). */ /* @@ -25,7 +28,7 @@ */ /* - * Building an adaptor to DB9 / DB25 RS232 + * Building an adaptor to DE9 / DB25 RS232 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * DISCLAIMER: Use this description AT YOUR OWN RISK! I'll not pay for @@ -42,8 +45,8 @@ * | 4 --- 3 | * \ 2 1 / * ------- - * - * DEC socket DB9 DB25 Note + * + * DEC socket DE9 DB25 Note * 1 (GND) 5 7 - * 2 (RxD) 2 3 - * 3 (TxD) 3 2 - @@ -82,7 +85,7 @@ #include #include -#define DRIVER_DESC "Serial DEC VSXXX-AA/GA mouse / DEC tablet driver" +#define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet" MODULE_AUTHOR ("Jan-Benedict Glaw "); MODULE_DESCRIPTION (DRIVER_DESC); @@ -104,7 +107,7 @@ #define VSXXXAA_PACKET_REL 0x80 #define VSXXXAA_PACKET_ABS 0xc0 #define VSXXXAA_PACKET_POR 0xa0 -#define MATCH_PACKET_TYPE(data, type) (((data) & VSXXXAA_PACKET_MASK) == type) +#define MATCH_PACKET_TYPE(data, type) (((data) & VSXXXAA_PACKET_MASK) == (type)) @@ -150,7 +153,7 @@ { switch (mouse->type) { case 0x02: - sprintf (mouse->name, "DEC VSXXX-AA/GA mouse"); + sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse"); break; case 0x04: @@ -158,7 +161,8 @@ break; default: - sprintf (mouse->name, "unknown DEC pointer device"); + sprintf (mouse->name, "unknown DEC pointer device " + "(type = 0x%02x)", mouse->type); break; } @@ -336,13 +340,10 @@ * * M: manufacturer location code * R: revision code - * E: Error code. I'm not sure about these, but gpm's sources, - * which support this mouse, too, tell about them: - * E = [0x00 .. 0x1f]: no error, byte #3 is button state - * E = 0x3d: button error, byte #3 tells which one. - * E = : other error + * E: Error code. If it's in the range of 0x00..0x1f, only some + * minor problem occured. Errors >= 0x20 are considered bad + * and the device may not work properly... * D: <0010> == mouse, <0100> == tablet - * */ mouse->version = buf[0] & 0x0f; @@ -363,28 +364,32 @@ vsxxxaa_detection_done (mouse); if (error <= 0x1f) { - /* No error. Report buttons */ + /* No (serious) error. Report buttons */ input_regs (dev, regs); input_report_key (dev, BTN_LEFT, left); input_report_key (dev, BTN_MIDDLE, middle); input_report_key (dev, BTN_RIGHT, right); input_report_key (dev, BTN_TOUCH, 0); input_sync (dev); - } else { - printk (KERN_ERR "Your %s on %s reports an undefined error, " - "please check it...\n", mouse->name, - mouse->phys); + + if (error != 0) + printk (KERN_INFO "Your %s on %s reports error=0x%02x\n", + mouse->name, mouse->phys, error); + } /* * If the mouse was hot-plugged, we need to force differential mode * now... However, give it a second to recover from it's reset. */ - printk (KERN_NOTICE "%s on %s: Forceing standard packet format and " - "streaming mode\n", mouse->name, mouse->phys); - mouse->serio->write (mouse->serio, 'S'); + printk (KERN_NOTICE "%s on %s: Forceing standard packet format, " + "incremental streaming mode and 72 samples/sec\n", + mouse->name, mouse->phys); + mouse->serio->write (mouse->serio, 'S'); /* Standard format */ + mdelay (50); + mouse->serio->write (mouse->serio, 'R'); /* Incremental */ mdelay (50); - mouse->serio->write (mouse->serio, 'R'); + mouse->serio->write (mouse->serio, 'L'); /* 72 samples/sec */ } static void @@ -519,11 +524,12 @@ mouse->dev.private = mouse; serio->private = mouse; - sprintf (mouse->name, "DEC VSXXX-AA/GA mouse or VSXXX-AB digitizer"); + sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer"); sprintf (mouse->phys, "%s/input0", serio->phys); mouse->dev.name = mouse->name; mouse->dev.phys = mouse->phys; mouse->dev.id.bustype = BUS_RS232; + mouse->dev.dev = &serio->dev; mouse->serio = serio; if (serio_open (serio, drv)) { diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c --- a/drivers/input/mousedev.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/mousedev.c 2005-01-02 23:11:39 -08:00 @@ -115,20 +115,26 @@ #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_touchpad_event(struct mousedev *mousedev, unsigned int code, int value) +static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value) { + int size; + if (mousedev->touch) { switch (code) { case ABS_X: + size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; + if (size == 0) size = xres; fx(0) = value; if (mousedev->pkt_count >= 2) - mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8; + mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) * xres / (size * 2); break; case ABS_Y: + size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y]; + if (size == 0) size = yres; fy(0) = value; if (mousedev->pkt_count >= 2) - mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8; + mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) * yres / (size * 2); break; } } @@ -279,7 +285,7 @@ return; if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) - mousedev_touchpad_event(mousedev, code, value); + mousedev_touchpad_event(handle->dev, mousedev, code, value); else mousedev_abs_event(handle->dev, mousedev, code, value); diff -Nru a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig --- a/drivers/input/serio/Kconfig 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/serio/Kconfig 2005-01-02 23:11:39 -08:00 @@ -131,6 +131,16 @@ To compile this driver as a module, choose M here: the module will be called maceps2. +config SERIO_LIBPS2 + tristate "PS/2 driver library" + depends on SERIO + help + Say Y here if you are using a driver for device connected + to a PS/2 port, such as PS/2 mouse or standard AT keyboard. + + To compile this driver as a module, choose M here: the + module will be called libps2. + config SERIO_RAW tristate "Raw access to serio ports" depends on SERIO diff -Nru a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile --- a/drivers/input/serio/Makefile 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/serio/Makefile 2005-01-02 23:11:39 -08:00 @@ -17,4 +17,5 @@ obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o +obj-$(CONFIG_SERIO_LIBPS2) += libps2.o obj-$(CONFIG_SERIO_RAW) += serio_raw.o diff -Nru a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c --- a/drivers/input/serio/gscps2.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/serio/gscps2.c 2005-01-02 23:11:39 -08:00 @@ -322,19 +322,6 @@ gscps2_enable(ps2port, DISABLE); } -static struct serio gscps2_serio_port = -{ - .name = "GSC PS/2", - .idbus = BUS_GSC, - .idvendor = PCI_VENDOR_ID_HP, - .idproduct = 0x0001, - .idversion = 0x0010, - .type = SERIO_8042, - .write = gscps2_write, - .open = gscps2_open, - .close = gscps2_close, -}; - /** * gscps2_probe() - Probes PS2 devices * @return: success/error report diff -Nru a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h --- a/drivers/input/serio/i8042-io.h 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/serio/i8042-io.h 2005-01-02 23:11:39 -08:00 @@ -3,7 +3,7 @@ /* * 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 + * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. */ @@ -22,9 +22,6 @@ #ifdef __alpha__ # define I8042_KBD_IRQ 1 # define I8042_AUX_IRQ (RTC_PORT(0) == 0x170 ? 9 : 12) /* Jensen is special */ -#elif defined(__ia64__) -# define I8042_KBD_IRQ isa_irq_to_vector(1) -# define I8042_AUX_IRQ isa_irq_to_vector(12) #elif defined(__arm__) /* defined in include/asm-arm/arch-xxx/irqs.h */ #include @@ -40,8 +37,8 @@ * Register numbers. */ -#define I8042_COMMAND_REG 0x64 -#define I8042_STATUS_REG 0x64 +#define I8042_COMMAND_REG 0x64 +#define I8042_STATUS_REG 0x64 #define I8042_DATA_REG 0x60 static inline int i8042_read_data(void) @@ -57,59 +54,25 @@ static inline void i8042_write_data(int val) { outb(val, I8042_DATA_REG); - return; } static inline void i8042_write_command(int val) { outb(val, I8042_COMMAND_REG); - return; } -#if defined(__i386__) - -#include - -static struct dmi_system_id __initdata i8042_dmi_table[] = { - { - .ident = "Compaq Proliant 8500", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), - DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), - DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), - }, - }, - { - .ident = "Compaq Proliant DL760", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), - DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), - DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), - }, - }, - { } -}; -#endif - static inline int i8042_platform_init(void) { /* - * On ix86 platforms touching the i8042 data register region can do really - * bad things. Because of this the region is always reserved on ix86 boxes. + * On some platforms touching the i8042 data register region can do really + * bad things. Because of this the region is always reserved on such boxes. */ -#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__) && !defined(__x86_64__) && !defined(__mips__) && !defined (CONFIG_PPC64) +#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC64) if (!request_region(I8042_DATA_REG, 16, "i8042")) return -1; #endif -#if !defined(__i386__) && !defined(__x86_64__) i8042_reset = 1; -#endif - -#if defined(__i386__) - if (dmi_check_system(i8042_dmi_table)) - i8042_noloop = 1; -#endif #if defined(CONFIG_PPC64) if (check_legacy_ioport(I8042_DATA_REG)) @@ -122,7 +85,7 @@ static inline void i8042_platform_exit(void) { -#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__) && !defined(__x86_64__) && !defined(CONFIG_PPC64) +#if !defined(__sh__) && !defined(__alpha__) && !defined(CONFIG_PPC64) release_region(I8042_DATA_REG, 16); #endif } diff -Nru a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/input/serio/i8042-x86ia64io.h 2005-01-02 23:11:39 -08:00 @@ -0,0 +1,308 @@ +#ifndef _I8042_X86IA64IO_H +#define _I8042_X86IA64IO_H + +/* + * 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 + * the Free Software Foundation. + */ + +/* + * Names. + */ + +#define I8042_KBD_PHYS_DESC "isa0060/serio0" +#define I8042_AUX_PHYS_DESC "isa0060/serio1" +#define I8042_MUX_PHYS_DESC "isa0060/serio%d" + +/* + * IRQs. + */ + +#if defined(__ia64__) +# define I8042_MAP_IRQ(x) isa_irq_to_vector((x)) +#else +# define I8042_MAP_IRQ(x) (x) +#endif + +#define I8042_KBD_IRQ i8042_kbd_irq +#define I8042_AUX_IRQ i8042_aux_irq + +static int i8042_kbd_irq; +static int i8042_aux_irq; + +/* + * Register numbers. + */ + +#define I8042_COMMAND_REG i8042_command_reg +#define I8042_STATUS_REG i8042_command_reg +#define I8042_DATA_REG i8042_data_reg + +static int i8042_command_reg = 0x64; +static int i8042_data_reg = 0x60; + + +static inline int i8042_read_data(void) +{ + return inb(I8042_DATA_REG); +} + +static inline int i8042_read_status(void) +{ + return inb(I8042_STATUS_REG); +} + +static inline void i8042_write_data(int val) +{ + outb(val, I8042_DATA_REG); +} + +static inline void i8042_write_command(int val) +{ + outb(val, I8042_COMMAND_REG); +} + +#if defined(__i386__) + +#include + +static struct dmi_system_id __initdata i8042_dmi_table[] = { + { + .ident = "Compaq Proliant 8500", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), + DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), + DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), + }, + }, + { + .ident = "Compaq Proliant DL760", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), + DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), + DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), + }, + }, + { } +}; +#endif + +#ifdef CONFIG_ACPI +#include +#include + +struct i8042_acpi_resources { + unsigned int port1; + unsigned int port2; + unsigned int irq; +}; + +static int i8042_acpi_kbd_registered; +static int i8042_acpi_aux_registered; + +static acpi_status i8042_acpi_parse_resource(struct acpi_resource *res, void *data) +{ + struct i8042_acpi_resources *i8042_res = data; + struct acpi_resource_io *io; + struct acpi_resource_fixed_io *fixed_io; + struct acpi_resource_irq *irq; + struct acpi_resource_ext_irq *ext_irq; + + switch (res->id) { + case ACPI_RSTYPE_IO: + io = &res->data.io; + if (io->range_length) { + if (!i8042_res->port1) + i8042_res->port1 = io->min_base_address; + else + i8042_res->port2 = io->min_base_address; + } + break; + + case ACPI_RSTYPE_FIXED_IO: + fixed_io = &res->data.fixed_io; + if (fixed_io->range_length) { + if (!i8042_res->port1) + i8042_res->port1 = fixed_io->base_address; + else + i8042_res->port2 = fixed_io->base_address; + } + break; + + case ACPI_RSTYPE_IRQ: + irq = &res->data.irq; + if (irq->number_of_interrupts > 0) + i8042_res->irq = + acpi_register_gsi(irq->interrupts[0], + irq->edge_level, + irq->active_high_low); + break; + + case ACPI_RSTYPE_EXT_IRQ: + ext_irq = &res->data.extended_irq; + if (ext_irq->number_of_interrupts > 0) + i8042_res->irq = + acpi_register_gsi(ext_irq->interrupts[0], + ext_irq->edge_level, + ext_irq->active_high_low); + break; + } + return AE_OK; +} + +static int i8042_acpi_kbd_add(struct acpi_device *device) +{ + struct i8042_acpi_resources kbd_res; + acpi_status status; + + memset(&kbd_res, 0, sizeof(kbd_res)); + status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, + i8042_acpi_parse_resource, &kbd_res); + if (ACPI_FAILURE(status)) + return -ENODEV; + + if (kbd_res.port1) + i8042_data_reg = kbd_res.port1; + else + printk(KERN_WARNING "ACPI: [%s] has no data port; default is 0x%x\n", + acpi_device_bid(device), i8042_data_reg); + + if (kbd_res.port2) + i8042_command_reg = kbd_res.port2; + else + printk(KERN_WARNING "ACPI: [%s] has no command port; default is 0x%x\n", + acpi_device_bid(device), i8042_command_reg); + + if (kbd_res.irq) + i8042_kbd_irq = kbd_res.irq; + else + printk(KERN_WARNING "ACPI: [%s] has no IRQ; default is %d\n", + acpi_device_bid(device), i8042_kbd_irq); + + strncpy(acpi_device_name(device), "PS/2 Keyboard Controller", + sizeof(acpi_device_name(device))); + printk("ACPI: %s [%s] at I/O 0x%x, 0x%x, irq %d\n", + acpi_device_name(device), acpi_device_bid(device), + i8042_data_reg, i8042_command_reg, i8042_kbd_irq); + + return 0; +} + +static int i8042_acpi_aux_add(struct acpi_device *device) +{ + struct i8042_acpi_resources aux_res; + acpi_status status; + + memset(&aux_res, 0, sizeof(aux_res)); + status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, + i8042_acpi_parse_resource, &aux_res); + if (ACPI_FAILURE(status)) + return -ENODEV; + + if (aux_res.irq) + i8042_aux_irq = aux_res.irq; + else + printk(KERN_WARNING "ACPI: [%s] has no IRQ; default is %d\n", + acpi_device_bid(device), i8042_aux_irq); + + strncpy(acpi_device_name(device), "PS/2 Mouse Controller", + sizeof(acpi_device_name(device))); + printk("ACPI: %s [%s] at irq %d\n", + acpi_device_name(device), acpi_device_bid(device), i8042_aux_irq); + + return 0; +} + +static struct acpi_driver i8042_acpi_kbd_driver = { + .name = "i8042", + .ids = "PNP0303,PNP030B", + .ops = { + .add = i8042_acpi_kbd_add, + }, +}; + +static struct acpi_driver i8042_acpi_aux_driver = { + .name = "i8042", + .ids = "PNP0F13,SYN0801", + .ops = { + .add = i8042_acpi_aux_add, + }, +}; + +static int i8042_acpi_init(void) +{ + int result; + + if (acpi_disabled || i8042_noacpi) { + printk("i8042: ACPI detection disabled\n"); + return 0; + } + + result = acpi_bus_register_driver(&i8042_acpi_kbd_driver); + if (result < 0) + return result; + + if (result == 0) { + acpi_bus_unregister_driver(&i8042_acpi_kbd_driver); + return -ENODEV; + } + i8042_acpi_kbd_registered = 1; + + result = acpi_bus_register_driver(&i8042_acpi_aux_driver); + if (result >= 0) + i8042_acpi_aux_registered = 1; + if (result == 0) + i8042_noaux = 1; + + return 0; +} + +static void i8042_acpi_exit(void) +{ + if (i8042_acpi_kbd_registered) + acpi_bus_unregister_driver(&i8042_acpi_kbd_driver); + + if (i8042_acpi_aux_registered) + acpi_bus_unregister_driver(&i8042_acpi_aux_driver); +} +#endif + +static inline int i8042_platform_init(void) +{ +/* + * On ix86 platforms touching the i8042 data register region can do really + * bad things. Because of this the region is always reserved on ix86 boxes. + * + * if (!request_region(I8042_DATA_REG, 16, "i8042")) + * return -1; + */ + + i8042_kbd_irq = I8042_MAP_IRQ(1); + i8042_aux_irq = I8042_MAP_IRQ(12); + +#ifdef CONFIG_ACPI + if (i8042_acpi_init()) + return -1; +#endif + +#if defined(__ia64__) + i8042_reset = 1; +#endif + +#if defined(__i386__) + if (dmi_check_system(i8042_dmi_table)) + i8042_noloop = 1; +#endif + + return 0; +} + +static inline void i8042_platform_exit(void) +{ +#ifdef CONFIG_ACPI + i8042_acpi_exit(); +#endif +} + +#endif /* _I8042_X86IA64IO_H */ diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c --- a/drivers/input/serio/i8042.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/serio/i8042.c 2005-01-02 23:11:39 -08:00 @@ -16,10 +16,7 @@ #include #include #include -#include #include -#include -#include #include #include @@ -57,6 +54,19 @@ module_param_named(noloop, i8042_noloop, bool, 0); MODULE_PARM_DESC(dumbkbd, "Disable the AUX Loopback command while probing for the AUX port"); +#ifdef CONFIG_ACPI +static int i8042_noacpi; +module_param_named(noacpi, i8042_noacpi, bool, 0); +MODULE_PARM_DESC(noacpi, "Do not use ACPI to detect controller settings"); +#endif + +#define DEBUG +#ifdef DEBUG +static int i8042_debug; +module_param_named(debug, i8042_debug, bool, 600); +MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off"); +#endif + __obsolete_setup("i8042_noaux"); __obsolete_setup("i8042_nomux"); __obsolete_setup("i8042_unlock"); @@ -64,7 +74,6 @@ __obsolete_setup("i8042_direct"); __obsolete_setup("i8042_dumbkbd"); -#undef DEBUG #include "i8042.h" spinlock_t i8042_lock = SPIN_LOCK_UNLOCKED; @@ -101,7 +110,6 @@ static unsigned char i8042_ctr; static unsigned char i8042_mux_open; static unsigned char i8042_mux_present; -static struct pm_dev *i8042_pm_dev; static struct timer_list i8042_timer; static struct platform_device *i8042_platform_device; @@ -852,10 +860,12 @@ * Here we try to restore the original BIOS settings */ -static int i8042_controller_suspend(void) +static int i8042_suspend(struct device *dev, u32 state, u32 level) { - del_timer_sync(&i8042_timer); - i8042_controller_reset(); + if (level == SUSPEND_DISABLE) { + del_timer_sync(&i8042_timer); + i8042_controller_reset(); + } return 0; } @@ -865,10 +875,13 @@ * Here we try to reset everything back to a state in which suspended */ -static int i8042_controller_resume(void) +static int i8042_resume(struct device *dev, u32 level) { int i; + if (level != RESUME_ENABLE) + return 0; + if (i8042_controller_init()) { printk(KERN_ERR "i8042: resume failed\n"); return -1; @@ -901,42 +914,14 @@ panic_blink = i8042_panic_blink; return 0; -} +} /* * We need to reset the 8042 back to original mode on system shutdown, * because otherwise BIOSes will be confused. */ -static int i8042_notify_sys(struct notifier_block *this, unsigned long code, - void *unused) -{ - if (code == SYS_DOWN || code == SYS_HALT) - i8042_controller_cleanup(); - return NOTIFY_DONE; -} - -static struct notifier_block i8042_notifier = -{ - i8042_notify_sys, - NULL, - 0 -}; - -/* - * Suspend/resume handlers for the new PM scheme (driver model) - */ -static int i8042_suspend(struct device *dev, u32 state, u32 level) -{ - return level == SUSPEND_DISABLE ? i8042_controller_suspend() : 0; -} - -static int i8042_resume(struct device *dev, u32 level) -{ - return level == RESUME_ENABLE ? i8042_controller_resume() : 0; -} - static void i8042_shutdown(struct device *dev) { i8042_controller_cleanup(); @@ -950,22 +935,6 @@ .shutdown = i8042_shutdown, }; -/* - * Suspend/resume handler for the old PM scheme (APM) - */ -static int i8042_pm_callback(struct pm_dev *dev, pm_request_t request, void *dummy) -{ - switch (request) { - case PM_SUSPEND: - return i8042_controller_suspend(); - - case PM_RESUME: - return i8042_controller_resume(); - } - - return 0; -} - static struct serio * __init i8042_allocate_kbd_port(void) { struct serio *serio; @@ -1080,21 +1049,12 @@ mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD); - i8042_pm_dev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, i8042_pm_callback); - - register_reboot_notifier(&i8042_notifier); - return 0; } void __exit i8042_exit(void) { int i; - - unregister_reboot_notifier(&i8042_notifier); - - if (i8042_pm_dev) - pm_unregister(i8042_pm_dev); i8042_controller_cleanup(); diff -Nru a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h --- a/drivers/input/serio/i8042.h 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/serio/i8042.h 2005-01-02 23:11:39 -08:00 @@ -23,6 +23,8 @@ #include "i8042-ppcio.h" #elif defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) #include "i8042-sparcio.h" +#elif defined(CONFIG_X86) || defined(CONFIG_IA64) +#include "i8042-x86ia64io.h" #else #include "i8042-io.h" #endif @@ -117,8 +119,12 @@ #ifdef DEBUG static unsigned long i8042_start; #define dbg_init() do { i8042_start = jiffies; } while (0) -#define dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" ,\ - ## arg, (int) (jiffies - i8042_start)) +#define dbg(format, arg...) \ + do { \ + if (i8042_debug) \ + printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" , \ + ## arg, (int) (jiffies - i8042_start)); \ + } while (0) #else #define dbg_init() do { } while (0) #define dbg(format, arg...) do {} while (0) diff -Nru a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/input/serio/libps2.c 2005-01-02 23:11:39 -08:00 @@ -0,0 +1,295 @@ +/* + * PS/2 driver library + * + * 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 + * the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_DESC "PS/2 driver library" + +MODULE_AUTHOR("Dmitry Torokhov "); +MODULE_DESCRIPTION("PS/2 driver library"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(ps2_init); +EXPORT_SYMBOL(ps2_sendbyte); +EXPORT_SYMBOL(ps2_command); +EXPORT_SYMBOL(ps2_schedule_command); +EXPORT_SYMBOL(ps2_handle_ack); +EXPORT_SYMBOL(ps2_handle_response); +EXPORT_SYMBOL(ps2_cmd_aborted); + +/* Work structure to schedule execution of a command */ +struct ps2work { + struct work_struct work; + struct ps2dev *ps2dev; + int command; + unsigned char param[0]; +}; + + +/* + * ps2_sendbyte() sends a byte to the mouse, and waits for acknowledge. + * It doesn't handle retransmission, though it could - because when there would + * be need for retransmissions, the mouse has to be replaced anyway. + * + * ps2_sendbyte() can only be called from a process context + */ + +int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) +{ + serio_pause_rx(ps2dev->serio); + ps2dev->nak = 1; + ps2dev->flags |= PS2_FLAG_ACK; + serio_continue_rx(ps2dev->serio); + + if (serio_write(ps2dev->serio, byte) == 0) + wait_event_interruptible_timeout(ps2dev->wait, + !(ps2dev->flags & PS2_FLAG_ACK), + msecs_to_jiffies(timeout)); + + serio_pause_rx(ps2dev->serio); + ps2dev->flags &= ~PS2_FLAG_ACK; + serio_continue_rx(ps2dev->serio); + + return -ps2dev->nak; +} + +/* + * ps2_command() sends a command and its parameters to the mouse, + * then waits for the response and puts it in the param array. + * + * ps2_command() can only be called from a process context + */ + +int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) +{ + int timeout; + int send = (command >> 12) & 0xf; + int receive = (command >> 8) & 0xf; + int rc = -1; + int i; + + down(&ps2dev->cmd_sem); + + serio_pause_rx(ps2dev->serio); + ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; + ps2dev->cmdcnt = receive; + if (receive && param) + for (i = 0; i < receive; i++) + ps2dev->cmdbuf[(receive - 1) - i] = param[i]; + serio_continue_rx(ps2dev->serio); + + /* + * Some devices (Synaptics) peform the reset before + * ACKing the reset command, and so it can take a long + * time before the ACK arrrives. + */ + if (command & 0xff) + if (ps2_sendbyte(ps2dev, command & 0xff, + command == PS2_CMD_RESET_BAT ? 1000 : 200)) + goto out; + + for (i = 0; i < send; i++) + if (ps2_sendbyte(ps2dev, param[i], 200)) + goto out; + + /* + * The reset command takes a long time to execute. + */ + timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500); + + wait_event_interruptible_timeout(ps2dev->wait, + !(ps2dev->flags & PS2_FLAG_CMD1), timeout); + + if (ps2dev->cmdcnt && timeout > 0) { + + if (command == PS2_CMD_RESET_BAT && timeout > msecs_to_jiffies(100)) { + /* + * Device has sent the first response byte + * after a reset command, reset is thus done, + * shorten the timeout. The next byte will come + * soon (keyboard) or not at all (mouse). + */ + timeout = msecs_to_jiffies(100); + } + + if (command == PS2_CMD_GETID && + ps2dev->cmdbuf[receive - 1] != 0xab && /* Regular keyboards */ + ps2dev->cmdbuf[receive - 1] != 0xac && /* NCD Sun keyboard */ + ps2dev->cmdbuf[receive - 1] != 0x2b && /* Trust keyboard, translated */ + ps2dev->cmdbuf[receive - 1] != 0x5d && /* Trust keyboard */ + ps2dev->cmdbuf[receive - 1] != 0x60 && /* NMB SGI keyboard, translated */ + ps2dev->cmdbuf[receive - 1] != 0x47) { /* NMB SGI keyboard */ + /* + * Device behind the port is not a keyboard + * so we don't need to wait for the 2nd byte + * of ID response. + */ + serio_pause_rx(ps2dev->serio); + ps2dev->flags = ps2dev->cmdcnt = 0; + serio_continue_rx(ps2dev->serio); + } + + wait_event_interruptible_timeout(ps2dev->wait, + !(ps2dev->flags & PS2_FLAG_CMD), timeout); + } + + if (param) + for (i = 0; i < receive; i++) + param[i] = ps2dev->cmdbuf[(receive - 1) - i]; + + if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) + goto out; + + rc = 0; + +out: + serio_pause_rx(ps2dev->serio); + ps2dev->flags = 0; + serio_continue_rx(ps2dev->serio); + + up(&ps2dev->cmd_sem); + return rc; +} + +/* + * ps2_execute_scheduled_command() sends a command, previously scheduled by + * ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.) + */ + +static void ps2_execute_scheduled_command(void *data) +{ + struct ps2work *ps2work = data; + + ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command); + kfree(ps2work); +} + +/* + * ps2_schedule_command() allows to schedule delayed execution of a PS/2 + * command and can be used to issue a command from an interrupt or softirq + * context. + */ + +int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command) +{ + struct ps2work *ps2work; + int send = (command >> 12) & 0xf; + int receive = (command >> 8) & 0xf; + + if (!(ps2work = kmalloc(sizeof(struct ps2work) + max(send, receive), GFP_ATOMIC))) + return -1; + + memset(ps2work, 0, sizeof(struct ps2work)); + ps2work->ps2dev = ps2dev; + ps2work->command = command; + memcpy(ps2work->param, param, send); + INIT_WORK(&ps2work->work, ps2_execute_scheduled_command, ps2work); + + if (!schedule_work(&ps2work->work)) { + kfree(ps2work); + return -1; + } + + return 0; +} + +/* + * ps2_init() initializes ps2dev structure + */ + +void ps2_init(struct ps2dev *ps2dev, struct serio *serio) +{ + init_MUTEX(&ps2dev->cmd_sem); + init_waitqueue_head(&ps2dev->wait); + ps2dev->serio = serio; +} + +/* + * ps2_handle_ack() + */ + +int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data) +{ + switch (data) { + case PS2_RET_ACK: + ps2dev->nak = 0; + break; + + case PS2_RET_NAK: + ps2dev->nak = 1; + break; + + /* + * Workaround for mice which don't ACK the Get ID command. + * These are valid mouse IDs that we recognize. + */ + case 0x00: + case 0x03: + case 0x04: + if (ps2dev->flags & PS2_FLAG_WAITID) { + ps2dev->nak = 0; + break; + } + /* Fall through */ + default: + return 1; + } + + if (!ps2dev->nak && ps2dev->cmdcnt) + ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1; + + ps2dev->flags &= ~PS2_FLAG_ACK; + wake_up_interruptible(&ps2dev->wait); + + return data == PS2_RET_ACK || data == PS2_RET_NAK; +} + + +int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data) +{ + if (ps2dev->cmdcnt) + ps2dev->cmdbuf[--ps2dev->cmdcnt] = data; + + if (ps2dev->flags & PS2_FLAG_CMD1) { + ps2dev->flags &= ~PS2_FLAG_CMD1; + if (ps2dev->cmdcnt) + wake_up_interruptible(&ps2dev->wait); + } + + if (!ps2dev->cmdcnt) { + ps2dev->flags &= ~PS2_FLAG_CMD; + wake_up_interruptible(&ps2dev->wait); + } + + return 1; +} + +void ps2_cmd_aborted(struct ps2dev *ps2dev) +{ + if (ps2dev->flags & PS2_FLAG_ACK) + ps2dev->nak = 1; + + if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD)) + wake_up_interruptible(&ps2dev->wait); + + ps2dev->flags = 0; +} + diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c --- a/drivers/input/serio/parkbd.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/serio/parkbd.c 2005-01-02 23:11:39 -08:00 @@ -37,15 +37,17 @@ MODULE_DESCRIPTION("Parallel port to Keyboard port adapter driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(parkbd, "1i"); -MODULE_PARM(parkbd_mode, "1i"); +static unsigned int parkbd_pp_no; +module_param_named(port, parkbd_pp_no, int, 0); +MODULE_PARM_DESC(port, "Parallel port the adapter is connected to (default is 0)"); + +static unsigned int parkbd_mode = SERIO_8042; +module_param_named(mode, parkbd_mode, uint, 0); +MODULE_PARM_DESC(mode, "Mode of operation: XT = 0/AT = 1 (default)"); #define PARKBD_CLOCK 0x01 /* Strobe & Ack */ #define PARKBD_DATA 0x02 /* AutoFd & Busy */ -static int parkbd; -static int parkbd_mode = SERIO_8042; - static int parkbd_buffer; static int parkbd_counter; static unsigned long parkbd_last; @@ -126,12 +128,7 @@ { struct parport *pp; - if (parkbd < 0) { - printk(KERN_ERR "parkbd: no port specified\n"); - return -ENODEV; - } - - pp = parport_find_number(parkbd); + pp = parport_find_number(parkbd_pp_no); if (pp == NULL) { printk(KERN_ERR "parkbd: no such parport\n"); diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c --- a/drivers/input/serio/serio.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/serio/serio.c 2005-01-02 23:11:39 -08:00 @@ -321,6 +321,7 @@ try_module_get(THIS_MODULE); spin_lock_init(&serio->lock); + init_MUTEX(&serio->drv_sem); list_add_tail(&serio->node, &serio_list); snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), "serio%d", serio_no++); serio->dev.bus = &serio_bus; @@ -590,17 +591,22 @@ up(&serio_sem); } -/* called from serio_driver->connect/disconnect methods under serio_sem */ -int serio_open(struct serio *serio, struct serio_driver *drv) +static void serio_set_drv(struct serio *serio, struct serio_driver *drv) { + down(&serio->drv_sem); serio_pause_rx(serio); serio->drv = drv; serio_continue_rx(serio); + up(&serio->drv_sem); +} + +/* called from serio_driver->connect/disconnect methods under serio_sem */ +int serio_open(struct serio *serio, struct serio_driver *drv) +{ + serio_set_drv(serio, drv); if (serio->open && serio->open(serio)) { - serio_pause_rx(serio); - serio->drv = NULL; - serio_continue_rx(serio); + serio_set_drv(serio, NULL); return -1; } return 0; @@ -612,9 +618,7 @@ if (serio->close) serio->close(serio); - serio_pause_rx(serio); - serio->drv = NULL; - serio_continue_rx(serio); + serio_set_drv(serio, NULL); } irqreturn_t serio_interrupt(struct serio *serio, 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 2005-01-02 23:11:39 -08:00 +++ b/drivers/input/touchscreen/h3600_ts_input.c 2005-01-02 23:11:39 -08:00 @@ -100,6 +100,7 @@ */ struct h3600_dev { struct input_dev dev; + struct pm_dev *pm_dev; struct serio *serio; unsigned char event; /* event ID from packet */ unsigned char chksum; @@ -452,8 +453,8 @@ //h3600_flite_control(1, 25); /* default brightness */ #ifdef CONFIG_PM - ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT, - h3600ts_pm_callback); + ts->pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT, + h3600ts_pm_callback); printk("registered pm callback\n"); #endif input_register_device(&ts->dev); diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c --- a/drivers/usb/input/hid-core.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/usb/input/hid-core.c 2005-01-02 23:11:39 -08:00 @@ -1281,9 +1281,14 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char type, void *buf, int size) { - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8), ifnum, buf, size, HZ * USB_CTRL_GET_TIMEOUT); + int result, retries = 4; + do { + result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, + (type << 8), ifnum, buf, size, HZ * USB_CTRL_GET_TIMEOUT); + retries--; + } while (result < 0 && retries); + return result; } int hid_open(struct hid_device *hid) @@ -1314,7 +1319,7 @@ struct hid_report_enum *report_enum; struct hid_report *report; struct list_head *list; - int err, ret; + int err, ret, size; /* * The Set_Idle request is supposed to affect only the @@ -1337,6 +1342,10 @@ list = report_enum->report_list.next; while (list != &report_enum->report_list) { report = (struct hid_report *) list; + size = ((report->size - 1) >> 3) + 1 + report_enum->numbered; + if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE; + if (size > hid->urbin->transfer_buffer_length) + hid->urbin->transfer_buffer_length = size; hid_submit_report(hid, report, USB_DIR_IN); list = list->next; } @@ -1460,11 +1469,11 @@ #define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 #define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 -#define USB_VENDOR_ID_CODEMERCS 0x07c0 -#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 -#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 -#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502 -#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503 +#define USB_VENDOR_ID_CODEMERCS 0x07c0 +#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500 +#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501 +#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502 +#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503 #define USB_VENDOR_ID_DELORME 0x1163 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 @@ -1485,8 +1494,16 @@ { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, @@ -1522,15 +1539,9 @@ { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, - - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, @@ -1539,8 +1550,8 @@ { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_BACK }, - { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA }, + { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, + { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, @@ -1669,17 +1680,12 @@ interval = 1 << (interval - 1); if (endpoint->bEndpointAddress & USB_DIR_IN) { - int len; - if (hid->urbin) continue; if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) goto fail; pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - len = usb_maxpacket(dev, pipe, 0); - if (len > HID_BUFFER_SIZE) - len = HID_BUFFER_SIZE; - usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, len, + usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0, hid_irq_in, hid, interval); hid->urbin->transfer_dma = hid->inbuf_dma; hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); diff -Nru a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h --- a/drivers/usb/input/hid-debug.h 2005-01-02 23:11:39 -08:00 +++ b/drivers/usb/input/hid-debug.h 2005-01-02 23:11:39 -08:00 @@ -27,6 +27,8 @@ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ +#include + struct hid_usage_entry { unsigned page; unsigned usage; @@ -323,7 +325,7 @@ printk("."); for (p = hid_usage_table; p->description; p++) if (p->page == (usage >> 16)) { - for(++p; p->description && p->page != 0; p++) + for(++p; p->description && p->usage != 0; p++) if (p->usage == (usage & 0xffff)) { printk("%s", p->description); return; @@ -461,4 +463,264 @@ printk("hid-debug: input "); resolv_usage(usage->hid); printk(" = %d\n", value); +} + + +static char *events[EV_MAX + 1] = { + [0 ... EV_MAX] = NULL, + [EV_SYN] = "Sync", [EV_KEY] = "Key", + [EV_REL] = "Relative", [EV_ABS] = "Absolute", + [EV_MSC] = "Misc", [EV_LED] = "LED", + [EV_SND] = "Sound", [EV_REP] = "Repeat", + [EV_FF] = "ForceFeedback", [EV_PWR] = "Power", + [EV_FF_STATUS] = "ForceFeedbackStatus", +}; + +static char *syncs[2] = { + [0 ... 1] = NULL, + [SYN_REPORT] = "Report", [SYN_CONFIG] = "Config", +}; +static char *keys[KEY_MAX + 1] = { + [0 ... KEY_MAX] = NULL, + [KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc", + [KEY_1] = "1", [KEY_2] = "2", + [KEY_3] = "3", [KEY_4] = "4", + [KEY_5] = "5", [KEY_6] = "6", + [KEY_7] = "7", [KEY_8] = "8", + [KEY_9] = "9", [KEY_0] = "0", + [KEY_MINUS] = "Minus", [KEY_EQUAL] = "Equal", + [KEY_BACKSPACE] = "Backspace", [KEY_TAB] = "Tab", + [KEY_Q] = "Q", [KEY_W] = "W", + [KEY_E] = "E", [KEY_R] = "R", + [KEY_T] = "T", [KEY_Y] = "Y", + [KEY_U] = "U", [KEY_I] = "I", + [KEY_O] = "O", [KEY_P] = "P", + [KEY_LEFTBRACE] = "LeftBrace", [KEY_RIGHTBRACE] = "RightBrace", + [KEY_ENTER] = "Enter", [KEY_LEFTCTRL] = "LeftControl", + [KEY_A] = "A", [KEY_S] = "S", + [KEY_D] = "D", [KEY_F] = "F", + [KEY_G] = "G", [KEY_H] = "H", + [KEY_J] = "J", [KEY_K] = "K", + [KEY_L] = "L", [KEY_SEMICOLON] = "Semicolon", + [KEY_APOSTROPHE] = "Apostrophe", [KEY_GRAVE] = "Grave", + [KEY_LEFTSHIFT] = "LeftShift", [KEY_BACKSLASH] = "BackSlash", + [KEY_Z] = "Z", [KEY_X] = "X", + [KEY_C] = "C", [KEY_V] = "V", + [KEY_B] = "B", [KEY_N] = "N", + [KEY_M] = "M", [KEY_COMMA] = "Comma", + [KEY_DOT] = "Dot", [KEY_SLASH] = "Slash", + [KEY_RIGHTSHIFT] = "RightShift", [KEY_KPASTERISK] = "KPAsterisk", + [KEY_LEFTALT] = "LeftAlt", [KEY_SPACE] = "Space", + [KEY_CAPSLOCK] = "CapsLock", [KEY_F1] = "F1", + [KEY_F2] = "F2", [KEY_F3] = "F3", + [KEY_F4] = "F4", [KEY_F5] = "F5", + [KEY_F6] = "F6", [KEY_F7] = "F7", + [KEY_F8] = "F8", [KEY_F9] = "F9", + [KEY_F10] = "F10", [KEY_NUMLOCK] = "NumLock", + [KEY_SCROLLLOCK] = "ScrollLock", [KEY_KP7] = "KP7", + [KEY_KP8] = "KP8", [KEY_KP9] = "KP9", + [KEY_KPMINUS] = "KPMinus", [KEY_KP4] = "KP4", + [KEY_KP5] = "KP5", [KEY_KP6] = "KP6", + [KEY_KPPLUS] = "KPPlus", [KEY_KP1] = "KP1", + [KEY_KP2] = "KP2", [KEY_KP3] = "KP3", + [KEY_KP0] = "KP0", [KEY_KPDOT] = "KPDot", + [KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd", + [KEY_F11] = "F11", [KEY_F12] = "F12", + [KEY_RO] = "RO", [KEY_KATAKANA] = "Katakana", + [KEY_HIRAGANA] = "HIRAGANA", [KEY_HENKAN] = "Henkan", + [KEY_KATAKANAHIRAGANA] = "Katakana/Hiragana", [KEY_MUHENKAN] = "Muhenkan", + [KEY_KPJPCOMMA] = "KPJpComma", [KEY_KPENTER] = "KPEnter", + [KEY_RIGHTCTRL] = "RightCtrl", [KEY_KPSLASH] = "KPSlash", + [KEY_SYSRQ] = "SysRq", [KEY_RIGHTALT] = "RightAlt", + [KEY_LINEFEED] = "LineFeed", [KEY_HOME] = "Home", + [KEY_UP] = "Up", [KEY_PAGEUP] = "PageUp", + [KEY_LEFT] = "Left", [KEY_RIGHT] = "Right", + [KEY_END] = "End", [KEY_DOWN] = "Down", + [KEY_PAGEDOWN] = "PageDown", [KEY_INSERT] = "Insert", + [KEY_DELETE] = "Delete", [KEY_MACRO] = "Macro", + [KEY_MUTE] = "Mute", [KEY_VOLUMEDOWN] = "VolumeDown", + [KEY_VOLUMEUP] = "VolumeUp", [KEY_POWER] = "Power", + [KEY_KPEQUAL] = "KPEqual", [KEY_KPPLUSMINUS] = "KPPlusMinus", + [KEY_PAUSE] = "Pause", [KEY_KPCOMMA] = "KPComma", + [KEY_HANGUEL] = "Hanguel", [KEY_HANJA] = "Hanja", + [KEY_YEN] = "Yen", [KEY_LEFTMETA] = "LeftMeta", + [KEY_RIGHTMETA] = "RightMeta", [KEY_COMPOSE] = "Compose", + [KEY_STOP] = "Stop", [KEY_AGAIN] = "Again", + [KEY_PROPS] = "Props", [KEY_UNDO] = "Undo", + [KEY_FRONT] = "Front", [KEY_COPY] = "Copy", + [KEY_OPEN] = "Open", [KEY_PASTE] = "Paste", + [KEY_FIND] = "Find", [KEY_CUT] = "Cut", + [KEY_HELP] = "Help", [KEY_MENU] = "Menu", + [KEY_CALC] = "Calc", [KEY_SETUP] = "Setup", + [KEY_SLEEP] = "Sleep", [KEY_WAKEUP] = "WakeUp", + [KEY_FILE] = "File", [KEY_SENDFILE] = "SendFile", + [KEY_DELETEFILE] = "DeleteFile", [KEY_XFER] = "X-fer", + [KEY_PROG1] = "Prog1", [KEY_PROG2] = "Prog2", + [KEY_WWW] = "WWW", [KEY_MSDOS] = "MSDOS", + [KEY_COFFEE] = "Coffee", [KEY_DIRECTION] = "Direction", + [KEY_CYCLEWINDOWS] = "CycleWindows", [KEY_MAIL] = "Mail", + [KEY_BOOKMARKS] = "Bookmarks", [KEY_COMPUTER] = "Computer", + [KEY_BACK] = "Back", [KEY_FORWARD] = "Forward", + [KEY_CLOSECD] = "CloseCD", [KEY_EJECTCD] = "EjectCD", + [KEY_EJECTCLOSECD] = "EjectCloseCD", [KEY_NEXTSONG] = "NextSong", + [KEY_PLAYPAUSE] = "PlayPause", [KEY_PREVIOUSSONG] = "PreviousSong", + [KEY_STOPCD] = "StopCD", [KEY_RECORD] = "Record", + [KEY_REWIND] = "Rewind", [KEY_PHONE] = "Phone", + [KEY_ISO] = "ISOKey", [KEY_CONFIG] = "Config", + [KEY_HOMEPAGE] = "HomePage", [KEY_REFRESH] = "Refresh", + [KEY_EXIT] = "Exit", [KEY_MOVE] = "Move", + [KEY_EDIT] = "Edit", [KEY_SCROLLUP] = "ScrollUp", + [KEY_SCROLLDOWN] = "ScrollDown", [KEY_KPLEFTPAREN] = "KPLeftParenthesis", + [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_F13] = "F13", + [KEY_F14] = "F14", [KEY_F15] = "F15", + [KEY_F16] = "F16", [KEY_F17] = "F17", + [KEY_F18] = "F18", [KEY_F19] = "F19", + [KEY_F20] = "F20", [KEY_F21] = "F21", + [KEY_F22] = "F22", [KEY_F23] = "F23", + [KEY_F24] = "F24", [KEY_PLAYCD] = "PlayCD", + [KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3", + [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend", + [KEY_CLOSE] = "Close", [KEY_PLAY] = "Play", + [KEY_FASTFORWARD] = "Fast Forward", [KEY_BASSBOOST] = "Bass Boost", + [KEY_PRINT] = "Print", [KEY_HP] = "HP", + [KEY_CAMERA] = "Camera", [KEY_SOUND] = "Sound", + [KEY_QUESTION] = "Question", [KEY_EMAIL] = "Email", + [KEY_CHAT] = "Chat", [KEY_SEARCH] = "Search", + [KEY_CONNECT] = "Connect", [KEY_FINANCE] = "Finance", + [KEY_SPORT] = "Sport", [KEY_SHOP] = "Shop", + [KEY_ALTERASE] = "Alternate Erase", [KEY_CANCEL] = "Cancel", + [KEY_BRIGHTNESSDOWN] = "Brightness down", [KEY_BRIGHTNESSUP] = "Brightness up", + [KEY_MEDIA] = "Media", [KEY_UNKNOWN] = "Unknown", + [BTN_0] = "Btn0", [BTN_1] = "Btn1", + [BTN_2] = "Btn2", [BTN_3] = "Btn3", + [BTN_4] = "Btn4", [BTN_5] = "Btn5", + [BTN_6] = "Btn6", [BTN_7] = "Btn7", + [BTN_8] = "Btn8", [BTN_9] = "Btn9", + [BTN_LEFT] = "LeftBtn", [BTN_RIGHT] = "RightBtn", + [BTN_MIDDLE] = "MiddleBtn", [BTN_SIDE] = "SideBtn", + [BTN_EXTRA] = "ExtraBtn", [BTN_FORWARD] = "ForwardBtn", + [BTN_BACK] = "BackBtn", [BTN_TASK] = "TaskBtn", + [BTN_TRIGGER] = "Trigger", [BTN_THUMB] = "ThumbBtn", + [BTN_THUMB2] = "ThumbBtn2", [BTN_TOP] = "TopBtn", + [BTN_TOP2] = "TopBtn2", [BTN_PINKIE] = "PinkieBtn", + [BTN_BASE] = "BaseBtn", [BTN_BASE2] = "BaseBtn2", + [BTN_BASE3] = "BaseBtn3", [BTN_BASE4] = "BaseBtn4", + [BTN_BASE5] = "BaseBtn5", [BTN_BASE6] = "BaseBtn6", + [BTN_DEAD] = "BtnDead", [BTN_A] = "BtnA", + [BTN_B] = "BtnB", [BTN_C] = "BtnC", + [BTN_X] = "BtnX", [BTN_Y] = "BtnY", + [BTN_Z] = "BtnZ", [BTN_TL] = "BtnTL", + [BTN_TR] = "BtnTR", [BTN_TL2] = "BtnTL2", + [BTN_TR2] = "BtnTR2", [BTN_SELECT] = "BtnSelect", + [BTN_START] = "BtnStart", [BTN_MODE] = "BtnMode", + [BTN_THUMBL] = "BtnThumbL", [BTN_THUMBR] = "BtnThumbR", + [BTN_TOOL_PEN] = "ToolPen", [BTN_TOOL_RUBBER] = "ToolRubber", + [BTN_TOOL_BRUSH] = "ToolBrush", [BTN_TOOL_PENCIL] = "ToolPencil", + [BTN_TOOL_AIRBRUSH] = "ToolAirbrush", [BTN_TOOL_FINGER] = "ToolFinger", + [BTN_TOOL_MOUSE] = "ToolMouse", [BTN_TOOL_LENS] = "ToolLens", + [BTN_TOUCH] = "Touch", [BTN_STYLUS] = "Stylus", + [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "Tool Doubletap", + [BTN_TOOL_TRIPLETAP] = "Tool Tripletap", [BTN_GEAR_DOWN] = "WheelBtn", + [BTN_GEAR_UP] = "Gear up", [KEY_OK] = "Ok", + [KEY_SELECT] = "Select", [KEY_GOTO] = "Goto", + [KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2", + [KEY_OPTION] = "Option", [KEY_INFO] = "Info", + [KEY_TIME] = "Time", [KEY_VENDOR] = "Vendor", + [KEY_ARCHIVE] = "Archive", [KEY_PROGRAM] = "Program", + [KEY_CHANNEL] = "Channel", [KEY_FAVORITES] = "Favorites", + [KEY_EPG] = "EPG", [KEY_PVR] = "PVR", + [KEY_MHP] = "MHP", [KEY_LANGUAGE] = "Language", + [KEY_TITLE] = "Title", [KEY_SUBTITLE] = "Subtitle", + [KEY_ANGLE] = "Angle", [KEY_ZOOM] = "Zoom", + [KEY_MODE] = "Mode", [KEY_KEYBOARD] = "Keyboard", + [KEY_SCREEN] = "Screen", [KEY_PC] = "PC", + [KEY_TV] = "TV", [KEY_TV2] = "TV2", + [KEY_VCR] = "VCR", [KEY_VCR2] = "VCR2", + [KEY_SAT] = "Sat", [KEY_SAT2] = "Sat2", + [KEY_CD] = "CD", [KEY_TAPE] = "Tape", + [KEY_RADIO] = "Radio", [KEY_TUNER] = "Tuner", + [KEY_PLAYER] = "Player", [KEY_TEXT] = "Text", + [KEY_DVD] = "DVD", [KEY_AUX] = "Aux", + [KEY_MP3] = "MP3", [KEY_AUDIO] = "Audio", + [KEY_VIDEO] = "Video", [KEY_DIRECTORY] = "Directory", + [KEY_LIST] = "List", [KEY_MEMO] = "Memo", + [KEY_CALENDAR] = "Calendar", [KEY_RED] = "Red", + [KEY_GREEN] = "Green", [KEY_YELLOW] = "Yellow", + [KEY_BLUE] = "Blue", [KEY_CHANNELUP] = "ChannelUp", + [KEY_CHANNELDOWN] = "ChannelDown", [KEY_FIRST] = "First", + [KEY_LAST] = "Last", [KEY_AB] = "AB", + [KEY_NEXT] = "Next", [KEY_RESTART] = "Restart", + [KEY_SLOW] = "Slow", [KEY_SHUFFLE] = "Shuffle", + [KEY_BREAK] = "Break", [KEY_PREVIOUS] = "Previous", + [KEY_DIGITS] = "Digits", [KEY_TEEN] = "TEEN", + [KEY_TWEN] = "TWEN", [KEY_DEL_EOL] = "Delete EOL", + [KEY_DEL_EOS] = "Delete EOS", [KEY_INS_LINE] = "Insert line", + [KEY_DEL_LINE] = "Delete line", +}; + +static char *absval[5] = { "Value", "Min ", "Max ", "Fuzz ", "Flat " }; + +static char *relatives[REL_MAX + 1] = { + [0 ... REL_MAX] = NULL, + [REL_X] = "X", [REL_Y] = "Y", + [REL_Z] = "Z", [REL_HWHEEL] = "HWheel", + [REL_DIAL] = "Dial", [REL_WHEEL] = "Wheel", + [REL_MISC] = "Misc", +}; + +static char *absolutes[ABS_MAX + 1] = { + [0 ... ABS_MAX] = NULL, + [ABS_X] = "X", [ABS_Y] = "Y", + [ABS_Z] = "Z", [ABS_RX] = "Rx", + [ABS_RY] = "Ry", [ABS_RZ] = "Rz", + [ABS_THROTTLE] = "Throttle", [ABS_RUDDER] = "Rudder", + [ABS_WHEEL] = "Wheel", [ABS_GAS] = "Gas", + [ABS_BRAKE] = "Brake", [ABS_HAT0X] = "Hat0X", + [ABS_HAT0Y] = "Hat0Y", [ABS_HAT1X] = "Hat1X", + [ABS_HAT1Y] = "Hat1Y", [ABS_HAT2X] = "Hat2X", + [ABS_HAT2Y] = "Hat2Y", [ABS_HAT3X] = "Hat3X", + [ABS_HAT3Y] = "Hat 3Y", [ABS_PRESSURE] = "Pressure", + [ABS_DISTANCE] = "Distance", [ABS_TILT_X] = "XTilt", + [ABS_TILT_Y] = "YTilt", [ABS_TOOL_WIDTH] = "Tool Width", + [ABS_VOLUME] = "Volume", [ABS_MISC] = "Misc", +}; + +static char *misc[MSC_MAX + 1] = { + [ 0 ... MSC_MAX] = NULL, + [MSC_SERIAL] = "Serial", [MSC_PULSELED] = "Pulseled", + [MSC_GESTURE] = "Gesture", [MSC_RAW] = "RawData" +}; + +static char *leds[LED_MAX + 1] = { + [0 ... LED_MAX] = NULL, + [LED_NUML] = "NumLock", [LED_CAPSL] = "CapsLock", + [LED_SCROLLL] = "ScrollLock", [LED_COMPOSE] = "Compose", + [LED_KANA] = "Kana", [LED_SLEEP] = "Sleep", + [LED_SUSPEND] = "Suspend", [LED_MUTE] = "Mute", + [LED_MISC] = "Misc", +}; + +static char *repeats[REP_MAX + 1] = { + [0 ... REP_MAX] = NULL, + [REP_DELAY] = "Delay", [REP_PERIOD] = "Period" +}; + +static char *sounds[SND_MAX + 1] = { + [0 ... SND_MAX] = NULL, + [SND_CLICK] = "Click", [SND_BELL] = "Bell", + [SND_TONE] = "Tone" +}; + +static char **names[EV_MAX + 1] = { + [0 ... EV_MAX] = NULL, + [EV_SYN] = syncs, [EV_KEY] = keys, + [EV_REL] = relatives, [EV_ABS] = absolutes, + [EV_MSC] = misc, [EV_LED] = leds, + [EV_SND] = sounds, [EV_REP] = repeats, +}; + +static void resolv_event(__u8 type, __u16 code) { + + printk("%s.%s", events[type] ? events[type] : "?", + names[type] ? (names[type][code] ? names[type][code] : "?") : "?"); } diff -Nru a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c --- a/drivers/usb/input/hid-input.c 2005-01-02 23:11:39 -08:00 +++ b/drivers/usb/input/hid-input.c 2005-01-02 23:11:39 -08:00 @@ -32,6 +32,8 @@ #include #include +#undef DEBUG + #include "hid.h" #define unk KEY_UNKNOWN @@ -60,114 +62,130 @@ __s32 y; } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; -static struct input_dev *find_input(struct hid_device *hid, struct hid_field *field) -{ - struct list_head *lh; - struct hid_input *hidinput; - - list_for_each (lh, &hid->inputs) { - int i; - - hidinput = list_entry(lh, struct hid_input, list); - - if (! hidinput->report) - continue; - - for (i = 0; i < hidinput->report->maxfield; i++) - if (hidinput->report->field[i] == field) - return &hidinput->input; - } - - /* Assume we only have one input and use it */ - if (!list_empty(&hid->inputs)) { - hidinput = list_entry(hid->inputs.next, struct hid_input, list); - return &hidinput->input; - } - - /* This is really a bug */ - return NULL; -} +#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; } while (0) +#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0) +#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0) +#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0) +#define map_ff(c) do { usage->code = c; usage->type = EV_FF; bit = input->ffbit; max = FF_MAX; } while (0) + +#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) +#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) +#define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0) static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, struct hid_usage *usage) { struct input_dev *input = &hidinput->input; struct hid_device *device = hidinput->input.private; - int max; - int is_abs = 0; + int max, code; unsigned long *bit; + field->hidinput = hidinput; + +#ifdef DEBUG + printk(KERN_DEBUG "Mapping: "); + resolv_usage(usage->hid); + printk(" ---> "); +#endif + + if (field->flags & HID_MAIN_ITEM_CONSTANT) + goto ignore; + switch (usage->hid & HID_USAGE_PAGE) { + case HID_UP_UNDEFINED: + goto ignore; + case HID_UP_KEYBOARD: set_bit(EV_REP, input->evbit); - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; if ((usage->hid & HID_USAGE) < 256) { - if (!(usage->code = hid_keyboard[usage->hid & HID_USAGE])) - return; - clear_bit(usage->code, bit); + if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore; + map_key_clear(hid_keyboard[usage->hid & HID_USAGE]); } else - usage->code = KEY_UNKNOWN; + map_key(KEY_UNKNOWN); break; case HID_UP_BUTTON: - usage->code = ((usage->hid - 1) & 0xf) + 0x100; - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; + code = ((usage->hid - 1) & 0xf); switch (field->application) { - case HID_GD_GAMEPAD: usage->code += 0x10; - case HID_GD_JOYSTICK: usage->code += 0x10; - case HID_GD_MOUSE: usage->code += 0x10; break; + case HID_GD_MOUSE: + case HID_GD_POINTER: code += 0x110; break; + case HID_GD_JOYSTICK: code += 0x120; break; + case HID_GD_GAMEPAD: code += 0x130; break; default: - if (field->physical == HID_GD_POINTER) - usage->code += 0x10; - break; + switch (field->physical) { + case HID_GD_MOUSE: + case HID_GD_POINTER: code += 0x110; break; + case HID_GD_JOYSTICK: code += 0x120; break; + case HID_GD_GAMEPAD: code += 0x130; break; + default: code += 0x100; + } } + + map_key(code); break; case HID_UP_GENDESK: if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */ switch (usage->hid & 0xf) { - case 0x1: usage->code = KEY_POWER; break; - case 0x2: usage->code = KEY_SLEEP; break; - case 0x3: usage->code = KEY_WAKEUP; break; - default: usage->code = KEY_UNKNOWN; break; + case 0x1: map_key_clear(KEY_POWER); break; + case 0x2: map_key_clear(KEY_SLEEP); break; + case 0x3: map_key_clear(KEY_WAKEUP); break; + default: goto unknown; } - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; break; } - usage->code = usage->hid & 0xf; - - if (field->report_size == 1) { - usage->code = BTN_MISC; - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; + if ((usage->hid & 0xf0) == 0x90) { /* D-pad */ + switch (usage->hid) { + case HID_GD_UP: usage->hat_dir = 1; break; + case HID_GD_DOWN: usage->hat_dir = 5; break; + case HID_GD_RIGHT: usage->hat_dir = 3; break; + case HID_GD_LEFT: usage->hat_dir = 7; break; + default: goto unknown; + } + if (field->dpad) { + map_abs(field->dpad); + goto ignore; + } + map_abs(ABS_HAT0X); break; } - if (field->flags & HID_MAIN_ITEM_RELATIVE) { - usage->type = EV_REL; bit = input->relbit; max = REL_MAX; - break; - } + switch (usage->hid) { - usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; + /* These usage IDs map directly to the usage codes. */ + case HID_GD_X: case HID_GD_Y: case HID_GD_Z: + case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: + case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: + if (field->flags & HID_MAIN_ITEM_RELATIVE) + map_rel(usage->hid & 0xf); + else + map_abs(usage->hid & 0xf); + break; - if (usage->hid == HID_GD_HATSWITCH) { - usage->code = ABS_HAT0X; - usage->hat_min = field->logical_minimum; - usage->hat_max = field->logical_maximum; + case HID_GD_HATSWITCH: + usage->hat_min = field->logical_minimum; + usage->hat_max = field->logical_maximum; + map_abs(ABS_HAT0X); + break; + + case HID_GD_START: map_key_clear(BTN_START); break; + case HID_GD_SELECT: map_key_clear(BTN_SELECT); break; + + default: goto unknown; } + break; case HID_UP_LED: - - usage->code = (usage->hid - 1) & 0xf; - usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; + map_led((usage->hid - 1) & 0xf); break; case HID_UP_DIGITIZER: @@ -175,49 +193,36 @@ switch (usage->hid & 0xff) { case 0x30: /* TipPressure */ - if (!test_bit(BTN_TOUCH, input->keybit)) { device->quirks |= HID_QUIRK_NOTOUCH; set_bit(EV_KEY, input->evbit); set_bit(BTN_TOUCH, input->keybit); } - usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; - usage->code = ABS_PRESSURE; - clear_bit(usage->code, bit); + + map_abs_clear(ABS_PRESSURE); break; case 0x32: /* InRange */ - - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; switch (field->physical & 0xff) { - case 0x21: usage->code = BTN_TOOL_MOUSE; break; - case 0x22: usage->code = BTN_TOOL_FINGER; break; - default: usage->code = BTN_TOOL_PEN; break; + case 0x21: map_key(BTN_TOOL_MOUSE); break; + case 0x22: map_key(BTN_TOOL_FINGER); break; + default: map_key(BTN_TOOL_PEN); break; } break; case 0x3c: /* Invert */ - - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; - usage->code = BTN_TOOL_RUBBER; - clear_bit(usage->code, bit); + map_key_clear(BTN_TOOL_RUBBER); break; case 0x33: /* Touch */ case 0x42: /* TipSwitch */ case 0x43: /* TipSwitch2 */ - device->quirks &= ~HID_QUIRK_NOTOUCH; - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; - usage->code = BTN_TOUCH; - clear_bit(usage->code, bit); + map_key_clear(BTN_TOUCH); break; case 0x44: /* BarrelSwitch */ - - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; - usage->code = BTN_STYLUS; - clear_bit(usage->code, bit); + map_key_clear(BTN_STYLUS); break; default: goto unknown; @@ -228,54 +233,42 @@ set_bit(EV_REP, input->evbit); switch (usage->hid & HID_USAGE) { - case 0x000: usage->code = 0; break; - case 0x034: usage->code = KEY_SLEEP; break; - case 0x036: usage->code = BTN_MISC; break; - case 0x08a: usage->code = KEY_WWW; break; - case 0x095: usage->code = KEY_HELP; break; - - case 0x0b0: usage->code = KEY_PLAY; break; - case 0x0b1: usage->code = KEY_PAUSE; break; - case 0x0b2: usage->code = KEY_RECORD; break; - case 0x0b3: usage->code = KEY_FASTFORWARD; break; - case 0x0b4: usage->code = KEY_REWIND; break; - case 0x0b5: usage->code = KEY_NEXTSONG; break; - case 0x0b6: usage->code = KEY_PREVIOUSSONG; break; - case 0x0b7: usage->code = KEY_STOPCD; break; - case 0x0b8: usage->code = KEY_EJECTCD; break; - case 0x0cd: usage->code = KEY_PLAYPAUSE; break; - case 0x0e0: is_abs = 1; - usage->code = ABS_VOLUME; - break; - case 0x0e2: usage->code = KEY_MUTE; break; - case 0x0e5: usage->code = KEY_BASSBOOST; break; - case 0x0e9: usage->code = KEY_VOLUMEUP; break; - case 0x0ea: usage->code = KEY_VOLUMEDOWN; break; - - case 0x183: usage->code = KEY_CONFIG; break; - case 0x18a: usage->code = KEY_MAIL; break; - case 0x192: usage->code = KEY_CALC; break; - case 0x194: usage->code = KEY_FILE; break; - case 0x21a: usage->code = KEY_UNDO; break; - case 0x21b: usage->code = KEY_COPY; break; - case 0x21c: usage->code = KEY_CUT; break; - case 0x21d: usage->code = KEY_PASTE; break; - - case 0x221: usage->code = KEY_FIND; break; - case 0x223: usage->code = KEY_HOMEPAGE; break; - case 0x224: usage->code = KEY_BACK; break; - case 0x225: usage->code = KEY_FORWARD; break; - case 0x226: usage->code = KEY_STOP; break; - case 0x227: usage->code = KEY_REFRESH; break; - case 0x22a: usage->code = KEY_BOOKMARKS; break; - - default: usage->code = KEY_UNKNOWN; break; - } - - if (is_abs) { - usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; - } else { - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; + case 0x000: goto ignore; + case 0x034: map_key_clear(KEY_SLEEP); break; + case 0x036: map_key_clear(BTN_MISC); break; + case 0x08a: map_key_clear(KEY_WWW); break; + case 0x095: map_key_clear(KEY_HELP); break; + case 0x0b0: map_key_clear(KEY_PLAY); break; + case 0x0b1: map_key_clear(KEY_PAUSE); break; + case 0x0b2: map_key_clear(KEY_RECORD); break; + case 0x0b3: map_key_clear(KEY_FASTFORWARD); break; + case 0x0b4: map_key_clear(KEY_REWIND); break; + case 0x0b5: map_key_clear(KEY_NEXTSONG); break; + case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; + case 0x0b7: map_key_clear(KEY_STOPCD); break; + case 0x0b8: map_key_clear(KEY_EJECTCD); break; + case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; + case 0x0e0: map_abs_clear(ABS_VOLUME); break; + case 0x0e2: map_key_clear(KEY_MUTE); break; + case 0x0e5: map_key_clear(KEY_BASSBOOST); break; + case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; + case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; + case 0x183: map_key_clear(KEY_CONFIG); break; + case 0x18a: map_key_clear(KEY_MAIL); break; + case 0x192: map_key_clear(KEY_CALC); break; + case 0x194: map_key_clear(KEY_FILE); break; + case 0x21a: map_key_clear(KEY_UNDO); break; + case 0x21b: map_key_clear(KEY_COPY); break; + case 0x21c: map_key_clear(KEY_CUT); break; + case 0x21d: map_key_clear(KEY_PASTE); break; + case 0x221: map_key_clear(KEY_FIND); break; + case 0x223: map_key_clear(KEY_HOMEPAGE); break; + case 0x224: map_key_clear(KEY_BACK); break; + case 0x225: map_key_clear(KEY_FORWARD); break; + case 0x226: map_key_clear(KEY_STOP); break; + case 0x227: map_key_clear(KEY_REFRESH); break; + case 0x22a: map_key_clear(KEY_BOOKMARKS); break; + default: goto unknown; } break; @@ -283,114 +276,82 @@ set_bit(EV_REP, input->evbit); switch (usage->hid & HID_USAGE) { - case 0x021: usage->code = KEY_PRINT; break; - case 0x070: usage->code = KEY_HP; break; - case 0x071: usage->code = KEY_CAMERA; break; - case 0x072: usage->code = KEY_SOUND; break; - case 0x073: usage->code = KEY_QUESTION; break; - - case 0x080: usage->code = KEY_EMAIL; break; - case 0x081: usage->code = KEY_CHAT; break; - case 0x082: usage->code = KEY_SEARCH; break; - case 0x083: usage->code = KEY_CONNECT; break; - case 0x084: usage->code = KEY_FINANCE; break; - case 0x085: usage->code = KEY_SPORT; break; - case 0x086: usage->code = KEY_SHOP; break; - - default: usage->code = KEY_UNKNOWN; break; - + case 0x021: map_key_clear(KEY_PRINT); break; + case 0x070: map_key_clear(KEY_HP); break; + case 0x071: map_key_clear(KEY_CAMERA); break; + case 0x072: map_key_clear(KEY_SOUND); break; + case 0x073: map_key_clear(KEY_QUESTION); break; + case 0x080: map_key_clear(KEY_EMAIL); break; + case 0x081: map_key_clear(KEY_CHAT); break; + case 0x082: map_key_clear(KEY_SEARCH); break; + case 0x083: map_key_clear(KEY_CONNECT); break; + case 0x084: map_key_clear(KEY_FINANCE); break; + case 0x085: map_key_clear(KEY_SPORT); break; + case 0x086: map_key_clear(KEY_SHOP); break; + default: goto unknown; } - - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; break; case HID_UP_PID: - usage->type = EV_FF; bit = input->ffbit; max = FF_MAX; - + set_bit(EV_FF, input->evbit); switch(usage->hid & HID_USAGE) { - case 0x26: set_bit(FF_CONSTANT, input->ffbit); break; - case 0x27: set_bit(FF_RAMP, input->ffbit); break; - case 0x28: set_bit(FF_CUSTOM, input->ffbit); break; - case 0x30: set_bit(FF_SQUARE, input->ffbit); - set_bit(FF_PERIODIC, input->ffbit); break; - case 0x31: set_bit(FF_SINE, input->ffbit); - set_bit(FF_PERIODIC, input->ffbit); break; - case 0x32: set_bit(FF_TRIANGLE, input->ffbit); - set_bit(FF_PERIODIC, input->ffbit); break; - case 0x33: set_bit(FF_SAW_UP, input->ffbit); - set_bit(FF_PERIODIC, input->ffbit); break; - case 0x34: set_bit(FF_SAW_DOWN, input->ffbit); - set_bit(FF_PERIODIC, input->ffbit); break; - case 0x40: set_bit(FF_SPRING, input->ffbit); break; - case 0x41: set_bit(FF_DAMPER, input->ffbit); break; - case 0x42: set_bit(FF_INERTIA , input->ffbit); break; - case 0x43: set_bit(FF_FRICTION, input->ffbit); break; - case 0x7e: usage->code = FF_GAIN; break; - case 0x83: /* Simultaneous Effects Max */ - input->ff_effects_max = (field->value[0]); - dbg("Maximum Effects - %d",input->ff_effects_max); - break; - case 0x98: /* Device Control */ - usage->code = FF_AUTOCENTER; break; - case 0xa4: /* Safety Switch */ - usage->code = BTN_DEAD; - bit = input->keybit; - usage->type = EV_KEY; - max = KEY_MAX; - dbg("Safety Switch Report\n"); - break; - case 0x9f: /* Device Paused */ - case 0xa0: /* Actuators Enabled */ - dbg("Not telling the input API about "); - resolv_usage(usage->hid); - return; + case 0x26: map_ff_effect(FF_CONSTANT); goto ignore; + case 0x27: map_ff_effect(FF_RAMP); goto ignore; + case 0x28: map_ff_effect(FF_CUSTOM); goto ignore; + case 0x30: map_ff_effect(FF_SQUARE); map_ff_effect(FF_PERIODIC); goto ignore; + case 0x31: map_ff_effect(FF_SINE); map_ff_effect(FF_PERIODIC); goto ignore; + case 0x32: map_ff_effect(FF_TRIANGLE); map_ff_effect(FF_PERIODIC); goto ignore; + case 0x33: map_ff_effect(FF_SAW_UP); map_ff_effect(FF_PERIODIC); goto ignore; + case 0x34: map_ff_effect(FF_SAW_DOWN); map_ff_effect(FF_PERIODIC); goto ignore; + case 0x40: map_ff_effect(FF_SPRING); goto ignore; + case 0x41: map_ff_effect(FF_DAMPER); goto ignore; + case 0x42: map_ff_effect(FF_INERTIA); goto ignore; + case 0x43: map_ff_effect(FF_FRICTION); goto ignore; + case 0x7e: map_ff(FF_GAIN); break; + case 0x83: input->ff_effects_max = field->value[0]; goto ignore; + case 0x98: map_ff(FF_AUTOCENTER); break; + case 0xa4: map_key_clear(BTN_DEAD); break; + default: goto ignore; } break; + default: unknown: - resolv_usage(usage->hid); - if (field->report_size == 1) { - if (field->report->type == HID_OUTPUT_REPORT) { - usage->code = LED_MISC; - usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; + map_led(LED_MISC); break; } - - usage->code = BTN_MISC; - usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; + map_key(BTN_MISC); break; } - if (field->flags & HID_MAIN_ITEM_RELATIVE) { - usage->code = REL_MISC; - usage->type = EV_REL; bit = input->relbit; max = REL_MAX; + map_rel(REL_MISC); break; } - - usage->code = ABS_MISC; - usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; + map_abs(ABS_MISC); break; } set_bit(usage->type, input->evbit); - if ((usage->type == EV_REL) - && (device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_BACK - | HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA)) - && (usage->code == REL_WHEEL)) { - set_bit(REL_HWHEEL, bit); - } - while (usage->code <= max && test_and_set_bit(usage->code, bit)) { + while (usage->code <= max && test_and_set_bit(usage->code, bit)) usage->code = find_next_zero_bit(bit, max + 1, usage->code); - } if (usage->code > max) - return; + goto ignore; + + if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && + (usage->type == EV_REL) && (usage->code == REL_WHEEL)) + set_bit(REL_HWHEEL, bit); + + if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) + || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) + goto ignore; if (usage->type == EV_ABS) { + int a = field->logical_minimum; int b = field->logical_maximum; @@ -399,61 +360,69 @@ b = field->logical_maximum = 255; } - input->absmin[usage->code] = a; - input->absmax[usage->code] = b; - input->absfuzz[usage->code] = 0; - input->absflat[usage->code] = 0; - - if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) { - input->absfuzz[usage->code] = (b - a) >> 8; - input->absflat[usage->code] = (b - a) >> 4; - } + if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) + input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); + else input_set_abs_params(input, usage->code, a, b, 0, 0); + } - if (usage->hat_min != usage->hat_max) { + if (usage->hat_min < usage->hat_max || usage->hat_dir) { int i; for (i = usage->code; i < usage->code + 2 && i <= max; i++) { - input->absmax[i] = 1; - input->absmin[i] = -1; - input->absfuzz[i] = 0; - input->absflat[i] = 0; + input_set_abs_params(input, i, -1, 1, 0, 0); + set_bit(i, input->absbit); } - set_bit(usage->code + 1, input->absbit); + if (usage->hat_dir && !field->dpad) + field->dpad = usage->code; } + +#ifdef DEBUG + resolv_event(usage->type, usage->code); + printk("\n"); +#endif + return; + +ignore: +#ifdef DEBUG + printk("IGNORED\n"); +#endif + return; } void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { - struct input_dev *input = find_input(hid, field); + struct input_dev *input = &field->hidinput->input; int *quirks = &hid->quirks; if (!input) return; + if (!usage->type) + return; + input_regs(input, regs); - if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA) && (usage->code == BTN_EXTRA)) - || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_BACK) && (usage->code == BTN_BACK))) { - if (value) - hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; - else - hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; + if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) + || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { + if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; + else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; return; } - if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) - && (usage->code == REL_WHEEL)) { + if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { input_event(input, usage->type, REL_HWHEEL, value); return; } - if (usage->hat_min != usage->hat_max ) { /* FIXME: hat_max can be 0 and hat_min 1 */ - value = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; - if (value < 0 || value > 8) value = 0; - input_event(input, usage->type, usage->code , hid_hat_to_axis[value].x); - input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[value].y); - return; - } + if (usage->hat_min < usage->hat_max || usage->hat_dir) { + int hat_dir = usage->hat_dir; + if (!hat_dir) + hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; + if (hat_dir < 0 || hat_dir > 8) hat_dir = 0; + input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x); + input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y); + return; + } if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */ *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT); @@ -481,6 +450,7 @@ dbg("Maximum Effects - %d",input->ff_effects_max); return; } + if (usage->hid == (HID_UP_PID | 0x7fUL)) { dbg("PID Pool Report\n"); return; @@ -556,9 +526,10 @@ INIT_LIST_HEAD(&hid->inputs); for (i = 0; i < hid->maxcollection; i++) - if (hid->collection[i].type == HID_COLLECTION_APPLICATION && - IS_INPUT_APPLICATION(hid->collection[i].usage)) - break; + if (hid->collection[i].type == HID_COLLECTION_APPLICATION || + hid->collection[i].type == HID_COLLECTION_PHYSICAL) + if (IS_INPUT_APPLICATION(hid->collection[i].usage)) + break; if (i == hid->maxcollection) return -1; diff -Nru a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h --- a/drivers/usb/input/hid.h 2005-01-02 23:11:39 -08:00 +++ b/drivers/usb/input/hid.h 2005-01-02 23:11:39 -08:00 @@ -171,6 +171,7 @@ #define HID_USAGE_PAGE 0xffff0000 +#define HID_UP_UNDEFINED 0x00000000 #define HID_UP_GENDESK 0x00010000 #define HID_UP_KEYBOARD 0x00070000 #define HID_UP_LED 0x00080000 @@ -187,7 +188,36 @@ #define HID_GD_MOUSE 0x00010002 #define HID_GD_JOYSTICK 0x00010004 #define HID_GD_GAMEPAD 0x00010005 +#define HID_GD_KEYBOARD 0x00010006 +#define HID_GD_KEYPAD 0x00010007 +#define HID_GD_MULTIAXIS 0x00010008 +#define HID_GD_X 0x00010030 +#define HID_GD_Y 0x00010031 +#define HID_GD_Z 0x00010032 +#define HID_GD_RX 0x00010033 +#define HID_GD_RY 0x00010034 +#define HID_GD_RZ 0x00010035 +#define HID_GD_SLIDER 0x00010036 +#define HID_GD_DIAL 0x00010037 +#define HID_GD_WHEEL 0x00010038 #define HID_GD_HATSWITCH 0x00010039 +#define HID_GD_BUFFER 0x0001003a +#define HID_GD_BYTECOUNT 0x0001003b +#define HID_GD_MOTION 0x0001003c +#define HID_GD_START 0x0001003d +#define HID_GD_SELECT 0x0001003e +#define HID_GD_VX 0x00010040 +#define HID_GD_VY 0x00010041 +#define HID_GD_VZ 0x00010042 +#define HID_GD_VBRX 0x00010043 +#define HID_GD_VBRY 0x00010044 +#define HID_GD_VBRZ 0x00010045 +#define HID_GD_VNO 0x00010046 +#define HID_GD_FEATURE 0x00010047 +#define HID_GD_UP 0x00010090 +#define HID_GD_DOWN 0x00010091 +#define HID_GD_RIGHT 0x00010092 +#define HID_GD_LEFT 0x00010093 /* * HID report types --- Ouch! HID spec says 1 2 3! @@ -208,8 +238,8 @@ #define HID_QUIRK_HIDDEV 0x010 #define HID_QUIRK_BADPAD 0x020 #define HID_QUIRK_MULTI_INPUT 0x040 -#define HID_QUIRK_2WHEEL_MOUSE_HACK_BACK 0x080 -#define HID_QUIRK_2WHEEL_MOUSE_HACK_EXTRA 0x100 +#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080 +#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200 /* @@ -262,12 +292,16 @@ struct hid_usage { unsigned hid; /* hid usage code */ unsigned collection_index; /* index into collection array */ + /* hidinput data */ __u16 code; /* input driver code */ __u8 type; /* input driver type */ __s8 hat_min; /* hat switch fun */ __s8 hat_max; /* ditto */ + __s8 hat_dir; /* ditto */ }; +struct hid_input; + struct hid_field { unsigned physical; /* physical usage for this field */ unsigned logical; /* logical usage for this field */ @@ -288,6 +322,9 @@ unsigned unit; struct hid_report *report; /* associated report */ unsigned index; /* index into report->field[] */ + /* hidinput data */ + struct hid_input *hidinput; /* associated input structure */ + __u16 dpad; /* dpad input code */ }; #define HID_MAX_FIELDS 64 @@ -423,6 +460,7 @@ #define hid_dump_device(c) do { } while (0) #define hid_dump_field(a,b) do { } while (0) #define resolv_usage(a) do { } while (0) +#define resolv_event(a,b) do { } while (0) #endif #endif @@ -430,7 +468,7 @@ #ifdef CONFIG_USB_HIDINPUT /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ /* We ignore a few input applications that are not widely used */ -#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001)) +#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001)) extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); extern int hidinput_connect(struct hid_device *); diff -Nru a/include/linux/input.h b/include/linux/input.h --- a/include/linux/input.h 2005-01-02 23:11:39 -08:00 +++ b/include/linux/input.h 2005-01-02 23:11:39 -08:00 @@ -504,6 +504,9 @@ #define REL_X 0x00 #define REL_Y 0x01 #define REL_Z 0x02 +#define REL_RX 0x03 +#define REL_RY 0x04 +#define REL_RZ 0x05 #define REL_HWHEEL 0x06 #define REL_DIAL 0x07 #define REL_WHEEL 0x08 @@ -566,6 +569,8 @@ #define LED_SUSPEND 0x06 #define LED_MUTE 0x07 #define LED_MISC 0x08 +#define LED_MAIL 0x09 +#define LED_CHARGING 0x0a #define LED_MAX 0x0f /* @@ -823,7 +828,6 @@ unsigned int repeat_key; struct timer_list timer; - struct pm_dev *pm_dev; struct pt_regs *regs; int state; diff -Nru a/include/linux/libps2.h b/include/linux/libps2.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/include/linux/libps2.h 2005-01-02 23:11:39 -08:00 @@ -0,0 +1,50 @@ +#ifndef _LIBPS2_H +#define _LIBPS2_H + +/* + * 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 + * the Free Software Foundation. + */ + + +#define PS2_CMD_GETID 0x02f2 +#define PS2_CMD_RESET_BAT 0x02ff + +#define PS2_RET_BAT 0xaa +#define PS2_RET_ID 0x00 +#define PS2_RET_ACK 0xfa +#define PS2_RET_NAK 0xfe + +#define PS2_FLAG_ACK 1 /* Waiting for ACK/NAK */ +#define PS2_FLAG_CMD 2 /* Waiting for command to finish */ +#define PS2_FLAG_CMD1 4 /* Waiting for the first byte of command response */ +#define PS2_FLAG_WAITID 8 /* Command execiting is GET ID */ + +struct ps2dev { + struct serio *serio; + + /* Ensures that only one command is executing at a time */ + struct semaphore cmd_sem; + + /* Used to signal completion from interrupt handler */ + wait_queue_head_t wait; + + unsigned long flags; + unsigned char cmdbuf[6]; + unsigned char cmdcnt; + unsigned char nak; +}; + +void ps2_init(struct ps2dev *ps2dev, struct serio *serio); +int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); +int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); +int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command); +int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); +int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data); +void ps2_cmd_aborted(struct ps2dev *ps2dev); + +#endif /* _LIBPS2_H */ diff -Nru a/include/linux/serio.h b/include/linux/serio.h --- a/include/linux/serio.h 2005-01-02 23:11:39 -08:00 +++ b/include/linux/serio.h 2005-01-02 23:11:39 -08:00 @@ -45,7 +45,8 @@ struct serio *parent, *child; - struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock */ + struct serio_driver *drv; /* accessed from interrupt, must be protected by serio->lock and serio->sem */ + struct semaphore drv_sem; /* protects serio->drv so attributes can pin driver */ struct device dev; @@ -120,6 +121,19 @@ static __inline__ void serio_continue_rx(struct serio *serio) { spin_unlock_irq(&serio->lock); +} + +/* + * Use the following fucntions to pin serio's driver in process context + */ +static __inline__ int serio_pin_driver(struct serio *serio) +{ + return down_interruptible(&serio->drv_sem); +} + +static __inline__ void serio_unpin_driver(struct serio *serio) +{ + up(&serio->drv_sem); }