diff options
38 files changed, 1119 insertions, 111 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 4dbd3425e928..45806d27579a 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/input.h> | 42 | #include <linux/input.h> |
43 | #include <linux/reboot.h> | 43 | #include <linux/reboot.h> |
44 | #include <linux/notifier.h> | 44 | #include <linux/notifier.h> |
45 | #include <linux/jiffies.h> | ||
45 | 46 | ||
46 | extern void ctrl_alt_del(void); | 47 | extern void ctrl_alt_del(void); |
47 | 48 | ||
@@ -928,7 +929,8 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) | |||
928 | if (up_flag) { | 929 | if (up_flag) { |
929 | if (brl_timeout) { | 930 | if (brl_timeout) { |
930 | if (!committing || | 931 | if (!committing || |
931 | jiffies - releasestart > (brl_timeout * HZ) / 1000) { | 932 | time_after(jiffies, |
933 | releasestart + msecs_to_jiffies(brl_timeout))) { | ||
932 | committing = pressed; | 934 | committing = pressed; |
933 | releasestart = jiffies; | 935 | releasestart = jiffies; |
934 | } | 936 | } |
@@ -1237,6 +1239,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1237 | } | 1239 | } |
1238 | 1240 | ||
1239 | param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; | 1241 | param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; |
1242 | param.ledstate = kbd->ledflagstate; | ||
1240 | key_map = key_maps[shift_final]; | 1243 | key_map = key_maps[shift_final]; |
1241 | 1244 | ||
1242 | if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, ¶m) == NOTIFY_STOP || !key_map) { | 1245 | if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, ¶m) == NOTIFY_STOP || !key_map) { |
@@ -1285,6 +1288,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1285 | 1288 | ||
1286 | (*k_handler[type])(vc, keysym & 0xff, !down); | 1289 | (*k_handler[type])(vc, keysym & 0xff, !down); |
1287 | 1290 | ||
1291 | param.ledstate = kbd->ledflagstate; | ||
1288 | atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m); | 1292 | atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m); |
1289 | 1293 | ||
1290 | if (type != KT_SLOCK) | 1294 | if (type != KT_SLOCK) |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index e29a057cbea2..17b2f49675d8 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -405,6 +405,9 @@ | |||
405 | #define USB_VENDOR_ID_YEALINK 0x6993 | 405 | #define USB_VENDOR_ID_YEALINK 0x6993 |
406 | #define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 | 406 | #define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 |
407 | 407 | ||
408 | #define USB_VENDOR_ID_KYE 0x0458 | ||
409 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 | ||
410 | |||
408 | /* | 411 | /* |
409 | * Alphabetically sorted blacklist by quirk type. | 412 | * Alphabetically sorted blacklist by quirk type. |
410 | */ | 413 | */ |
@@ -703,6 +706,7 @@ static const struct hid_blacklist { | |||
703 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_63, HID_QUIRK_IGNORE }, | 706 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_63, HID_QUIRK_IGNORE }, |
704 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_64, HID_QUIRK_IGNORE }, | 707 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_64, HID_QUIRK_IGNORE }, |
705 | { USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY, HID_QUIRK_IGNORE }, | 708 | { USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY, HID_QUIRK_IGNORE }, |
709 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560, HID_QUIRK_IGNORE }, | ||
706 | 710 | ||
707 | { 0, 0 } | 711 | { 0, 0 } |
708 | }; | 712 | }; |
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 7c662ee594a3..be5c14a5a0a4 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig | |||
@@ -193,6 +193,18 @@ config JOYSTICK_TWIDJOY | |||
193 | To compile this driver as a module, choose M here: the | 193 | To compile this driver as a module, choose M here: the |
194 | module will be called twidjoy. | 194 | module will be called twidjoy. |
195 | 195 | ||
196 | config JOYSTICK_ZHENHUA | ||
197 | tristate "5-byte Zhenhua RC transmitter" | ||
198 | select SERIO | ||
199 | help | ||
200 | Say Y here if you have a Zhen Hua PPM-4CH transmitter which is | ||
201 | supplied with a ready to fly micro electric indoor helicopters | ||
202 | such as EasyCopter, Lama, MiniCopter, DragonFly or Jabo and want | ||
203 | to use it via serial cable as a joystick. | ||
204 | |||
205 | To compile this driver as a module, choose M here: the | ||
206 | module will be called zhenhua. | ||
207 | |||
196 | config JOYSTICK_DB9 | 208 | config JOYSTICK_DB9 |
197 | tristate "Multisystem, Sega Genesis, Saturn joysticks and gamepads" | 209 | tristate "Multisystem, Sega Genesis, Saturn joysticks and gamepads" |
198 | depends on PARPORT | 210 | depends on PARPORT |
diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile index e855abb0cc51..fdbf8c4c2876 100644 --- a/drivers/input/joystick/Makefile +++ b/drivers/input/joystick/Makefile | |||
@@ -15,6 +15,7 @@ obj-$(CONFIG_JOYSTICK_GF2K) += gf2k.o | |||
15 | obj-$(CONFIG_JOYSTICK_GRIP) += grip.o | 15 | obj-$(CONFIG_JOYSTICK_GRIP) += grip.o |
16 | obj-$(CONFIG_JOYSTICK_GRIP_MP) += grip_mp.o | 16 | obj-$(CONFIG_JOYSTICK_GRIP_MP) += grip_mp.o |
17 | obj-$(CONFIG_JOYSTICK_GUILLEMOT) += guillemot.o | 17 | obj-$(CONFIG_JOYSTICK_GUILLEMOT) += guillemot.o |
18 | obj-$(CONFIG_JOYSTICK_IFORCE) += iforce/ | ||
18 | obj-$(CONFIG_JOYSTICK_INTERACT) += interact.o | 19 | obj-$(CONFIG_JOYSTICK_INTERACT) += interact.o |
19 | obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydump.o | 20 | obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydump.o |
20 | obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o | 21 | obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o |
@@ -27,5 +28,5 @@ obj-$(CONFIG_JOYSTICK_TURBOGRAFX) += turbografx.o | |||
27 | obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o | 28 | obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o |
28 | obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o | 29 | obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o |
29 | obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o | 30 | obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o |
31 | obj-$(CONFIG_JOYSTICK_ZHENHUA) += zhenhua.o | ||
30 | 32 | ||
31 | obj-$(CONFIG_JOYSTICK_IFORCE) += iforce/ | ||
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 0380597249bb..52ddb04644ab 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * X-Box gamepad - v0.0.6 | 2 | * X-Box gamepad driver |
3 | * | 3 | * |
4 | * Copyright (c) 2002 Marko Friedemann <mfr@bmx-chemnitz.de> | 4 | * Copyright (c) 2002 Marko Friedemann <mfr@bmx-chemnitz.de> |
5 | * 2004 Oliver Schwartz <Oliver.Schwartz@gmx.de>, | 5 | * 2004 Oliver Schwartz <Oliver.Schwartz@gmx.de>, |
@@ -68,6 +68,8 @@ | |||
68 | * - dance pads will map D-PAD to buttons, not axes | 68 | * - dance pads will map D-PAD to buttons, not axes |
69 | * - pass the module paramater 'dpad_to_buttons' to force | 69 | * - pass the module paramater 'dpad_to_buttons' to force |
70 | * the D-PAD to map to buttons if your pad is not detected | 70 | * the D-PAD to map to buttons if your pad is not detected |
71 | * | ||
72 | * Later changes can be tracked in SCM. | ||
71 | */ | 73 | */ |
72 | 74 | ||
73 | #include <linux/kernel.h> | 75 | #include <linux/kernel.h> |
@@ -77,7 +79,6 @@ | |||
77 | #include <linux/module.h> | 79 | #include <linux/module.h> |
78 | #include <linux/usb/input.h> | 80 | #include <linux/usb/input.h> |
79 | 81 | ||
80 | #define DRIVER_VERSION "v0.0.6" | ||
81 | #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>" | 82 | #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>" |
82 | #define DRIVER_DESC "X-Box pad driver" | 83 | #define DRIVER_DESC "X-Box pad driver" |
83 | 84 | ||
@@ -87,10 +88,12 @@ | |||
87 | but we map them to axes when possible to simplify things */ | 88 | but we map them to axes when possible to simplify things */ |
88 | #define MAP_DPAD_TO_BUTTONS 0 | 89 | #define MAP_DPAD_TO_BUTTONS 0 |
89 | #define MAP_DPAD_TO_AXES 1 | 90 | #define MAP_DPAD_TO_AXES 1 |
90 | #define MAP_DPAD_UNKNOWN -1 | 91 | #define MAP_DPAD_UNKNOWN 2 |
91 | 92 | ||
92 | #define XTYPE_XBOX 0 | 93 | #define XTYPE_XBOX 0 |
93 | #define XTYPE_XBOX360 1 | 94 | #define XTYPE_XBOX360 1 |
95 | #define XTYPE_XBOX360W 2 | ||
96 | #define XTYPE_UNKNOWN 3 | ||
94 | 97 | ||
95 | static int dpad_to_buttons; | 98 | static int dpad_to_buttons; |
96 | module_param(dpad_to_buttons, bool, S_IRUGO); | 99 | module_param(dpad_to_buttons, bool, S_IRUGO); |
@@ -107,8 +110,10 @@ static const struct xpad_device { | |||
107 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 110 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
108 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 111 | { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
109 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 112 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
113 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, | ||
110 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 114 | { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
111 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 115 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
116 | { 0x046d, 0xc242, "Logitech Chillstream Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | ||
112 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 117 | { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
113 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 118 | { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
114 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 119 | { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
@@ -135,18 +140,26 @@ static const struct xpad_device { | |||
135 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 140 | { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
136 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 141 | { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
137 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 142 | { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
143 | { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | ||
138 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 144 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
139 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 145 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, |
140 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 146 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
141 | { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_XBOX } | 147 | { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN } |
142 | }; | 148 | }; |
143 | 149 | ||
144 | static const signed short xpad_btn[] = { | 150 | /* buttons shared with xbox and xbox360 */ |
145 | BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ | 151 | static const signed short xpad_common_btn[] = { |
152 | BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */ | ||
146 | BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ | 153 | BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ |
147 | -1 /* terminating entry */ | 154 | -1 /* terminating entry */ |
148 | }; | 155 | }; |
149 | 156 | ||
157 | /* original xbox controllers only */ | ||
158 | static const signed short xpad_btn[] = { | ||
159 | BTN_C, BTN_Z, /* "analog" buttons */ | ||
160 | -1 /* terminating entry */ | ||
161 | }; | ||
162 | |||
150 | /* only used if MAP_DPAD_TO_BUTTONS */ | 163 | /* only used if MAP_DPAD_TO_BUTTONS */ |
151 | static const signed short xpad_btn_pad[] = { | 164 | static const signed short xpad_btn_pad[] = { |
152 | BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ | 165 | BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ |
@@ -173,12 +186,27 @@ static const signed short xpad_abs_pad[] = { | |||
173 | -1 /* terminating entry */ | 186 | -1 /* terminating entry */ |
174 | }; | 187 | }; |
175 | 188 | ||
176 | /* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only | 189 | /* Xbox 360 has a vendor-specific class, so we cannot match it with only |
177 | * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols, | 190 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we |
178 | * but we need only one of them. */ | 191 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, |
192 | * wireless controllers have protocol 129. */ | ||
193 | #define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \ | ||
194 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ | ||
195 | .idVendor = (vend), \ | ||
196 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ | ||
197 | .bInterfaceSubClass = 93, \ | ||
198 | .bInterfaceProtocol = (pr) | ||
199 | #define XPAD_XBOX360_VENDOR(vend) \ | ||
200 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \ | ||
201 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) } | ||
202 | |||
179 | static struct usb_device_id xpad_table [] = { | 203 | static struct usb_device_id xpad_table [] = { |
180 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ | 204 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ |
181 | { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */ | 205 | XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ |
206 | XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ | ||
207 | XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ | ||
208 | XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ | ||
209 | XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ | ||
182 | { } | 210 | { } |
183 | }; | 211 | }; |
184 | 212 | ||
@@ -188,10 +216,15 @@ struct usb_xpad { | |||
188 | struct input_dev *dev; /* input device interface */ | 216 | struct input_dev *dev; /* input device interface */ |
189 | struct usb_device *udev; /* usb device */ | 217 | struct usb_device *udev; /* usb device */ |
190 | 218 | ||
219 | int pad_present; | ||
220 | |||
191 | struct urb *irq_in; /* urb for interrupt in report */ | 221 | struct urb *irq_in; /* urb for interrupt in report */ |
192 | unsigned char *idata; /* input data */ | 222 | unsigned char *idata; /* input data */ |
193 | dma_addr_t idata_dma; | 223 | dma_addr_t idata_dma; |
194 | 224 | ||
225 | struct urb *bulk_out; | ||
226 | unsigned char *bdata; | ||
227 | |||
195 | #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) | 228 | #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) |
196 | struct urb *irq_out; /* urb for interrupt out report */ | 229 | struct urb *irq_out; /* urb for interrupt out report */ |
197 | unsigned char *odata; /* output data */ | 230 | unsigned char *odata; /* output data */ |
@@ -227,13 +260,13 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d | |||
227 | input_report_abs(dev, ABS_X, | 260 | input_report_abs(dev, ABS_X, |
228 | (__s16) le16_to_cpup((__le16 *)(data + 12))); | 261 | (__s16) le16_to_cpup((__le16 *)(data + 12))); |
229 | input_report_abs(dev, ABS_Y, | 262 | input_report_abs(dev, ABS_Y, |
230 | (__s16) le16_to_cpup((__le16 *)(data + 14))); | 263 | ~(__s16) le16_to_cpup((__le16 *)(data + 14))); |
231 | 264 | ||
232 | /* right stick */ | 265 | /* right stick */ |
233 | input_report_abs(dev, ABS_RX, | 266 | input_report_abs(dev, ABS_RX, |
234 | (__s16) le16_to_cpup((__le16 *)(data + 16))); | 267 | (__s16) le16_to_cpup((__le16 *)(data + 16))); |
235 | input_report_abs(dev, ABS_RY, | 268 | input_report_abs(dev, ABS_RY, |
236 | (__s16) le16_to_cpup((__le16 *)(data + 18))); | 269 | ~(__s16) le16_to_cpup((__le16 *)(data + 18))); |
237 | 270 | ||
238 | /* triggers left/right */ | 271 | /* triggers left/right */ |
239 | input_report_abs(dev, ABS_Z, data[10]); | 272 | input_report_abs(dev, ABS_Z, data[10]); |
@@ -321,13 +354,13 @@ static void xpad360_process_packet(struct usb_xpad *xpad, | |||
321 | input_report_abs(dev, ABS_X, | 354 | input_report_abs(dev, ABS_X, |
322 | (__s16) le16_to_cpup((__le16 *)(data + 6))); | 355 | (__s16) le16_to_cpup((__le16 *)(data + 6))); |
323 | input_report_abs(dev, ABS_Y, | 356 | input_report_abs(dev, ABS_Y, |
324 | (__s16) le16_to_cpup((__le16 *)(data + 8))); | 357 | ~(__s16) le16_to_cpup((__le16 *)(data + 8))); |
325 | 358 | ||
326 | /* right stick */ | 359 | /* right stick */ |
327 | input_report_abs(dev, ABS_RX, | 360 | input_report_abs(dev, ABS_RX, |
328 | (__s16) le16_to_cpup((__le16 *)(data + 10))); | 361 | (__s16) le16_to_cpup((__le16 *)(data + 10))); |
329 | input_report_abs(dev, ABS_RY, | 362 | input_report_abs(dev, ABS_RY, |
330 | (__s16) le16_to_cpup((__le16 *)(data + 12))); | 363 | ~(__s16) le16_to_cpup((__le16 *)(data + 12))); |
331 | 364 | ||
332 | /* triggers left/right */ | 365 | /* triggers left/right */ |
333 | input_report_abs(dev, ABS_Z, data[4]); | 366 | input_report_abs(dev, ABS_Z, data[4]); |
@@ -336,6 +369,39 @@ static void xpad360_process_packet(struct usb_xpad *xpad, | |||
336 | input_sync(dev); | 369 | input_sync(dev); |
337 | } | 370 | } |
338 | 371 | ||
372 | /* | ||
373 | * xpad360w_process_packet | ||
374 | * | ||
375 | * Completes a request by converting the data into events for the | ||
376 | * input subsystem. It is version for xbox 360 wireless controller. | ||
377 | * | ||
378 | * Byte.Bit | ||
379 | * 00.1 - Status change: The controller or headset has connected/disconnected | ||
380 | * Bits 01.7 and 01.6 are valid | ||
381 | * 01.7 - Controller present | ||
382 | * 01.6 - Headset present | ||
383 | * 01.1 - Pad state (Bytes 4+) valid | ||
384 | * | ||
385 | */ | ||
386 | |||
387 | static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) | ||
388 | { | ||
389 | /* Presence change */ | ||
390 | if (data[0] & 0x08) { | ||
391 | if (data[1] & 0x80) { | ||
392 | xpad->pad_present = 1; | ||
393 | usb_submit_urb(xpad->bulk_out, GFP_ATOMIC); | ||
394 | } else | ||
395 | xpad->pad_present = 0; | ||
396 | } | ||
397 | |||
398 | /* Valid pad data */ | ||
399 | if (!(data[1] & 0x1)) | ||
400 | return; | ||
401 | |||
402 | xpad360_process_packet(xpad, cmd, &data[4]); | ||
403 | } | ||
404 | |||
339 | static void xpad_irq_in(struct urb *urb) | 405 | static void xpad_irq_in(struct urb *urb) |
340 | { | 406 | { |
341 | struct usb_xpad *xpad = urb->context; | 407 | struct usb_xpad *xpad = urb->context; |
@@ -358,10 +424,16 @@ static void xpad_irq_in(struct urb *urb) | |||
358 | goto exit; | 424 | goto exit; |
359 | } | 425 | } |
360 | 426 | ||
361 | if (xpad->xtype == XTYPE_XBOX360) | 427 | switch (xpad->xtype) { |
428 | case XTYPE_XBOX360: | ||
362 | xpad360_process_packet(xpad, 0, xpad->idata); | 429 | xpad360_process_packet(xpad, 0, xpad->idata); |
363 | else | 430 | break; |
431 | case XTYPE_XBOX360W: | ||
432 | xpad360w_process_packet(xpad, 0, xpad->idata); | ||
433 | break; | ||
434 | default: | ||
364 | xpad_process_packet(xpad, 0, xpad->idata); | 435 | xpad_process_packet(xpad, 0, xpad->idata); |
436 | } | ||
365 | 437 | ||
366 | exit: | 438 | exit: |
367 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 439 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
@@ -399,6 +471,23 @@ exit: | |||
399 | __FUNCTION__, retval); | 471 | __FUNCTION__, retval); |
400 | } | 472 | } |
401 | 473 | ||
474 | static void xpad_bulk_out(struct urb *urb) | ||
475 | { | ||
476 | switch (urb->status) { | ||
477 | case 0: | ||
478 | /* success */ | ||
479 | break; | ||
480 | case -ECONNRESET: | ||
481 | case -ENOENT: | ||
482 | case -ESHUTDOWN: | ||
483 | /* this urb is terminated, clean up */ | ||
484 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | ||
485 | break; | ||
486 | default: | ||
487 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | ||
488 | } | ||
489 | } | ||
490 | |||
402 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | 491 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) |
403 | { | 492 | { |
404 | struct usb_endpoint_descriptor *ep_irq_out; | 493 | struct usb_endpoint_descriptor *ep_irq_out; |
@@ -408,7 +497,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
408 | return 0; | 497 | return 0; |
409 | 498 | ||
410 | xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, | 499 | xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, |
411 | GFP_ATOMIC, &xpad->odata_dma ); | 500 | GFP_KERNEL, &xpad->odata_dma); |
412 | if (!xpad->odata) | 501 | if (!xpad->odata) |
413 | goto fail1; | 502 | goto fail1; |
414 | 503 | ||
@@ -469,6 +558,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, | |||
469 | xpad->odata[5] = 0x00; | 558 | xpad->odata[5] = 0x00; |
470 | xpad->odata[6] = 0x00; | 559 | xpad->odata[6] = 0x00; |
471 | xpad->odata[7] = 0x00; | 560 | xpad->odata[7] = 0x00; |
561 | xpad->irq_out->transfer_buffer_length = 8; | ||
472 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); | 562 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); |
473 | } | 563 | } |
474 | 564 | ||
@@ -477,6 +567,9 @@ static int xpad_play_effect(struct input_dev *dev, void *data, | |||
477 | 567 | ||
478 | static int xpad_init_ff(struct usb_xpad *xpad) | 568 | static int xpad_init_ff(struct usb_xpad *xpad) |
479 | { | 569 | { |
570 | if (xpad->xtype != XTYPE_XBOX360) | ||
571 | return 0; | ||
572 | |||
480 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); | 573 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); |
481 | 574 | ||
482 | return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); | 575 | return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); |
@@ -502,6 +595,7 @@ static void xpad_send_led_command(struct usb_xpad *xpad, int command) | |||
502 | xpad->odata[0] = 0x01; | 595 | xpad->odata[0] = 0x01; |
503 | xpad->odata[1] = 0x03; | 596 | xpad->odata[1] = 0x03; |
504 | xpad->odata[2] = command; | 597 | xpad->odata[2] = command; |
598 | xpad->irq_out->transfer_buffer_length = 3; | ||
505 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); | 599 | usb_submit_urb(xpad->irq_out, GFP_KERNEL); |
506 | mutex_unlock(&xpad->odata_mutex); | 600 | mutex_unlock(&xpad->odata_mutex); |
507 | } | 601 | } |
@@ -574,6 +668,10 @@ static int xpad_open(struct input_dev *dev) | |||
574 | { | 668 | { |
575 | struct usb_xpad *xpad = input_get_drvdata(dev); | 669 | struct usb_xpad *xpad = input_get_drvdata(dev); |
576 | 670 | ||
671 | /* URB was submitted in probe */ | ||
672 | if(xpad->xtype == XTYPE_XBOX360W) | ||
673 | return 0; | ||
674 | |||
577 | xpad->irq_in->dev = xpad->udev; | 675 | xpad->irq_in->dev = xpad->udev; |
578 | if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) | 676 | if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) |
579 | return -EIO; | 677 | return -EIO; |
@@ -585,7 +683,8 @@ static void xpad_close(struct input_dev *dev) | |||
585 | { | 683 | { |
586 | struct usb_xpad *xpad = input_get_drvdata(dev); | 684 | struct usb_xpad *xpad = input_get_drvdata(dev); |
587 | 685 | ||
588 | usb_kill_urb(xpad->irq_in); | 686 | if(xpad->xtype != XTYPE_XBOX360W) |
687 | usb_kill_urb(xpad->irq_in); | ||
589 | xpad_stop_output(xpad); | 688 | xpad_stop_output(xpad); |
590 | } | 689 | } |
591 | 690 | ||
@@ -632,7 +731,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
632 | goto fail1; | 731 | goto fail1; |
633 | 732 | ||
634 | xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, | 733 | xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN, |
635 | GFP_ATOMIC, &xpad->idata_dma); | 734 | GFP_KERNEL, &xpad->idata_dma); |
636 | if (!xpad->idata) | 735 | if (!xpad->idata) |
637 | goto fail1; | 736 | goto fail1; |
638 | 737 | ||
@@ -644,7 +743,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
644 | xpad->dpad_mapping = xpad_device[i].dpad_mapping; | 743 | xpad->dpad_mapping = xpad_device[i].dpad_mapping; |
645 | xpad->xtype = xpad_device[i].xtype; | 744 | xpad->xtype = xpad_device[i].xtype; |
646 | if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) | 745 | if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN) |
647 | xpad->dpad_mapping = dpad_to_buttons; | 746 | xpad->dpad_mapping = !dpad_to_buttons; |
747 | if (xpad->xtype == XTYPE_UNKNOWN) { | ||
748 | if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) { | ||
749 | if (intf->cur_altsetting->desc.bInterfaceProtocol == 129) | ||
750 | xpad->xtype = XTYPE_XBOX360W; | ||
751 | else | ||
752 | xpad->xtype = XTYPE_XBOX360; | ||
753 | } else | ||
754 | xpad->xtype = XTYPE_XBOX; | ||
755 | } | ||
648 | xpad->dev = input_dev; | 756 | xpad->dev = input_dev; |
649 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); | 757 | usb_make_path(udev, xpad->phys, sizeof(xpad->phys)); |
650 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); | 758 | strlcat(xpad->phys, "/input0", sizeof(xpad->phys)); |
@@ -662,11 +770,14 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
662 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 770 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
663 | 771 | ||
664 | /* set up buttons */ | 772 | /* set up buttons */ |
665 | for (i = 0; xpad_btn[i] >= 0; i++) | 773 | for (i = 0; xpad_common_btn[i] >= 0; i++) |
666 | set_bit(xpad_btn[i], input_dev->keybit); | 774 | set_bit(xpad_common_btn[i], input_dev->keybit); |
667 | if (xpad->xtype == XTYPE_XBOX360) | 775 | if ((xpad->xtype == XTYPE_XBOX360) || (xpad->xtype == XTYPE_XBOX360W)) |
668 | for (i = 0; xpad360_btn[i] >= 0; i++) | 776 | for (i = 0; xpad360_btn[i] >= 0; i++) |
669 | set_bit(xpad360_btn[i], input_dev->keybit); | 777 | set_bit(xpad360_btn[i], input_dev->keybit); |
778 | else | ||
779 | for (i = 0; xpad_btn[i] >= 0; i++) | ||
780 | set_bit(xpad_btn[i], input_dev->keybit); | ||
670 | if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) | 781 | if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) |
671 | for (i = 0; xpad_btn_pad[i] >= 0; i++) | 782 | for (i = 0; xpad_btn_pad[i] >= 0; i++) |
672 | set_bit(xpad_btn_pad[i], input_dev->keybit); | 783 | set_bit(xpad_btn_pad[i], input_dev->keybit); |
@@ -703,8 +814,57 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
703 | goto fail4; | 814 | goto fail4; |
704 | 815 | ||
705 | usb_set_intfdata(intf, xpad); | 816 | usb_set_intfdata(intf, xpad); |
817 | |||
818 | /* | ||
819 | * Submit the int URB immediatly rather than waiting for open | ||
820 | * because we get status messages from the device whether | ||
821 | * or not any controllers are attached. In fact, it's | ||
822 | * exactly the message that a controller has arrived that | ||
823 | * we're waiting for. | ||
824 | */ | ||
825 | if (xpad->xtype == XTYPE_XBOX360W) { | ||
826 | xpad->irq_in->dev = xpad->udev; | ||
827 | error = usb_submit_urb(xpad->irq_in, GFP_KERNEL); | ||
828 | if (error) | ||
829 | goto fail4; | ||
830 | |||
831 | /* | ||
832 | * Setup the message to set the LEDs on the | ||
833 | * controller when it shows up | ||
834 | */ | ||
835 | xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL); | ||
836 | if(!xpad->bulk_out) | ||
837 | goto fail5; | ||
838 | |||
839 | xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL); | ||
840 | if(!xpad->bdata) | ||
841 | goto fail6; | ||
842 | |||
843 | xpad->bdata[2] = 0x08; | ||
844 | switch (intf->cur_altsetting->desc.bInterfaceNumber) { | ||
845 | case 0: | ||
846 | xpad->bdata[3] = 0x42; | ||
847 | break; | ||
848 | case 2: | ||
849 | xpad->bdata[3] = 0x43; | ||
850 | break; | ||
851 | case 4: | ||
852 | xpad->bdata[3] = 0x44; | ||
853 | break; | ||
854 | case 6: | ||
855 | xpad->bdata[3] = 0x45; | ||
856 | } | ||
857 | |||
858 | ep_irq_in = &intf->cur_altsetting->endpoint[1].desc; | ||
859 | usb_fill_bulk_urb(xpad->bulk_out, udev, | ||
860 | usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress), | ||
861 | xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad); | ||
862 | } | ||
863 | |||
706 | return 0; | 864 | return 0; |
707 | 865 | ||
866 | fail6: usb_free_urb(xpad->bulk_out); | ||
867 | fail5: usb_kill_urb(xpad->irq_in); | ||
708 | fail4: usb_free_urb(xpad->irq_in); | 868 | fail4: usb_free_urb(xpad->irq_in); |
709 | fail3: xpad_deinit_output(xpad); | 869 | fail3: xpad_deinit_output(xpad); |
710 | fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); | 870 | fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); |
@@ -723,6 +883,11 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
723 | xpad_led_disconnect(xpad); | 883 | xpad_led_disconnect(xpad); |
724 | input_unregister_device(xpad->dev); | 884 | input_unregister_device(xpad->dev); |
725 | xpad_deinit_output(xpad); | 885 | xpad_deinit_output(xpad); |
886 | if (xpad->xtype == XTYPE_XBOX360W) { | ||
887 | usb_kill_urb(xpad->bulk_out); | ||
888 | usb_free_urb(xpad->bulk_out); | ||
889 | usb_kill_urb(xpad->irq_in); | ||
890 | } | ||
726 | usb_free_urb(xpad->irq_in); | 891 | usb_free_urb(xpad->irq_in); |
727 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, | 892 | usb_buffer_free(xpad->udev, XPAD_PKT_LEN, |
728 | xpad->idata, xpad->idata_dma); | 893 | xpad->idata, xpad->idata_dma); |
@@ -741,7 +906,7 @@ static int __init usb_xpad_init(void) | |||
741 | { | 906 | { |
742 | int result = usb_register(&xpad_driver); | 907 | int result = usb_register(&xpad_driver); |
743 | if (result == 0) | 908 | if (result == 0) |
744 | info(DRIVER_DESC ":" DRIVER_VERSION); | 909 | info(DRIVER_DESC); |
745 | return result; | 910 | return result; |
746 | } | 911 | } |
747 | 912 | ||
diff --git a/drivers/input/joystick/zhenhua.c b/drivers/input/joystick/zhenhua.c new file mode 100644 index 000000000000..b5853125c898 --- /dev/null +++ b/drivers/input/joystick/zhenhua.c | |||
@@ -0,0 +1,243 @@ | |||
1 | /* | ||
2 | * derived from "twidjoy.c" | ||
3 | * | ||
4 | * Copyright (c) 2008 Martin Kebert | ||
5 | * Copyright (c) 2001 Arndt Schoenewald | ||
6 | * Copyright (c) 2000-2001 Vojtech Pavlik | ||
7 | * Copyright (c) 2000 Mark Fletcher | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * Driver to use 4CH RC transmitter using Zhen Hua 5-byte protocol (Walkera Lama, | ||
13 | * EasyCopter etc.) as a joystick under Linux. | ||
14 | * | ||
15 | * RC transmitters using Zhen Hua 5-byte protocol are cheap four channels | ||
16 | * transmitters for control a RC planes or RC helicopters with possibility to | ||
17 | * connect on a serial port. | ||
18 | * Data coming from transmitter is in this order: | ||
19 | * 1. byte = synchronisation byte | ||
20 | * 2. byte = X axis | ||
21 | * 3. byte = Y axis | ||
22 | * 4. byte = RZ axis | ||
23 | * 5. byte = Z axis | ||
24 | * (and this is repeated) | ||
25 | * | ||
26 | * For questions or feedback regarding this driver module please contact: | ||
27 | * Martin Kebert <gkmarty@gmail.com> - but I am not a C-programmer nor kernel | ||
28 | * coder :-( | ||
29 | */ | ||
30 | |||
31 | /* | ||
32 | * This program is free software; you can redistribute it and/or modify | ||
33 | * it under the terms of the GNU General Public License as published by | ||
34 | * the Free Software Foundation; either version 2 of the License, or | ||
35 | * (at your option) any later version. | ||
36 | * | ||
37 | * This program is distributed in the hope that it will be useful, | ||
38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
40 | * GNU General Public License for more details. | ||
41 | * | ||
42 | * You should have received a copy of the GNU General Public License | ||
43 | * along with this program; if not, write to the Free Software | ||
44 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
45 | */ | ||
46 | |||
47 | #include <linux/kernel.h> | ||
48 | #include <linux/module.h> | ||
49 | #include <linux/slab.h> | ||
50 | #include <linux/input.h> | ||
51 | #include <linux/serio.h> | ||
52 | #include <linux/init.h> | ||
53 | |||
54 | #define DRIVER_DESC "RC transmitter with 5-byte Zhen Hua protocol joystick driver" | ||
55 | |||
56 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
57 | MODULE_LICENSE("GPL"); | ||
58 | |||
59 | /* | ||
60 | * Constants. | ||
61 | */ | ||
62 | |||
63 | #define ZHENHUA_MAX_LENGTH 5 | ||
64 | |||
65 | /* | ||
66 | * Zhen Hua data. | ||
67 | */ | ||
68 | |||
69 | struct zhenhua { | ||
70 | struct input_dev *dev; | ||
71 | int idx; | ||
72 | unsigned char data[ZHENHUA_MAX_LENGTH]; | ||
73 | char phys[32]; | ||
74 | }; | ||
75 | |||
76 | |||
77 | /* bits in all incoming bytes needs to be "reversed" */ | ||
78 | static int zhenhua_bitreverse(int x) | ||
79 | { | ||
80 | x = ((x & 0xaa) >> 1) | ((x & 0x55) << 1); | ||
81 | x = ((x & 0xcc) >> 2) | ((x & 0x33) << 2); | ||
82 | x = ((x & 0xf0) >> 4) | ((x & 0x0f) << 4); | ||
83 | return x; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * zhenhua_process_packet() decodes packets the driver receives from the | ||
88 | * RC transmitter. It updates the data accordingly. | ||
89 | */ | ||
90 | |||
91 | static void zhenhua_process_packet(struct zhenhua *zhenhua) | ||
92 | { | ||
93 | struct input_dev *dev = zhenhua->dev; | ||
94 | unsigned char *data = zhenhua->data; | ||
95 | |||
96 | input_report_abs(dev, ABS_Y, data[1]); | ||
97 | input_report_abs(dev, ABS_X, data[2]); | ||
98 | input_report_abs(dev, ABS_RZ, data[3]); | ||
99 | input_report_abs(dev, ABS_Z, data[4]); | ||
100 | |||
101 | input_sync(dev); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * zhenhua_interrupt() is called by the low level driver when characters | ||
106 | * are ready for us. We then buffer them for further processing, or call the | ||
107 | * packet processing routine. | ||
108 | */ | ||
109 | |||
110 | static irqreturn_t zhenhua_interrupt(struct serio *serio, unsigned char data, unsigned int flags) | ||
111 | { | ||
112 | struct zhenhua *zhenhua = serio_get_drvdata(serio); | ||
113 | |||
114 | /* All Zhen Hua packets are 5 bytes. The fact that the first byte | ||
115 | * is allways 0xf7 and all others are in range 0x32 - 0xc8 (50-200) | ||
116 | * can be used to check and regain sync. */ | ||
117 | |||
118 | if (data == 0xef) | ||
119 | zhenhua->idx = 0; /* this byte starts a new packet */ | ||
120 | else if (zhenhua->idx == 0) | ||
121 | return IRQ_HANDLED; /* wrong MSB -- ignore this byte */ | ||
122 | |||
123 | if (zhenhua->idx < ZHENHUA_MAX_LENGTH) | ||
124 | zhenhua->data[zhenhua->idx++] = zhenhua_bitreverse(data); | ||
125 | |||
126 | if (zhenhua->idx == ZHENHUA_MAX_LENGTH) { | ||
127 | zhenhua_process_packet(zhenhua); | ||
128 | zhenhua->idx = 0; | ||
129 | } | ||
130 | |||
131 | return IRQ_HANDLED; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * zhenhua_disconnect() is the opposite of zhenhua_connect() | ||
136 | */ | ||
137 | |||
138 | static void zhenhua_disconnect(struct serio *serio) | ||
139 | { | ||
140 | struct zhenhua *zhenhua = serio_get_drvdata(serio); | ||
141 | |||
142 | serio_close(serio); | ||
143 | serio_set_drvdata(serio, NULL); | ||
144 | input_unregister_device(zhenhua->dev); | ||
145 | kfree(zhenhua); | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * zhenhua_connect() is the routine that is called when someone adds a | ||
150 | * new serio device. It looks for the Twiddler, and if found, registers | ||
151 | * it as an input device. | ||
152 | */ | ||
153 | |||
154 | static int zhenhua_connect(struct serio *serio, struct serio_driver *drv) | ||
155 | { | ||
156 | struct zhenhua *zhenhua; | ||
157 | struct input_dev *input_dev; | ||
158 | int err = -ENOMEM; | ||
159 | |||
160 | zhenhua = kzalloc(sizeof(struct zhenhua), GFP_KERNEL); | ||
161 | input_dev = input_allocate_device(); | ||
162 | if (!zhenhua || !input_dev) | ||
163 | goto fail1; | ||
164 | |||
165 | zhenhua->dev = input_dev; | ||
166 | snprintf(zhenhua->phys, sizeof(zhenhua->phys), "%s/input0", serio->phys); | ||
167 | |||
168 | input_dev->name = "Zhen Hua 5-byte device"; | ||
169 | input_dev->phys = zhenhua->phys; | ||
170 | input_dev->id.bustype = BUS_RS232; | ||
171 | input_dev->id.vendor = SERIO_ZHENHUA; | ||
172 | input_dev->id.product = 0x0001; | ||
173 | input_dev->id.version = 0x0100; | ||
174 | input_dev->dev.parent = &serio->dev; | ||
175 | |||
176 | input_dev->evbit[0] = BIT(EV_ABS); | ||
177 | input_set_abs_params(input_dev, ABS_X, 50, 200, 0, 0); | ||
178 | input_set_abs_params(input_dev, ABS_Y, 50, 200, 0, 0); | ||
179 | input_set_abs_params(input_dev, ABS_Z, 50, 200, 0, 0); | ||
180 | input_set_abs_params(input_dev, ABS_RZ, 50, 200, 0, 0); | ||
181 | |||
182 | serio_set_drvdata(serio, zhenhua); | ||
183 | |||
184 | err = serio_open(serio, drv); | ||
185 | if (err) | ||
186 | goto fail2; | ||
187 | |||
188 | err = input_register_device(zhenhua->dev); | ||
189 | if (err) | ||
190 | goto fail3; | ||
191 | |||
192 | return 0; | ||
193 | |||
194 | fail3: serio_close(serio); | ||
195 | fail2: serio_set_drvdata(serio, NULL); | ||
196 | fail1: input_free_device(input_dev); | ||
197 | kfree(zhenhua); | ||
198 | return err; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * The serio driver structure. | ||
203 | */ | ||
204 | |||
205 | static struct serio_device_id zhenhua_serio_ids[] = { | ||
206 | { | ||
207 | .type = SERIO_RS232, | ||
208 | .proto = SERIO_ZHENHUA, | ||
209 | .id = SERIO_ANY, | ||
210 | .extra = SERIO_ANY, | ||
211 | }, | ||
212 | { 0 } | ||
213 | }; | ||
214 | |||
215 | MODULE_DEVICE_TABLE(serio, zhenhua_serio_ids); | ||
216 | |||
217 | static struct serio_driver zhenhua_drv = { | ||
218 | .driver = { | ||
219 | .name = "zhenhua", | ||
220 | }, | ||
221 | .description = DRIVER_DESC, | ||
222 | .id_table = zhenhua_serio_ids, | ||
223 | .interrupt = zhenhua_interrupt, | ||
224 | .connect = zhenhua_connect, | ||
225 | .disconnect = zhenhua_disconnect, | ||
226 | }; | ||
227 | |||
228 | /* | ||
229 | * The functions for inserting/removing us as a module. | ||
230 | */ | ||
231 | |||
232 | static int __init zhenhua_init(void) | ||
233 | { | ||
234 | return serio_register_driver(&zhenhua_drv); | ||
235 | } | ||
236 | |||
237 | static void __exit zhenhua_exit(void) | ||
238 | { | ||
239 | serio_unregister_driver(&zhenhua_drv); | ||
240 | } | ||
241 | |||
242 | module_init(zhenhua_init); | ||
243 | module_exit(zhenhua_exit); | ||
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c index 72abc196ce66..a293e8b3f508 100644 --- a/drivers/input/keyboard/aaed2000_kbd.c +++ b/drivers/input/keyboard/aaed2000_kbd.c | |||
@@ -156,11 +156,15 @@ static int __devexit aaedkbd_remove(struct platform_device *pdev) | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | /* work with hotplug and coldplug */ | ||
160 | MODULE_ALIAS("platform:aaed2000-keyboard"); | ||
161 | |||
159 | static struct platform_driver aaedkbd_driver = { | 162 | static struct platform_driver aaedkbd_driver = { |
160 | .probe = aaedkbd_probe, | 163 | .probe = aaedkbd_probe, |
161 | .remove = __devexit_p(aaedkbd_remove), | 164 | .remove = __devexit_p(aaedkbd_remove), |
162 | .driver = { | 165 | .driver = { |
163 | .name = "aaed2000-keyboard", | 166 | .name = "aaed2000-keyboard", |
167 | .owner = THIS_MODULE, | ||
164 | }, | 168 | }, |
165 | }; | 169 | }; |
166 | 170 | ||
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 05e3494cf8b8..54ed8e2e1c02 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -312,6 +312,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
312 | 312 | ||
313 | bfin_write_KPAD_CTL(bfin_read_KPAD_CTL() | KPAD_EN); | 313 | bfin_write_KPAD_CTL(bfin_read_KPAD_CTL() | KPAD_EN); |
314 | 314 | ||
315 | device_init_wakeup(&pdev->dev, 1); | ||
316 | |||
315 | printk(KERN_ERR DRV_NAME | 317 | printk(KERN_ERR DRV_NAME |
316 | ": Blackfin BF54x Keypad registered IRQ %d\n", bf54x_kpad->irq); | 318 | ": Blackfin BF54x Keypad registered IRQ %d\n", bf54x_kpad->irq); |
317 | 319 | ||
@@ -354,12 +356,40 @@ static int __devexit bfin_kpad_remove(struct platform_device *pdev) | |||
354 | return 0; | 356 | return 0; |
355 | } | 357 | } |
356 | 358 | ||
359 | #ifdef CONFIG_PM | ||
360 | static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state) | ||
361 | { | ||
362 | struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); | ||
363 | |||
364 | if (device_may_wakeup(&pdev->dev)) | ||
365 | enable_irq_wake(bf54x_kpad->irq); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static int bfin_kpad_resume(struct platform_device *pdev) | ||
371 | { | ||
372 | struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); | ||
373 | |||
374 | if (device_may_wakeup(&pdev->dev)) | ||
375 | disable_irq_wake(bf54x_kpad->irq); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | #else | ||
380 | # define bfin_kpad_suspend NULL | ||
381 | # define bfin_kpad_resume NULL | ||
382 | #endif | ||
383 | |||
357 | struct platform_driver bfin_kpad_device_driver = { | 384 | struct platform_driver bfin_kpad_device_driver = { |
358 | .probe = bfin_kpad_probe, | ||
359 | .remove = __devexit_p(bfin_kpad_remove), | ||
360 | .driver = { | 385 | .driver = { |
361 | .name = DRV_NAME, | 386 | .name = DRV_NAME, |
362 | } | 387 | .owner = THIS_MODULE, |
388 | }, | ||
389 | .probe = bfin_kpad_probe, | ||
390 | .remove = __devexit_p(bfin_kpad_remove), | ||
391 | .suspend = bfin_kpad_suspend, | ||
392 | .resume = bfin_kpad_resume, | ||
363 | }; | 393 | }; |
364 | 394 | ||
365 | static int __init bfin_kpad_init(void) | 395 | static int __init bfin_kpad_init(void) |
@@ -378,3 +408,4 @@ module_exit(bfin_kpad_exit); | |||
378 | MODULE_LICENSE("GPL"); | 408 | MODULE_LICENSE("GPL"); |
379 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 409 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
380 | MODULE_DESCRIPTION("Keypad driver for BF54x Processors"); | 410 | MODULE_DESCRIPTION("Keypad driver for BF54x Processors"); |
411 | MODULE_ALIAS("platform:bf54x-keys"); | ||
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index 790fed368aae..5187c0c7a222 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c | |||
@@ -392,6 +392,7 @@ static struct platform_driver corgikbd_driver = { | |||
392 | .resume = corgikbd_resume, | 392 | .resume = corgikbd_resume, |
393 | .driver = { | 393 | .driver = { |
394 | .name = "corgi-keyboard", | 394 | .name = "corgi-keyboard", |
395 | .owner = THIS_MODULE, | ||
395 | }, | 396 | }, |
396 | }; | 397 | }; |
397 | 398 | ||
@@ -411,3 +412,4 @@ module_exit(corgikbd_exit); | |||
411 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | 412 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); |
412 | MODULE_DESCRIPTION("Corgi Keyboard Driver"); | 413 | MODULE_DESCRIPTION("Corgi Keyboard Driver"); |
413 | MODULE_LICENSE("GPLv2"); | 414 | MODULE_LICENSE("GPLv2"); |
415 | MODULE_ALIAS("platform:corgi-keyboard"); | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 6a9ca4bdcb74..bbd00c3fe98c 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -43,10 +43,11 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
43 | 43 | ||
44 | input_event(input, type, button->code, !!state); | 44 | input_event(input, type, button->code, !!state); |
45 | input_sync(input); | 45 | input_sync(input); |
46 | return IRQ_HANDLED; | ||
46 | } | 47 | } |
47 | } | 48 | } |
48 | 49 | ||
49 | return IRQ_HANDLED; | 50 | return IRQ_NONE; |
50 | } | 51 | } |
51 | 52 | ||
52 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 53 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
@@ -213,6 +214,7 @@ struct platform_driver gpio_keys_device_driver = { | |||
213 | .resume = gpio_keys_resume, | 214 | .resume = gpio_keys_resume, |
214 | .driver = { | 215 | .driver = { |
215 | .name = "gpio-keys", | 216 | .name = "gpio-keys", |
217 | .owner = THIS_MODULE, | ||
216 | } | 218 | } |
217 | }; | 219 | }; |
218 | 220 | ||
@@ -232,3 +234,4 @@ module_exit(gpio_keys_exit); | |||
232 | MODULE_LICENSE("GPL"); | 234 | MODULE_LICENSE("GPL"); |
233 | MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>"); | 235 | MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>"); |
234 | MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs"); | 236 | MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs"); |
237 | MODULE_ALIAS("platform:gpio-keys"); | ||
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index a23633a2e1b4..9387da343f97 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c | |||
@@ -254,6 +254,7 @@ static int __devexit jornada680kbd_remove(struct platform_device *pdev) | |||
254 | static struct platform_driver jornada680kbd_driver = { | 254 | static struct platform_driver jornada680kbd_driver = { |
255 | .driver = { | 255 | .driver = { |
256 | .name = "jornada680_kbd", | 256 | .name = "jornada680_kbd", |
257 | .owner = THIS_MODULE, | ||
257 | }, | 258 | }, |
258 | .probe = jornada680kbd_probe, | 259 | .probe = jornada680kbd_probe, |
259 | .remove = __devexit_p(jornada680kbd_remove), | 260 | .remove = __devexit_p(jornada680kbd_remove), |
@@ -275,3 +276,4 @@ module_exit(jornada680kbd_exit); | |||
275 | MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); | 276 | MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); |
276 | MODULE_DESCRIPTION("HP Jornada 620/660/680/690 Keyboard Driver"); | 277 | MODULE_DESCRIPTION("HP Jornada 620/660/680/690 Keyboard Driver"); |
277 | MODULE_LICENSE("GPLv2"); | 278 | MODULE_LICENSE("GPLv2"); |
279 | MODULE_ALIAS("platform:jornada680_kbd"); | ||
diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index 986f93cfc6b8..a1164a0c7736 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c | |||
@@ -162,9 +162,13 @@ static int __devexit jornada720_kbd_remove(struct platform_device *pdev) | |||
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | /* work with hotplug and coldplug */ | ||
166 | MODULE_ALIAS("platform:jornada720_kbd"); | ||
167 | |||
165 | static struct platform_driver jornada720_kbd_driver = { | 168 | static struct platform_driver jornada720_kbd_driver = { |
166 | .driver = { | 169 | .driver = { |
167 | .name = "jornada720_kbd", | 170 | .name = "jornada720_kbd", |
171 | .owner = THIS_MODULE, | ||
168 | }, | 172 | }, |
169 | .probe = jornada720_kbd_probe, | 173 | .probe = jornada720_kbd_probe, |
170 | .remove = __devexit_p(jornada720_kbd_remove), | 174 | .remove = __devexit_p(jornada720_kbd_remove), |
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 5a0ca18d6755..9caed30f3bbb 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005 John Lenz | 2 | * LoCoMo keyboard driver for Linux-based ARM PDAs: |
3 | * - SHARP Zaurus Collie (SL-5500) | ||
4 | * - SHARP Zaurus Poodle (SL-5600) | ||
3 | * | 5 | * |
6 | * Copyright (c) 2005 John Lenz | ||
4 | * Based on from xtkbd.c | 7 | * Based on from xtkbd.c |
5 | */ | 8 | * |
6 | 9 | * | |
7 | /* | ||
8 | * LoCoMo keyboard driver for Linux/ARM | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
@@ -47,7 +45,8 @@ MODULE_LICENSE("GPL"); | |||
47 | #define KEY_CONTACT KEY_F18 | 45 | #define KEY_CONTACT KEY_F18 |
48 | #define KEY_CENTER KEY_F15 | 46 | #define KEY_CENTER KEY_F15 |
49 | 47 | ||
50 | static unsigned char locomokbd_keycode[LOCOMOKBD_NUMKEYS] = { | 48 | static const unsigned char |
49 | locomokbd_keycode[LOCOMOKBD_NUMKEYS] __devinitconst = { | ||
51 | 0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0, /* 0 - 9 */ | 50 | 0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0, /* 0 - 9 */ |
52 | 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT, /* 10 - 19 */ | 51 | 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT, /* 10 - 19 */ |
53 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 29 */ | 52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 29 */ |
@@ -67,22 +66,21 @@ static unsigned char locomokbd_keycode[LOCOMOKBD_NUMKEYS] = { | |||
67 | #define KB_COLS 8 | 66 | #define KB_COLS 8 |
68 | #define KB_ROWMASK(r) (1 << (r)) | 67 | #define KB_ROWMASK(r) (1 << (r)) |
69 | #define SCANCODE(c,r) ( ((c)<<4) + (r) + 1 ) | 68 | #define SCANCODE(c,r) ( ((c)<<4) + (r) + 1 ) |
70 | #define NR_SCANCODES 128 | ||
71 | 69 | ||
72 | #define KB_DELAY 8 | 70 | #define KB_DELAY 8 |
73 | #define SCAN_INTERVAL (HZ/10) | 71 | #define SCAN_INTERVAL (HZ/10) |
74 | #define LOCOMOKBD_PRESSED 1 | ||
75 | 72 | ||
76 | struct locomokbd { | 73 | struct locomokbd { |
77 | unsigned char keycode[LOCOMOKBD_NUMKEYS]; | 74 | unsigned char keycode[LOCOMOKBD_NUMKEYS]; |
78 | struct input_dev *input; | 75 | struct input_dev *input; |
79 | char phys[32]; | 76 | char phys[32]; |
80 | 77 | ||
81 | struct locomo_dev *ldev; | ||
82 | unsigned long base; | 78 | unsigned long base; |
83 | spinlock_t lock; | 79 | spinlock_t lock; |
84 | 80 | ||
85 | struct timer_list timer; | 81 | struct timer_list timer; |
82 | unsigned long suspend_jiffies; | ||
83 | unsigned int count_cancel; | ||
86 | }; | 84 | }; |
87 | 85 | ||
88 | /* helper functions for reading the keyboard matrix */ | 86 | /* helper functions for reading the keyboard matrix */ |
@@ -128,7 +126,7 @@ static inline void locomokbd_reset_col(unsigned long membase, int col) | |||
128 | /* Scan the hardware keyboard and push any changes up through the input layer */ | 126 | /* Scan the hardware keyboard and push any changes up through the input layer */ |
129 | static void locomokbd_scankeyboard(struct locomokbd *locomokbd) | 127 | static void locomokbd_scankeyboard(struct locomokbd *locomokbd) |
130 | { | 128 | { |
131 | unsigned int row, col, rowd, scancode; | 129 | unsigned int row, col, rowd; |
132 | unsigned long flags; | 130 | unsigned long flags; |
133 | unsigned int num_pressed; | 131 | unsigned int num_pressed; |
134 | unsigned long membase = locomokbd->base; | 132 | unsigned long membase = locomokbd->base; |
@@ -145,13 +143,33 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) | |||
145 | 143 | ||
146 | rowd = ~locomo_readl(membase + LOCOMO_KIB); | 144 | rowd = ~locomo_readl(membase + LOCOMO_KIB); |
147 | for (row = 0; row < KB_ROWS; row++) { | 145 | for (row = 0; row < KB_ROWS; row++) { |
146 | unsigned int scancode, pressed, key; | ||
147 | |||
148 | scancode = SCANCODE(col, row); | 148 | scancode = SCANCODE(col, row); |
149 | if (rowd & KB_ROWMASK(row)) { | 149 | pressed = rowd & KB_ROWMASK(row); |
150 | num_pressed += 1; | 150 | key = locomokbd->keycode[scancode]; |
151 | input_report_key(locomokbd->input, locomokbd->keycode[scancode], 1); | 151 | |
152 | } else { | 152 | input_report_key(locomokbd->input, key, pressed); |
153 | input_report_key(locomokbd->input, locomokbd->keycode[scancode], 0); | 153 | if (likely(!pressed)) |
154 | } | 154 | continue; |
155 | |||
156 | num_pressed++; | ||
157 | |||
158 | /* The "Cancel/ESC" key is labeled "On/Off" on | ||
159 | * Collie and Poodle and should suspend the device | ||
160 | * if it was pressed for more than a second. */ | ||
161 | if (unlikely(key == KEY_ESC)) { | ||
162 | if (!time_after(jiffies, | ||
163 | locomokbd->suspend_jiffies + HZ)) | ||
164 | continue; | ||
165 | if (locomokbd->count_cancel++ | ||
166 | != (HZ/SCAN_INTERVAL + 1)) | ||
167 | continue; | ||
168 | input_event(locomokbd->input, EV_PWR, | ||
169 | KEY_SUSPEND, 1); | ||
170 | locomokbd->suspend_jiffies = jiffies; | ||
171 | } else | ||
172 | locomokbd->count_cancel = 0; | ||
155 | } | 173 | } |
156 | locomokbd_reset_col(membase, col); | 174 | locomokbd_reset_col(membase, col); |
157 | } | 175 | } |
@@ -162,6 +180,8 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd) | |||
162 | /* if any keys are pressed, enable the timer */ | 180 | /* if any keys are pressed, enable the timer */ |
163 | if (num_pressed) | 181 | if (num_pressed) |
164 | mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL); | 182 | mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL); |
183 | else | ||
184 | locomokbd->count_cancel = 0; | ||
165 | 185 | ||
166 | spin_unlock_irqrestore(&locomokbd->lock, flags); | 186 | spin_unlock_irqrestore(&locomokbd->lock, flags); |
167 | } | 187 | } |
@@ -186,10 +206,11 @@ static irqreturn_t locomokbd_interrupt(int irq, void *dev_id) | |||
186 | static void locomokbd_timer_callback(unsigned long data) | 206 | static void locomokbd_timer_callback(unsigned long data) |
187 | { | 207 | { |
188 | struct locomokbd *locomokbd = (struct locomokbd *) data; | 208 | struct locomokbd *locomokbd = (struct locomokbd *) data; |
209 | |||
189 | locomokbd_scankeyboard(locomokbd); | 210 | locomokbd_scankeyboard(locomokbd); |
190 | } | 211 | } |
191 | 212 | ||
192 | static int locomokbd_probe(struct locomo_dev *dev) | 213 | static int __devinit locomokbd_probe(struct locomo_dev *dev) |
193 | { | 214 | { |
194 | struct locomokbd *locomokbd; | 215 | struct locomokbd *locomokbd; |
195 | struct input_dev *input_dev; | 216 | struct input_dev *input_dev; |
@@ -211,7 +232,6 @@ static int locomokbd_probe(struct locomo_dev *dev) | |||
211 | goto err_free_mem; | 232 | goto err_free_mem; |
212 | } | 233 | } |
213 | 234 | ||
214 | locomokbd->ldev = dev; | ||
215 | locomo_set_drvdata(dev, locomokbd); | 235 | locomo_set_drvdata(dev, locomokbd); |
216 | 236 | ||
217 | locomokbd->base = (unsigned long) dev->mapbase; | 237 | locomokbd->base = (unsigned long) dev->mapbase; |
@@ -222,6 +242,8 @@ static int locomokbd_probe(struct locomo_dev *dev) | |||
222 | locomokbd->timer.function = locomokbd_timer_callback; | 242 | locomokbd->timer.function = locomokbd_timer_callback; |
223 | locomokbd->timer.data = (unsigned long) locomokbd; | 243 | locomokbd->timer.data = (unsigned long) locomokbd; |
224 | 244 | ||
245 | locomokbd->suspend_jiffies = jiffies; | ||
246 | |||
225 | locomokbd->input = input_dev; | 247 | locomokbd->input = input_dev; |
226 | strcpy(locomokbd->phys, "locomokbd/input0"); | 248 | strcpy(locomokbd->phys, "locomokbd/input0"); |
227 | 249 | ||
@@ -233,9 +255,10 @@ static int locomokbd_probe(struct locomo_dev *dev) | |||
233 | input_dev->id.version = 0x0100; | 255 | input_dev->id.version = 0x0100; |
234 | input_dev->dev.parent = &dev->dev; | 256 | input_dev->dev.parent = &dev->dev; |
235 | 257 | ||
236 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 258 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | |
259 | BIT_MASK(EV_PWR); | ||
237 | input_dev->keycode = locomokbd->keycode; | 260 | input_dev->keycode = locomokbd->keycode; |
238 | input_dev->keycodesize = sizeof(unsigned char); | 261 | input_dev->keycodesize = sizeof(locomokbd_keycode[0]); |
239 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); | 262 | input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); |
240 | 263 | ||
241 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); | 264 | memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); |
@@ -268,7 +291,7 @@ static int locomokbd_probe(struct locomo_dev *dev) | |||
268 | return err; | 291 | return err; |
269 | } | 292 | } |
270 | 293 | ||
271 | static int locomokbd_remove(struct locomo_dev *dev) | 294 | static int __devexit locomokbd_remove(struct locomo_dev *dev) |
272 | { | 295 | { |
273 | struct locomokbd *locomokbd = locomo_get_drvdata(dev); | 296 | struct locomokbd *locomokbd = locomo_get_drvdata(dev); |
274 | 297 | ||
@@ -292,7 +315,7 @@ static struct locomo_driver keyboard_driver = { | |||
292 | }, | 315 | }, |
293 | .devid = LOCOMO_DEVID_KEYBOARD, | 316 | .devid = LOCOMO_DEVID_KEYBOARD, |
294 | .probe = locomokbd_probe, | 317 | .probe = locomokbd_probe, |
295 | .remove = locomokbd_remove, | 318 | .remove = __devexit_p(locomokbd_remove), |
296 | }; | 319 | }; |
297 | 320 | ||
298 | static int __init locomokbd_init(void) | 321 | static int __init locomokbd_init(void) |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index babc913d5492..10afd2068068 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -352,6 +352,9 @@ static int __init omap_kp_probe(struct platform_device *pdev) | |||
352 | } | 352 | } |
353 | omap_set_gpio_direction(row_gpios[row_idx], 1); | 353 | omap_set_gpio_direction(row_gpios[row_idx], 1); |
354 | } | 354 | } |
355 | } else { | ||
356 | col_idx = 0; | ||
357 | row_idx = 0; | ||
355 | } | 358 | } |
356 | 359 | ||
357 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); | 360 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); |
@@ -415,10 +418,10 @@ err4: | |||
415 | err3: | 418 | err3: |
416 | device_remove_file(&pdev->dev, &dev_attr_enable); | 419 | device_remove_file(&pdev->dev, &dev_attr_enable); |
417 | err2: | 420 | err2: |
418 | for (i = row_idx-1; i >=0; i--) | 421 | for (i = row_idx - 1; i >=0; i--) |
419 | omap_free_gpio(row_gpios[i]); | 422 | omap_free_gpio(row_gpios[i]); |
420 | err1: | 423 | err1: |
421 | for (i = col_idx-1; i >=0; i--) | 424 | for (i = col_idx - 1; i >=0; i--) |
422 | omap_free_gpio(col_gpios[i]); | 425 | omap_free_gpio(col_gpios[i]); |
423 | 426 | ||
424 | kfree(omap_kp); | 427 | kfree(omap_kp); |
@@ -464,6 +467,7 @@ static struct platform_driver omap_kp_driver = { | |||
464 | .resume = omap_kp_resume, | 467 | .resume = omap_kp_resume, |
465 | .driver = { | 468 | .driver = { |
466 | .name = "omap-keypad", | 469 | .name = "omap-keypad", |
470 | .owner = THIS_MODULE, | ||
467 | }, | 471 | }, |
468 | }; | 472 | }; |
469 | 473 | ||
@@ -484,3 +488,4 @@ module_exit(omap_kp_exit); | |||
484 | MODULE_AUTHOR("Timo Teräs"); | 488 | MODULE_AUTHOR("Timo Teräs"); |
485 | MODULE_DESCRIPTION("OMAP Keypad Driver"); | 489 | MODULE_DESCRIPTION("OMAP Keypad Driver"); |
486 | MODULE_LICENSE("GPL"); | 490 | MODULE_LICENSE("GPL"); |
491 | MODULE_ALIAS("platform:omap-keypad"); | ||
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 4e651c11c1da..3dea0c5077a9 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -545,6 +545,9 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) | |||
545 | return 0; | 545 | return 0; |
546 | } | 546 | } |
547 | 547 | ||
548 | /* work with hotplug and coldplug */ | ||
549 | MODULE_ALIAS("platform:pxa27x-keypad"); | ||
550 | |||
548 | static struct platform_driver pxa27x_keypad_driver = { | 551 | static struct platform_driver pxa27x_keypad_driver = { |
549 | .probe = pxa27x_keypad_probe, | 552 | .probe = pxa27x_keypad_probe, |
550 | .remove = __devexit_p(pxa27x_keypad_remove), | 553 | .remove = __devexit_p(pxa27x_keypad_remove), |
@@ -552,6 +555,7 @@ static struct platform_driver pxa27x_keypad_driver = { | |||
552 | .resume = pxa27x_keypad_resume, | 555 | .resume = pxa27x_keypad_resume, |
553 | .driver = { | 556 | .driver = { |
554 | .name = "pxa27x-keypad", | 557 | .name = "pxa27x-keypad", |
558 | .owner = THIS_MODULE, | ||
555 | }, | 559 | }, |
556 | }; | 560 | }; |
557 | 561 | ||
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 1d59a2dc3c17..92102f9e4b8b 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c | |||
@@ -494,3 +494,4 @@ module_exit(spitzkbd_exit); | |||
494 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | 494 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); |
495 | MODULE_DESCRIPTION("Spitz Keyboard Driver"); | 495 | MODULE_DESCRIPTION("Spitz Keyboard Driver"); |
496 | MODULE_LICENSE("GPLv2"); | 496 | MODULE_LICENSE("GPLv2"); |
497 | MODULE_ALIAS("platform:spitz-keyboard"); | ||
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c index 3884d1e3f070..94e444b4ee15 100644 --- a/drivers/input/keyboard/tosakbd.c +++ b/drivers/input/keyboard/tosakbd.c | |||
@@ -52,7 +52,7 @@ KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_ | |||
52 | struct tosakbd { | 52 | struct tosakbd { |
53 | unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)]; | 53 | unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)]; |
54 | struct input_dev *input; | 54 | struct input_dev *input; |
55 | 55 | int suspended; | |
56 | spinlock_t lock; /* protect kbd scanning */ | 56 | spinlock_t lock; /* protect kbd scanning */ |
57 | struct timer_list timer; | 57 | struct timer_list timer; |
58 | }; | 58 | }; |
@@ -133,6 +133,9 @@ static void tosakbd_scankeyboard(struct platform_device *dev) | |||
133 | 133 | ||
134 | spin_lock_irqsave(&tosakbd->lock, flags); | 134 | spin_lock_irqsave(&tosakbd->lock, flags); |
135 | 135 | ||
136 | if (tosakbd->suspended) | ||
137 | goto out; | ||
138 | |||
136 | for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) { | 139 | for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) { |
137 | /* | 140 | /* |
138 | * Discharge the output driver capacitatance | 141 | * Discharge the output driver capacitatance |
@@ -174,6 +177,7 @@ static void tosakbd_scankeyboard(struct platform_device *dev) | |||
174 | if (num_pressed) | 177 | if (num_pressed) |
175 | mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL); | 178 | mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL); |
176 | 179 | ||
180 | out: | ||
177 | spin_unlock_irqrestore(&tosakbd->lock, flags); | 181 | spin_unlock_irqrestore(&tosakbd->lock, flags); |
178 | } | 182 | } |
179 | 183 | ||
@@ -200,6 +204,7 @@ static irqreturn_t tosakbd_interrupt(int irq, void *__dev) | |||
200 | static void tosakbd_timer_callback(unsigned long __dev) | 204 | static void tosakbd_timer_callback(unsigned long __dev) |
201 | { | 205 | { |
202 | struct platform_device *dev = (struct platform_device *)__dev; | 206 | struct platform_device *dev = (struct platform_device *)__dev; |
207 | |||
203 | tosakbd_scankeyboard(dev); | 208 | tosakbd_scankeyboard(dev); |
204 | } | 209 | } |
205 | 210 | ||
@@ -207,6 +212,13 @@ static void tosakbd_timer_callback(unsigned long __dev) | |||
207 | static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) | 212 | static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) |
208 | { | 213 | { |
209 | struct tosakbd *tosakbd = platform_get_drvdata(dev); | 214 | struct tosakbd *tosakbd = platform_get_drvdata(dev); |
215 | unsigned long flags; | ||
216 | |||
217 | spin_lock_irqsave(&tosakbd->lock, flags); | ||
218 | PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT); | ||
219 | PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT); | ||
220 | tosakbd->suspended = 1; | ||
221 | spin_unlock_irqrestore(&tosakbd->lock, flags); | ||
210 | 222 | ||
211 | del_timer_sync(&tosakbd->timer); | 223 | del_timer_sync(&tosakbd->timer); |
212 | 224 | ||
@@ -215,6 +227,9 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state) | |||
215 | 227 | ||
216 | static int tosakbd_resume(struct platform_device *dev) | 228 | static int tosakbd_resume(struct platform_device *dev) |
217 | { | 229 | { |
230 | struct tosakbd *tosakbd = platform_get_drvdata(dev); | ||
231 | |||
232 | tosakbd->suspended = 0; | ||
218 | tosakbd_scankeyboard(dev); | 233 | tosakbd_scankeyboard(dev); |
219 | 234 | ||
220 | return 0; | 235 | return 0; |
@@ -365,8 +380,8 @@ fail: | |||
365 | return error; | 380 | return error; |
366 | } | 381 | } |
367 | 382 | ||
368 | static int __devexit tosakbd_remove(struct platform_device *dev) { | 383 | static int __devexit tosakbd_remove(struct platform_device *dev) |
369 | 384 | { | |
370 | int i; | 385 | int i; |
371 | struct tosakbd *tosakbd = platform_get_drvdata(dev); | 386 | struct tosakbd *tosakbd = platform_get_drvdata(dev); |
372 | 387 | ||
@@ -394,6 +409,7 @@ static struct platform_driver tosakbd_driver = { | |||
394 | .resume = tosakbd_resume, | 409 | .resume = tosakbd_resume, |
395 | .driver = { | 410 | .driver = { |
396 | .name = "tosa-keyboard", | 411 | .name = "tosa-keyboard", |
412 | .owner = THIS_MODULE, | ||
397 | }, | 413 | }, |
398 | }; | 414 | }; |
399 | 415 | ||
@@ -413,3 +429,4 @@ module_exit(tosakbd_exit); | |||
413 | MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>"); | 429 | MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>"); |
414 | MODULE_DESCRIPTION("Tosa Keyboard Driver"); | 430 | MODULE_DESCRIPTION("Tosa Keyboard Driver"); |
415 | MODULE_LICENSE("GPL v2"); | 431 | MODULE_LICENSE("GPL v2"); |
432 | MODULE_ALIAS("platform:tosa-keyboard"); | ||
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index 5511ef006a66..6a1f48b76e32 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c | |||
@@ -148,6 +148,9 @@ static int __devexit cobalt_buttons_remove(struct platform_device *pdev) | |||
148 | return 0; | 148 | return 0; |
149 | } | 149 | } |
150 | 150 | ||
151 | /* work with hotplug and coldplug */ | ||
152 | MODULE_ALIAS("platform:Cobalt buttons"); | ||
153 | |||
151 | static struct platform_driver cobalt_buttons_driver = { | 154 | static struct platform_driver cobalt_buttons_driver = { |
152 | .probe = cobalt_buttons_probe, | 155 | .probe = cobalt_buttons_probe, |
153 | .remove = __devexit_p(cobalt_buttons_remove), | 156 | .remove = __devexit_p(cobalt_buttons_remove), |
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index b4423a471f02..8dd3942f3022 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -62,6 +62,10 @@ | |||
62 | #define GEYSER4_ISO_PRODUCT_ID 0x021B | 62 | #define GEYSER4_ISO_PRODUCT_ID 0x021B |
63 | #define GEYSER4_JIS_PRODUCT_ID 0x021C | 63 | #define GEYSER4_JIS_PRODUCT_ID 0x021C |
64 | 64 | ||
65 | #define GEYSER4_HF_ANSI_PRODUCT_ID 0x0229 | ||
66 | #define GEYSER4_HF_ISO_PRODUCT_ID 0x022A | ||
67 | #define GEYSER4_HF_JIS_PRODUCT_ID 0x022B | ||
68 | |||
65 | #define ATP_DEVICE(prod) \ | 69 | #define ATP_DEVICE(prod) \ |
66 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ | 70 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ |
67 | USB_DEVICE_ID_MATCH_INT_CLASS | \ | 71 | USB_DEVICE_ID_MATCH_INT_CLASS | \ |
@@ -93,6 +97,10 @@ static struct usb_device_id atp_table [] = { | |||
93 | { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) }, | 97 | { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) }, |
94 | { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) }, | 98 | { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) }, |
95 | 99 | ||
100 | { ATP_DEVICE(GEYSER4_HF_ANSI_PRODUCT_ID) }, | ||
101 | { ATP_DEVICE(GEYSER4_HF_ISO_PRODUCT_ID) }, | ||
102 | { ATP_DEVICE(GEYSER4_HF_JIS_PRODUCT_ID) }, | ||
103 | |||
96 | /* Terminating entry */ | 104 | /* Terminating entry */ |
97 | { } | 105 | { } |
98 | }; | 106 | }; |
@@ -217,7 +225,10 @@ static inline int atp_is_geyser_3(struct atp *dev) | |||
217 | (productId == GEYSER3_JIS_PRODUCT_ID) || | 225 | (productId == GEYSER3_JIS_PRODUCT_ID) || |
218 | (productId == GEYSER4_ANSI_PRODUCT_ID) || | 226 | (productId == GEYSER4_ANSI_PRODUCT_ID) || |
219 | (productId == GEYSER4_ISO_PRODUCT_ID) || | 227 | (productId == GEYSER4_ISO_PRODUCT_ID) || |
220 | (productId == GEYSER4_JIS_PRODUCT_ID); | 228 | (productId == GEYSER4_JIS_PRODUCT_ID) || |
229 | (productId == GEYSER4_HF_ANSI_PRODUCT_ID) || | ||
230 | (productId == GEYSER4_HF_ISO_PRODUCT_ID) || | ||
231 | (productId == GEYSER4_HF_JIS_PRODUCT_ID); | ||
221 | } | 232 | } |
222 | 233 | ||
223 | /* | 234 | /* |
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index 0936d6ba015c..339290184871 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c | |||
@@ -171,10 +171,14 @@ static int __devexit gpio_mouse_remove(struct platform_device *pdev) | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
174 | /* work with hotplug and coldplug */ | ||
175 | MODULE_ALIAS("platform:gpio_mouse"); | ||
176 | |||
174 | struct platform_driver gpio_mouse_device_driver = { | 177 | struct platform_driver gpio_mouse_device_driver = { |
175 | .remove = __devexit_p(gpio_mouse_remove), | 178 | .remove = __devexit_p(gpio_mouse_remove), |
176 | .driver = { | 179 | .driver = { |
177 | .name = "gpio_mouse", | 180 | .name = "gpio_mouse", |
181 | .owner = THIS_MODULE, | ||
178 | } | 182 | } |
179 | }; | 183 | }; |
180 | 184 | ||
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index b88569e21d60..ec4b6610f730 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -88,6 +88,16 @@ config SERIO_RPCKBD | |||
88 | To compile this driver as a module, choose M here: the | 88 | To compile this driver as a module, choose M here: the |
89 | module will be called rpckbd. | 89 | module will be called rpckbd. |
90 | 90 | ||
91 | config SERIO_AT32PSIF | ||
92 | tristate "AVR32 PSIF PS/2 keyboard and mouse controller" | ||
93 | depends on AVR32 | ||
94 | help | ||
95 | Say Y here if you want to use the PSIF peripheral on AVR32 devices | ||
96 | and connect a PS/2 keyboard and/or mouse to it. | ||
97 | |||
98 | To compile this driver as a module, choose M here: the module will | ||
99 | be called at32psif. | ||
100 | |||
91 | config SERIO_AMBAKMI | 101 | config SERIO_AMBAKMI |
92 | tristate "AMBA KMI keyboard controller" | 102 | tristate "AMBA KMI keyboard controller" |
93 | depends on ARM_AMBA | 103 | depends on ARM_AMBA |
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 4155197867a3..38b886887cbc 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -12,6 +12,7 @@ obj-$(CONFIG_SERIO_CT82C710) += ct82c710.o | |||
12 | obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o | 12 | obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o |
13 | obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o | 13 | obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o |
14 | obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o | 14 | obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o |
15 | obj-$(CONFIG_SERIO_AT32PSIF) += at32psif.o | ||
15 | obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o | 16 | obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o |
16 | obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o | 17 | obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o |
17 | obj-$(CONFIG_HP_SDC) += hp_sdc.o | 18 | obj-$(CONFIG_HP_SDC) += hp_sdc.o |
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c new file mode 100644 index 000000000000..41fda8c67b1e --- /dev/null +++ b/drivers/input/serio/at32psif.c | |||
@@ -0,0 +1,375 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Atmel Corporation | ||
3 | * | ||
4 | * Driver for the AT32AP700X PS/2 controller (PSIF). | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/serio.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | /* PSIF register offsets */ | ||
23 | #define PSIF_CR 0x00 | ||
24 | #define PSIF_RHR 0x04 | ||
25 | #define PSIF_THR 0x08 | ||
26 | #define PSIF_SR 0x10 | ||
27 | #define PSIF_IER 0x14 | ||
28 | #define PSIF_IDR 0x18 | ||
29 | #define PSIF_IMR 0x1c | ||
30 | #define PSIF_PSR 0x24 | ||
31 | |||
32 | /* Bitfields in control register. */ | ||
33 | #define PSIF_CR_RXDIS_OFFSET 1 | ||
34 | #define PSIF_CR_RXDIS_SIZE 1 | ||
35 | #define PSIF_CR_RXEN_OFFSET 0 | ||
36 | #define PSIF_CR_RXEN_SIZE 1 | ||
37 | #define PSIF_CR_SWRST_OFFSET 15 | ||
38 | #define PSIF_CR_SWRST_SIZE 1 | ||
39 | #define PSIF_CR_TXDIS_OFFSET 9 | ||
40 | #define PSIF_CR_TXDIS_SIZE 1 | ||
41 | #define PSIF_CR_TXEN_OFFSET 8 | ||
42 | #define PSIF_CR_TXEN_SIZE 1 | ||
43 | |||
44 | /* Bitfields in interrupt disable, enable, mask and status register. */ | ||
45 | #define PSIF_NACK_OFFSET 8 | ||
46 | #define PSIF_NACK_SIZE 1 | ||
47 | #define PSIF_OVRUN_OFFSET 5 | ||
48 | #define PSIF_OVRUN_SIZE 1 | ||
49 | #define PSIF_PARITY_OFFSET 9 | ||
50 | #define PSIF_PARITY_SIZE 1 | ||
51 | #define PSIF_RXRDY_OFFSET 4 | ||
52 | #define PSIF_RXRDY_SIZE 1 | ||
53 | #define PSIF_TXEMPTY_OFFSET 1 | ||
54 | #define PSIF_TXEMPTY_SIZE 1 | ||
55 | #define PSIF_TXRDY_OFFSET 0 | ||
56 | #define PSIF_TXRDY_SIZE 1 | ||
57 | |||
58 | /* Bitfields in prescale register. */ | ||
59 | #define PSIF_PSR_PRSCV_OFFSET 0 | ||
60 | #define PSIF_PSR_PRSCV_SIZE 12 | ||
61 | |||
62 | /* Bitfields in receive hold register. */ | ||
63 | #define PSIF_RHR_RXDATA_OFFSET 0 | ||
64 | #define PSIF_RHR_RXDATA_SIZE 8 | ||
65 | |||
66 | /* Bitfields in transmit hold register. */ | ||
67 | #define PSIF_THR_TXDATA_OFFSET 0 | ||
68 | #define PSIF_THR_TXDATA_SIZE 8 | ||
69 | |||
70 | /* Bit manipulation macros */ | ||
71 | #define PSIF_BIT(name) \ | ||
72 | (1 << PSIF_##name##_OFFSET) | ||
73 | |||
74 | #define PSIF_BF(name, value) \ | ||
75 | (((value) & ((1 << PSIF_##name##_SIZE) - 1)) \ | ||
76 | << PSIF_##name##_OFFSET) | ||
77 | |||
78 | #define PSIF_BFEXT(name, value) \ | ||
79 | (((value) >> PSIF_##name##_OFFSET) \ | ||
80 | & ((1 << PSIF_##name##_SIZE) - 1)) | ||
81 | |||
82 | #define PSIF_BFINS(name, value, old) \ | ||
83 | (((old) & ~(((1 << PSIF_##name##_SIZE) - 1) \ | ||
84 | << PSIF_##name##_OFFSET)) \ | ||
85 | | PSIF_BF(name, value)) | ||
86 | |||
87 | /* Register access macros */ | ||
88 | #define psif_readl(port, reg) \ | ||
89 | __raw_readl((port)->regs + PSIF_##reg) | ||
90 | |||
91 | #define psif_writel(port, reg, value) \ | ||
92 | __raw_writel((value), (port)->regs + PSIF_##reg) | ||
93 | |||
94 | struct psif { | ||
95 | struct platform_device *pdev; | ||
96 | struct clk *pclk; | ||
97 | struct serio *io; | ||
98 | void __iomem *regs; | ||
99 | unsigned int irq; | ||
100 | unsigned int open; | ||
101 | /* Prevent concurrent writes to PSIF THR. */ | ||
102 | spinlock_t lock; | ||
103 | }; | ||
104 | |||
105 | static irqreturn_t psif_interrupt(int irq, void *_ptr) | ||
106 | { | ||
107 | struct psif *psif = _ptr; | ||
108 | int retval = IRQ_NONE; | ||
109 | unsigned int io_flags = 0; | ||
110 | unsigned long status; | ||
111 | |||
112 | status = psif_readl(psif, SR); | ||
113 | |||
114 | if (status & PSIF_BIT(RXRDY)) { | ||
115 | unsigned char val = (unsigned char) psif_readl(psif, RHR); | ||
116 | |||
117 | if (status & PSIF_BIT(PARITY)) | ||
118 | io_flags |= SERIO_PARITY; | ||
119 | if (status & PSIF_BIT(OVRUN)) | ||
120 | dev_err(&psif->pdev->dev, "overrun read error\n"); | ||
121 | |||
122 | serio_interrupt(psif->io, val, io_flags); | ||
123 | |||
124 | retval = IRQ_HANDLED; | ||
125 | } | ||
126 | |||
127 | return retval; | ||
128 | } | ||
129 | |||
130 | static int psif_write(struct serio *io, unsigned char val) | ||
131 | { | ||
132 | struct psif *psif = io->port_data; | ||
133 | unsigned long flags; | ||
134 | int timeout = 10; | ||
135 | int retval = 0; | ||
136 | |||
137 | spin_lock_irqsave(&psif->lock, flags); | ||
138 | |||
139 | while (!(psif_readl(psif, SR) & PSIF_BIT(TXEMPTY)) && timeout--) | ||
140 | msleep(10); | ||
141 | |||
142 | if (timeout >= 0) { | ||
143 | psif_writel(psif, THR, val); | ||
144 | } else { | ||
145 | dev_dbg(&psif->pdev->dev, "timeout writing to THR\n"); | ||
146 | retval = -EBUSY; | ||
147 | } | ||
148 | |||
149 | spin_unlock_irqrestore(&psif->lock, flags); | ||
150 | |||
151 | return retval; | ||
152 | } | ||
153 | |||
154 | static int psif_open(struct serio *io) | ||
155 | { | ||
156 | struct psif *psif = io->port_data; | ||
157 | int retval; | ||
158 | |||
159 | retval = clk_enable(psif->pclk); | ||
160 | if (retval) | ||
161 | goto out; | ||
162 | |||
163 | psif_writel(psif, CR, PSIF_BIT(CR_TXEN) | PSIF_BIT(CR_RXEN)); | ||
164 | psif_writel(psif, IER, PSIF_BIT(RXRDY)); | ||
165 | |||
166 | psif->open = 1; | ||
167 | out: | ||
168 | return retval; | ||
169 | } | ||
170 | |||
171 | static void psif_close(struct serio *io) | ||
172 | { | ||
173 | struct psif *psif = io->port_data; | ||
174 | |||
175 | psif->open = 0; | ||
176 | |||
177 | psif_writel(psif, IDR, ~0UL); | ||
178 | psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); | ||
179 | |||
180 | clk_disable(psif->pclk); | ||
181 | } | ||
182 | |||
183 | static void psif_set_prescaler(struct psif *psif) | ||
184 | { | ||
185 | unsigned long prscv; | ||
186 | unsigned long rate = clk_get_rate(psif->pclk); | ||
187 | |||
188 | /* PRSCV = Pulse length (100 us) * PSIF module frequency. */ | ||
189 | prscv = 100 * (rate / 1000000UL); | ||
190 | |||
191 | if (prscv > ((1<<PSIF_PSR_PRSCV_SIZE) - 1)) { | ||
192 | prscv = (1<<PSIF_PSR_PRSCV_SIZE) - 1; | ||
193 | dev_dbg(&psif->pdev->dev, "pclk too fast, " | ||
194 | "prescaler set to max\n"); | ||
195 | } | ||
196 | |||
197 | clk_enable(psif->pclk); | ||
198 | psif_writel(psif, PSR, prscv); | ||
199 | clk_disable(psif->pclk); | ||
200 | } | ||
201 | |||
202 | static int __init psif_probe(struct platform_device *pdev) | ||
203 | { | ||
204 | struct resource *regs; | ||
205 | struct psif *psif; | ||
206 | struct serio *io; | ||
207 | struct clk *pclk; | ||
208 | int irq; | ||
209 | int ret; | ||
210 | |||
211 | psif = kzalloc(sizeof(struct psif), GFP_KERNEL); | ||
212 | if (!psif) { | ||
213 | dev_dbg(&pdev->dev, "out of memory\n"); | ||
214 | ret = -ENOMEM; | ||
215 | goto out; | ||
216 | } | ||
217 | psif->pdev = pdev; | ||
218 | |||
219 | io = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
220 | if (!io) { | ||
221 | dev_dbg(&pdev->dev, "out of memory\n"); | ||
222 | ret = -ENOMEM; | ||
223 | goto out_free_psif; | ||
224 | } | ||
225 | psif->io = io; | ||
226 | |||
227 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
228 | if (!regs) { | ||
229 | dev_dbg(&pdev->dev, "no mmio resources defined\n"); | ||
230 | ret = -ENOMEM; | ||
231 | goto out_free_io; | ||
232 | } | ||
233 | |||
234 | psif->regs = ioremap(regs->start, regs->end - regs->start + 1); | ||
235 | if (!psif->regs) { | ||
236 | ret = -ENOMEM; | ||
237 | dev_dbg(&pdev->dev, "could not map I/O memory\n"); | ||
238 | goto out_free_io; | ||
239 | } | ||
240 | |||
241 | pclk = clk_get(&pdev->dev, "pclk"); | ||
242 | if (IS_ERR(pclk)) { | ||
243 | dev_dbg(&pdev->dev, "could not get peripheral clock\n"); | ||
244 | ret = PTR_ERR(pclk); | ||
245 | goto out_iounmap; | ||
246 | } | ||
247 | psif->pclk = pclk; | ||
248 | |||
249 | /* Reset the PSIF to enter at a known state. */ | ||
250 | ret = clk_enable(pclk); | ||
251 | if (ret) { | ||
252 | dev_dbg(&pdev->dev, "could not enable pclk\n"); | ||
253 | goto out_put_clk; | ||
254 | } | ||
255 | psif_writel(psif, CR, PSIF_BIT(CR_SWRST)); | ||
256 | clk_disable(pclk); | ||
257 | |||
258 | irq = platform_get_irq(pdev, 0); | ||
259 | if (irq < 0) { | ||
260 | dev_dbg(&pdev->dev, "could not get irq\n"); | ||
261 | ret = -ENXIO; | ||
262 | goto out_put_clk; | ||
263 | } | ||
264 | ret = request_irq(irq, psif_interrupt, IRQF_SHARED, "at32psif", psif); | ||
265 | if (ret) { | ||
266 | dev_dbg(&pdev->dev, "could not request irq %d\n", irq); | ||
267 | goto out_put_clk; | ||
268 | } | ||
269 | psif->irq = irq; | ||
270 | |||
271 | io->id.type = SERIO_8042; | ||
272 | io->write = psif_write; | ||
273 | io->open = psif_open; | ||
274 | io->close = psif_close; | ||
275 | snprintf(io->name, sizeof(io->name), "AVR32 PS/2 port%d", pdev->id); | ||
276 | snprintf(io->phys, sizeof(io->phys), "at32psif/serio%d", pdev->id); | ||
277 | io->port_data = psif; | ||
278 | io->dev.parent = &pdev->dev; | ||
279 | |||
280 | psif_set_prescaler(psif); | ||
281 | |||
282 | spin_lock_init(&psif->lock); | ||
283 | serio_register_port(psif->io); | ||
284 | platform_set_drvdata(pdev, psif); | ||
285 | |||
286 | dev_info(&pdev->dev, "Atmel AVR32 PSIF PS/2 driver on 0x%08x irq %d\n", | ||
287 | (int)psif->regs, psif->irq); | ||
288 | |||
289 | return 0; | ||
290 | |||
291 | out_put_clk: | ||
292 | clk_put(psif->pclk); | ||
293 | out_iounmap: | ||
294 | iounmap(psif->regs); | ||
295 | out_free_io: | ||
296 | kfree(io); | ||
297 | out_free_psif: | ||
298 | kfree(psif); | ||
299 | out: | ||
300 | return ret; | ||
301 | } | ||
302 | |||
303 | static int __exit psif_remove(struct platform_device *pdev) | ||
304 | { | ||
305 | struct psif *psif = platform_get_drvdata(pdev); | ||
306 | |||
307 | psif_writel(psif, IDR, ~0UL); | ||
308 | psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); | ||
309 | |||
310 | serio_unregister_port(psif->io); | ||
311 | iounmap(psif->regs); | ||
312 | free_irq(psif->irq, psif); | ||
313 | clk_put(psif->pclk); | ||
314 | kfree(psif); | ||
315 | |||
316 | platform_set_drvdata(pdev, NULL); | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | #ifdef CONFIG_PM | ||
322 | static int psif_suspend(struct platform_device *pdev, pm_message_t state) | ||
323 | { | ||
324 | struct psif *psif = platform_get_drvdata(pdev); | ||
325 | |||
326 | if (psif->open) { | ||
327 | psif_writel(psif, CR, PSIF_BIT(CR_RXDIS) | PSIF_BIT(CR_TXDIS)); | ||
328 | clk_disable(psif->pclk); | ||
329 | } | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static int psif_resume(struct platform_device *pdev) | ||
335 | { | ||
336 | struct psif *psif = platform_get_drvdata(pdev); | ||
337 | |||
338 | if (psif->open) { | ||
339 | clk_enable(psif->pclk); | ||
340 | psif_set_prescaler(psif); | ||
341 | psif_writel(psif, CR, PSIF_BIT(CR_RXEN) | PSIF_BIT(CR_TXEN)); | ||
342 | } | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | #else | ||
347 | #define psif_suspend NULL | ||
348 | #define psif_resume NULL | ||
349 | #endif | ||
350 | |||
351 | static struct platform_driver psif_driver = { | ||
352 | .remove = __exit_p(psif_remove), | ||
353 | .driver = { | ||
354 | .name = "atmel_psif", | ||
355 | }, | ||
356 | .suspend = psif_suspend, | ||
357 | .resume = psif_resume, | ||
358 | }; | ||
359 | |||
360 | static int __init psif_init(void) | ||
361 | { | ||
362 | return platform_driver_probe(&psif_driver, psif_probe); | ||
363 | } | ||
364 | |||
365 | static void __exit psif_exit(void) | ||
366 | { | ||
367 | platform_driver_unregister(&psif_driver); | ||
368 | } | ||
369 | |||
370 | module_init(psif_init); | ||
371 | module_exit(psif_exit); | ||
372 | |||
373 | MODULE_AUTHOR("Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>"); | ||
374 | MODULE_DESCRIPTION("Atmel AVR32 PSIF PS/2 driver"); | ||
375 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 60931aceb828..5ece9f56babc 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -370,10 +370,10 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * | |||
370 | if (pnp_irq_valid(dev,0)) | 370 | if (pnp_irq_valid(dev,0)) |
371 | i8042_pnp_kbd_irq = pnp_irq(dev, 0); | 371 | i8042_pnp_kbd_irq = pnp_irq(dev, 0); |
372 | 372 | ||
373 | strncpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); | 373 | strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); |
374 | if (strlen(pnp_dev_name(dev))) { | 374 | if (strlen(pnp_dev_name(dev))) { |
375 | strncat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); | 375 | strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); |
376 | strncat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); | 376 | strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); |
377 | } | 377 | } |
378 | 378 | ||
379 | i8042_pnp_kbd_devices++; | 379 | i8042_pnp_kbd_devices++; |
@@ -391,10 +391,10 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id * | |||
391 | if (pnp_irq_valid(dev, 0)) | 391 | if (pnp_irq_valid(dev, 0)) |
392 | i8042_pnp_aux_irq = pnp_irq(dev, 0); | 392 | i8042_pnp_aux_irq = pnp_irq(dev, 0); |
393 | 393 | ||
394 | strncpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); | 394 | strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); |
395 | if (strlen(pnp_dev_name(dev))) { | 395 | if (strlen(pnp_dev_name(dev))) { |
396 | strncat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); | 396 | strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); |
397 | strncat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); | 397 | strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); |
398 | } | 398 | } |
399 | 399 | ||
400 | i8042_pnp_aux_devices++; | 400 | i8042_pnp_aux_devices++; |
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 49f84315cb32..34c59d9c6205 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c | |||
@@ -45,6 +45,7 @@ | |||
45 | MODULE_AUTHOR("Vojtech Pavlik, Russell King"); | 45 | MODULE_AUTHOR("Vojtech Pavlik, Russell King"); |
46 | MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver"); | 46 | MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver"); |
47 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
48 | MODULE_ALIAS("platform:kart"); | ||
48 | 49 | ||
49 | static int rpckbd_write(struct serio *port, unsigned char val) | 50 | static int rpckbd_write(struct serio *port, unsigned char val) |
50 | { | 51 | { |
@@ -140,6 +141,7 @@ static struct platform_driver rpckbd_driver = { | |||
140 | .remove = __devexit_p(rpckbd_remove), | 141 | .remove = __devexit_p(rpckbd_remove), |
141 | .driver = { | 142 | .driver = { |
142 | .name = "kart", | 143 | .name = "kart", |
144 | .owner = THIS_MODULE, | ||
143 | }, | 145 | }, |
144 | }; | 146 | }; |
145 | 147 | ||
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index d371c0bdc0bd..effb49ea24aa 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig | |||
@@ -25,14 +25,14 @@ config TABLET_USB_ACECAD | |||
25 | module will be called acecad. | 25 | module will be called acecad. |
26 | 26 | ||
27 | config TABLET_USB_AIPTEK | 27 | config TABLET_USB_AIPTEK |
28 | tristate "Aiptek 6000U/8000U tablet support (USB)" | 28 | tristate "Aiptek 6000U/8000U and Genius G_PEN tablet support (USB)" |
29 | depends on USB_ARCH_HAS_HCD | 29 | depends on USB_ARCH_HAS_HCD |
30 | select USB | 30 | select USB |
31 | help | 31 | help |
32 | Say Y here if you want to use the USB version of the Aiptek 6000U | 32 | Say Y here if you want to use the USB version of the Aiptek 6000U, |
33 | or Aiptek 8000U tablet. Make sure to say Y to "Mouse support" | 33 | Aiptek 8000U or Genius G-PEN 560 tablet. Make sure to say Y to |
34 | (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" | 34 | "Mouse support" (CONFIG_INPUT_MOUSEDEV) and/or "Event interface |
35 | (CONFIG_INPUT_EVDEV) as well. | 35 | support" (CONFIG_INPUT_EVDEV) as well. |
36 | 36 | ||
37 | To compile this driver as a module, choose M here: the | 37 | To compile this driver as a module, choose M here: the |
38 | module will be called aiptek. | 38 | module will be called aiptek. |
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 94683f58c9e1..1d759f6f8076 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
@@ -184,6 +184,7 @@ | |||
184 | */ | 184 | */ |
185 | 185 | ||
186 | #define USB_VENDOR_ID_AIPTEK 0x08ca | 186 | #define USB_VENDOR_ID_AIPTEK 0x08ca |
187 | #define USB_VENDOR_ID_KYE 0x0458 | ||
187 | #define USB_REQ_GET_REPORT 0x01 | 188 | #define USB_REQ_GET_REPORT 0x01 |
188 | #define USB_REQ_SET_REPORT 0x09 | 189 | #define USB_REQ_SET_REPORT 0x09 |
189 | 190 | ||
@@ -832,6 +833,7 @@ static const struct usb_device_id aiptek_ids[] = { | |||
832 | {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x22)}, | 833 | {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x22)}, |
833 | {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x23)}, | 834 | {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x23)}, |
834 | {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x24)}, | 835 | {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x24)}, |
836 | {USB_DEVICE(USB_VENDOR_ID_KYE, 0x5003)}, | ||
835 | {} | 837 | {} |
836 | }; | 838 | }; |
837 | 839 | ||
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index acf9830698cb..706619d06f71 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -101,8 +101,11 @@ struct wacom { | |||
101 | dma_addr_t data_dma; | 101 | dma_addr_t data_dma; |
102 | struct input_dev *dev; | 102 | struct input_dev *dev; |
103 | struct usb_device *usbdev; | 103 | struct usb_device *usbdev; |
104 | struct usb_interface *intf; | ||
104 | struct urb *irq; | 105 | struct urb *irq; |
105 | struct wacom_wac * wacom_wac; | 106 | struct wacom_wac * wacom_wac; |
107 | struct mutex lock; | ||
108 | int open:1; | ||
106 | char phys[32]; | 109 | char phys[32]; |
107 | }; | 110 | }; |
108 | 111 | ||
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 41caaef8e2d7..71cc0c140790 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -70,6 +70,7 @@ static void wacom_sys_irq(struct urb *urb) | |||
70 | input_sync(get_input_dev(&wcombo)); | 70 | input_sync(get_input_dev(&wcombo)); |
71 | 71 | ||
72 | exit: | 72 | exit: |
73 | usb_mark_last_busy(wacom->usbdev); | ||
73 | retval = usb_submit_urb (urb, GFP_ATOMIC); | 74 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
74 | if (retval) | 75 | if (retval) |
75 | err ("%s - usb_submit_urb failed with result %d", | 76 | err ("%s - usb_submit_urb failed with result %d", |
@@ -124,10 +125,25 @@ static int wacom_open(struct input_dev *dev) | |||
124 | { | 125 | { |
125 | struct wacom *wacom = input_get_drvdata(dev); | 126 | struct wacom *wacom = input_get_drvdata(dev); |
126 | 127 | ||
128 | mutex_lock(&wacom->lock); | ||
129 | |||
127 | wacom->irq->dev = wacom->usbdev; | 130 | wacom->irq->dev = wacom->usbdev; |
128 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) | 131 | |
132 | if (usb_autopm_get_interface(wacom->intf) < 0) { | ||
133 | mutex_unlock(&wacom->lock); | ||
129 | return -EIO; | 134 | return -EIO; |
135 | } | ||
136 | |||
137 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { | ||
138 | usb_autopm_put_interface(wacom->intf); | ||
139 | mutex_unlock(&wacom->lock); | ||
140 | return -EIO; | ||
141 | } | ||
142 | |||
143 | wacom->open = 1; | ||
144 | wacom->intf->needs_remote_wakeup = 1; | ||
130 | 145 | ||
146 | mutex_unlock(&wacom->lock); | ||
131 | return 0; | 147 | return 0; |
132 | } | 148 | } |
133 | 149 | ||
@@ -135,7 +151,11 @@ static void wacom_close(struct input_dev *dev) | |||
135 | { | 151 | { |
136 | struct wacom *wacom = input_get_drvdata(dev); | 152 | struct wacom *wacom = input_get_drvdata(dev); |
137 | 153 | ||
154 | mutex_lock(&wacom->lock); | ||
138 | usb_kill_urb(wacom->irq); | 155 | usb_kill_urb(wacom->irq); |
156 | wacom->open = 0; | ||
157 | wacom->intf->needs_remote_wakeup = 0; | ||
158 | mutex_unlock(&wacom->lock); | ||
139 | } | 159 | } |
140 | 160 | ||
141 | void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 161 | void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
@@ -243,6 +263,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
243 | 263 | ||
244 | wacom->usbdev = dev; | 264 | wacom->usbdev = dev; |
245 | wacom->dev = input_dev; | 265 | wacom->dev = input_dev; |
266 | wacom->intf = intf; | ||
267 | mutex_init(&wacom->lock); | ||
246 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); | 268 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); |
247 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); | 269 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); |
248 | 270 | ||
@@ -304,23 +326,57 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
304 | 326 | ||
305 | static void wacom_disconnect(struct usb_interface *intf) | 327 | static void wacom_disconnect(struct usb_interface *intf) |
306 | { | 328 | { |
307 | struct wacom *wacom = usb_get_intfdata (intf); | 329 | struct wacom *wacom = usb_get_intfdata(intf); |
308 | 330 | ||
309 | usb_set_intfdata(intf, NULL); | 331 | usb_set_intfdata(intf, NULL); |
310 | if (wacom) { | 332 | |
311 | usb_kill_urb(wacom->irq); | 333 | usb_kill_urb(wacom->irq); |
312 | input_unregister_device(wacom->dev); | 334 | input_unregister_device(wacom->dev); |
313 | usb_free_urb(wacom->irq); | 335 | usb_free_urb(wacom->irq); |
314 | usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); | 336 | usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); |
315 | kfree(wacom->wacom_wac); | 337 | kfree(wacom->wacom_wac); |
316 | kfree(wacom); | 338 | kfree(wacom); |
317 | } | 339 | } |
340 | |||
341 | static int wacom_suspend(struct usb_interface *intf, pm_message_t message) | ||
342 | { | ||
343 | struct wacom *wacom = usb_get_intfdata(intf); | ||
344 | |||
345 | mutex_lock(&wacom->lock); | ||
346 | usb_kill_urb(wacom->irq); | ||
347 | mutex_unlock(&wacom->lock); | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static int wacom_resume(struct usb_interface *intf) | ||
353 | { | ||
354 | struct wacom *wacom = usb_get_intfdata(intf); | ||
355 | int rv; | ||
356 | |||
357 | mutex_lock(&wacom->lock); | ||
358 | if (wacom->open) | ||
359 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); | ||
360 | else | ||
361 | rv = 0; | ||
362 | mutex_unlock(&wacom->lock); | ||
363 | |||
364 | return rv; | ||
365 | } | ||
366 | |||
367 | static int wacom_reset_resume(struct usb_interface *intf) | ||
368 | { | ||
369 | return wacom_resume(intf); | ||
318 | } | 370 | } |
319 | 371 | ||
320 | static struct usb_driver wacom_driver = { | 372 | static struct usb_driver wacom_driver = { |
321 | .name = "wacom", | 373 | .name = "wacom", |
322 | .probe = wacom_probe, | 374 | .probe = wacom_probe, |
323 | .disconnect = wacom_disconnect, | 375 | .disconnect = wacom_disconnect, |
376 | .suspend = wacom_suspend, | ||
377 | .resume = wacom_resume, | ||
378 | .reset_resume = wacom_reset_resume, | ||
379 | .supports_autosuspend = 1, | ||
324 | }; | 380 | }; |
325 | 381 | ||
326 | static int __init wacom_init(void) | 382 | static int __init wacom_init(void) |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 57a1c28bf122..a571aa965da0 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -87,6 +87,7 @@ struct ads7846 { | |||
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | u16 model; | 89 | u16 model; |
90 | u16 vref_mv; | ||
90 | u16 vref_delay_usecs; | 91 | u16 vref_delay_usecs; |
91 | u16 x_plate_ohms; | 92 | u16 x_plate_ohms; |
92 | u16 pressure_max; | 93 | u16 pressure_max; |
@@ -184,9 +185,6 @@ struct ads7846 { | |||
184 | * The range is GND..vREF. The ads7843 and ads7835 must use external vREF; | 185 | * The range is GND..vREF. The ads7843 and ads7835 must use external vREF; |
185 | * ads7846 lets that pin be unconnected, to use internal vREF. | 186 | * ads7846 lets that pin be unconnected, to use internal vREF. |
186 | */ | 187 | */ |
187 | static unsigned vREF_mV; | ||
188 | module_param(vREF_mV, uint, 0); | ||
189 | MODULE_PARM_DESC(vREF_mV, "external vREF voltage, in milliVolts"); | ||
190 | 188 | ||
191 | struct ser_req { | 189 | struct ser_req { |
192 | u8 ref_on; | 190 | u8 ref_on; |
@@ -213,7 +211,6 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
213 | struct ads7846 *ts = dev_get_drvdata(dev); | 211 | struct ads7846 *ts = dev_get_drvdata(dev); |
214 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 212 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); |
215 | int status; | 213 | int status; |
216 | int uninitialized_var(sample); | ||
217 | int use_internal; | 214 | int use_internal; |
218 | 215 | ||
219 | if (!req) | 216 | if (!req) |
@@ -270,13 +267,13 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
270 | 267 | ||
271 | if (status == 0) { | 268 | if (status == 0) { |
272 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ | 269 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ |
273 | sample = be16_to_cpu(req->sample); | 270 | status = be16_to_cpu(req->sample); |
274 | sample = sample >> 3; | 271 | status = status >> 3; |
275 | sample &= 0x0fff; | 272 | status &= 0x0fff; |
276 | } | 273 | } |
277 | 274 | ||
278 | kfree(req); | 275 | kfree(req); |
279 | return status ? status : sample; | 276 | return status; |
280 | } | 277 | } |
281 | 278 | ||
282 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) | 279 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) |
@@ -317,7 +314,7 @@ static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) | |||
317 | unsigned retval = v; | 314 | unsigned retval = v; |
318 | 315 | ||
319 | /* external resistors may scale vAUX into 0..vREF */ | 316 | /* external resistors may scale vAUX into 0..vREF */ |
320 | retval *= vREF_mV; | 317 | retval *= ts->vref_mv; |
321 | retval = retval >> 12; | 318 | retval = retval >> 12; |
322 | return retval; | 319 | return retval; |
323 | } | 320 | } |
@@ -375,14 +372,14 @@ static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) | |||
375 | /* hwmon sensors need a reference voltage */ | 372 | /* hwmon sensors need a reference voltage */ |
376 | switch (ts->model) { | 373 | switch (ts->model) { |
377 | case 7846: | 374 | case 7846: |
378 | if (!vREF_mV) { | 375 | if (!ts->vref_mv) { |
379 | dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); | 376 | dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); |
380 | vREF_mV = 2500; | 377 | ts->vref_mv = 2500; |
381 | } | 378 | } |
382 | break; | 379 | break; |
383 | case 7845: | 380 | case 7845: |
384 | case 7843: | 381 | case 7843: |
385 | if (!vREF_mV) { | 382 | if (!ts->vref_mv) { |
386 | dev_warn(&spi->dev, | 383 | dev_warn(&spi->dev, |
387 | "external vREF for ADS%d not specified\n", | 384 | "external vREF for ADS%d not specified\n", |
388 | ts->model); | 385 | ts->model); |
@@ -875,6 +872,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
875 | 872 | ||
876 | ts->spi = spi; | 873 | ts->spi = spi; |
877 | ts->input = input_dev; | 874 | ts->input = input_dev; |
875 | ts->vref_mv = pdata->vref_mv; | ||
878 | 876 | ||
879 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 877 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
880 | ts->timer.function = ads7846_timer; | 878 | ts->timer.function = ads7846_timer; |
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 99d92f5c93d6..765e964b7969 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c | |||
@@ -361,6 +361,7 @@ static struct platform_driver corgits_driver = { | |||
361 | .resume = corgits_resume, | 361 | .resume = corgits_resume, |
362 | .driver = { | 362 | .driver = { |
363 | .name = "corgi-ts", | 363 | .name = "corgi-ts", |
364 | .owner = THIS_MODULE, | ||
364 | }, | 365 | }, |
365 | }; | 366 | }; |
366 | 367 | ||
@@ -380,3 +381,4 @@ module_exit(corgits_exit); | |||
380 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | 381 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); |
381 | MODULE_DESCRIPTION("Corgi TouchScreen Driver"); | 382 | MODULE_DESCRIPTION("Corgi TouchScreen Driver"); |
382 | MODULE_LICENSE("GPL"); | 383 | MODULE_LICENSE("GPL"); |
384 | MODULE_ALIAS("platform:corgi-ts"); | ||
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index 42a1c9a1940e..742242111bf1 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c | |||
@@ -160,11 +160,15 @@ static int __devexit jornada720_ts_remove(struct platform_device *pdev) | |||
160 | return 0; | 160 | return 0; |
161 | } | 161 | } |
162 | 162 | ||
163 | /* work with hotplug and coldplug */ | ||
164 | MODULE_ALIAS("platform:jornada_ts"); | ||
165 | |||
163 | static struct platform_driver jornada720_ts_driver = { | 166 | static struct platform_driver jornada720_ts_driver = { |
164 | .probe = jornada720_ts_probe, | 167 | .probe = jornada720_ts_probe, |
165 | .remove = __devexit_p(jornada720_ts_remove), | 168 | .remove = __devexit_p(jornada720_ts_remove), |
166 | .driver = { | 169 | .driver = { |
167 | .name = "jornada_ts", | 170 | .name = "jornada_ts", |
171 | .owner = THIS_MODULE, | ||
168 | }, | 172 | }, |
169 | }; | 173 | }; |
170 | 174 | ||
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 607f9933aa1f..bce018e45bce 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -427,10 +427,6 @@ static int ucb1400_detect_irq(struct ucb1400 *ucb) | |||
427 | unsigned long mask, timeout; | 427 | unsigned long mask, timeout; |
428 | 428 | ||
429 | mask = probe_irq_on(); | 429 | mask = probe_irq_on(); |
430 | if (!mask) { | ||
431 | probe_irq_off(mask); | ||
432 | return -EBUSY; | ||
433 | } | ||
434 | 430 | ||
435 | /* Enable the ADC interrupt. */ | 431 | /* Enable the ADC interrupt. */ |
436 | ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC); | 432 | ucb1400_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC); |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 63f9664a066f..3a0a8ca57076 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -396,9 +396,12 @@ static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
396 | static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) | 396 | static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) |
397 | { | 397 | { |
398 | struct usb_device *dev = usbtouch->udev; | 398 | struct usb_device *dev = usbtouch->udev; |
399 | int ret; | 399 | int ret = -ENOMEM; |
400 | unsigned char buf[2]; | 400 | unsigned char *buf; |
401 | 401 | ||
402 | buf = kmalloc(2, GFP_KERNEL); | ||
403 | if (!buf) | ||
404 | goto err_nobuf; | ||
402 | /* reset */ | 405 | /* reset */ |
403 | buf[0] = buf[1] = 0xFF; | 406 | buf[0] = buf[1] = 0xFF; |
404 | ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), | 407 | ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), |
@@ -406,9 +409,11 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) | |||
406 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 409 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
407 | 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT); | 410 | 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT); |
408 | if (ret < 0) | 411 | if (ret < 0) |
409 | return ret; | 412 | goto err_out; |
410 | if (buf[0] != 0x06 || buf[1] != 0x00) | 413 | if (buf[0] != 0x06 || buf[1] != 0x00) { |
411 | return -ENODEV; | 414 | ret = -ENODEV; |
415 | goto err_out; | ||
416 | } | ||
412 | 417 | ||
413 | /* set coordinate output rate */ | 418 | /* set coordinate output rate */ |
414 | buf[0] = buf[1] = 0xFF; | 419 | buf[0] = buf[1] = 0xFF; |
@@ -417,20 +422,22 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) | |||
417 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 422 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
418 | TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT); | 423 | TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT); |
419 | if (ret < 0) | 424 | if (ret < 0) |
420 | return ret; | 425 | goto err_out; |
421 | if ((buf[0] != 0x06 || buf[1] != 0x00) && | 426 | if ((buf[0] != 0x06 || buf[1] != 0x00) && |
422 | (buf[0] != 0x15 || buf[1] != 0x01)) | 427 | (buf[0] != 0x15 || buf[1] != 0x01)) { |
423 | return -ENODEV; | 428 | ret = -ENODEV; |
429 | goto err_out; | ||
430 | } | ||
424 | 431 | ||
425 | /* start sending data */ | 432 | /* start sending data */ |
426 | ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), | 433 | ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), |
427 | TSC10_CMD_DATA1, | 434 | TSC10_CMD_DATA1, |
428 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 435 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
429 | 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); | 436 | 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); |
430 | if (ret < 0) | 437 | err_out: |
431 | return ret; | 438 | kfree(buf); |
432 | 439 | err_nobuf: | |
433 | return 0; | 440 | return ret; |
434 | } | 441 | } |
435 | 442 | ||
436 | 443 | ||
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 89302309da92..f972ff377b63 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c | |||
@@ -103,6 +103,9 @@ int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down) | |||
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | 105 | ||
106 | static struct lock_class_key emumousebtn_event_class; | ||
107 | static struct lock_class_key emumousebtn_mutex_class; | ||
108 | |||
106 | static int emumousebtn_input_register(void) | 109 | static int emumousebtn_input_register(void) |
107 | { | 110 | { |
108 | int ret; | 111 | int ret; |
@@ -111,6 +114,9 @@ static int emumousebtn_input_register(void) | |||
111 | if (!emumousebtn) | 114 | if (!emumousebtn) |
112 | return -ENOMEM; | 115 | return -ENOMEM; |
113 | 116 | ||
117 | lockdep_set_class(emumousebtn->event_lock, &emumousebtn_event_class); | ||
118 | lockdep_set_class(emumousebtn->mutex, &emumousebtn_mutex_class); | ||
119 | |||
114 | emumousebtn->name = "Macintosh mouse button emulation"; | 120 | emumousebtn->name = "Macintosh mouse button emulation"; |
115 | emumousebtn->id.bustype = BUS_ADB; | 121 | emumousebtn->id.bustype = BUS_ADB; |
116 | emumousebtn->id.vendor = 0x0001; | 122 | emumousebtn->id.vendor = 0x0001; |
diff --git a/include/linux/keyboard.h b/include/linux/keyboard.h index 65c2d70853e9..a3c984d780f0 100644 --- a/include/linux/keyboard.h +++ b/include/linux/keyboard.h | |||
@@ -33,6 +33,7 @@ struct keyboard_notifier_param { | |||
33 | struct vc_data *vc; /* VC on which the keyboard press was done */ | 33 | struct vc_data *vc; /* VC on which the keyboard press was done */ |
34 | int down; /* Pressure of the key? */ | 34 | int down; /* Pressure of the key? */ |
35 | int shift; /* Current shift mask */ | 35 | int shift; /* Current shift mask */ |
36 | int ledstate; /* Current led state */ | ||
36 | unsigned int value; /* keycode, unicode value or keysym */ | 37 | unsigned int value; /* keycode, unicode value or keysym */ |
37 | }; | 38 | }; |
38 | 39 | ||
diff --git a/include/linux/serio.h b/include/linux/serio.h index 9f3825014674..95674d97dabd 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h | |||
@@ -211,5 +211,6 @@ static inline void serio_unpin_driver(struct serio *serio) | |||
211 | #define SERIO_TOUCHWIN 0x33 | 211 | #define SERIO_TOUCHWIN 0x33 |
212 | #define SERIO_TAOSEVM 0x34 | 212 | #define SERIO_TAOSEVM 0x34 |
213 | #define SERIO_FUJITSU 0x35 | 213 | #define SERIO_FUJITSU 0x35 |
214 | #define SERIO_ZHENHUA 0x36 | ||
214 | 215 | ||
215 | #endif | 216 | #endif |
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 334d31411629..daf744017a31 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h | |||
@@ -14,7 +14,8 @@ enum ads7846_filter { | |||
14 | struct ads7846_platform_data { | 14 | struct ads7846_platform_data { |
15 | u16 model; /* 7843, 7845, 7846. */ | 15 | u16 model; /* 7843, 7845, 7846. */ |
16 | u16 vref_delay_usecs; /* 0 for external vref; etc */ | 16 | u16 vref_delay_usecs; /* 0 for external vref; etc */ |
17 | int keep_vref_on:1; /* set to keep vref on for differential | 17 | u16 vref_mv; /* external vref value, milliVolts */ |
18 | bool keep_vref_on; /* set to keep vref on for differential | ||
18 | * measurements as well */ | 19 | * measurements as well */ |
19 | 20 | ||
20 | /* Settling time of the analog signals; a function of Vcc and the | 21 | /* Settling time of the analog signals; a function of Vcc and the |