Browse Source

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (48 commits)
  Input: add switch for dock events
  Input: add microphone insert switch definition
  Input: i8042 - add Arima-Rioworks HDAMB board to noloop list
  Input: sgi_btns - add support for SGI Indy volume buttons
  Input: add option to disable HP SDC driver
  Input: serio - trivial documentation fix
  Input: add new serio driver for Xilinx XPS PS2 IP
  Input: add driver for Tabletkiosk Sahara TouchIT-213 touchscreen
  Input: new driver for SGI O2 volume buttons
  Input: yealink - reliably kill urbs
  Input: q40kbd - make q40kbd_lock static
  Input: gtco - eliminate early return
  Input: i8042 - add Dritek quirk for Acer Aspire 5720
  Input: usbtouchscreen - ignore eGalax screens supporting HID protocol
  Input: i8042 - add Medion NAM 2070 to noloop blacklist
  Input: i8042 - add Gericom Bellagio to nomux blacklist
  Input: i8042 - add Acer Aspire 1360 to nomux blacklist
  Input: hp_sdc_mlc.c - make a struct static
  Input: hil_mlc.c - make code static
  Input: wistron - generate normal key event if bluetooth or wifi not present
  ...
Linus Torvalds 17 năm trước cách đây
mục cha
commit
519f0141f1
100 tập tin đã thay đổi với 2283 bổ sung550 xóa
  1. 0 2
      Documentation/input/gameport-programming.txt
  2. 0 1
      Documentation/input/input.txt
  3. 0 2
      Documentation/input/joystick-api.txt
  4. 0 1
      Documentation/input/joystick-parport.txt
  5. 0 1
      Documentation/input/joystick.txt
  6. 6 0
      MAINTAINERS
  7. 2 0
      drivers/char/keyboard.c
  8. 2 0
      drivers/hwmon/hdaps.c
  9. 7 5
      drivers/input/evbug.c
  10. 90 11
      drivers/input/evdev.c
  11. 2 2
      drivers/input/ff-memless.c
  12. 0 2
      drivers/input/gameport/emu10k1-gp.c
  13. 0 22
      drivers/input/gameport/gameport.c
  14. 0 2
      drivers/input/gameport/lightning.c
  15. 0 2
      drivers/input/gameport/ns558.c
  16. 1 1
      drivers/input/input.c
  17. 0 2
      drivers/input/joystick/a3d.c
  18. 0 2
      drivers/input/joystick/amijoy.c
  19. 0 2
      drivers/input/joystick/cobra.c
  20. 0 2
      drivers/input/joystick/db9.c
  21. 0 2
      drivers/input/joystick/gf2k.c
  22. 0 2
      drivers/input/joystick/grip.c
  23. 0 2
      drivers/input/joystick/grip_mp.c
  24. 0 2
      drivers/input/joystick/guillemot.c
  25. 0 2
      drivers/input/joystick/iforce/iforce-ff.c
  26. 0 2
      drivers/input/joystick/iforce/iforce-main.c
  27. 0 2
      drivers/input/joystick/iforce/iforce-packets.c
  28. 0 2
      drivers/input/joystick/iforce/iforce-serio.c
  29. 3 5
      drivers/input/joystick/iforce/iforce-usb.c
  30. 0 2
      drivers/input/joystick/iforce/iforce.h
  31. 0 2
      drivers/input/joystick/interact.c
  32. 0 2
      drivers/input/joystick/joydump.c
  33. 0 2
      drivers/input/joystick/magellan.c
  34. 0 2
      drivers/input/joystick/spaceball.c
  35. 0 2
      drivers/input/joystick/spaceorb.c
  36. 0 2
      drivers/input/joystick/stinger.c
  37. 0 2
      drivers/input/joystick/tmdc.c
  38. 0 2
      drivers/input/joystick/turbografx.c
  39. 0 4
      drivers/input/joystick/twidjoy.c
  40. 0 2
      drivers/input/joystick/warrior.c
  41. 6 6
      drivers/input/joystick/xpad.c
  42. 0 2
      drivers/input/keyboard/amikbd.c
  43. 36 10
      drivers/input/keyboard/atkbd.c
  44. 69 20
      drivers/input/keyboard/gpio_keys.c
  45. 3 3
      drivers/input/keyboard/lkkbd.c
  46. 14 1
      drivers/input/keyboard/pxa27x_keypad.c
  47. 0 2
      drivers/input/keyboard/sunkbd.c
  48. 0 2
      drivers/input/keyboard/xtkbd.c
  49. 10 0
      drivers/input/misc/Kconfig
  50. 1 0
      drivers/input/misc/Makefile
  51. 9 9
      drivers/input/misc/ati_remote.c
  52. 9 9
      drivers/input/misc/ati_remote2.c
  53. 10 10
      drivers/input/misc/keyspan_remote.c
  54. 3 3
      drivers/input/misc/powermate.c
  55. 178 0
      drivers/input/misc/sgi_btns.c
  56. 18 1
      drivers/input/misc/wistron_btns.c
  57. 32 18
      drivers/input/misc/yealink.c
  58. 138 161
      drivers/input/mouse/appletouch.c
  59. 12 15
      drivers/input/mouse/atarimouse.c
  60. 26 11
      drivers/input/mouse/hil_ptr.c
  61. 0 2
      drivers/input/mouse/inport.c
  62. 0 2
      drivers/input/mouse/logibm.c
  63. 0 2
      drivers/input/mouse/pc110pad.c
  64. 0 2
      drivers/input/mouse/sermouse.c
  65. 10 0
      drivers/input/serio/Kconfig
  66. 1 0
      drivers/input/serio/Makefile
  67. 0 2
      drivers/input/serio/ct82c710.c
  68. 3 3
      drivers/input/serio/hil_mlc.c
  69. 9 0
      drivers/input/serio/hp_sdc.c
  70. 1 1
      drivers/input/serio/hp_sdc_mlc.c
  71. 56 11
      drivers/input/serio/i8042-x86ia64io.h
  72. 0 52
      drivers/input/serio/libps2.c
  73. 1 3
      drivers/input/serio/q40kbd.c
  74. 0 2
      drivers/input/serio/rpckbd.c
  75. 6 3
      drivers/input/serio/serio.c
  76. 380 0
      drivers/input/serio/xilinx_ps2.c
  77. 2 2
      drivers/input/tablet/acecad.c
  78. 3 3
      drivers/input/tablet/aiptek.c
  79. 1 1
      drivers/input/tablet/gtco.c
  80. 3 3
      drivers/input/tablet/kbtab.c
  81. 1 1
      drivers/input/tablet/wacom.h
  82. 3 3
      drivers/input/tablet/wacom_sys.c
  83. 19 20
      drivers/input/tablet/wacom_wac.c
  84. 46 0
      drivers/input/touchscreen/Kconfig
  85. 4 0
      drivers/input/touchscreen/Makefile
  86. 0 2
      drivers/input/touchscreen/gunze.c
  87. 0 2
      drivers/input/touchscreen/h3600_ts_input.c
  88. 255 0
      drivers/input/touchscreen/htcpen.c
  89. 207 0
      drivers/input/touchscreen/inexio.c
  90. 250 0
      drivers/input/touchscreen/migor_ts.c
  91. 234 0
      drivers/input/touchscreen/touchit213.c
  92. 30 12
      drivers/input/touchscreen/usbtouchscreen.c
  93. 12 6
      drivers/input/touchscreen/wm9712.c
  94. 51 10
      drivers/macintosh/adbhid.c
  95. 0 1
      include/linux/gameport.h
  96. 1 0
      include/linux/gpio_keys.h
  97. 4 5
      include/linux/input.h
  98. 0 2
      include/linux/joystick.h
  99. 0 1
      include/linux/libps2.h
  100. 3 1
      include/linux/serio.h

+ 0 - 2
Documentation/input/gameport-programming.txt

@@ -1,5 +1,3 @@
-$Id: gameport-programming.txt,v 1.3 2001/04/24 13:51:37 vojtech Exp $
-
 Programming gameport drivers
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

+ 0 - 1
Documentation/input/input.txt

@@ -1,7 +1,6 @@
 			  Linux Input drivers v1.0
 	       (c) 1999-2001 Vojtech Pavlik <vojtech@ucw.cz>
 			     Sponsored by SuSE
-	    $Id: input.txt,v 1.8 2002/05/29 03:15:01 bradleym Exp $
 ----------------------------------------------------------------------------
 
 0. Disclaimer

+ 0 - 2
Documentation/input/joystick-api.txt

@@ -5,8 +5,6 @@
 
 			      7 Aug 1998
 
-	$Id: joystick-api.txt,v 1.2 2001/05/08 21:21:23 vojtech Exp $
-
 1. Initialization
 ~~~~~~~~~~~~~~~~~
 

+ 0 - 1
Documentation/input/joystick-parport.txt

@@ -2,7 +2,6 @@
 	       (c) 1998-2000 Vojtech Pavlik <vojtech@ucw.cz>
 	       (c) 1998 Andree Borrmann <a.borrmann@tu-bs.de>
 			     Sponsored by SuSE
-	$Id: joystick-parport.txt,v 1.6 2001/09/25 09:31:32 vojtech Exp $
 ----------------------------------------------------------------------------
 
 0. Disclaimer

+ 0 - 1
Documentation/input/joystick.txt

@@ -1,7 +1,6 @@
 		       Linux Joystick driver v2.0.0
 	       (c) 1996-2000 Vojtech Pavlik <vojtech@ucw.cz>
 			     Sponsored by SuSE
-	   $Id: joystick.txt,v 1.12 2002/03/03 12:13:07 jdeneux Exp $
 ----------------------------------------------------------------------------
 
 0. Disclaimer

+ 6 - 0
MAINTAINERS

@@ -1988,6 +1988,12 @@ M:	mikulas@artax.karlin.mff.cuni.cz
 W:	http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
 S:	Maintained
 
+HTCPEN TOUCHSCREEN DRIVER
+P:	Pau Oliva Fora
+M:	pof@eslack.org
+L:	linux-input@vger.kernel.org
+S:	Maintained
+
 HUGETLB FILESYSTEM
 P:	William Irwin
 M:	wli@holomorphy.com

+ 2 - 0
drivers/char/keyboard.c

@@ -46,6 +46,8 @@
 
 extern void ctrl_alt_del(void);
 
+#define to_handle_h(n) container_of(n, struct input_handle, h_node)
+
 /*
  * Exported functions/variables
  */

+ 2 - 0
drivers/hwmon/hdaps.c

@@ -581,6 +581,8 @@ static int __init hdaps_init(void)
 	/* initialize the input class */
 	idev = hdaps_idev->input;
 	idev->name = "hdaps";
+	idev->phys = "isa1600/input0";
+	idev->id.bustype = BUS_ISA;
 	idev->dev.parent = &pdev->dev;
 	idev->evbit[0] = BIT_MASK(EV_ABS);
 	input_set_abs_params(idev, ABS_X,

+ 7 - 5
drivers/input/evbug.c

@@ -1,6 +1,4 @@
 /*
- * $Id: evbug.c,v 1.10 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
@@ -41,7 +39,7 @@ MODULE_LICENSE("GPL");
 static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
 {
 	printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
-		handle->dev->phys, type, code, value);
+		handle->dev->dev.bus_id, type, code, value);
 }
 
 static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
@@ -66,7 +64,10 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
 	if (error)
 		goto err_unregister_handle;
 
-	printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys);
+	printk(KERN_DEBUG "evbug.c: Connected device: %s (%s at %s)\n",
+		dev->dev.bus_id,
+		dev->name ?: "unknown",
+		dev->phys ?: "unknown");
 
 	return 0;
 
@@ -79,7 +80,8 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
 
 static void evbug_disconnect(struct input_handle *handle)
 {
-	printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys);
+	printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n",
+		handle->dev->dev.bus_id);
 
 	input_close_device(handle);
 	input_unregister_handle(handle);

+ 90 - 11
drivers/input/evdev.c

@@ -300,6 +300,35 @@ struct input_event_compat {
 	__s32 value;
 };
 
+struct ff_periodic_effect_compat {
+	__u16 waveform;
+	__u16 period;
+	__s16 magnitude;
+	__s16 offset;
+	__u16 phase;
+
+	struct ff_envelope envelope;
+
+	__u32 custom_len;
+	compat_uptr_t custom_data;
+};
+
+struct ff_effect_compat {
+	__u16 type;
+	__s16 id;
+	__u16 direction;
+	struct ff_trigger trigger;
+	struct ff_replay replay;
+
+	union {
+		struct ff_constant_effect constant;
+		struct ff_ramp_effect ramp;
+		struct ff_periodic_effect_compat periodic;
+		struct ff_condition_effect condition[2]; /* One for each axis */
+		struct ff_rumble_effect rumble;
+	} u;
+};
+
 /* Note to the author of this code: did it ever occur to
    you why the ifdefs are needed? Think about it again. -AK */
 #ifdef CONFIG_X86_64
@@ -368,6 +397,42 @@ static int evdev_event_to_user(char __user *buffer,
 	return 0;
 }
 
+static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
+				     struct ff_effect *effect)
+{
+	if (COMPAT_TEST) {
+		struct ff_effect_compat *compat_effect;
+
+		if (size != sizeof(struct ff_effect_compat))
+			return -EINVAL;
+
+		/*
+		 * It so happens that the pointer which needs to be changed
+		 * is the last field in the structure, so we can copy the
+		 * whole thing and replace just the pointer.
+		 */
+
+		compat_effect = (struct ff_effect_compat *)effect;
+
+		if (copy_from_user(compat_effect, buffer,
+				   sizeof(struct ff_effect_compat)))
+			return -EFAULT;
+
+		if (compat_effect->type == FF_PERIODIC &&
+		    compat_effect->u.periodic.waveform == FF_CUSTOM)
+			effect->u.periodic.custom_data =
+				compat_ptr(compat_effect->u.periodic.custom_data);
+	} else {
+		if (size != sizeof(struct ff_effect))
+			return -EINVAL;
+
+		if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
 #else
 
 static inline size_t evdev_event_size(void)
@@ -393,6 +458,18 @@ static int evdev_event_to_user(char __user *buffer,
 	return 0;
 }
 
+static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
+				     struct ff_effect *effect)
+{
+	if (size != sizeof(struct ff_effect))
+		return -EINVAL;
+
+	if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
+		return -EFAULT;
+
+	return 0;
+}
+
 #endif /* CONFIG_COMPAT */
 
 static ssize_t evdev_write(struct file *file, const char __user *buffer,
@@ -633,17 +710,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 
 		return input_set_keycode(dev, t, v);
 
-	case EVIOCSFF:
-		if (copy_from_user(&effect, p, sizeof(effect)))
-			return -EFAULT;
-
-		error = input_ff_upload(dev, &effect, file);
-
-		if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
-			return -EFAULT;
-
-		return error;
-
 	case EVIOCRMFF:
 		return input_ff_erase(dev, (int)(unsigned long) p, file);
 
@@ -733,6 +799,19 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 
 		if (_IOC_DIR(cmd) == _IOC_WRITE) {
 
+			if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) {
+
+				if (evdev_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect))
+					return -EFAULT;
+
+				error = input_ff_upload(dev, &effect, file);
+
+				if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
+					return -EFAULT;
+
+				return error;
+			}
+
 			if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
 
 				t = _IOC_NR(cmd) & ABS_MAX;

+ 2 - 2
drivers/input/ff-memless.c

@@ -247,9 +247,9 @@ static void ml_combine_effects(struct ff_effect *effect,
 		 * in s8, this should be changed to something more generic
 		 */
 		effect->u.ramp.start_level =
-			max(min(effect->u.ramp.start_level + x, 0x7f), -0x80);
+			clamp_val(effect->u.ramp.start_level + x, -0x80, 0x7f);
 		effect->u.ramp.end_level =
-			max(min(effect->u.ramp.end_level + y, 0x7f), -0x80);
+			clamp_val(effect->u.ramp.end_level + y, -0x80, 0x7f);
 		break;
 
 	case FF_RUMBLE:

+ 0 - 2
drivers/input/gameport/emu10k1-gp.c

@@ -1,6 +1,4 @@
 /*
- * $Id: emu10k1-gp.c,v 1.8 2002/01/22 20:40:46 vojtech Exp $
- *
  *  Copyright (c) 2001 Vojtech Pavlik
  */
 

+ 0 - 22
drivers/input/gameport/gameport.c

@@ -36,7 +36,6 @@ EXPORT_SYMBOL(__gameport_register_driver);
 EXPORT_SYMBOL(gameport_unregister_driver);
 EXPORT_SYMBOL(gameport_open);
 EXPORT_SYMBOL(gameport_close);
-EXPORT_SYMBOL(gameport_rescan);
 EXPORT_SYMBOL(gameport_set_phys);
 EXPORT_SYMBOL(gameport_start_polling);
 EXPORT_SYMBOL(gameport_stop_polling);
@@ -230,8 +229,6 @@ static void gameport_find_driver(struct gameport *gameport)
  */
 
 enum gameport_event_type {
-	GAMEPORT_RESCAN,
-	GAMEPORT_RECONNECT,
 	GAMEPORT_REGISTER_PORT,
 	GAMEPORT_REGISTER_DRIVER,
 };
@@ -365,15 +362,6 @@ static void gameport_handle_event(void)
 				gameport_add_port(event->object);
 				break;
 
-			case GAMEPORT_RECONNECT:
-				gameport_reconnect_port(event->object);
-				break;
-
-			case GAMEPORT_RESCAN:
-				gameport_disconnect_port(event->object);
-				gameport_find_driver(event->object);
-				break;
-
 			case GAMEPORT_REGISTER_DRIVER:
 				gameport_add_driver(event->object);
 				break;
@@ -651,16 +639,6 @@ static void gameport_disconnect_port(struct gameport *gameport)
 	device_release_driver(&gameport->dev);
 }
 
-void gameport_rescan(struct gameport *gameport)
-{
-	gameport_queue_event(gameport, NULL, GAMEPORT_RESCAN);
-}
-
-void gameport_reconnect(struct gameport *gameport)
-{
-	gameport_queue_event(gameport, NULL, GAMEPORT_RECONNECT);
-}
-
 /*
  * Submits register request to kgameportd for subsequent execution.
  * Note that port registration is always asynchronous.

+ 0 - 2
drivers/input/gameport/lightning.c

@@ -1,6 +1,4 @@
 /*
- * $Id: lightning.c,v 1.20 2002/01/22 20:41:31 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/gameport/ns558.c

@@ -1,6 +1,4 @@
 /*
- * $Id: ns558.c,v 1.43 2002/01/24 19:23:21 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *  Copyright (c) 1999 Brian Gerst
  */

+ 1 - 1
drivers/input/input.c

@@ -242,7 +242,7 @@ static void input_handle_event(struct input_dev *dev,
 		break;
 	}
 
-	if (type != EV_SYN)
+	if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
 		dev->sync = 0;
 
 	if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)

+ 0 - 2
drivers/input/joystick/a3d.c

@@ -1,6 +1,4 @@
 /*
- * $Id: a3d.c,v 1.21 2002/01/22 20:11:50 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/joystick/amijoy.c

@@ -1,6 +1,4 @@
 /*
- * $Id: amijoy.c,v 1.13 2002/01/22 20:26:32 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/joystick/cobra.c

@@ -1,6 +1,4 @@
 /*
- * $Id: cobra.c,v 1.19 2002/01/22 20:26:52 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/joystick/db9.c

@@ -1,6 +1,4 @@
 /*
- * $Id: db9.c,v 1.13 2002/04/07 20:13:37 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:

+ 0 - 2
drivers/input/joystick/gf2k.c

@@ -1,6 +1,4 @@
 /*
- * $Id: gf2k.c,v 1.19 2002/01/22 20:27:43 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/joystick/grip.c

@@ -1,6 +1,4 @@
 /*
- * $Id: grip.c,v 1.21 2002/01/22 20:27:57 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/joystick/grip_mp.c

@@ -1,6 +1,4 @@
 /*
- * $Id: grip_mp.c,v 1.9 2002/07/20 19:28:45 bonnland Exp $
- *
  *  Driver for the Gravis Grip Multiport, a gamepad "hub" that
  *  connects up to four 9-pin digital gamepads/joysticks.
  *  Driver tested on SMP and UP kernel versions 2.4.18-4 and 2.4.18-5.

+ 0 - 2
drivers/input/joystick/guillemot.c

@@ -1,6 +1,4 @@
 /*
- * $Id: guillemot.c,v 1.10 2002/01/22 20:28:12 vojtech Exp $
- *
  *  Copyright (c) 2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/joystick/iforce/iforce-ff.c

@@ -1,6 +1,4 @@
 /*
- * $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *

+ 0 - 2
drivers/input/joystick/iforce/iforce-main.c

@@ -1,6 +1,4 @@
 /*
- * $Id: iforce-main.c,v 1.19 2002/07/07 10:22:50 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *

+ 0 - 2
drivers/input/joystick/iforce/iforce-packets.c

@@ -1,6 +1,4 @@
 /*
- * $Id: iforce-packets.c,v 1.16 2002/07/07 10:22:50 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *

+ 0 - 2
drivers/input/joystick/iforce/iforce-serio.c

@@ -1,6 +1,4 @@
 /*
- * $Id: iforce-serio.c,v 1.4 2002/01/28 22:45:00 jdeneux Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001, 2007 Johann Deneux <johann.deneux@gmail.com>
  *

+ 3 - 5
drivers/input/joystick/iforce/iforce-usb.c

@@ -1,6 +1,4 @@
  /*
- * $Id: iforce-usb.c,v 1.16 2002/06/09 11:08:04 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *
@@ -89,10 +87,10 @@ static void iforce_usb_irq(struct urb *urb)
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
 		dbg("%s - urb shutting down with status: %d",
-		    __FUNCTION__, urb->status);
+		    __func__, urb->status);
 		return;
 	default:
-		dbg("%s - urb has status of: %d", __FUNCTION__, urb->status);
+		dbg("%s - urb has status of: %d", __func__, urb->status);
 		goto exit;
 	}
 
@@ -103,7 +101,7 @@ exit:
 	status = usb_submit_urb (urb, GFP_ATOMIC);
 	if (status)
 		err ("%s - usb_submit_urb failed with result %d",
-		     __FUNCTION__, status);
+		     __func__, status);
 }
 
 static void iforce_usb_out(struct urb *urb)

+ 0 - 2
drivers/input/joystick/iforce/iforce.h

@@ -1,6 +1,4 @@
 /*
- * $Id: iforce.h,v 1.13 2002/07/07 10:22:50 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *

+ 0 - 2
drivers/input/joystick/interact.c

@@ -1,6 +1,4 @@
 /*
- * $Id: interact.c,v 1.16 2002/01/22 20:28:25 vojtech Exp $
- *
  *  Copyright (c) 2001 Vojtech Pavlik
  *
  *  Based on the work of:

+ 0 - 2
drivers/input/joystick/joydump.c

@@ -1,6 +1,4 @@
 /*
- * $Id: joydump.c,v 1.1 2002/01/23 06:56:16 jsimmons Exp $
- *
  *  Copyright (c) 1996-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/joystick/magellan.c

@@ -1,6 +1,4 @@
 /*
- * $Id: magellan.c,v 1.16 2002/01/22 20:28:39 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/joystick/spaceball.c

@@ -1,6 +1,4 @@
 /*
- * $Id: spaceball.c,v 1.17 2002/01/22 20:29:03 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:

+ 0 - 2
drivers/input/joystick/spaceorb.c

@@ -1,6 +1,4 @@
 /*
- * $Id: spaceorb.c,v 1.15 2002/01/22 20:29:19 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:

+ 0 - 2
drivers/input/joystick/stinger.c

@@ -1,6 +1,4 @@
 /*
- * $Id: stinger.c,v 1.10 2002/01/22 20:29:31 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *  Copyright (c) 2000 Mark Fletcher
  */

+ 0 - 2
drivers/input/joystick/tmdc.c

@@ -1,6 +1,4 @@
 /*
- * $Id: tmdc.c,v 1.31 2002/01/22 20:29:52 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  *
  *   Based on the work of:

+ 0 - 2
drivers/input/joystick/turbografx.c

@@ -1,6 +1,4 @@
 /*
- * $Id: turbografx.c,v 1.14 2002/01/22 20:30:39 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  *
  *  Based on the work of:

+ 0 - 4
drivers/input/joystick/twidjoy.c

@@ -1,8 +1,4 @@
 /*
- * $Id: twidjoy.c,v 1.5 2002/01/22 20:31:53 vojtech Exp $
- *
- *  derived from CVS-ID "stinger.c,v 1.5 2001/05/29 12:57:18 vojtech Exp"
- *
  *  Copyright (c) 2001 Arndt Schoenewald
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *  Copyright (c) 2000 Mark Fletcher

+ 0 - 2
drivers/input/joystick/warrior.c

@@ -1,6 +1,4 @@
 /*
- * $Id: warrior.c,v 1.14 2002/01/22 20:32:10 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 

+ 6 - 6
drivers/input/joystick/xpad.c

@@ -418,11 +418,11 @@ static void xpad_irq_in(struct urb *urb)
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
 		dbg("%s - urb shutting down with status: %d",
-			__FUNCTION__, status);
+			__func__, status);
 		return;
 	default:
 		dbg("%s - nonzero urb status received: %d",
-			__FUNCTION__, status);
+			__func__, status);
 		goto exit;
 	}
 
@@ -441,7 +441,7 @@ exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
-		     __FUNCTION__, retval);
+		     __func__, retval);
 }
 
 static void xpad_bulk_out(struct urb *urb)
@@ -477,11 +477,11 @@ static void xpad_irq_out(struct urb *urb)
 		case -ESHUTDOWN:
 			/* this urb is terminated, clean up */
 			dbg("%s - urb shutting down with status: %d",
-				__FUNCTION__, status);
+				__func__, status);
 			return;
 		default:
 			dbg("%s - nonzero urb status received: %d",
-				__FUNCTION__, status);
+				__func__, status);
 			goto exit;
 	}
 
@@ -489,7 +489,7 @@ exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
 		err("%s - usb_submit_urb failed with result %d",
-		    __FUNCTION__, retval);
+		    __func__, retval);
 }
 
 static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)

+ 0 - 2
drivers/input/keyboard/amikbd.c

@@ -1,6 +1,4 @@
 /*
- * $Id: amikbd.c,v 1.13 2002/02/01 16:02:24 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
  *  Based on the work of:

+ 36 - 10
drivers/input/keyboard/atkbd.c

@@ -68,7 +68,7 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and
  * are loadable via an userland utility.
  */
 
-static unsigned char atkbd_set2_keycode[512] = {
+static const unsigned short atkbd_set2_keycode[512] = {
 
 #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
 
@@ -99,7 +99,7 @@ static unsigned char atkbd_set2_keycode[512] = {
 #endif
 };
 
-static unsigned char atkbd_set3_keycode[512] = {
+static const unsigned short atkbd_set3_keycode[512] = {
 
 	  0,  0,  0,  0,  0,  0,  0, 59,  1,138,128,129,130, 15, 41, 60,
 	131, 29, 42, 86, 58, 16,  2, 61,133, 56, 44, 31, 30, 17,  3, 62,
@@ -115,7 +115,7 @@ static unsigned char atkbd_set3_keycode[512] = {
 	148,149,147,140
 };
 
-static unsigned char atkbd_unxlate_table[128] = {
+static const unsigned short atkbd_unxlate_table[128] = {
           0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
          21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
          35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
@@ -161,7 +161,7 @@ static unsigned char atkbd_unxlate_table[128] = {
 #define ATKBD_SCR_LEFT		249
 #define ATKBD_SCR_RIGHT		248
 
-#define ATKBD_SPECIAL		248
+#define ATKBD_SPECIAL		ATKBD_SCR_RIGHT
 
 #define ATKBD_LED_EVENT_BIT	0
 #define ATKBD_REP_EVENT_BIT	1
@@ -173,7 +173,7 @@ static unsigned char atkbd_unxlate_table[128] = {
 #define ATKBD_XL_HANGEUL	0x10
 #define ATKBD_XL_HANJA		0x20
 
-static struct {
+static const struct {
 	unsigned char keycode;
 	unsigned char set2;
 } atkbd_scroll_keys[] = {
@@ -200,7 +200,7 @@ struct atkbd {
 	char phys[32];
 
 	unsigned short id;
-	unsigned char keycode[512];
+	unsigned short keycode[512];
 	DECLARE_BITMAP(force_release_mask, 512);
 	unsigned char set;
 	unsigned char translated;
@@ -357,7 +357,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
 	unsigned int code = data;
 	int scroll = 0, hscroll = 0, click = -1;
 	int value;
-	unsigned char keycode;
+	unsigned short keycode;
 
 #ifdef ATKBD_DEBUG
 	printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
@@ -850,6 +850,23 @@ static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd)
 				  atkbd->force_release_mask);
 }
 
+/*
+ * Perform fixup for HP system that doesn't generate release
+ * for its video switch
+ */
+static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
+{
+	const unsigned int forced_release_keys[] = {
+		0x94,
+	};
+	int i;
+
+	if (atkbd->set == 2)
+		for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
+			__set_bit(forced_release_keys[i],
+					atkbd->force_release_mask);
+}
+
 /*
  * atkbd_set_keycode_table() initializes keyboard's keycode table
  * according to the selected scancode set
@@ -961,16 +978,16 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
 		input_dev->evbit[0] |= BIT_MASK(EV_REL);
 		input_dev->relbit[0] = BIT_MASK(REL_WHEEL) |
 			BIT_MASK(REL_HWHEEL);
-		set_bit(BTN_MIDDLE, input_dev->keybit);
+		__set_bit(BTN_MIDDLE, input_dev->keybit);
 	}
 
 	input_dev->keycode = atkbd->keycode;
-	input_dev->keycodesize = sizeof(unsigned char);
+	input_dev->keycodesize = sizeof(unsigned short);
 	input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
 
 	for (i = 0; i < 512; i++)
 		if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
-			set_bit(atkbd->keycode[i], input_dev->keybit);
+			__set_bit(atkbd->keycode[i], input_dev->keybit);
 }
 
 /*
@@ -1452,6 +1469,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
 		.callback = atkbd_setup_fixup,
 		.driver_data = atkbd_latitude_keymap_fixup,
 	},
+	{
+		.ident = "HP 2133",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
+		},
+		.callback = atkbd_setup_fixup,
+		.driver_data = atkbd_hp_keymap_fixup,
+	},
 	{ }
 };
 

+ 69 - 20
drivers/input/keyboard/gpio_keys.c

@@ -26,23 +26,54 @@
 
 #include <asm/gpio.h>
 
+struct gpio_button_data {
+	struct gpio_keys_button *button;
+	struct input_dev *input;
+	struct timer_list timer;
+};
+
+struct gpio_keys_drvdata {
+	struct input_dev *input;
+	struct gpio_button_data data[0];
+};
+
+static void gpio_keys_report_event(struct gpio_keys_button *button,
+				   struct input_dev *input)
+{
+	unsigned int type = button->type ?: EV_KEY;
+	int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
+
+	input_event(input, type, button->code, !!state);
+	input_sync(input);
+}
+
+static void gpio_check_button(unsigned long _data)
+{
+	struct gpio_button_data *data = (struct gpio_button_data *)_data;
+
+	gpio_keys_report_event(data->button, data->input);
+}
+
 static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
 {
-	int i;
 	struct platform_device *pdev = dev_id;
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
-	struct input_dev *input = platform_get_drvdata(pdev);
+	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
+	int i;
 
 	for (i = 0; i < pdata->nbuttons; i++) {
 		struct gpio_keys_button *button = &pdata->buttons[i];
-		int gpio = button->gpio;
 
-		if (irq == gpio_to_irq(gpio)) {
-			unsigned int type = button->type ?: EV_KEY;
-			int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low;
+		if (irq == gpio_to_irq(button->gpio)) {
+			struct gpio_button_data *bdata = &ddata->data[i];
+
+			if (button->debounce_interval)
+				mod_timer(&bdata->timer,
+					  jiffies +
+					  msecs_to_jiffies(button->debounce_interval));
+			else
+				gpio_keys_report_event(button, bdata->input);
 
-			input_event(input, type, button->code, !!state);
-			input_sync(input);
 			return IRQ_HANDLED;
 		}
 	}
@@ -53,17 +84,21 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
 static int __devinit gpio_keys_probe(struct platform_device *pdev)
 {
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+	struct gpio_keys_drvdata *ddata;
 	struct input_dev *input;
 	int i, error;
 	int wakeup = 0;
 
+	ddata = kzalloc(sizeof(struct gpio_keys_drvdata) +
+			pdata->nbuttons * sizeof(struct gpio_button_data),
+			GFP_KERNEL);
 	input = input_allocate_device();
-	if (!input)
-		return -ENOMEM;
-
-	platform_set_drvdata(pdev, input);
+	if (!ddata || !input) {
+		error = -ENOMEM;
+		goto fail1;
+	}
 
-	input->evbit[0] = BIT_MASK(EV_KEY);
+	platform_set_drvdata(pdev, ddata);
 
 	input->name = pdev->name;
 	input->phys = "gpio-keys/input0";
@@ -74,16 +109,23 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 	input->id.product = 0x0001;
 	input->id.version = 0x0100;
 
+	ddata->input = input;
+
 	for (i = 0; i < pdata->nbuttons; i++) {
 		struct gpio_keys_button *button = &pdata->buttons[i];
+		struct gpio_button_data *bdata = &ddata->data[i];
 		int irq;
 		unsigned int type = button->type ?: EV_KEY;
 
+		bdata->input = input;
+		setup_timer(&bdata->timer,
+			    gpio_check_button, (unsigned long)bdata);
+
 		error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
 		if (error < 0) {
 			pr_err("gpio-keys: failed to request GPIO %d,"
 				" error %d\n", button->gpio, error);
-			goto fail;
+			goto fail2;
 		}
 
 		error = gpio_direction_input(button->gpio);
@@ -92,7 +134,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 				" direction for GPIO %d, error %d\n",
 				button->gpio, error);
 			gpio_free(button->gpio);
-			goto fail;
+			goto fail2;
 		}
 
 		irq = gpio_to_irq(button->gpio);
@@ -102,7 +144,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 				" for GPIO %d, error %d\n",
 				button->gpio, error);
 			gpio_free(button->gpio);
-			goto fail;
+			goto fail2;
 		}
 
 		error = request_irq(irq, gpio_keys_isr,
@@ -114,7 +156,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 			pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
 				irq, error);
 			gpio_free(button->gpio);
-			goto fail;
+			goto fail2;
 		}
 
 		if (button->wakeup)
@@ -127,21 +169,25 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 	if (error) {
 		pr_err("gpio-keys: Unable to register input device, "
 			"error: %d\n", error);
-		goto fail;
+		goto fail2;
 	}
 
 	device_init_wakeup(&pdev->dev, wakeup);
 
 	return 0;
 
- fail:
+ fail2:
 	while (--i >= 0) {
 		free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
+		if (pdata->buttons[i].debounce_interval)
+			del_timer_sync(&ddata->data[i].timer);
 		gpio_free(pdata->buttons[i].gpio);
 	}
 
 	platform_set_drvdata(pdev, NULL);
+ fail1:
 	input_free_device(input);
+	kfree(ddata);
 
 	return error;
 }
@@ -149,7 +195,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 static int __devexit gpio_keys_remove(struct platform_device *pdev)
 {
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
-	struct input_dev *input = platform_get_drvdata(pdev);
+	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
+	struct input_dev *input = ddata->input;
 	int i;
 
 	device_init_wakeup(&pdev->dev, 0);
@@ -157,6 +204,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
 	for (i = 0; i < pdata->nbuttons; i++) {
 		int irq = gpio_to_irq(pdata->buttons[i].gpio);
 		free_irq(irq, pdev);
+		if (pdata->buttons[i].debounce_interval)
+			del_timer_sync(&ddata->data[i].timer);
 		gpio_free(pdata->buttons[i].gpio);
 	}
 

+ 3 - 3
drivers/input/keyboard/lkkbd.c

@@ -538,11 +538,11 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
 			switch (code) {
 				case SND_CLICK:
 					if (value == 0) {
-						DBG ("%s: Deactivating key clicks\n", __FUNCTION__);
+						DBG ("%s: Deactivating key clicks\n", __func__);
 						lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
 						lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
 					} else {
-						DBG ("%s: Activating key clicks\n", __FUNCTION__);
+						DBG ("%s: Activating key clicks\n", __func__);
 						lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
 						lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
 						lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
@@ -560,7 +560,7 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
 
 		default:
 			printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n",
-					__FUNCTION__, type, code, value);
+					__func__, type, code, value);
 	}
 
 	return -1;

+ 14 - 1
drivers/input/keyboard/pxa27x_keypad.c

@@ -105,6 +105,8 @@ struct pxa27x_keypad {
 	struct input_dev *input_dev;
 	void __iomem *mmio_base;
 
+	int irq;
+
 	/* matrix key code map */
 	unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
 
@@ -392,6 +394,10 @@ static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t stat
 	struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
 
 	clk_disable(keypad->clk);
+
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(keypad->irq);
+
 	return 0;
 }
 
@@ -400,6 +406,9 @@ static int pxa27x_keypad_resume(struct platform_device *pdev)
 	struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
 	struct input_dev *input_dev = keypad->input_dev;
 
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(keypad->irq);
+
 	mutex_lock(&input_dev->mutex);
 
 	if (input_dev->users) {
@@ -509,6 +518,8 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
 		goto failed_free_dev;
 	}
 
+	keypad->irq = irq;
+
 	/* Register the input device */
 	error = input_register_device(input_dev);
 	if (error) {
@@ -516,6 +527,8 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
 		goto failed_free_irq;
 	}
 
+	device_init_wakeup(&pdev->dev, 1);
+
 	return 0;
 
 failed_free_irq:
@@ -539,7 +552,7 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev)
 	struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
 	struct resource *res;
 
-	free_irq(platform_get_irq(pdev, 0), pdev);
+	free_irq(keypad->irq, pdev);
 
 	clk_disable(keypad->clk);
 	clk_put(keypad->clk);

+ 0 - 2
drivers/input/keyboard/sunkbd.c

@@ -1,6 +1,4 @@
 /*
- * $Id: sunkbd.c,v 1.14 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/keyboard/xtkbd.c

@@ -1,6 +1,4 @@
 /*
- * $Id: xtkbd.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 

+ 10 - 0
drivers/input/misc/Kconfig

@@ -189,6 +189,16 @@ config INPUT_UINPUT
 	  To compile this driver as a module, choose M here: the
 	  module will be called uinput.
 
+config INPUT_SGI_BTNS
+	tristate "SGI Indy/O2 volume button interface"
+	depends on SGI_IP22 || SGI_IP32
+	select INPUT_POLLDEV
+	help
+	  Say Y here if you want to support SGI Indy/O2 volume button interface.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sgi_btns.
+
 config HP_SDC_RTC
 	tristate "HP SDC Real Time Clock"
 	depends on GSC || HP300

+ 1 - 0
drivers/input/misc/Makefile

@@ -19,3 +19,4 @@ obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
+obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o

+ 9 - 9
drivers/input/misc/ati_remote.c

@@ -330,7 +330,7 @@ static int ati_remote_open(struct input_dev *inputdev)
 	ati_remote->irq_urb->dev = ati_remote->udev;
 	if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) {
 		dev_err(&ati_remote->interface->dev,
-			"%s: usb_submit_urb failed!\n", __FUNCTION__);
+			"%s: usb_submit_urb failed!\n", __func__);
 		return -EIO;
 	}
 
@@ -356,7 +356,7 @@ static void ati_remote_irq_out(struct urb *urb)
 
 	if (urb->status) {
 		dev_dbg(&ati_remote->interface->dev, "%s: status %d\n",
-			__FUNCTION__, urb->status);
+			__func__, urb->status);
 		return;
 	}
 
@@ -601,17 +601,17 @@ static void ati_remote_irq_in(struct urb *urb)
 	case -ENOENT:
 	case -ESHUTDOWN:
 		dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n",
-			__FUNCTION__);
+			__func__);
 		return;
 	default:		/* error */
 		dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n",
-			__FUNCTION__, urb->status);
+			__func__, urb->status);
 	}
 
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
 		dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n",
-			__FUNCTION__, retval);
+			__func__, retval);
 }
 
 /*
@@ -734,7 +734,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
 	int err = -ENOMEM;
 
 	if (iface_host->desc.bNumEndpoints != 2) {
-		err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__);
+		err("%s: Unexpected desc.bNumEndpoints\n", __func__);
 		return -ENODEV;
 	}
 
@@ -742,11 +742,11 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
 	endpoint_out = &iface_host->endpoint[1].desc;
 
 	if (!usb_endpoint_is_int_in(endpoint_in)) {
-		err("%s: Unexpected endpoint_in\n", __FUNCTION__);
+		err("%s: Unexpected endpoint_in\n", __func__);
 		return -ENODEV;
 	}
 	if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
-		err("%s: endpoint_in message size==0? \n", __FUNCTION__);
+		err("%s: endpoint_in message size==0? \n", __func__);
 		return -ENODEV;
 	}
 
@@ -814,7 +814,7 @@ static void ati_remote_disconnect(struct usb_interface *interface)
 	ati_remote = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
 	if (!ati_remote) {
-		warn("%s - null device?\n", __FUNCTION__);
+		warn("%s - null device?\n", __func__);
 		return;
 	}
 

+ 9 - 9
drivers/input/misc/ati_remote2.c

@@ -137,14 +137,14 @@ static int ati_remote2_open(struct input_dev *idev)
 	r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
 	if (r) {
 		dev_err(&ar2->intf[0]->dev,
-			"%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+			"%s: usb_submit_urb() = %d\n", __func__, r);
 		return r;
 	}
 	r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
 	if (r) {
 		usb_kill_urb(ar2->urb[0]);
 		dev_err(&ar2->intf[1]->dev,
-			"%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+			"%s: usb_submit_urb() = %d\n", __func__, r);
 		return r;
 	}
 
@@ -294,17 +294,17 @@ static void ati_remote2_complete_mouse(struct urb *urb)
 	case -ECONNRESET:
 	case -ESHUTDOWN:
 		dev_dbg(&ar2->intf[0]->dev,
-			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+			"%s(): urb status = %d\n", __func__, urb->status);
 		return;
 	default:
 		dev_err(&ar2->intf[0]->dev,
-			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+			"%s(): urb status = %d\n", __func__, urb->status);
 	}
 
 	r = usb_submit_urb(urb, GFP_ATOMIC);
 	if (r)
 		dev_err(&ar2->intf[0]->dev,
-			"%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+			"%s(): usb_submit_urb() = %d\n", __func__, r);
 }
 
 static void ati_remote2_complete_key(struct urb *urb)
@@ -321,17 +321,17 @@ static void ati_remote2_complete_key(struct urb *urb)
 	case -ECONNRESET:
 	case -ESHUTDOWN:
 		dev_dbg(&ar2->intf[1]->dev,
-			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+			"%s(): urb status = %d\n", __func__, urb->status);
 		return;
 	default:
 		dev_err(&ar2->intf[1]->dev,
-			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+			"%s(): urb status = %d\n", __func__, urb->status);
 	}
 
 	r = usb_submit_urb(urb, GFP_ATOMIC);
 	if (r)
 		dev_err(&ar2->intf[1]->dev,
-			"%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+			"%s(): usb_submit_urb() = %d\n", __func__, r);
 }
 
 static int ati_remote2_input_init(struct ati_remote2 *ar2)
@@ -438,7 +438,7 @@ static int ati_remote2_setup(struct ati_remote2 *ar2)
 			    channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT);
 	if (r) {
 		dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n",
-			__FUNCTION__, r);
+			__func__, r);
 		return r;
 	}
 

+ 10 - 10
drivers/input/misc/keyspan_remote.c

@@ -159,7 +159,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
 	if (dev->data.pos >= dev->data.len) {
 		dev_dbg(&dev->udev->dev,
 			"%s - Error ran out of data. pos: %d, len: %d\n",
-			__FUNCTION__, dev->data.pos, dev->data.len);
+			__func__, dev->data.pos, dev->data.len);
 		return -1;
 	}
 
@@ -267,7 +267,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
 				remote->data.tester = remote->data.tester >> 6;
 				remote->data.bits_left -= 6;
 			} else {
-				err("%s - Unknown sequence found in system data.\n", __FUNCTION__);
+				err("%s - Unknown sequence found in system data.\n", __func__);
 				remote->stage = 0;
 				return;
 			}
@@ -286,7 +286,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
 				remote->data.tester = remote->data.tester >> 6;
 				remote->data.bits_left -= 6;
 			} else {
-				err("%s - Unknown sequence found in button data.\n", __FUNCTION__);
+				err("%s - Unknown sequence found in button data.\n", __func__);
 				remote->stage = 0;
 				return;
 			}
@@ -302,7 +302,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
 			remote->data.tester = remote->data.tester >> 6;
 			remote->data.bits_left -= 6;
 		} else {
-			err("%s - Error in message, invalid toggle.\n", __FUNCTION__);
+			err("%s - Error in message, invalid toggle.\n", __func__);
 			remote->stage = 0;
 			return;
 		}
@@ -317,7 +317,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
 
 		dev_dbg(&remote->udev->dev,
 			"%s found valid message: system: %d, button: %d, toggle: %d\n",
-			__FUNCTION__, message.system, message.button, message.toggle);
+			__func__, message.system, message.button, message.toggle);
 
 		if (message.toggle != remote->toggle) {
 			keyspan_report_button(remote, message.button, 1);
@@ -341,7 +341,7 @@ static int keyspan_setup(struct usb_device* dev)
 				 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0);
 	if (retval) {
 		dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n",
-			__FUNCTION__, retval);
+			__func__, retval);
 		return(retval);
 	}
 
@@ -349,7 +349,7 @@ static int keyspan_setup(struct usb_device* dev)
 				 0x44, 0x40, 0x0, 0x0, NULL, 0, 0);
 	if (retval) {
 		dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n",
-			__FUNCTION__, retval);
+			__func__, retval);
 		return(retval);
 	}
 
@@ -357,11 +357,11 @@ static int keyspan_setup(struct usb_device* dev)
 				 0x22, 0x40, 0x0, 0x0, NULL, 0, 0);
 	if (retval) {
 		dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n",
-			__FUNCTION__, retval);
+			__func__, retval);
 		return(retval);
 	}
 
-	dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__);
+	dev_dbg(&dev->dev, "%s - Setup complete.\n", __func__);
 	return(retval);
 }
 
@@ -397,7 +397,7 @@ static void keyspan_irq_recv(struct urb *urb)
 resubmit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
-		err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval);
+		err ("%s - usb_submit_urb failed with result: %d", __func__, retval);
 }
 
 static int keyspan_open(struct input_dev *dev)

+ 3 - 3
drivers/input/misc/powermate.c

@@ -96,10 +96,10 @@ static void powermate_irq(struct urb *urb)
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
 		goto exit;
 	}
 
@@ -112,7 +112,7 @@ exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
-		     __FUNCTION__, retval);
+		     __func__, retval);
 }
 
 /* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */

+ 178 - 0
drivers/input/misc/sgi_btns.c

@@ -0,0 +1,178 @@
+/*
+ *  SGI Volume Button interface driver
+ *
+ *  Copyright (C) 2008  Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+ *
+ *  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
+ *  (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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+#include <linux/input-polldev.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#ifdef CONFIG_SGI_IP22
+#include <asm/sgi/ioc.h>
+
+static inline u8 button_status(void)
+{
+	u8 status;
+
+	status = readb(&sgioc->panel) ^ 0xa0;
+	return ((status & 0x80) >> 6) | ((status & 0x20) >> 5);
+}
+#endif
+
+#ifdef CONFIG_SGI_IP32
+#include <asm/ip32/mace.h>
+
+static inline u8 button_status(void)
+{
+	u64 status;
+
+	status = readq(&mace->perif.audio.control);
+	writeq(status & ~(3U << 23), &mace->perif.audio.control);
+
+	return (status >> 23) & 3;
+}
+#endif
+
+#define BUTTONS_POLL_INTERVAL	30	/* msec */
+#define BUTTONS_COUNT_THRESHOLD	3
+
+static const unsigned short sgi_map[] = {
+	KEY_VOLUMEDOWN,
+	KEY_VOLUMEUP
+};
+
+struct buttons_dev {
+	struct input_polled_dev *poll_dev;
+	unsigned short keymap[ARRAY_SIZE(sgi_map)];
+	int count[ARRAY_SIZE(sgi_map)];
+};
+
+static void handle_buttons(struct input_polled_dev *dev)
+{
+	struct buttons_dev *bdev = dev->private;
+	struct input_dev *input = dev->input;
+	u8 status;
+	int i;
+
+	status = button_status();
+
+	for (i = 0; i < ARRAY_SIZE(bdev->keymap); i++) {
+		if (status & (1U << i)) {
+			if (++bdev->count[i] == BUTTONS_COUNT_THRESHOLD) {
+				input_event(input, EV_MSC, MSC_SCAN, i);
+				input_report_key(input, bdev->keymap[i], 1);
+				input_sync(input);
+			}
+		} else {
+			if (bdev->count[i] >= BUTTONS_COUNT_THRESHOLD) {
+				input_event(input, EV_MSC, MSC_SCAN, i);
+				input_report_key(input, bdev->keymap[i], 0);
+				input_sync(input);
+			}
+			bdev->count[i] = 0;
+		}
+	}
+}
+
+static int __devinit sgi_buttons_probe(struct platform_device *pdev)
+{
+	struct buttons_dev *bdev;
+	struct input_polled_dev *poll_dev;
+	struct input_dev *input;
+	int error, i;
+
+	bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL);
+	poll_dev = input_allocate_polled_device();
+	if (!bdev || !poll_dev) {
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	memcpy(bdev->keymap, sgi_map, sizeof(bdev->keymap));
+
+	poll_dev->private = bdev;
+	poll_dev->poll = handle_buttons;
+	poll_dev->poll_interval = BUTTONS_POLL_INTERVAL;
+
+	input = poll_dev->input;
+	input->name = "SGI buttons";
+	input->phys = "sgi/input0";
+	input->id.bustype = BUS_HOST;
+	input->dev.parent = &pdev->dev;
+
+	input->keycode = bdev->keymap;
+	input->keycodemax = ARRAY_SIZE(bdev->keymap);
+	input->keycodesize = sizeof(unsigned short);
+
+	input_set_capability(input, EV_MSC, MSC_SCAN);
+	__set_bit(EV_KEY, input->evbit);
+	for (i = 0; i < ARRAY_SIZE(sgi_map); i++)
+		__set_bit(bdev->keymap[i], input->keybit);
+	__clear_bit(KEY_RESERVED, input->keybit);
+
+	bdev->poll_dev = poll_dev;
+	dev_set_drvdata(&pdev->dev, bdev);
+
+	error = input_register_polled_device(poll_dev);
+	if (error)
+		goto err_free_mem;
+
+	return 0;
+
+ err_free_mem:
+	input_free_polled_device(poll_dev);
+	kfree(bdev);
+	dev_set_drvdata(&pdev->dev, NULL);
+	return error;
+}
+
+static int __devexit sgi_buttons_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct buttons_dev *bdev = dev_get_drvdata(dev);
+
+	input_unregister_polled_device(bdev->poll_dev);
+	input_free_polled_device(bdev->poll_dev);
+	kfree(bdev);
+	dev_set_drvdata(dev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver sgi_buttons_driver = {
+	.probe	= sgi_buttons_probe,
+	.remove	= __devexit_p(sgi_buttons_remove),
+	.driver	= {
+		.name	= "sgibtns",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init sgi_buttons_init(void)
+{
+	return platform_driver_register(&sgi_buttons_driver);
+}
+
+static void __exit sgi_buttons_exit(void)
+{
+	platform_driver_unregister(&sgi_buttons_driver);
+}
+
+module_init(sgi_buttons_init);
+module_exit(sgi_buttons_exit);

+ 18 - 1
drivers/input/misc/wistron_btns.c

@@ -1186,7 +1186,7 @@ static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
 
 static int __devinit setup_input_dev(void)
 {
-	const struct key_entry *key;
+	struct key_entry *key;
 	struct input_dev *input_dev;
 	int error;
 
@@ -1219,6 +1219,23 @@ static int __devinit setup_input_dev(void)
 				set_bit(key->sw.code, input_dev->swbit);
 				break;
 
+			/* if wifi or bluetooth are not available, create normal keys */
+			case KE_WIFI:
+				if (!have_wifi) {
+					key->type = KE_KEY;
+					key->keycode = KEY_WLAN;
+					key--;
+				}
+				break;
+
+			case KE_BLUETOOTH:
+				if (!have_bluetooth) {
+					key->type = KE_KEY;
+					key->keycode = KEY_BLUETOOTH;
+					key--;
+				}
+				break;
+
 			default:
 				break;
 		}

+ 32 - 18
drivers/input/misc/yealink.c

@@ -119,6 +119,8 @@ struct yealink_dev {
 	u8 lcdMap[ARRAY_SIZE(lcdMap)];	/* state of LCD, LED ... */
 	int key_code;			/* last reported key	 */
 
+	unsigned int shutdown:1;
+
 	int	stat_ix;
 	union {
 		struct yld_status s;
@@ -424,10 +426,10 @@ send_update:
 static void urb_irq_callback(struct urb *urb)
 {
 	struct yealink_dev *yld = urb->context;
-	int ret;
+	int ret, status = urb->status;
 
-	if (urb->status)
-		err("%s - urb status %d", __FUNCTION__, urb->status);
+	if (status)
+		err("%s - urb status %d", __func__, status);
 
 	switch (yld->irq_data->cmd) {
 	case CMD_KEYPRESS:
@@ -447,33 +449,38 @@ static void urb_irq_callback(struct urb *urb)
 
 	yealink_do_idle_tasks(yld);
 
-	ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
-	if (ret)
-		err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
+	if (!yld->shutdown) {
+		ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+		if (ret && ret != -EPERM)
+			err("%s - usb_submit_urb failed %d", __func__, ret);
+	}
 }
 
 static void urb_ctl_callback(struct urb *urb)
 {
 	struct yealink_dev *yld = urb->context;
-	int ret;
+	int ret = 0, status = urb->status;
 
-	if (urb->status)
-		err("%s - urb status %d", __FUNCTION__, urb->status);
+	if (status)
+		err("%s - urb status %d", __func__, status);
 
 	switch (yld->ctl_data->cmd) {
 	case CMD_KEYPRESS:
 	case CMD_SCANCODE:
 		/* ask for a response */
-		ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
+		if (!yld->shutdown)
+			ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
 		break;
 	default:
 		/* send new command */
 		yealink_do_idle_tasks(yld);
-		ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+		if (!yld->shutdown)
+			ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+		break;
 	}
 
-	if (ret)
-		err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
+	if (ret && ret != -EPERM)
+		err("%s - usb_submit_urb failed %d", __func__, ret);
 }
 
 /*******************************************************************************
@@ -505,7 +512,7 @@ static int input_open(struct input_dev *dev)
 	struct yealink_dev *yld = input_get_drvdata(dev);
 	int i, ret;
 
-	dbg("%s", __FUNCTION__);
+	dbg("%s", __func__);
 
 	/* force updates to device */
 	for (i = 0; i<sizeof(yld->master); i++)
@@ -521,7 +528,7 @@ static int input_open(struct input_dev *dev)
 	yld->ctl_data->sum	= 0x100-CMD_INIT-10;
 	if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
 		dbg("%s - usb_submit_urb failed with result %d",
-		     __FUNCTION__, ret);
+		     __func__, ret);
 		return ret;
 	}
 	return 0;
@@ -531,8 +538,18 @@ static void input_close(struct input_dev *dev)
 {
 	struct yealink_dev *yld = input_get_drvdata(dev);
 
+	yld->shutdown = 1;
+	/*
+	 * Make sure the flag is seen by other CPUs before we start
+	 * killing URBs so new URBs won't be submitted
+	 */
+	smp_wmb();
+
 	usb_kill_urb(yld->urb_ctl);
 	usb_kill_urb(yld->urb_irq);
+
+	yld->shutdown = 0;
+	smp_wmb();
 }
 
 /*******************************************************************************
@@ -809,9 +826,6 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
 	if (yld == NULL)
 		return err;
 
-	usb_kill_urb(yld->urb_irq);	/* parameter validation in core/urb */
-	usb_kill_urb(yld->urb_ctl);	/* parameter validation in core/urb */
-
         if (yld->idev) {
 		if (err)
 			input_free_device(yld->idev);

+ 138 - 161
drivers/input/mouse/appletouch.c

@@ -2,12 +2,13 @@
  * Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver
  *
  * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2005      Johannes Berg (johannes@sipsolutions.net)
+ * Copyright (C) 2005-2008 Johannes Berg (johannes@sipsolutions.net)
  * Copyright (C) 2005      Stelian Pop (stelian@popies.net)
  * Copyright (C) 2005      Frank Arnold (frank@scirocco-5v-turbo.de)
  * Copyright (C) 2005      Peter Osterlund (petero2@telia.com)
  * Copyright (C) 2005      Michael Hanselmann (linux-kernel@hansmi.ch)
  * Copyright (C) 2006      Nicolas Boichat (nicolas@boichat.ch)
+ * Copyright (C) 2007-2008 Sven Anders (anders@anduras.de)
  *
  * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
  *
@@ -34,77 +35,64 @@
 #include <linux/module.h>
 #include <linux/usb/input.h>
 
-/* Apple has powerbooks which have the keyboard with different Product IDs */
-#define APPLE_VENDOR_ID		0x05AC
-
-/* These names come from Info.plist in AppleUSBTrackpad.kext */
-#define FOUNTAIN_ANSI_PRODUCT_ID	0x020E
-#define FOUNTAIN_ISO_PRODUCT_ID		0x020F
-
-#define FOUNTAIN_TP_ONLY_PRODUCT_ID	0x030A
-
-#define GEYSER1_TP_ONLY_PRODUCT_ID	0x030B
-
-#define GEYSER_ANSI_PRODUCT_ID		0x0214
-#define GEYSER_ISO_PRODUCT_ID		0x0215
-#define GEYSER_JIS_PRODUCT_ID		0x0216
-
-/* MacBook devices */
-#define GEYSER3_ANSI_PRODUCT_ID		0x0217
-#define GEYSER3_ISO_PRODUCT_ID		0x0218
-#define GEYSER3_JIS_PRODUCT_ID		0x0219
-
-/*
- * Geyser IV: same as Geyser III according to Info.plist in AppleUSBTrackpad.kext
- * -> same IOClass (AppleUSBGrIIITrackpad), same acceleration tables
- */
-#define GEYSER4_ANSI_PRODUCT_ID	0x021A
-#define GEYSER4_ISO_PRODUCT_ID	0x021B
-#define GEYSER4_JIS_PRODUCT_ID	0x021C
-
-#define GEYSER4_HF_ANSI_PRODUCT_ID	0x0229
-#define GEYSER4_HF_ISO_PRODUCT_ID	0x022A
-#define GEYSER4_HF_JIS_PRODUCT_ID	0x022B
+/* Type of touchpad */
+enum atp_touchpad_type {
+	ATP_FOUNTAIN,
+	ATP_GEYSER1,
+	ATP_GEYSER2,
+	ATP_GEYSER3,
+	ATP_GEYSER4
+};
 
-#define ATP_DEVICE(prod)					\
+#define ATP_DEVICE(prod, type)					\
+{								\
 	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |		\
 		       USB_DEVICE_ID_MATCH_INT_CLASS |		\
 		       USB_DEVICE_ID_MATCH_INT_PROTOCOL,	\
-	.idVendor = APPLE_VENDOR_ID,				\
+	.idVendor = 0x05ac, /* Apple */				\
 	.idProduct = (prod),					\
 	.bInterfaceClass = 0x03,				\
-	.bInterfaceProtocol = 0x02
+	.bInterfaceProtocol = 0x02,				\
+	.driver_info = ATP_ ## type,				\
+}
+
+/*
+ * Table of devices (Product IDs) that work with this driver.
+ * (The names come from Info.plist in AppleUSBTrackpad.kext,
+ *  According to Info.plist Geyser IV is the same as Geyser III.)
+ */
 
-/* table of devices that work with this driver */
 static struct usb_device_id atp_table [] = {
-	{ ATP_DEVICE(FOUNTAIN_ANSI_PRODUCT_ID) },
-	{ ATP_DEVICE(FOUNTAIN_ISO_PRODUCT_ID) },
-	{ ATP_DEVICE(FOUNTAIN_TP_ONLY_PRODUCT_ID) },
-	{ ATP_DEVICE(GEYSER1_TP_ONLY_PRODUCT_ID) },
+	/* PowerBooks Feb 2005, iBooks G4 */
+	ATP_DEVICE(0x020e, FOUNTAIN),	/* FOUNTAIN ANSI */
+	ATP_DEVICE(0x020f, FOUNTAIN),	/* FOUNTAIN ISO */
+	ATP_DEVICE(0x030a, FOUNTAIN),	/* FOUNTAIN TP ONLY */
+	ATP_DEVICE(0x030b, GEYSER1),	/* GEYSER 1 TP ONLY */
 
 	/* PowerBooks Oct 2005 */
-	{ ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) },
-	{ ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
-	{ ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
+	ATP_DEVICE(0x0214, GEYSER2),	/* GEYSER 2 ANSI */
+	ATP_DEVICE(0x0215, GEYSER2),	/* GEYSER 2 ISO */
+	ATP_DEVICE(0x0216, GEYSER2),	/* GEYSER 2 JIS */
 
 	/* Core Duo MacBook & MacBook Pro */
-	{ ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) },
-	{ ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) },
-	{ ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) },
+	ATP_DEVICE(0x0217, GEYSER3),	/* GEYSER 3 ANSI */
+	ATP_DEVICE(0x0218, GEYSER3),	/* GEYSER 3 ISO */
+	ATP_DEVICE(0x0219, GEYSER3),	/* GEYSER 3 JIS */
 
 	/* Core2 Duo MacBook & MacBook Pro */
-	{ ATP_DEVICE(GEYSER4_ANSI_PRODUCT_ID) },
-	{ ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) },
-	{ ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) },
+	ATP_DEVICE(0x021a, GEYSER4),	/* GEYSER 4 ANSI */
+	ATP_DEVICE(0x021b, GEYSER4),	/* GEYSER 4 ISO */
+	ATP_DEVICE(0x021c, GEYSER4),	/* GEYSER 4 JIS */
 
-	{ ATP_DEVICE(GEYSER4_HF_ANSI_PRODUCT_ID) },
-	{ ATP_DEVICE(GEYSER4_HF_ISO_PRODUCT_ID) },
-	{ ATP_DEVICE(GEYSER4_HF_JIS_PRODUCT_ID) },
+	/* Core2 Duo MacBook3,1 */
+	ATP_DEVICE(0x0229, GEYSER4),	/* GEYSER 4 HF ANSI */
+	ATP_DEVICE(0x022a, GEYSER4),	/* GEYSER 4 HF ISO */
+	ATP_DEVICE(0x022b, GEYSER4),	/* GEYSER 4 HF JIS */
 
 	/* Terminating entry */
 	{ }
 };
-MODULE_DEVICE_TABLE (usb, atp_table);
+MODULE_DEVICE_TABLE(usb, atp_table);
 
 /*
  * number of sensors. Note that only 16 instead of 26 X (horizontal)
@@ -124,9 +112,13 @@ MODULE_DEVICE_TABLE (usb, atp_table);
  * We try to keep the touchpad aspect ratio while still doing only simple
  * arithmetics.
  * The factors below give coordinates like:
- *	0 <= x <  960 on 12" and 15" Powerbooks
- *	0 <= x < 1600 on 17" Powerbooks
- *	0 <= y <  646
+ *
+ *      0 <= x <  960 on 12" and 15" Powerbooks
+ *      0 <= x < 1600 on 17" Powerbooks and 17" MacBook Pro
+ *      0 <= x < 1216 on MacBooks and 15" MacBook Pro
+ *
+ *      0 <= y <  646 on all Powerbooks
+ *      0 <= y <  774 on all MacBooks
  */
 #define ATP_XFACT	64
 #define ATP_YFACT	43
@@ -147,43 +139,46 @@ MODULE_DEVICE_TABLE (usb, atp_table);
 /* Structure to hold all of our device specific stuff */
 struct atp {
 	char			phys[64];
-	struct usb_device *	udev;		/* usb device */
-	struct urb *		urb;		/* usb request block */
-	signed char *		data;		/* transferred data */
-	struct input_dev *	input;		/* input dev */
-	unsigned char		open;		/* non-zero if opened */
-	unsigned char		valid;		/* are the sensors valid ? */
-	unsigned char		size_detect_done;
-	unsigned char		overflowwarn;	/* overflow warning printed? */
+	struct usb_device	*udev;		/* usb device */
+	struct urb		*urb;		/* usb request block */
+	signed char		*data;		/* transferred data */
+	struct input_dev	*input;		/* input dev */
+	enum atp_touchpad_type	type;		/* type of touchpad */
+	bool			open;
+	bool			valid;		/* are the samples valid? */
+	bool			size_detect_done;
+	bool			overflow_warned;
 	int			x_old;		/* last reported x/y, */
 	int			y_old;		/* used for smoothing */
-						/* current value of the sensors */
 	signed char		xy_cur[ATP_XSENSORS + ATP_YSENSORS];
-						/* last value of the sensors */
 	signed char		xy_old[ATP_XSENSORS + ATP_YSENSORS];
-						/* accumulated sensors */
 	int			xy_acc[ATP_XSENSORS + ATP_YSENSORS];
-	int			datalen;	/* size of an USB urb transfer */
-	int			idlecount;      /* number of empty packets */
-	struct work_struct      work;
+	int			datalen;	/* size of USB transfer */
+	int			idlecount;	/* number of empty packets */
+	struct work_struct	work;
 };
 
 #define dbg_dump(msg, tab) \
 	if (debug > 1) {						\
-		int i;							\
-		printk("appletouch: %s %lld", msg, (long long)jiffies); \
-		for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++)	\
-			printk(" %02x", tab[i]);			\
+		int __i;						\
+		printk(KERN_DEBUG "appletouch: %s", msg);		\
+		for (__i = 0; __i < ATP_XSENSORS + ATP_YSENSORS; __i++)	\
+			printk(" %02x", tab[__i]);			\
 		printk("\n");						\
 	}
 
 #define dprintk(format, a...)						\
 	do {								\
-		if (debug) printk(KERN_DEBUG format, ##a);		\
+		if (debug)						\
+			printk(KERN_DEBUG format, ##a);			\
 	} while (0)
 
-MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann");
-MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
+MODULE_AUTHOR("Johannes Berg");
+MODULE_AUTHOR("Stelian Pop");
+MODULE_AUTHOR("Frank Arnold");
+MODULE_AUTHOR("Michael Hanselmann");
+MODULE_AUTHOR("Sven Anders");
+MODULE_DESCRIPTION("Apple PowerBook and MacBook USB touchpad driver");
 MODULE_LICENSE("GPL");
 
 /*
@@ -191,46 +186,14 @@ MODULE_LICENSE("GPL");
  */
 static int threshold = ATP_THRESHOLD;
 module_param(threshold, int, 0644);
-MODULE_PARM_DESC(threshold, "Discards any change in data from a sensor (trackpad has hundreds of these sensors) less than this value");
+MODULE_PARM_DESC(threshold, "Discard any change in data from a sensor"
+			    " (the trackpad has many of these sensors)"
+			    " less than this value.");
 
-static int debug = 1;
+static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Activate debugging output");
 
-static inline int atp_is_fountain(struct atp *dev)
-{
-	u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
-
-	return productId == FOUNTAIN_ANSI_PRODUCT_ID ||
-	       productId == FOUNTAIN_ISO_PRODUCT_ID ||
-	       productId == FOUNTAIN_TP_ONLY_PRODUCT_ID;
-}
-
-/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
-static inline int atp_is_geyser_2(struct atp *dev)
-{
-	u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
-
-	return (productId == GEYSER_ANSI_PRODUCT_ID) ||
-		(productId == GEYSER_ISO_PRODUCT_ID) ||
-		(productId == GEYSER_JIS_PRODUCT_ID);
-}
-
-static inline int atp_is_geyser_3(struct atp *dev)
-{
-	u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
-
-	return (productId == GEYSER3_ANSI_PRODUCT_ID) ||
-		(productId == GEYSER3_ISO_PRODUCT_ID) ||
-		(productId == GEYSER3_JIS_PRODUCT_ID) ||
-		(productId == GEYSER4_ANSI_PRODUCT_ID) ||
-		(productId == GEYSER4_ISO_PRODUCT_ID) ||
-		(productId == GEYSER4_JIS_PRODUCT_ID) ||
-		(productId == GEYSER4_HF_ANSI_PRODUCT_ID) ||
-		(productId == GEYSER4_HF_ISO_PRODUCT_ID) ||
-		(productId == GEYSER4_HF_JIS_PRODUCT_ID);
-}
-
 /*
  * By default newer Geyser devices send standard USB HID mouse
  * packets (Report ID 2). This code changes device mode, so it
@@ -240,6 +203,7 @@ static int atp_geyser_init(struct usb_device *udev)
 {
 	char data[8];
 	int size;
+	int i;
 
 	size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 			ATP_GEYSER_MODE_READ_REQUEST_ID,
@@ -248,8 +212,11 @@ static int atp_geyser_init(struct usb_device *udev)
 			ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
 
 	if (size != 8) {
-		err("Could not do mode read request from device"
-		    " (Geyser Raw mode)");
+		dprintk("atp_geyser_init: read error\n");
+		for (i = 0; i < 8; i++)
+			dprintk("appletouch[%d]: %d\n", i, data[i]);
+
+		err("Failed to read mode from device.");
 		return -EIO;
 	}
 
@@ -263,8 +230,11 @@ static int atp_geyser_init(struct usb_device *udev)
 			ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
 
 	if (size != 8) {
-		err("Could not do mode write request to device"
-		    " (Geyser Raw mode)");
+		dprintk("atp_geyser_init: write error\n");
+		for (i = 0; i < 8; i++)
+			dprintk("appletouch[%d]: %d\n", i, data[i]);
+
+		err("Failed to request geyser raw mode");
 		return -EIO;
 	}
 	return 0;
@@ -280,15 +250,15 @@ static void atp_reinit(struct work_struct *work)
 	struct usb_device *udev = dev->udev;
 	int retval;
 
+	dprintk("appletouch: putting appletouch to sleep (reinit)\n");
 	dev->idlecount = 0;
 
 	atp_geyser_init(udev);
 
 	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
-	if (retval) {
-		err("%s - usb_submit_urb failed with result %d",
-		    __FUNCTION__, retval);
-	}
+	if (retval)
+		err("atp_reinit: usb_submit_urb failed with error %d",
+		    retval);
 }
 
 static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
@@ -323,7 +293,8 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
 		 *
 		 * - Jason Parekh <jasonparekh@gmail.com>
 		 */
-		if (i < 1 || (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
+		if (i < 1 ||
+		    (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
 			(*fingers)++;
 			is_increasing = 1;
 		} else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) {
@@ -331,11 +302,11 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
 		}
 
 		/*
-		 * Subtracts threshold so a high sensor that just passes the threshold
-		 * won't skew the calculated absolute coordinate.  Fixes an issue
-		 * where slowly moving the mouse would occassionaly jump a number of
-		 * pixels (let me restate--slowly moving the mouse makes this issue
-		 * most apparent).
+		 * Subtracts threshold so a high sensor that just passes the
+		 * threshold won't skew the calculated absolute coordinate.
+		 * Fixes an issue where slowly moving the mouse would
+		 * occasionally jump a number of pixels (slowly moving the
+		 * finger makes this issue most apparent.)
 		 */
 		pcum += (xy_sensors[i] - threshold) * i;
 		psum += (xy_sensors[i] - threshold);
@@ -356,7 +327,7 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
 	input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
 }
 
-static void atp_complete(struct urb* urb)
+static void atp_complete(struct urb *urb)
 {
 	int x, y, x_z, y_z, x_f, y_f;
 	int retval, i, j;
@@ -368,22 +339,22 @@ static void atp_complete(struct urb* urb)
 		/* success */
 		break;
 	case -EOVERFLOW:
-		if(!dev->overflowwarn) {
+		if (!dev->overflow_warned) {
 			printk(KERN_WARNING "appletouch: OVERFLOW with data "
 				"length %d, actual length is %d\n",
 				dev->datalen, dev->urb->actual_length);
-			dev->overflowwarn = 1;
+			dev->overflow_warned = true;
 		}
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* This urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d",
-		    __FUNCTION__, urb->status);
+		dbg("atp_complete: urb shutting down with status: %d",
+		    urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d",
-		    __FUNCTION__, urb->status);
+		dbg("atp_complete: nonzero urb status received: %d",
+		    urb->status);
 		goto exit;
 	}
 
@@ -396,7 +367,7 @@ static void atp_complete(struct urb* urb)
 	}
 
 	/* reorder the sensors values */
-	if (atp_is_geyser_3(dev)) {
+	if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
 		memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
 
 		/*
@@ -415,7 +386,7 @@ static void atp_complete(struct urb* urb)
 			dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
 			dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
 		}
-	} else if (atp_is_geyser_2(dev)) {
+	} else if (dev->type == ATP_GEYSER2) {
 		memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
 
 		/*
@@ -438,7 +409,7 @@ static void atp_complete(struct urb* urb)
 	} else {
 		for (i = 0; i < 8; i++) {
 			/* X values */
-			dev->xy_cur[i     ] = dev->data[5 * i +  2];
+			dev->xy_cur[i +  0] = dev->data[5 * i +  2];
 			dev->xy_cur[i +  8] = dev->data[5 * i +  4];
 			dev->xy_cur[i + 16] = dev->data[5 * i + 42];
 			if (i < 2)
@@ -454,21 +425,22 @@ static void atp_complete(struct urb* urb)
 
 	if (!dev->valid) {
 		/* first sample */
-		dev->valid = 1;
+		dev->valid = true;
 		dev->x_old = dev->y_old = -1;
 		memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
 
 		if (dev->size_detect_done ||
-		    atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */
+		    dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */
 			goto exit;
 
 		/* 17" Powerbooks have extra X sensors */
-		for (i = (atp_is_geyser_2(dev) ? 15 : 16); i < ATP_XSENSORS; i++) {
+		for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
+		     i < ATP_XSENSORS; i++) {
 			if (!dev->xy_cur[i])
 				continue;
 
 			printk(KERN_INFO "appletouch: 17\" model detected.\n");
-			if (atp_is_geyser_2(dev))
+			if (dev->type == ATP_GEYSER2)
 				input_set_abs_params(dev->input, ABS_X, 0,
 						     (20 - 1) *
 						     ATP_XFACT - 1,
@@ -548,11 +520,15 @@ static void atp_complete(struct urb* urb)
 	 * several hundred times a second. Re-initialization does not
 	 * work on Fountain touchpads.
 	 */
-	if (!atp_is_fountain(dev)) {
+	if (dev->type != ATP_FOUNTAIN) {
+		/*
+		 * Button must not be pressed when entering suspend,
+		 * otherwise we will never release the button.
+		 */
 		if (!x && !y && !key) {
 			dev->idlecount++;
 			if (dev->idlecount == 10) {
-				dev->valid = 0;
+				dev->valid = false;
 				schedule_work(&dev->work);
 				/* Don't resubmit urb here, wait for reinit */
 				return;
@@ -561,12 +537,11 @@ static void atp_complete(struct urb* urb)
 			dev->idlecount = 0;
 	}
 
-exit:
+ exit:
 	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
-	if (retval) {
-		err("%s - usb_submit_urb failed with result %d",
-		    __FUNCTION__, retval);
-	}
+	if (retval)
+		err("atp_complete: usb_submit_urb failed with result %d",
+		    retval);
 }
 
 static int atp_open(struct input_dev *input)
@@ -593,7 +568,7 @@ static int atp_handle_geyser(struct atp *dev)
 {
 	struct usb_device *udev = dev->udev;
 
-	if (!atp_is_fountain(dev)) {
+	if (dev->type != ATP_FOUNTAIN) {
 		/* switch to raw sensor mode */
 		if (atp_geyser_init(udev))
 			return -EIO;
@@ -604,7 +579,8 @@ static int atp_handle_geyser(struct atp *dev)
 	return 0;
 }
 
-static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
+static int atp_probe(struct usb_interface *iface,
+		     const struct usb_device_id *id)
 {
 	struct atp *dev;
 	struct input_dev *input_dev;
@@ -640,13 +616,12 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
 
 	dev->udev = udev;
 	dev->input = input_dev;
-	dev->overflowwarn = 0;
-	if (atp_is_geyser_3(dev))
-		dev->datalen = 64;
-	else if (atp_is_geyser_2(dev))
-		dev->datalen = 64;
-	else
+	dev->type = id->driver_info;
+	dev->overflow_warned = false;
+	if (dev->type == ATP_FOUNTAIN || dev->type == ATP_GEYSER1)
 		dev->datalen = 81;
+	else
+		dev->datalen = 64;
 
 	dev->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->urb)
@@ -680,7 +655,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
 
 	set_bit(EV_ABS, input_dev->evbit);
 
-	if (atp_is_geyser_3(dev)) {
+	if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
 		/*
 		 * MacBook have 20 X sensors, 10 Y sensors
 		 */
@@ -688,7 +663,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
 				     ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
 		input_set_abs_params(input_dev, ABS_Y, 0,
 				     ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
-	} else if (atp_is_geyser_2(dev)) {
+	} else if (dev->type == ATP_GEYSER2) {
 		/*
 		 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
 		 * later.
@@ -703,9 +678,11 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
 		 * 17" models are detected later.
 		 */
 		input_set_abs_params(input_dev, ABS_X, 0,
-				     (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
+				     (16 - 1) * ATP_XFACT - 1,
+				     ATP_FUZZ, 0);
 		input_set_abs_params(input_dev, ABS_Y, 0,
-				     (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
+				     (ATP_YSENSORS - 1) * ATP_YFACT - 1,
+				     ATP_FUZZ, 0);
 	}
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
 
@@ -774,7 +751,7 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
 	struct atp *dev = usb_get_intfdata(iface);
 
 	usb_kill_urb(dev->urb);
-	dev->valid = 0;
+	dev->valid = false;
 
 	return 0;
 }

+ 12 - 15
drivers/input/mouse/atarimouse.c

@@ -57,15 +57,12 @@ MODULE_AUTHOR("Michael Schmitz <schmitz@biophys.uni-duesseldorf.de>");
 MODULE_DESCRIPTION("Atari mouse driver");
 MODULE_LICENSE("GPL");
 
-static int mouse_threshold[2] = {2,2};
+static int mouse_threshold[2] = {2, 2};
+module_param_array(mouse_threshold, int, NULL, 0);
 
-#ifdef __MODULE__
-MODULE_PARM(mouse_threshold, "2i");
-#endif
 #ifdef FIXED_ATARI_JOYSTICK
 extern int atari_mouse_buttons;
 #endif
-static int atamouse_used = 0;
 
 static struct input_dev *atamouse_dev;
 
@@ -97,9 +94,6 @@ static void atamouse_interrupt(char *buf)
 
 static int atamouse_open(struct input_dev *dev)
 {
-	if (atamouse_used++)
-		return 0;
-
 #ifdef FIXED_ATARI_JOYSTICK
 	atari_mouse_buttons = 0;
 #endif
@@ -107,23 +101,24 @@ static int atamouse_open(struct input_dev *dev)
 	ikbd_mouse_thresh(mouse_threshold[0], mouse_threshold[1]);
 	ikbd_mouse_rel_pos();
 	atari_input_mouse_interrupt_hook = atamouse_interrupt;
+
 	return 0;
 }
 
 static void atamouse_close(struct input_dev *dev)
 {
-	if (!--atamouse_used) {
-		ikbd_mouse_disable();
-		atari_mouse_interrupt_hook = NULL;
-	}
+	ikbd_mouse_disable();
+	atari_mouse_interrupt_hook = NULL;
 }
 
 static int __init atamouse_init(void)
 {
+	int error;
+
 	if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP))
 		return -ENODEV;
 
-	if (!(atari_keyb_init()))
+	if (!atari_keyb_init())
 		return -ENODEV;
 
 	atamouse_dev = input_allocate_device();
@@ -141,12 +136,14 @@ static int __init atamouse_init(void)
 	atamouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
 	atamouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
 		BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+
 	atamouse_dev->open = atamouse_open;
 	atamouse_dev->close = atamouse_close;
 
-	if (input_register_device(atamouse_dev)) {
+	error = input_register_device(atamouse_dev);
+	if (error) {
 		input_free_device(atamouse_dev);
-		return -ENOMEM;
+		return error;
 	}
 
 	return 0;

+ 26 - 11
drivers/input/mouse/hil_ptr.c

@@ -247,19 +247,24 @@ static void hil_ptr_disconnect(struct serio *serio)
 
 static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 {
-	struct hil_ptr	 *ptr;
-	const char	 *txt;
-	unsigned int	 i, naxsets, btntype;
-	uint8_t		 did, *idd;
-
-	if (!(ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL)))
+	struct hil_ptr	*ptr;
+	const char	*txt;
+	unsigned int	i, naxsets, btntype;
+	uint8_t		did, *idd;
+	int		error;
+
+	ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL);
+	if (!ptr)
 		return -ENOMEM;
 
 	ptr->dev = input_allocate_device();
-	if (!ptr->dev)
+	if (!ptr->dev) {
+		error = -ENOMEM;
 		goto bail0;
+	}
 
-	if (serio_open(serio, driver))
+	error = serio_open(serio, driver);
+	if (error)
 		goto bail1;
 
 	serio_set_drvdata(serio, ptr);
@@ -297,6 +302,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 	did = ptr->idd[0];
 	idd = ptr->idd + 1;
 	txt = "unknown";
+
 	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
 		ptr->dev->evbit[0] = BIT_MASK(EV_REL);
 		txt = "relative";
@@ -306,8 +312,11 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 		ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
 		txt = "absolute";
 	}
-	if (!ptr->dev->evbit[0])
+
+	if (!ptr->dev->evbit[0]) {
+		error = -ENODEV;
 		goto bail2;
+	}
 
 	ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
 	if (ptr->nbtn)
@@ -380,13 +389,19 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 	ptr->dev->id.version	= 0x0100; /* TODO: get from ptr->rsc */
 	ptr->dev->dev.parent	= &serio->dev;
 
-	input_register_device(ptr->dev);
+	error = input_register_device(ptr->dev);
+	if (error) {
+		printk(KERN_INFO PREFIX "Unable to register input device\n");
+		goto bail2;
+	}
+
 	printk(KERN_INFO "input: %s (%s), ID: %d\n",
 		ptr->dev->name,
 		(btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
 		did);
 
 	return 0;
+
  bail2:
 	serio_close(serio);
  bail1:
@@ -394,7 +409,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
  bail0:
 	kfree(ptr);
 	serio_set_drvdata(serio, NULL);
-	return -ENODEV;
+	return error;
 }
 
 static struct serio_device_id hil_ptr_ids[] = {

+ 0 - 2
drivers/input/mouse/inport.c

@@ -1,6 +1,4 @@
 /*
- * $Id: inport.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:

+ 0 - 2
drivers/input/mouse/logibm.c

@@ -1,6 +1,4 @@
 /*
- * $Id: logibm.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:

+ 0 - 2
drivers/input/mouse/pc110pad.c

@@ -1,6 +1,4 @@
 /*
- * $Id: pc110pad.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
  *  Based on the work of:

+ 0 - 2
drivers/input/mouse/sermouse.c

@@ -1,6 +1,4 @@
 /*
- * $Id: sermouse.c,v 1.17 2002/03/13 10:03:43 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 

+ 10 - 0
drivers/input/serio/Kconfig

@@ -190,4 +190,14 @@ config SERIO_RAW
 	  To compile this driver as a module, choose M here: the
 	  module will be called serio_raw.
 
+config SERIO_XILINX_XPS_PS2
+	tristate "Xilinx XPS PS/2 Controller Support"
+	depends on PPC
+	help
+	  This driver supports XPS PS/2 IP from the Xilinx EDK on
+	  PowerPC platform.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called xilinx_ps2.
+
 endif

+ 1 - 0
drivers/input/serio/Makefile

@@ -21,3 +21,4 @@ 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
+obj-$(CONFIG_SERIO_XILINX_XPS_PS2)	+= xilinx_ps2.o

+ 0 - 2
drivers/input/serio/ct82c710.c

@@ -1,6 +1,4 @@
 /*
- * $Id: ct82c710.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 

+ 3 - 3
drivers/input/serio/hil_mlc.c

@@ -76,7 +76,7 @@ static struct timer_list	hil_mlcs_kicker;
 static int			hil_mlcs_probe;
 
 static void hil_mlcs_process(unsigned long unused);
-DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
+static DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
 
 
 /* #define HIL_MLC_DEBUG */
@@ -459,7 +459,7 @@ static int hilse_operate(hil_mlc *mlc, int repoll)
 #define OUT_LAST(pack) \
 { HILSE_OUT_LAST,	{ .packet = pack }, 0, 0, 0, 0 },
 
-const struct hilse_node hil_mlc_se[HILSEN_END] = {
+static const struct hilse_node hil_mlc_se[HILSEN_END] = {
 
 	/* 0  HILSEN_START */
 	FUNC(hilse_init_lcv, 0,	HILSEN_NEXT,	HILSEN_SLEEP,	0)
@@ -784,7 +784,7 @@ static void hil_mlcs_process(unsigned long unused)
 
 /************************* Keepalive timer task *********************/
 
-void hil_mlcs_timer(unsigned long data)
+static void hil_mlcs_timer(unsigned long data)
 {
 	hil_mlcs_probe = 1;
 	tasklet_schedule(&hil_mlcs_tasklet);

+ 9 - 0
drivers/input/serio/hp_sdc.c

@@ -105,6 +105,10 @@ EXPORT_SYMBOL(__hp_sdc_enqueue_transaction);
 EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
 EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
 
+static unsigned int hp_sdc_disabled;
+module_param_named(no_hpsdc, hp_sdc_disabled, bool, 0);
+MODULE_PARM_DESC(no_hpsdc, "Do not enable HP SDC driver.");
+
 static hp_i8042_sdc	hp_sdc;	/* All driver state is kept in here. */
 
 /*************** primitives for use in any context *********************/
@@ -980,6 +984,11 @@ static int __init hp_sdc_register(void)
 	unsigned char i;
 #endif
 
+	if (hp_sdc_disabled) {
+		printk(KERN_WARNING PREFIX "HP SDC driver disabled by no_hpsdc=1.\n");
+		return -ENODEV;
+	}
+
 	hp_sdc.dev = NULL;
 	hp_sdc.dev_err = 0;
 #if defined(__hppa__)

+ 1 - 1
drivers/input/serio/hp_sdc_mlc.c

@@ -50,7 +50,7 @@ MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
 MODULE_DESCRIPTION("Glue for onboard HIL MLC in HP-PARISC machines");
 MODULE_LICENSE("Dual BSD/GPL");
 
-struct hp_sdc_mlc_priv_s {
+static struct hp_sdc_mlc_priv_s {
 	int emtestmode;
 	hp_sdc_transaction trans;
 	u8 tseq[16];

+ 56 - 11
drivers/input/serio/i8042-x86ia64io.h

@@ -63,11 +63,20 @@ static inline void i8042_write_command(int val)
 	outb(val, I8042_COMMAND_REG);
 }
 
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_X86
 
 #include <linux/dmi.h>
 
 static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
+	{
+		/* AUX LOOP command does not raise AUX IRQ */
+		.ident = "Arima-Rioworks HDAMB",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
+			DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
+			DMI_MATCH(DMI_BOARD_VERSION, "Rev E"),
+		},
+	},
 	{
 		/* AUX LOOP command does not raise AUX IRQ */
 		.ident = "ASUS P65UP5",
@@ -118,6 +127,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
 			DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
 		},
 	},
+	{
+		.ident = "Medion MAM 2070",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
+		},
+	},
 	{ }
 };
 
@@ -291,17 +308,36 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
 			DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
 		},
 	},
+	{
+		.ident = "Acer Aspire 1360",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
+		},
+	},
+	{
+		.ident = "Gericom Bellagio",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
+		},
+	},
 	{ }
 };
 
-
-
+#ifdef CONFIG_PNP
+static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
+	{
+		.ident = "Intel MBO Desktop D845PESV",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+		},
+	},
+	{ }
+};
 #endif
 
-#ifdef CONFIG_X86
-
-#include <linux/dmi.h>
-
 /*
  * Some Wistron based laptops need us to explicitly enable the 'Dritek
  * keyboard extension' to make their extra keys start generating scancodes.
@@ -330,6 +366,13 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
 		},
 	},
+	{
+		.ident = "Acer Aspire 5720",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
+		},
+	},
 	{
 		.ident = "Acer Aspire 9110",
 		.matches = {
@@ -356,7 +399,6 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
 
 #endif /* CONFIG_X86 */
 
-
 #ifdef CONFIG_PNP
 #include <linux/pnp.h>
 
@@ -466,6 +508,11 @@ static int __init i8042_pnp_init(void)
 	int pnp_data_busted = 0;
 	int err;
 
+#ifdef CONFIG_X86
+	if (dmi_check_system(i8042_dmi_nopnp_table))
+		i8042_nopnp = 1;
+#endif
+
 	if (i8042_nopnp) {
 		printk(KERN_INFO "i8042: PNP detection disabled\n");
 		return 0;
@@ -591,15 +638,13 @@ static int __init i8042_platform_init(void)
         i8042_reset = 1;
 #endif
 
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_X86
 	if (dmi_check_system(i8042_dmi_noloop_table))
 		i8042_noloop = 1;
 
 	if (dmi_check_system(i8042_dmi_nomux_table))
 		i8042_nomux = 1;
-#endif
 
-#ifdef CONFIG_X86
 	if (dmi_check_system(i8042_dmi_dritek_table))
 		i8042_dritek = 1;
 #endif /* CONFIG_X86 */

+ 0 - 52
drivers/input/serio/libps2.c

@@ -26,15 +26,6 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
 MODULE_DESCRIPTION("PS/2 driver library");
 MODULE_LICENSE("GPL");
 
-/* 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 device and waits for acknowledge.
  * It doesn't handle retransmission, though it could - because if there
@@ -245,49 +236,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 }
 EXPORT_SYMBOL(ps2_command);
 
-/*
- * 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(struct work_struct *work)
-{
-	struct ps2work *ps2work = container_of(work, struct ps2work, work);
-
-	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);
-
-	if (!schedule_work(&ps2work->work)) {
-		kfree(ps2work);
-		return -1;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(ps2_schedule_command);
-
 /*
  * ps2_init() initializes ps2dev structure
  */

+ 1 - 3
drivers/input/serio/q40kbd.c

@@ -1,6 +1,4 @@
 /*
- * $Id: q40kbd.c,v 1.12 2002/02/02 22:26:44 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
  *  Based on the work of:
@@ -49,7 +47,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
-DEFINE_SPINLOCK(q40kbd_lock);
+static DEFINE_SPINLOCK(q40kbd_lock);
 static struct serio *q40kbd_port;
 static struct platform_device *q40kbd_device;
 

+ 0 - 2
drivers/input/serio/rpckbd.c

@@ -1,6 +1,4 @@
 /*
- * $Id: rpckbd.c,v 1.7 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *  Copyright (c) 2002 Russell King
  */

+ 6 - 3
drivers/input/serio/serio.c

@@ -331,9 +331,10 @@ static void serio_handle_event(void)
 }
 
 /*
- * Remove all events that have been submitted for a given serio port.
+ * Remove all events that have been submitted for a given
+ * object, be it serio port or driver.
  */
-static void serio_remove_pending_events(struct serio *serio)
+static void serio_remove_pending_events(void *object)
 {
 	struct list_head *node, *next;
 	struct serio_event *event;
@@ -343,7 +344,7 @@ static void serio_remove_pending_events(struct serio *serio)
 
 	list_for_each_safe(node, next, &serio_event_list) {
 		event = list_entry(node, struct serio_event, node);
-		if (event->object == serio) {
+		if (event->object == object) {
 			list_del_init(node);
 			serio_free_event(event);
 		}
@@ -837,7 +838,9 @@ void serio_unregister_driver(struct serio_driver *drv)
 	struct serio *serio;
 
 	mutex_lock(&serio_mutex);
+
 	drv->manual_bind = 1;	/* so serio_find_driver ignores it */
+	serio_remove_pending_events(drv);
 
 start_over:
 	list_for_each_entry(serio, &serio_list, node) {

+ 380 - 0
drivers/input/serio/xilinx_ps2.c

@@ -0,0 +1,380 @@
+/*
+ * Xilinx XPS PS/2 device driver
+ *
+ * (c) 2005 MontaVista Software, Inc.
+ * (c) 2008 Xilinx, Inc.
+ *
+ * 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 (at your
+ * option) any later version.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/module.h>
+#include <linux/serio.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#define DRIVER_NAME		"xilinx_ps2"
+
+/* Register offsets for the xps2 device */
+#define XPS2_SRST_OFFSET	0x00000000 /* Software Reset register */
+#define XPS2_STATUS_OFFSET	0x00000004 /* Status register */
+#define XPS2_RX_DATA_OFFSET	0x00000008 /* Receive Data register */
+#define XPS2_TX_DATA_OFFSET	0x0000000C /* Transmit Data register */
+#define XPS2_GIER_OFFSET	0x0000002C /* Global Interrupt Enable reg */
+#define XPS2_IPISR_OFFSET	0x00000030 /* Interrupt Status register */
+#define XPS2_IPIER_OFFSET	0x00000038 /* Interrupt Enable register */
+
+/* Reset Register Bit Definitions */
+#define XPS2_SRST_RESET		0x0000000A /* Software Reset  */
+
+/* Status Register Bit Positions */
+#define XPS2_STATUS_RX_FULL	0x00000001 /* Receive Full  */
+#define XPS2_STATUS_TX_FULL	0x00000002 /* Transmit Full  */
+
+/* Bit definitions for ISR/IER registers. Both the registers have the same bit
+ * definitions and are only defined once. */
+#define XPS2_IPIXR_WDT_TOUT	0x00000001 /* Watchdog Timeout Interrupt */
+#define XPS2_IPIXR_TX_NOACK	0x00000002 /* Transmit No ACK Interrupt */
+#define XPS2_IPIXR_TX_ACK	0x00000004 /* Transmit ACK (Data) Interrupt */
+#define XPS2_IPIXR_RX_OVF	0x00000008 /* Receive Overflow Interrupt */
+#define XPS2_IPIXR_RX_ERR	0x00000010 /* Receive Error Interrupt */
+#define XPS2_IPIXR_RX_FULL	0x00000020 /* Receive Data Interrupt */
+
+/* Mask for all the Transmit Interrupts */
+#define XPS2_IPIXR_TX_ALL	(XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_TX_ACK)
+
+/* Mask for all the Receive Interrupts */
+#define XPS2_IPIXR_RX_ALL	(XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR |  \
+					XPS2_IPIXR_RX_FULL)
+
+/* Mask for all the Interrupts */
+#define XPS2_IPIXR_ALL		(XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL |  \
+					XPS2_IPIXR_WDT_TOUT)
+
+/* Global Interrupt Enable mask */
+#define XPS2_GIER_GIE_MASK	0x80000000
+
+struct xps2data {
+	int irq;
+	u32 phys_addr;
+	u32 remap_size;
+	spinlock_t lock;
+	u8 rxb;				/* Rx buffer */
+	void __iomem *base_address;	/* virt. address of control registers */
+	unsigned int dfl;
+	struct serio serio;		/* serio */
+};
+
+/************************************/
+/* XPS PS/2 data transmission calls */
+/************************************/
+
+/*
+ * xps2_recv() will attempt to receive a byte of data from the PS/2 port.
+ */
+static int xps2_recv(struct xps2data *drvdata, u8 *byte)
+{
+	u32 sr;
+	int status = -1;
+
+	/* If there is data available in the PS/2 receiver, read it */
+	sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
+	if (sr & XPS2_STATUS_RX_FULL) {
+		*byte = in_be32(drvdata->base_address + XPS2_RX_DATA_OFFSET);
+		status = 0;
+	}
+
+	return status;
+}
+
+/*********************/
+/* Interrupt handler */
+/*********************/
+static irqreturn_t xps2_interrupt(int irq, void *dev_id)
+{
+	struct xps2data *drvdata = dev_id;
+	u32 intr_sr;
+	u8 c;
+	int status;
+
+	/* Get the PS/2 interrupts and clear them */
+	intr_sr = in_be32(drvdata->base_address + XPS2_IPISR_OFFSET);
+	out_be32(drvdata->base_address + XPS2_IPISR_OFFSET, intr_sr);
+
+	/* Check which interrupt is active */
+	if (intr_sr & XPS2_IPIXR_RX_OVF)
+		printk(KERN_WARNING "%s: receive overrun error\n",
+			drvdata->serio.name);
+
+	if (intr_sr & XPS2_IPIXR_RX_ERR)
+		drvdata->dfl |= SERIO_PARITY;
+
+	if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT))
+		drvdata->dfl |= SERIO_TIMEOUT;
+
+	if (intr_sr & XPS2_IPIXR_RX_FULL) {
+		status = xps2_recv(drvdata, &drvdata->rxb);
+
+		/* Error, if a byte is not received */
+		if (status) {
+			printk(KERN_ERR
+				"%s: wrong rcvd byte count (%d)\n",
+				drvdata->serio.name, status);
+		} else {
+			c = drvdata->rxb;
+			serio_interrupt(&drvdata->serio, c, drvdata->dfl);
+			drvdata->dfl = 0;
+		}
+	}
+
+	if (intr_sr & XPS2_IPIXR_TX_ACK)
+		drvdata->dfl = 0;
+
+	return IRQ_HANDLED;
+}
+
+/*******************/
+/* serio callbacks */
+/*******************/
+
+/*
+ * sxps2_write() sends a byte out through the PS/2 interface.
+ */
+static int sxps2_write(struct serio *pserio, unsigned char c)
+{
+	struct xps2data *drvdata = pserio->port_data;
+	unsigned long flags;
+	u32 sr;
+	int status = -1;
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+
+	/* If the PS/2 transmitter is empty send a byte of data */
+	sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
+	if (!(sr & XPS2_STATUS_TX_FULL)) {
+		out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c);
+		status = 0;
+	}
+
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	return status;
+}
+
+/*
+ * sxps2_open() is called when a port is open by the higher layer.
+ */
+static int sxps2_open(struct serio *pserio)
+{
+	struct xps2data *drvdata = pserio->port_data;
+	int retval;
+
+	retval = request_irq(drvdata->irq, &xps2_interrupt, 0,
+				DRIVER_NAME, drvdata);
+	if (retval) {
+		printk(KERN_ERR
+			"%s: Couldn't allocate interrupt %d\n",
+			drvdata->serio.name, drvdata->irq);
+		return retval;
+	}
+
+	/* start reception by enabling the interrupts */
+	out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK);
+	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL);
+	(void)xps2_recv(drvdata, &drvdata->rxb);
+
+	return 0;		/* success */
+}
+
+/*
+ * sxps2_close() frees the interrupt.
+ */
+static void sxps2_close(struct serio *pserio)
+{
+	struct xps2data *drvdata = pserio->port_data;
+
+	/* Disable the PS2 interrupts */
+	out_be32(drvdata->base_address + XPS2_GIER_OFFSET, 0x00);
+	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0x00);
+	free_irq(drvdata->irq, drvdata);
+}
+
+/*********************/
+/* Device setup code */
+/*********************/
+
+static int xps2_setup(struct device *dev, struct resource *regs_res,
+		      struct resource *irq_res)
+{
+	struct xps2data *drvdata;
+	struct serio *serio;
+	unsigned long remap_size;
+	int retval;
+
+	if (!dev)
+		return -EINVAL;
+
+	if (!regs_res || !irq_res) {
+		dev_err(dev, "IO resource(s) not found\n");
+		return -EINVAL;
+	}
+
+	drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
+	if (!drvdata) {
+		dev_err(dev, "Couldn't allocate device private record\n");
+		return -ENOMEM;
+	}
+
+	dev_set_drvdata(dev, drvdata);
+
+	spin_lock_init(&drvdata->lock);
+	drvdata->irq = irq_res->start;
+
+	remap_size = regs_res->end - regs_res->start + 1;
+	if (!request_mem_region(regs_res->start, remap_size, DRIVER_NAME)) {
+		dev_err(dev, "Couldn't lock memory region at 0x%08X\n",
+			(unsigned int)regs_res->start);
+		retval = -EBUSY;
+		goto failed1;
+	}
+
+	/* Fill in configuration data and add them to the list */
+	drvdata->phys_addr = regs_res->start;
+	drvdata->remap_size = remap_size;
+	drvdata->base_address = ioremap(regs_res->start, remap_size);
+	if (drvdata->base_address == NULL) {
+		dev_err(dev, "Couldn't ioremap memory at 0x%08X\n",
+			(unsigned int)regs_res->start);
+		retval = -EFAULT;
+		goto failed2;
+	}
+
+	/* Disable all the interrupts, just in case */
+	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);
+
+	/* Reset the PS2 device and abort any current transaction, to make sure
+	 * we have the PS2 in a good state */
+	out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);
+
+	dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%08X, irq=%d\n",
+		drvdata->phys_addr, (u32)drvdata->base_address, drvdata->irq);
+
+	serio = &drvdata->serio;
+	serio->id.type = SERIO_8042;
+	serio->write = sxps2_write;
+	serio->open = sxps2_open;
+	serio->close = sxps2_close;
+	serio->port_data = drvdata;
+	serio->dev.parent = dev;
+	snprintf(serio->name, sizeof(serio->name),
+		 "Xilinx XPS PS/2 at %08X", drvdata->phys_addr);
+	snprintf(serio->phys, sizeof(serio->phys),
+		 "xilinxps2/serio at %08X", drvdata->phys_addr);
+	serio_register_port(serio);
+
+	return 0;		/* success */
+
+failed2:
+	release_mem_region(regs_res->start, remap_size);
+failed1:
+	kfree(drvdata);
+	dev_set_drvdata(dev, NULL);
+
+	return retval;
+}
+
+/***************************/
+/* OF Platform Bus Support */
+/***************************/
+
+static int __devinit xps2_of_probe(struct of_device *ofdev, const struct
+				   of_device_id * match)
+{
+	struct resource r_irq; /* Interrupt resources */
+	struct resource r_mem; /* IO mem resources */
+	int rc = 0;
+
+	printk(KERN_INFO "Device Tree Probing \'%s\'\n",
+			ofdev->node->name);
+
+	/* Get iospace for the device */
+	rc = of_address_to_resource(ofdev->node, 0, &r_mem);
+	if (rc) {
+		dev_err(&ofdev->dev, "invalid address\n");
+		return rc;
+	}
+
+	/* Get IRQ for the device */
+	rc = of_irq_to_resource(ofdev->node, 0, &r_irq);
+	if (rc == NO_IRQ) {
+		dev_err(&ofdev->dev, "no IRQ found\n");
+		return rc;
+	}
+
+	return xps2_setup(&ofdev->dev, &r_mem, &r_irq);
+}
+
+static int __devexit xps2_of_remove(struct of_device *of_dev)
+{
+	struct device *dev = &of_dev->dev;
+	struct xps2data *drvdata;
+
+	if (!dev)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(dev);
+
+	serio_unregister_port(&drvdata->serio);
+	iounmap(drvdata->base_address);
+	release_mem_region(drvdata->phys_addr, drvdata->remap_size);
+	kfree(drvdata);
+
+	dev_set_drvdata(dev, NULL);
+
+	return 0;		/* success */
+}
+
+/* Match table for of_platform binding */
+static struct of_device_id xps2_of_match[] __devinitdata = {
+	{ .compatible = "xlnx,xps-ps2-1.00.a", },
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, xps2_of_match);
+
+static struct of_platform_driver xps2_of_driver = {
+	.name		= DRIVER_NAME,
+	.match_table	= xps2_of_match,
+	.probe		= xps2_of_probe,
+	.remove		= __devexit_p(xps2_of_remove),
+};
+
+static int __init xps2_init(void)
+{
+	return of_register_platform_driver(&xps2_of_driver);
+}
+
+static void __exit xps2_cleanup(void)
+{
+	of_unregister_platform_driver(&xps2_of_driver);
+}
+
+module_init(xps2_init);
+module_exit(xps2_cleanup);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx XPS PS/2 driver");
+MODULE_LICENSE("GPL");
+

+ 2 - 2
drivers/input/tablet/acecad.c

@@ -73,10 +73,10 @@ static void usb_acecad_irq(struct urb *urb)
 		case -ENOENT:
 		case -ESHUTDOWN:
 			/* this urb is terminated, clean up */
-			dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+			dbg("%s - urb shutting down with status: %d", __func__, urb->status);
 			return;
 		default:
-			dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+			dbg("%s - nonzero urb status received: %d", __func__, urb->status);
 			goto resubmit;
 	}
 

+ 3 - 3
drivers/input/tablet/aiptek.c

@@ -449,12 +449,12 @@ static void aiptek_irq(struct urb *urb)
 	case -ESHUTDOWN:
 		/* This urb is terminated, clean up */
 		dbg("%s - urb shutting down with status: %d",
-		    __FUNCTION__, urb->status);
+		    __func__, urb->status);
 		return;
 
 	default:
 		dbg("%s - nonzero urb status received: %d",
-		    __FUNCTION__, urb->status);
+		    __func__, urb->status);
 		goto exit;
 	}
 
@@ -813,7 +813,7 @@ exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval != 0) {
 		err("%s - usb_submit_urb failed with result %d",
-		    __FUNCTION__, retval);
+		    __func__, retval);
 	}
 }
 

+ 1 - 1
drivers/input/tablet/gtco.c

@@ -863,7 +863,7 @@ static int gtco_probe(struct usb_interface *usbinterface,
 	gtco->urbinfo = usb_alloc_urb(0, GFP_KERNEL);
 	if (!gtco->urbinfo) {
 		err("Failed to allocate URB");
-		return -ENOMEM;
+		error = -ENOMEM;
 		goto err_free_buf;
 	}
 

+ 3 - 3
drivers/input/tablet/kbtab.c

@@ -56,10 +56,10 @@ static void kbtab_irq(struct urb *urb)
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
 		goto exit;
 	}
 
@@ -88,7 +88,7 @@ static void kbtab_irq(struct urb *urb)
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
-		     __FUNCTION__, retval);
+		     __func__, retval);
 }
 
 static struct usb_device_id kbtab_ids[] = {

+ 1 - 1
drivers/input/tablet/wacom.h

@@ -105,7 +105,7 @@ struct wacom {
 	struct urb *irq;
 	struct wacom_wac * wacom_wac;
 	struct mutex lock;
-	int open:1;
+	unsigned int open:1;
 	char phys[32];
 };
 

+ 3 - 3
drivers/input/tablet/wacom_sys.c

@@ -56,10 +56,10 @@ static void wacom_sys_irq(struct urb *urb)
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
 		return;
 	default:
-		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
 		goto exit;
 	}
 
@@ -74,7 +74,7 @@ static void wacom_sys_irq(struct urb *urb)
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
-		     __FUNCTION__, retval);
+		     __func__, retval);
 }
 
 void wacom_report_key(void *wcombo, unsigned int key_type, int key_data)

+ 19 - 20
drivers/input/tablet/wacom_wac.c

@@ -56,7 +56,7 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo)
 static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
 {
 	unsigned char *data = wacom->data;
-	int prox, id, pressure;
+	int prox, pressure;
 
 	if (data[0] != 2) {
 		dbg("wacom_pl_irq: received unknown report #%d", data[0]);
@@ -65,7 +65,7 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
 
 	prox = data[1] & 0x40;
 
-	id = ERASER_DEVICE_ID;
+	wacom->id[0] = ERASER_DEVICE_ID;
 	if (prox) {
 
 		pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
@@ -99,10 +99,10 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
 		if (wacom->tool[1] != BTN_TOOL_RUBBER) {
 			/* Unknown tool selected default to pen tool */
 			wacom->tool[1] = BTN_TOOL_PEN;
-			id = STYLUS_DEVICE_ID;
+			wacom->id[0] = STYLUS_DEVICE_ID;
 		}
 		wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */
-		wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
+		wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
 		wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
 		wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
 		wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
@@ -127,7 +127,6 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
 static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
 {
 	unsigned char *data = wacom->data;
-	int id;
 
 	if (data[0] != 2) {
 		printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
@@ -137,13 +136,13 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
 	if (data[1] & 0x04) {
 		wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20);
 		wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08);
-		id = ERASER_DEVICE_ID;
+		wacom->id[0] = ERASER_DEVICE_ID;
 	} else {
 		wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20);
 		wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
-		id = STYLUS_DEVICE_ID;
+		wacom->id[0] = STYLUS_DEVICE_ID;
 	}
-	wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
+	wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
 	wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
 	wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
 	wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6]));
@@ -155,27 +154,26 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
 static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 {
 	unsigned char *data = wacom->data;
-	int x, y, id, rw;
+	int x, y, rw;
 
 	if (data[0] != 2) {
 		dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
 		return 0;
 	}
 
-	id = STYLUS_DEVICE_ID;
-	if ((data[1] & 0x80) && ((data[1] & 0x07) || data[2] || data[3] || data[4]
-			|| data[5] || data[6] || (data[7] & 0x07))) {
+	if (data[1] & 0x80) {
 		/* in prox and not a pad data */
 
 		switch ((data[1] >> 5) & 3) {
 
 			case 0:	/* Pen */
 				wacom->tool[0] = BTN_TOOL_PEN;
+				wacom->id[0] = STYLUS_DEVICE_ID;
 				break;
 
 			case 1: /* Rubber */
 				wacom->tool[0] = BTN_TOOL_RUBBER;
-				id = ERASER_DEVICE_ID;
+				wacom->id[0] = ERASER_DEVICE_ID;
 				break;
 
 			case 2: /* Mouse with wheel */
@@ -190,7 +188,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 
 			case 3: /* Mouse without wheel */
 				wacom->tool[0] = BTN_TOOL_MOUSE;
-				id = CURSOR_DEVICE_ID;
+				wacom->id[0] = CURSOR_DEVICE_ID;
 				wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
 				wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
 				if (wacom->features->type == WACOM_G4 ||
@@ -210,9 +208,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 			wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
 			wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
 		}
-		wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
+		wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
 		wacom_report_key(wcombo, wacom->tool[0], 1);
-	} else if (!(data[1] & 0x90)) {
+	} else if (wacom->id[0]) {
 		wacom_report_abs(wcombo, ABS_X, 0);
 		wacom_report_abs(wcombo, ABS_Y, 0);
 		if (wacom->tool[0] == BTN_TOOL_MOUSE) {
@@ -225,6 +223,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 			wacom_report_key(wcombo, BTN_STYLUS, 0);
 			wacom_report_key(wcombo, BTN_STYLUS2, 0);
 		}
+		wacom->id[0] = 0;
 		wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
 		wacom_report_key(wcombo, wacom->tool[0], 0);
 	}
@@ -234,13 +233,13 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 	    case WACOM_G4:
 		if (data[7] & 0xf8) {
 			wacom_input_sync(wcombo); /* sync last event */
-			wacom->id[1] = 1;
+			wacom->id[1] = PAD_DEVICE_ID;
 			wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
 			wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
 			rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
 			wacom_report_rel(wcombo, REL_WHEEL, rw);
 			wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
-			wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
+			wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
 			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
 		} else if (wacom->id[1]) {
 			wacom_input_sync(wcombo); /* sync last event */
@@ -255,14 +254,14 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 	    case WACOM_MO:
 		if ((data[7] & 0xf8) || (data[8] & 0xff)) {
 			wacom_input_sync(wcombo); /* sync last event */
-			wacom->id[1] = 1;
+			wacom->id[1] = PAD_DEVICE_ID;
 			wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
 			wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
 			wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
 			wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
 			wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
 			wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
-			wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
+			wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
 			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
 		} else if (wacom->id[1]) {
 			wacom_input_sync(wcombo); /* sync last event */

+ 46 - 0
drivers/input/touchscreen/Kconfig

@@ -103,6 +103,18 @@ config TOUCHSCREEN_MTOUCH
 	  To compile this driver as a module, choose M here: the
 	  module will be called mtouch.
 
+config TOUCHSCREEN_INEXIO
+	tristate "iNexio serial touchscreens"
+	select SERIO
+	help
+	  Say Y here if you have an iNexio serial touchscreen connected to
+	  your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called inexio.
+
 config TOUCHSCREEN_MK712
 	tristate "ICS MicroClock MK712 touchscreen"
 	help
@@ -134,6 +146,18 @@ config TOUCHSCREEN_HP7XX
 	  To compile this driver as a module, choose M here: the
 	  module will be called jornada720_ts.
 
+config TOUCHSCREEN_HTCPEN
+	tristate "HTC Shift X9500 touchscreen"
+	depends on ISA
+	help
+	  Say Y here if you have an HTC Shift UMPC also known as HTC X9500
+	  Clio / Shangrila and want to support the built-in touchscreen.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called htcpen.
+
 config TOUCHSCREEN_PENMOUNT
 	tristate "Penmount serial touchscreen"
 	select SERIO
@@ -146,6 +170,17 @@ config TOUCHSCREEN_PENMOUNT
 	  To compile this driver as a module, choose M here: the
 	  module will be called penmount.
 
+config TOUCHSCREEN_MIGOR
+	tristate "Renesas MIGO-R touchscreen"
+	depends on SH_MIGOR && I2C
+	help
+	  Say Y here to enable MIGO-R touchscreen support.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called migor_ts.
+
 config TOUCHSCREEN_TOUCHRIGHT
 	tristate "Touchright serial touchscreen"
 	select SERIO
@@ -316,4 +351,15 @@ config TOUCHSCREEN_USB_GOTOP
 	bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
 	depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_TOUCHIT213
+	tristate "Sahara TouchIT-213 touchscreen"
+	select SERIO
+	help
+	  Say Y here if you have a Sahara TouchIT-213 Tablet PC.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called touchit213.
+
 endif

+ 4 - 0
drivers/input/touchscreen/Makefile

@@ -12,12 +12,16 @@ obj-$(CONFIG_TOUCHSCREEN_CORGI)		+= corgi_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)		+= gunze.o
 obj-$(CONFIG_TOUCHSCREEN_ELO)		+= elo.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
+obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
+obj-$(CONFIG_TOUCHSCREEN_MIGOR)		+= migor_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH)	+= mtouch.o
 obj-$(CONFIG_TOUCHSCREEN_MK712)		+= mk712.o
 obj-$(CONFIG_TOUCHSCREEN_HP600)		+= hp680_ts_input.o
 obj-$(CONFIG_TOUCHSCREEN_HP7XX)		+= jornada720_ts.o
+obj-$(CONFIG_TOUCHSCREEN_HTCPEN)	+= htcpen.o
 obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE)	+= usbtouchscreen.o
 obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)	+= penmount.o
+obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)	+= touchit213.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)	+= touchright.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)	+= touchwin.o
 obj-$(CONFIG_TOUCHSCREEN_UCB1400)	+= ucb1400_ts.o

+ 0 - 2
drivers/input/touchscreen/gunze.c

@@ -1,6 +1,4 @@
 /*
- * $Id: gunze.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  */
 

+ 0 - 2
drivers/input/touchscreen/h3600_ts_input.c

@@ -1,6 +1,4 @@
 /*
- * $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $
- *
  *  Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
  *
  *  Sponsored by Transvirtual Technology.

+ 255 - 0
drivers/input/touchscreen/htcpen.c

@@ -0,0 +1,255 @@
+/*
+ * HTC Shift touchscreen driver
+ *
+ * Copyright (C) 2008 Pau Oliva Fora <pof@eslack.org>
+ *
+ * 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 <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/isa.h>
+#include <linux/ioport.h>
+#include <linux/dmi.h>
+
+MODULE_AUTHOR("Pau Oliva Fora <pau@eslack.org>");
+MODULE_DESCRIPTION("HTC Shift touchscreen driver");
+MODULE_LICENSE("GPL");
+
+#define HTCPEN_PORT_IRQ_CLEAR	0x068
+#define HTCPEN_PORT_INIT	0x06c
+#define HTCPEN_PORT_INDEX	0x0250
+#define HTCPEN_PORT_DATA	0x0251
+#define HTCPEN_IRQ		3
+
+#define DEVICE_ENABLE		0xa2
+#define DEVICE_DISABLE		0xa3
+
+#define X_INDEX			3
+#define Y_INDEX			5
+#define TOUCH_INDEX		0xb
+#define LSB_XY_INDEX		0xc
+#define X_AXIS_MAX		2040
+#define Y_AXIS_MAX		2040
+
+static int invert_x;
+module_param(invert_x, bool, 0644);
+MODULE_PARM_DESC(invert_x, "If set, X axis is inverted");
+static int invert_y;
+module_param(invert_y, bool, 0644);
+MODULE_PARM_DESC(invert_y, "If set, Y axis is inverted");
+
+static struct pnp_device_id pnp_ids[] = {
+	{ .id = "PNP0cc0" },
+	{ .id = "" }
+};
+MODULE_DEVICE_TABLE(pnp, pnp_ids);
+
+static irqreturn_t htcpen_interrupt(int irq, void *handle)
+{
+	struct input_dev *htcpen_dev = handle;
+	unsigned short x, y, xy;
+
+	/* 0 = press; 1 = release */
+	outb_p(TOUCH_INDEX, HTCPEN_PORT_INDEX);
+
+	if (inb_p(HTCPEN_PORT_DATA)) {
+		input_report_key(htcpen_dev, BTN_TOUCH, 0);
+	} else {
+		outb_p(X_INDEX, HTCPEN_PORT_INDEX);
+		x = inb_p(HTCPEN_PORT_DATA);
+
+		outb_p(Y_INDEX, HTCPEN_PORT_INDEX);
+		y = inb_p(HTCPEN_PORT_DATA);
+
+		outb_p(LSB_XY_INDEX, HTCPEN_PORT_INDEX);
+		xy = inb_p(HTCPEN_PORT_DATA);
+
+		/* get high resolution value of X and Y using LSB */
+		x = X_AXIS_MAX - ((x * 8) + ((xy >> 4) & 0xf));
+		y = (y * 8) + (xy & 0xf);
+		if (invert_x)
+			x = X_AXIS_MAX - x;
+		if (invert_y)
+			y = Y_AXIS_MAX - y;
+
+		if (x != X_AXIS_MAX && x != 0) {
+			input_report_key(htcpen_dev, BTN_TOUCH, 1);
+			input_report_abs(htcpen_dev, ABS_X, x);
+			input_report_abs(htcpen_dev, ABS_Y, y);
+		}
+	}
+
+	input_sync(htcpen_dev);
+
+	inb_p(HTCPEN_PORT_IRQ_CLEAR);
+
+	return IRQ_HANDLED;
+}
+
+static int htcpen_open(struct input_dev *dev)
+{
+	outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT);
+
+	return 0;
+}
+
+static void htcpen_close(struct input_dev *dev)
+{
+	outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT);
+	synchronize_irq(HTCPEN_IRQ);
+}
+
+static int __devinit htcpen_isa_probe(struct device *dev, unsigned int id)
+{
+	struct input_dev *htcpen_dev;
+	int err = -EBUSY;
+
+	if (!request_region(HTCPEN_PORT_IRQ_CLEAR, 1, "htcpen")) {
+		printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
+			HTCPEN_PORT_IRQ_CLEAR);
+		goto request_region1_failed;
+	}
+
+	if (!request_region(HTCPEN_PORT_INIT, 1, "htcpen")) {
+		printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
+			HTCPEN_PORT_INIT);
+		goto request_region2_failed;
+	}
+
+	if (!request_region(HTCPEN_PORT_INDEX, 2, "htcpen")) {
+		printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
+			HTCPEN_PORT_INDEX);
+		goto request_region3_failed;
+	}
+
+	htcpen_dev = input_allocate_device();
+	if (!htcpen_dev) {
+		printk(KERN_ERR "htcpen: can't allocate device\n");
+		err = -ENOMEM;
+		goto input_alloc_failed;
+	}
+
+	htcpen_dev->name = "HTC Shift EC TouchScreen";
+	htcpen_dev->id.bustype = BUS_ISA;
+
+	htcpen_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+	htcpen_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(htcpen_dev, ABS_X, 0, X_AXIS_MAX, 0, 0);
+	input_set_abs_params(htcpen_dev, ABS_Y, 0, Y_AXIS_MAX, 0, 0);
+
+	htcpen_dev->open = htcpen_open;
+	htcpen_dev->close = htcpen_close;
+
+	err = request_irq(HTCPEN_IRQ, htcpen_interrupt, 0, "htcpen",
+			htcpen_dev);
+	if (err) {
+		printk(KERN_ERR "htcpen: irq busy\n");
+		goto request_irq_failed;
+	}
+
+	inb_p(HTCPEN_PORT_IRQ_CLEAR);
+
+	err = input_register_device(htcpen_dev);
+	if (err)
+		goto input_register_failed;
+
+	dev_set_drvdata(dev, htcpen_dev);
+
+	return 0;
+
+ input_register_failed:
+	free_irq(HTCPEN_IRQ, htcpen_dev);
+ request_irq_failed:
+	input_free_device(htcpen_dev);
+ input_alloc_failed:
+	release_region(HTCPEN_PORT_INDEX, 2);
+ request_region3_failed:
+	release_region(HTCPEN_PORT_INIT, 1);
+ request_region2_failed:
+	release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
+ request_region1_failed:
+	return err;
+}
+
+static int __devexit htcpen_isa_remove(struct device *dev, unsigned int id)
+{
+	struct input_dev *htcpen_dev = dev_get_drvdata(dev);
+
+	input_unregister_device(htcpen_dev);
+
+	free_irq(HTCPEN_IRQ, htcpen_dev);
+
+	release_region(HTCPEN_PORT_INDEX, 2);
+	release_region(HTCPEN_PORT_INIT, 1);
+	release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
+
+	dev_set_drvdata(dev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int htcpen_isa_suspend(struct device *dev, unsigned int n,
+				pm_message_t state)
+{
+	outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT);
+
+	return 0;
+}
+
+static int htcpen_isa_resume(struct device *dev, unsigned int n)
+{
+	outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT);
+
+	return 0;
+}
+#endif
+
+static struct isa_driver htcpen_isa_driver = {
+	.probe		= htcpen_isa_probe,
+	.remove		= __devexit_p(htcpen_isa_remove),
+#ifdef CONFIG_PM
+	.suspend	= htcpen_isa_suspend,
+	.resume		= htcpen_isa_resume,
+#endif
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "htcpen",
+	}
+};
+
+static struct dmi_system_id __initdata htcshift_dmi_table[] = {
+	{
+		.ident = "Shift",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "High Tech Computer Corp"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Shift"),
+		},
+	},
+	{ }
+};
+
+static int __init htcpen_isa_init(void)
+{
+	if (!dmi_check_system(htcshift_dmi_table))
+		return -ENODEV;
+
+	return isa_register_driver(&htcpen_isa_driver, 1);
+}
+
+static void __exit htcpen_isa_exit(void)
+{
+	isa_unregister_driver(&htcpen_isa_driver);
+}
+
+module_init(htcpen_isa_init);
+module_exit(htcpen_isa_exit);

+ 207 - 0
drivers/input/touchscreen/inexio.c

@@ -0,0 +1,207 @@
+/*
+ * iNexio serial touchscreen driver
+ *
+ * Copyright (c) 2008 Richard Lemon
+ * Based on the mtouch driver (c) Vojtech Pavlik and Dan Streetman
+ *
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * 2008/06/19 Richard Lemon <richard@codelemon.com>
+ *   Copied mtouch.c and edited for iNexio protocol
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC	"iNexio serial touchscreen driver"
+
+MODULE_AUTHOR("Richard Lemon <richard@codelemon.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define INEXIO_FORMAT_TOUCH_BIT 0x01
+#define INEXIO_FORMAT_LENGTH 5
+#define INEXIO_RESPONSE_BEGIN_BYTE 0x80
+
+/* todo: check specs for max length of all responses */
+#define INEXIO_MAX_LENGTH 16
+
+#define INEXIO_MIN_XC 0
+#define INEXIO_MAX_XC 0x3fff
+#define INEXIO_MIN_YC 0
+#define INEXIO_MAX_YC 0x3fff
+
+#define INEXIO_GET_XC(data) (((data[1])<<7) | data[2])
+#define INEXIO_GET_YC(data) (((data[3])<<7) | data[4])
+#define INEXIO_GET_TOUCHED(data) (INEXIO_FORMAT_TOUCH_BIT & data[0])
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct inexio {
+	struct input_dev *dev;
+	struct serio *serio;
+	int idx;
+	unsigned char data[INEXIO_MAX_LENGTH];
+	char phys[32];
+};
+
+static void inexio_process_data(struct inexio *pinexio)
+{
+	struct input_dev *dev = pinexio->dev;
+
+	if (INEXIO_FORMAT_LENGTH == ++pinexio->idx) {
+		input_report_abs(dev, ABS_X, INEXIO_GET_XC(pinexio->data));
+		input_report_abs(dev, ABS_Y, INEXIO_GET_YC(pinexio->data));
+		input_report_key(dev, BTN_TOUCH, INEXIO_GET_TOUCHED(pinexio->data));
+		input_sync(dev);
+
+		pinexio->idx = 0;
+	}
+}
+
+static irqreturn_t inexio_interrupt(struct serio *serio,
+		unsigned char data, unsigned int flags)
+{
+	struct inexio* pinexio = serio_get_drvdata(serio);
+
+	pinexio->data[pinexio->idx] = data;
+
+	if (INEXIO_RESPONSE_BEGIN_BYTE&pinexio->data[0])
+		inexio_process_data(pinexio);
+	else
+		printk(KERN_DEBUG "inexio.c: unknown/unsynchronized data from device, byte %x\n",pinexio->data[0]);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * inexio_disconnect() is the opposite of inexio_connect()
+ */
+
+static void inexio_disconnect(struct serio *serio)
+{
+	struct inexio* pinexio = serio_get_drvdata(serio);
+
+	input_get_device(pinexio->dev);
+	input_unregister_device(pinexio->dev);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_put_device(pinexio->dev);
+	kfree(pinexio);
+}
+
+/*
+ * inexio_connect() is the routine that is called when someone adds a
+ * new serio device that supports iNexio protocol and registers it as
+ * an input device. This is usually accomplished using inputattach.
+ */
+
+static int inexio_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct inexio *pinexio;
+	struct input_dev *input_dev;
+	int err;
+
+	pinexio = kzalloc(sizeof(struct inexio), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!pinexio || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
+
+	pinexio->serio = serio;
+	pinexio->dev = input_dev;
+	snprintf(pinexio->phys, sizeof(pinexio->phys), "%s/input0", serio->phys);
+
+	input_dev->name = "iNexio Serial TouchScreen";
+	input_dev->phys = pinexio->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_INEXIO;
+	input_dev->id.product = 0;
+	input_dev->id.version = 0x0001;
+	input_dev->dev.parent = &serio->dev;
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(pinexio->dev, ABS_X, INEXIO_MIN_XC, INEXIO_MAX_XC, 0, 0);
+	input_set_abs_params(pinexio->dev, ABS_Y, INEXIO_MIN_YC, INEXIO_MAX_YC, 0, 0);
+
+	serio_set_drvdata(serio, pinexio);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto fail2;
+
+	err = input_register_device(pinexio->dev);
+	if (err)
+		goto fail3;
+
+	return 0;
+
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(pinexio);
+	return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id inexio_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_INEXIO,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, inexio_serio_ids);
+
+static struct serio_driver inexio_drv = {
+	.driver		= {
+		.name	= "inexio",
+	},
+	.description	= DRIVER_DESC,
+	.id_table	= inexio_serio_ids,
+	.interrupt	= inexio_interrupt,
+	.connect	= inexio_connect,
+	.disconnect	= inexio_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init inexio_init(void)
+{
+	return serio_register_driver(&inexio_drv);
+}
+
+static void __exit inexio_exit(void)
+{
+	serio_unregister_driver(&inexio_drv);
+}
+
+module_init(inexio_init);
+module_exit(inexio_exit);

+ 250 - 0
drivers/input/touchscreen/migor_ts.c

@@ -0,0 +1,250 @@
+/*
+ * Touch Screen driver for Renesas MIGO-R Platform
+ *
+ * Copyright (c) 2008 Magnus Damm
+ * Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>,
+ *  Kenati Technologies Pvt Ltd.
+ *
+ * This file 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 (at your option) any later version.
+ *
+ * This file 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <linux/i2c.h>
+#include <linux/timer.h>
+
+#define EVENT_PENDOWN 1
+#define EVENT_REPEAT  2
+#define EVENT_PENUP   3
+
+struct migor_ts_priv {
+	struct i2c_client *client;
+	struct input_dev *input;
+	struct delayed_work work;
+	int irq;
+};
+
+static const u_int8_t migor_ts_ena_seq[17] = { 0x33, 0x22, 0x11,
+					       0x01, 0x06, 0x07, };
+static const u_int8_t migor_ts_dis_seq[17] = { };
+
+static void migor_ts_poscheck(struct work_struct *work)
+{
+	struct migor_ts_priv *priv = container_of(work,
+						  struct migor_ts_priv,
+						  work.work);
+	unsigned short xpos, ypos;
+	unsigned char event;
+	u_int8_t buf[16];
+
+	memset(buf, 0, sizeof(buf));
+
+	/* Set Index 0 */
+	buf[0] = 0;
+	if (i2c_master_send(priv->client, buf, 1) != 1) {
+		dev_err(&priv->client->dev, "Unable to write i2c index\n");
+		goto out;
+	}
+
+	/* Now do Page Read */
+	if (i2c_master_recv(priv->client, buf, sizeof(buf)) != sizeof(buf)) {
+		dev_err(&priv->client->dev, "Unable to read i2c page\n");
+		goto out;
+	}
+
+	ypos = ((buf[9] & 0x03) << 8 | buf[8]);
+	xpos = ((buf[11] & 0x03) << 8 | buf[10]);
+	event = buf[12];
+
+	if (event == EVENT_PENDOWN || event == EVENT_REPEAT) {
+		input_report_key(priv->input, BTN_TOUCH, 1);
+		input_report_abs(priv->input, ABS_X, ypos); /*X-Y swap*/
+		input_report_abs(priv->input, ABS_Y, xpos);
+		input_sync(priv->input);
+	} else if (event == EVENT_PENUP) {
+		input_report_key(priv->input, BTN_TOUCH, 0);
+		input_sync(priv->input);
+	}
+ out:
+	enable_irq(priv->irq);
+}
+
+static irqreturn_t migor_ts_isr(int irq, void *dev_id)
+{
+	struct migor_ts_priv *priv = dev_id;
+
+	/* the touch screen controller chip is hooked up to the cpu
+	 * using i2c and a single interrupt line. the interrupt line
+	 * is pulled low whenever someone taps the screen. to deassert
+	 * the interrupt line we need to acknowledge the interrupt by
+	 * communicating with the controller over the slow i2c bus.
+	 *
+	 * we can't acknowledge from interrupt context since the i2c
+	 * bus controller may sleep, so we just disable the interrupt
+	 * here and handle the acknowledge using delayed work.
+	 */
+
+	disable_irq_nosync(irq);
+	schedule_delayed_work(&priv->work, HZ / 20);
+
+	return IRQ_HANDLED;
+}
+
+
+static int migor_ts_open(struct input_dev *dev)
+{
+	struct migor_ts_priv *priv = input_get_drvdata(dev);
+	struct i2c_client *client = priv->client;
+	int count;
+
+	/* enable controller */
+	count = i2c_master_send(client, migor_ts_ena_seq,
+				sizeof(migor_ts_ena_seq));
+	if (count != sizeof(migor_ts_ena_seq)) {
+		dev_err(&client->dev, "Unable to enable touchscreen.\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static void migor_ts_close(struct input_dev *dev)
+{
+	struct migor_ts_priv *priv = input_get_drvdata(dev);
+	struct i2c_client *client = priv->client;
+
+	disable_irq(priv->irq);
+
+	/* cancel pending work and wait for migor_ts_poscheck() to finish */
+	if (cancel_delayed_work_sync(&priv->work)) {
+		/*
+		 * if migor_ts_poscheck was canceled we need to enable IRQ
+		 * here to balance disable done in migor_ts_isr.
+		 */
+		enable_irq(priv->irq);
+	}
+
+	/* disable controller */
+	i2c_master_send(client, migor_ts_dis_seq, sizeof(migor_ts_dis_seq));
+
+	enable_irq(priv->irq);
+}
+
+static int migor_ts_probe(struct i2c_client *client,
+			  const struct i2c_device_id *idp)
+{
+	struct migor_ts_priv *priv;
+	struct input_dev *input;
+	int error;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(&client->dev, "failed to allocate driver data\n");
+		error = -ENOMEM;
+		goto err0;
+	}
+
+	dev_set_drvdata(&client->dev, priv);
+
+	input = input_allocate_device();
+	if (!input) {
+		dev_err(&client->dev, "Failed to allocate input device.\n");
+		error = -ENOMEM;
+		goto err1;
+	}
+
+	input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+	input_set_abs_params(input, ABS_X, 95, 955, 0, 0);
+	input_set_abs_params(input, ABS_Y, 85, 935, 0, 0);
+
+	input->name = client->driver_name;
+	input->id.bustype = BUS_I2C;
+	input->dev.parent = &client->dev;
+
+	input->open = migor_ts_open;
+	input->close = migor_ts_close;
+
+	input_set_drvdata(input, priv);
+
+	priv->client = client;
+	priv->input = input;
+	INIT_DELAYED_WORK(&priv->work, migor_ts_poscheck);
+	priv->irq = client->irq;
+
+	error = input_register_device(input);
+	if (error)
+		goto err1;
+
+	error = request_irq(priv->irq, migor_ts_isr, IRQF_TRIGGER_LOW,
+			    client->driver_name, priv);
+	if (error) {
+		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
+		goto err2;
+	}
+
+	return 0;
+
+ err2:
+	input_unregister_device(input);
+	input = NULL; /* so we dont try to free it below */
+ err1:
+	input_free_device(input);
+	kfree(priv);
+ err0:
+	dev_set_drvdata(&client->dev, NULL);
+	return error;
+}
+
+static int migor_ts_remove(struct i2c_client *client)
+{
+	struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+	free_irq(priv->irq, priv);
+	input_unregister_device(priv->input);
+	kfree(priv);
+
+	dev_set_drvdata(&client->dev, NULL);
+
+	return 0;
+}
+
+static struct i2c_driver migor_ts_driver = {
+	.driver = {
+		.name = "migor_ts",
+	},
+	.probe = migor_ts_probe,
+	.remove = migor_ts_remove,
+};
+
+static int __init migor_ts_init(void)
+{
+	return i2c_add_driver(&migor_ts_driver);
+}
+
+static void __exit migor_ts_exit(void)
+{
+	i2c_del_driver(&migor_ts_driver);
+}
+
+MODULE_DESCRIPTION("MigoR Touchscreen driver");
+MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
+MODULE_LICENSE("GPL");
+
+module_init(migor_ts_init);
+module_exit(migor_ts_exit);

+ 234 - 0
drivers/input/touchscreen/touchit213.c

@@ -0,0 +1,234 @@
+/*
+ * Sahara TouchIT-213 serial touchscreen driver
+ *
+ * Copyright (c) 2007-2008 Claudio Nieder <private@claudio.ch>
+ *
+ * Based on Touchright driver (drivers/input/touchscreen/touchright.c)
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ * Copyright (c) 2004 Vojtech Pavlik
+ * and Dan Streetman <ddstreet@ieee.org>
+ */
+
+/*
+ * 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 <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC	"Sahara TouchIT-213 serial touchscreen driver"
+
+MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+/*
+ * Data is received through COM1 at 9600bit/s,8bit,no parity in packets
+ * of 5 byte each.
+ *
+ *   +--------+   +--------+   +--------+   +--------+   +--------+
+ *   |1000000p|   |0xxxxxxx|   |0xxxxxxx|   |0yyyyyyy|   |0yyyyyyy|
+ *   +--------+   +--------+   +--------+   +--------+   +--------+
+ *                    MSB          LSB          MSB          LSB
+ *
+ * The value of p is 1 as long as the screen is touched and 0 when
+ * reporting the location where touching stopped, e.g. where the pen was
+ * lifted from the screen.
+ *
+ * When holding the screen in landscape mode as the BIOS text output is
+ * presented, x is the horizontal axis with values growing from left to
+ * right and y is the vertical axis with values growing from top to
+ * bottom.
+ *
+ * When holding the screen in portrait mode with the Sahara logo in its
+ * correct position, x ist the vertical axis with values growing from
+ * top to bottom and y is the horizontal axis with values growing from
+ * right to left.
+ */
+
+#define T213_FORMAT_TOUCH_BIT	0x01
+#define T213_FORMAT_STATUS_BYTE	0x80
+#define T213_FORMAT_STATUS_MASK	~T213_FORMAT_TOUCH_BIT
+
+/*
+ * On my Sahara Touch-IT 213 I have observed x values from 0 to 0x7f0
+ * and y values from 0x1d to 0x7e9, so the actual measurement is
+ * probably done with an 11 bit precision.
+ */
+#define T213_MIN_XC 0
+#define T213_MAX_XC 0x07ff
+#define T213_MIN_YC 0
+#define T213_MAX_YC 0x07ff
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct touchit213 {
+	struct input_dev *dev;
+	struct serio *serio;
+	int idx;
+	unsigned char csum;
+	unsigned char data[5];
+	char phys[32];
+};
+
+static irqreturn_t touchit213_interrupt(struct serio *serio,
+		unsigned char data, unsigned int flags)
+{
+	struct touchit213 *touchit213 = serio_get_drvdata(serio);
+	struct input_dev *dev = touchit213->dev;
+
+	touchit213->data[touchit213->idx] = data;
+
+	switch (touchit213->idx++) {
+	case 0:
+		if ((touchit213->data[0] & T213_FORMAT_STATUS_MASK) !=
+				T213_FORMAT_STATUS_BYTE) {
+			pr_debug("unsynchronized data: 0x%02x\n", data);
+			touchit213->idx = 0;
+		}
+		break;
+
+	case 4:
+		touchit213->idx = 0;
+		input_report_abs(dev, ABS_X,
+			(touchit213->data[1] << 7) | touchit213->data[2]);
+		input_report_abs(dev, ABS_Y,
+			(touchit213->data[3] << 7) | touchit213->data[4]);
+		input_report_key(dev, BTN_TOUCH,
+			touchit213->data[0] & T213_FORMAT_TOUCH_BIT);
+		input_sync(dev);
+		break;
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * touchit213_disconnect() is the opposite of touchit213_connect()
+ */
+
+static void touchit213_disconnect(struct serio *serio)
+{
+	struct touchit213 *touchit213 = serio_get_drvdata(serio);
+
+	input_get_device(touchit213->dev);
+	input_unregister_device(touchit213->dev);
+	serio_close(serio);
+	serio_set_drvdata(serio, NULL);
+	input_put_device(touchit213->dev);
+	kfree(touchit213);
+}
+
+/*
+ * touchit213_connect() is the routine that is called when someone adds a
+ * new serio device that supports the Touchright protocol and registers it as
+ * an input device.
+ */
+
+static int touchit213_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct touchit213 *touchit213;
+	struct input_dev *input_dev;
+	int err;
+
+	touchit213 = kzalloc(sizeof(struct touchit213), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!touchit213 || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
+
+	touchit213->serio = serio;
+	touchit213->dev = input_dev;
+	snprintf(touchit213->phys, sizeof(touchit213->phys),
+		 "%s/input0", serio->phys);
+
+	input_dev->name = "Sahara Touch-iT213 Serial TouchScreen";
+	input_dev->phys = touchit213->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_TOUCHIT213;
+	input_dev->id.product = 0;
+	input_dev->id.version = 0x0100;
+	input_dev->dev.parent = &serio->dev;
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(touchit213->dev, ABS_X,
+			     T213_MIN_XC, T213_MAX_XC, 0, 0);
+	input_set_abs_params(touchit213->dev, ABS_Y,
+			     T213_MIN_YC, T213_MAX_YC, 0, 0);
+
+	serio_set_drvdata(serio, touchit213);
+
+	err = serio_open(serio, drv);
+	if (err)
+		goto fail2;
+
+	err = input_register_device(touchit213->dev);
+	if (err)
+		goto fail3;
+
+	return 0;
+
+ fail3:	serio_close(serio);
+ fail2:	serio_set_drvdata(serio, NULL);
+ fail1:	input_free_device(input_dev);
+	kfree(touchit213);
+	return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id touchit213_serio_ids[] = {
+	{
+		.type	= SERIO_RS232,
+		.proto	= SERIO_TOUCHIT213,
+		.id	= SERIO_ANY,
+		.extra	= SERIO_ANY,
+	},
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, touchit213_serio_ids);
+
+static struct serio_driver touchit213_drv = {
+	.driver		= {
+		.name	= "touchit213",
+	},
+	.description	= DRIVER_DESC,
+	.id_table	= touchit213_serio_ids,
+	.interrupt	= touchit213_interrupt,
+	.connect	= touchit213_connect,
+	.disconnect	= touchit213_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init touchit213_init(void)
+{
+	return serio_register_driver(&touchit213_drv);
+}
+
+static void __exit touchit213_exit(void)
+{
+	serio_unregister_driver(&touchit213_drv);
+}
+
+module_init(touchit213_init);
+module_exit(touchit213_exit);

+ 30 - 12
drivers/input/touchscreen/usbtouchscreen.c

@@ -49,6 +49,7 @@
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/usb/input.h>
+#include <linux/hid.h>
 
 
 #define DRIVER_VERSION		"v0.6"
@@ -101,7 +102,7 @@ struct usbtouch_usb {
 
 /* device types */
 enum {
-	DEVTPYE_DUMMY = -1,
+	DEVTYPE_IGNORE = -1,
 	DEVTYPE_EGALAX,
 	DEVTYPE_PANJIT,
 	DEVTYPE_3M,
@@ -115,8 +116,21 @@ enum {
 	DEVTYPE_GOTOP,
 };
 
+#define USB_DEVICE_HID_CLASS(vend, prod) \
+	.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \
+		| USB_DEVICE_ID_MATCH_DEVICE, \
+	.idVendor = (vend), \
+	.idProduct = (prod), \
+	.bInterfaceClass = USB_INTERFACE_CLASS_HID, \
+	.bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE
+
 static struct usb_device_id usbtouch_devices[] = {
 #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
+	/* ignore the HID capable devices, handled by usbhid */
+	{USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE},
+	{USB_DEVICE_HID_CLASS(0x0eef, 0x0002), .driver_info = DEVTYPE_IGNORE},
+
+	/* normal device IDs */
 	{USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
 	{USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX},
 	{USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX},
@@ -262,7 +276,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
 	                      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 	                      1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
 	dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
-	    __FUNCTION__, ret);
+	    __func__, ret);
 	if (ret < 0)
 		return ret;
 	msleep(150);
@@ -273,7 +287,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
 				      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 				      1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
 		dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
-		    __FUNCTION__, ret);
+		    __func__, ret);
 		if (ret >= 0)
 			break;
 		if (ret != -EPIPE)
@@ -793,18 +807,18 @@ static void usbtouch_irq(struct urb *urb)
 	case -ETIME:
 		/* this urb is timing out */
 		dbg("%s - urb timed out - was the device unplugged?",
-		    __FUNCTION__);
+		    __func__);
 		return;
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
 		/* this urb is terminated, clean up */
 		dbg("%s - urb shutting down with status: %d",
-		    __FUNCTION__, urb->status);
+		    __func__, urb->status);
 		return;
 	default:
 		dbg("%s - nonzero urb status received: %d",
-		    __FUNCTION__, urb->status);
+		    __func__, urb->status);
 		goto exit;
 	}
 
@@ -814,7 +828,7 @@ exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
 	if (retval)
 		err("%s - usb_submit_urb failed with result: %d",
-		    __FUNCTION__, retval);
+		    __func__, retval);
 }
 
 static int usbtouch_open(struct input_dev *input)
@@ -857,6 +871,10 @@ static int usbtouch_probe(struct usb_interface *intf,
 	struct usbtouch_device_info *type;
 	int err = -ENOMEM;
 
+	/* some devices are ignored */
+	if (id->driver_info == DEVTYPE_IGNORE)
+		return -ENODEV;
+
 	interface = intf->cur_altsetting;
 	endpoint = &interface->endpoint[0].desc;
 
@@ -883,7 +901,7 @@ static int usbtouch_probe(struct usb_interface *intf,
 
 	usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
 	if (!usbtouch->irq) {
-		dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__);
+		dbg("%s - usb_alloc_urb failed: usbtouch->irq", __func__);
 		goto out_free_buffers;
 	}
 
@@ -939,14 +957,14 @@ static int usbtouch_probe(struct usb_interface *intf,
 	if (type->init) {
 		err = type->init(usbtouch);
 		if (err) {
-			dbg("%s - type->init() failed, err: %d", __FUNCTION__, err);
+			dbg("%s - type->init() failed, err: %d", __func__, err);
 			goto out_free_buffers;
 		}
 	}
 
 	err = input_register_device(usbtouch->input);
 	if (err) {
-		dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err);
+		dbg("%s - input_register_device failed, err: %d", __func__, err);
 		goto out_free_buffers;
 	}
 
@@ -966,12 +984,12 @@ static void usbtouch_disconnect(struct usb_interface *intf)
 {
 	struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
 
-	dbg("%s - called", __FUNCTION__);
+	dbg("%s - called", __func__);
 
 	if (!usbtouch)
 		return;
 
-	dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__);
+	dbg("%s - usbtouch is initialized, cleaning up", __func__);
 	usb_set_intfdata(intf, NULL);
 	usb_kill_urb(usbtouch->irq);
 	input_unregister_device(usbtouch->input);

+ 12 - 6
drivers/input/touchscreen/wm9712.c

@@ -168,6 +168,18 @@ static void wm9712_phy_init(struct wm97xx *wm)
 			64000 / rpu);
 	}
 
+	/* WM9712 five wire */
+	if (five_wire) {
+		dig2 |= WM9712_45W;
+		dev_dbg(wm->dev, "setting 5-wire touchscreen mode.");
+
+		if (pil) {
+			dev_warn(wm->dev, "pressure measurement is not "
+				 "supported in 5-wire mode\n");
+			pil = 0;
+		}
+	}
+
 	/* touchpanel pressure current*/
 	if (pil == 2) {
 		dig2 |= WM9712_PIL;
@@ -179,12 +191,6 @@ static void wm9712_phy_init(struct wm97xx *wm)
 	if (!pil)
 		pressure = 0;
 
-	/* WM9712 five wire */
-	if (five_wire) {
-		dig2 |= WM9712_45W;
-		dev_dbg(wm->dev, "setting 5-wire touchscreen mode.");
-	}
-
 	/* polling mode sample settling delay */
 	if (delay < 0 || delay > 15) {
 		dev_dbg(wm->dev, "supplied delay out of range.");

+ 51 - 10
drivers/macintosh/adbhid.c

@@ -219,11 +219,13 @@ struct adbhid {
 	int flags;
 };
 
-#define FLAG_FN_KEY_PRESSED	0x00000001
-#define FLAG_POWER_FROM_FN	0x00000002
-#define FLAG_EMU_FWDEL_DOWN	0x00000004
-#define FLAG_CAPSLOCK_TRANSLATE	0x00000008
-#define FLAG_CAPSLOCK_DOWN	0x00000010
+#define FLAG_FN_KEY_PRESSED		0x00000001
+#define FLAG_POWER_FROM_FN		0x00000002
+#define FLAG_EMU_FWDEL_DOWN		0x00000004
+#define FLAG_CAPSLOCK_TRANSLATE		0x00000008
+#define FLAG_CAPSLOCK_DOWN		0x00000010
+#define FLAG_CAPSLOCK_IGNORE_NEXT	0x00000020
+#define FLAG_POWER_KEY_PRESSED		0x00000040
 
 static struct adbhid *adbhid[16];
 
@@ -291,11 +293,20 @@ adbhid_input_keycode(int id, int scancode, int repeat)
 		if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
 			/* Key pressed, turning on the CapsLock LED.
 			 * The next 0xff will be interpreted as a release. */
-			ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
+			if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) {
+				/* Throw away this key event if it happens
+				 * just after resume. */
+				ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT;
+				return;
+			} else {
+				ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
 					| FLAG_CAPSLOCK_DOWN;
-		} else if (scancode == 0xff) {
+			}
+		} else if (scancode == 0xff &&
+			   !(ahid->flags & FLAG_POWER_KEY_PRESSED)) {
 			/* Scancode 0xff usually signifies that the capslock
-			 * key was either pressed or released. */
+			 * key was either pressed or released, or that the
+			 * power button was released. */
 			if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
 				keycode = ADB_KEY_CAPSLOCK;
 				if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
@@ -309,7 +320,7 @@ adbhid_input_keycode(int id, int scancode, int repeat)
 				}
 			} else {
 				printk(KERN_INFO "Spurious caps lock event "
-						"(scancode 0xff).");
+						 "(scancode 0xff).\n");
 			}
 		}
 	}
@@ -336,6 +347,12 @@ adbhid_input_keycode(int id, int scancode, int repeat)
 		}
 		break;
 	case ADB_KEY_POWER:
+		/* Keep track of the power key state */
+		if (up_flag)
+			ahid->flags &= ~FLAG_POWER_KEY_PRESSED;
+		else
+			ahid->flags |= FLAG_POWER_KEY_PRESSED;
+
 		/* Fn + Command will produce a bogus "power" keycode */
 		if (ahid->flags & FLAG_FN_KEY_PRESSED) {
 			keycode = ADB_KEY_CMD;
@@ -681,6 +698,21 @@ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned i
 	return -1;
 }
 
+static void
+adbhid_kbd_capslock_remember(void)
+{
+	struct adbhid *ahid;
+	int i;
+
+	for (i = 1; i < 16; i++) {
+		ahid = adbhid[i];
+
+		if (ahid && ahid->id == ADB_KEYBOARD)
+			if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE)
+				ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT;
+	}
+}
+
 static int
 adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
 {
@@ -697,8 +729,17 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
 		}
 
 		/* Stop pending led requests */
-		while(leds_req_pending)
+		while (leds_req_pending)
 			adb_poll();
+
+		/* After resume, and if the capslock LED is on, the PMU will
+		 * send a "capslock down" key event. This confuses the
+		 * restore_capslock_events logic. Remember if the capslock
+		 * LED was on before suspend so the unwanted key event can
+		 * be ignored after resume. */
+		if (restore_capslock_events)
+			adbhid_kbd_capslock_remember();
+
 		break;
 
 	case ADB_MSG_POST_RESET:

+ 0 - 1
include/linux/gameport.h

@@ -68,7 +68,6 @@ struct gameport_driver {
 
 int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode);
 void gameport_close(struct gameport *gameport);
-void gameport_rescan(struct gameport *gameport);
 
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 

+ 1 - 0
include/linux/gpio_keys.h

@@ -9,6 +9,7 @@ struct gpio_keys_button {
 	char *desc;
 	int type;		/* input event type (EV_KEY, EV_SW) */
 	int wakeup;		/* configure the button as a wake-up source */
+	int debounce_interval;	/* debounce ticks interval in msecs */
 };
 
 struct gpio_keys_platform_data {

+ 4 - 5
include/linux/input.h

@@ -373,6 +373,8 @@ struct input_absinfo {
 
 #define KEY_WIMAX		246
 
+/* Range 248 - 255 is reserved for special needs of AT keyboard driver */
+
 #define BTN_MISC		0x100
 #define BTN_0			0x100
 #define BTN_1			0x101
@@ -640,6 +642,8 @@ struct input_absinfo {
 #define SW_RFKILL_ALL		0x03  /* rfkill master switch, type "any"
 					 set = radio enabled */
 #define SW_RADIO		SW_RFKILL_ALL	/* deprecated */
+#define SW_MICROPHONE_INSERT	0x04  /* set = inserted */
+#define SW_DOCK			0x05  /* set = plugged into dock */
 #define SW_MAX			0x0f
 #define SW_CNT			(SW_MAX+1)
 
@@ -1215,11 +1219,6 @@ struct input_handle {
 	struct list_head	h_node;
 };
 
-#define to_dev(n) container_of(n, struct input_dev, node)
-#define to_handler(n) container_of(n, struct input_handler, node)
-#define to_handle(n) container_of(n, struct input_handle, d_node)
-#define to_handle_h(n) container_of(n, struct input_handle, h_node)
-
 struct input_dev *input_allocate_device(void);
 void input_free_device(struct input_dev *dev);
 

+ 0 - 2
include/linux/joystick.h

@@ -2,8 +2,6 @@
 #define _LINUX_JOYSTICK_H
 
 /*
- * $Id: joystick.h,v 1.3 2000/11/30 11:07:05 vojtech Exp $
- *
  *  Copyright (C) 1996-2000 Vojtech Pavlik
  *
  *  Sponsored by SuSE

+ 0 - 1
include/linux/libps2.h

@@ -43,7 +43,6 @@ void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
 int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
 void ps2_drain(struct ps2dev *ps2dev, int maxbytes, 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);

+ 3 - 1
include/linux/serio.h

@@ -175,7 +175,7 @@ static inline void serio_unpin_driver(struct serio *serio)
 #define SERIO_8042_XL	0x06
 
 /*
- * Serio types
+ * Serio protocols
  */
 #define SERIO_UNKNOWN	0x00
 #define SERIO_MSC	0x01
@@ -212,5 +212,7 @@ static inline void serio_unpin_driver(struct serio *serio)
 #define SERIO_TAOSEVM	0x34
 #define SERIO_FUJITSU	0x35
 #define SERIO_ZHENHUA	0x36
+#define SERIO_INEXIO	0x37
+#define SERIO_TOUCHIT213	0x37
 
 #endif