diff options
-rw-r--r-- | drivers/hid/Kconfig | 6 | ||||
-rw-r--r-- | drivers/hid/Makefile | 1 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-elecom.c | 57 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 81 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-picolcd.c | 199 | ||||
-rw-r--r-- | drivers/hid/hidraw.c | 2 |
8 files changed, 276 insertions, 74 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 434099369058..d51f0144a3b9 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -148,6 +148,12 @@ config HID_EGALAX | |||
148 | ---help--- | 148 | ---help--- |
149 | Support for the eGalax dual-touch panel. | 149 | Support for the eGalax dual-touch panel. |
150 | 150 | ||
151 | config HID_ELECOM | ||
152 | tristate "ELECOM" | ||
153 | depends on BT_HIDP | ||
154 | ---help--- | ||
155 | Support for the ELECOM BM084 (bluetooth mouse). | ||
156 | |||
151 | config HID_EZKEY | 157 | config HID_EZKEY |
152 | tristate "Ezkey" if EMBEDDED | 158 | tristate "Ezkey" if EMBEDDED |
153 | depends on USB_HID | 159 | depends on USB_HID |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 987fa0627367..2ec042f57138 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -32,6 +32,7 @@ obj-$(CONFIG_HID_CHICONY) += hid-chicony.o | |||
32 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o | 32 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o |
33 | obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o | 33 | obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o |
34 | obj-$(CONFIG_HID_EGALAX) += hid-egalax.o | 34 | obj-$(CONFIG_HID_EGALAX) += hid-egalax.o |
35 | obj-$(CONFIG_HID_ELECOM) += hid-elecom.o | ||
35 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o | 36 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o |
36 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o | 37 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o |
37 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o | 38 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 866e54ec5fb2..a204d092e2d7 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1294,6 +1294,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1294 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, | 1294 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, |
1295 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1295 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
1296 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 1296 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
1297 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, | ||
1297 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1298 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1298 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1299 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
1299 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, | 1300 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, |
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c new file mode 100644 index 000000000000..7a40878f46b4 --- /dev/null +++ b/drivers/hid/hid-elecom.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * HID driver for Elecom BM084 (bluetooth mouse). | ||
3 | * Removes a non-existing horizontal wheel from | ||
4 | * the HID descriptor. | ||
5 | * (This module is based on "hid-ortek".) | ||
6 | * | ||
7 | * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com> | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the Free | ||
13 | * Software Foundation; either version 2 of the License, or (at your option) | ||
14 | * any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/device.h> | ||
18 | #include <linux/hid.h> | ||
19 | #include <linux/module.h> | ||
20 | |||
21 | #include "hid-ids.h" | ||
22 | |||
23 | static void elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
24 | unsigned int rsize) | ||
25 | { | ||
26 | if (rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) { | ||
27 | dev_info(&hdev->dev, "Fixing up Elecom BM084 " | ||
28 | "report descriptor.\n"); | ||
29 | rdesc[47] = 0x00; | ||
30 | } | ||
31 | } | ||
32 | |||
33 | static const struct hid_device_id elecom_devices[] = { | ||
34 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084)}, | ||
35 | { } | ||
36 | }; | ||
37 | MODULE_DEVICE_TABLE(hid, elecom_devices); | ||
38 | |||
39 | static struct hid_driver elecom_driver = { | ||
40 | .name = "elecom", | ||
41 | .id_table = elecom_devices, | ||
42 | .report_fixup = elecom_report_fixup | ||
43 | }; | ||
44 | |||
45 | static int __init elecom_init(void) | ||
46 | { | ||
47 | return hid_register_driver(&elecom_driver); | ||
48 | } | ||
49 | |||
50 | static void __exit elecom_exit(void) | ||
51 | { | ||
52 | hid_unregister_driver(&elecom_driver); | ||
53 | } | ||
54 | |||
55 | module_init(elecom_init); | ||
56 | module_exit(elecom_exit); | ||
57 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 31601eef25dd..7f0e40bdb47e 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 | 34 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 |
35 | #define USB_DEVICE_ID_ACECAD_302 0x0008 | 35 | #define USB_DEVICE_ID_ACECAD_302 0x0008 |
36 | 36 | ||
37 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 | 37 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 |
38 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 | 38 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 |
39 | 39 | ||
40 | #define USB_VENDOR_ID_AFATECH 0x15a4 | 40 | #define USB_VENDOR_ID_AFATECH 0x15a4 |
@@ -81,12 +81,12 @@ | |||
81 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 | 81 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 |
82 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 | 82 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 |
83 | #define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 | 83 | #define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 |
84 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 | 84 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 |
85 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a | 85 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a |
86 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b | 86 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b |
87 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c | 87 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c |
88 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d | 88 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d |
89 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e | 89 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e |
90 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 | 90 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 |
91 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 | 91 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 |
92 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 | 92 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 |
@@ -118,8 +118,8 @@ | |||
118 | #define USB_VENDOR_ID_AVERMEDIA 0x07ca | 118 | #define USB_VENDOR_ID_AVERMEDIA 0x07ca |
119 | #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 | 119 | #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 |
120 | 120 | ||
121 | #define USB_VENDOR_ID_BELKIN 0x050d | 121 | #define USB_VENDOR_ID_BELKIN 0x050d |
122 | #define USB_DEVICE_ID_FLIP_KVM 0x3201 | 122 | #define USB_DEVICE_ID_FLIP_KVM 0x3201 |
123 | 123 | ||
124 | #define USB_VENDOR_ID_BERKSHIRE 0x0c98 | 124 | #define USB_VENDOR_ID_BERKSHIRE 0x0c98 |
125 | #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 | 125 | #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 |
@@ -128,7 +128,7 @@ | |||
128 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 | 128 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 |
129 | 129 | ||
130 | #define USB_VENDOR_ID_CANDO 0x2087 | 130 | #define USB_VENDOR_ID_CANDO 0x2087 |
131 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 | 131 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 |
132 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 | 132 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 |
133 | 133 | ||
134 | #define USB_VENDOR_ID_CH 0x068e | 134 | #define USB_VENDOR_ID_CH 0x068e |
@@ -175,7 +175,7 @@ | |||
175 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a | 175 | #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a |
176 | 176 | ||
177 | #define USB_VENDOR_ID_DELORME 0x1163 | 177 | #define USB_VENDOR_ID_DELORME 0x1163 |
178 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 | 178 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 |
179 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 | 179 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 |
180 | 180 | ||
181 | #define USB_VENDOR_ID_DMI 0x0c0b | 181 | #define USB_VENDOR_ID_DMI 0x0c0b |
@@ -187,19 +187,22 @@ | |||
187 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 | 187 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 |
188 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d | 188 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d |
189 | 189 | ||
190 | #define USB_VENDOR_ID_ELECOM 0x056e | ||
191 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 | ||
192 | |||
190 | #define USB_VENDOR_ID_ELO 0x04E7 | 193 | #define USB_VENDOR_ID_ELO 0x04E7 |
191 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 | 194 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 |
192 | 195 | ||
193 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f | 196 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f |
194 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 | 197 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 |
195 | 198 | ||
196 | #define USB_VENDOR_ID_ETURBOTOUCH 0x22b9 | ||
197 | #define USB_DEVICE_ID_ETURBOTOUCH 0x0006 | ||
198 | |||
199 | #define USB_VENDOR_ID_ETT 0x0664 | 199 | #define USB_VENDOR_ID_ETT 0x0664 |
200 | #define USB_DEVICE_ID_TC5UH 0x0309 | 200 | #define USB_DEVICE_ID_TC5UH 0x0309 |
201 | 201 | ||
202 | #define USB_VENDOR_ID_EZKEY 0x0518 | 202 | #define USB_VENDOR_ID_ETURBOTOUCH 0x22b9 |
203 | #define USB_DEVICE_ID_ETURBOTOUCH 0x0006 | ||
204 | |||
205 | #define USB_VENDOR_ID_EZKEY 0x0518 | ||
203 | #define USB_DEVICE_ID_BTC_8193 0x0002 | 206 | #define USB_DEVICE_ID_BTC_8193 0x0002 |
204 | 207 | ||
205 | #define USB_VENDOR_ID_GAMERON 0x0810 | 208 | #define USB_VENDOR_ID_GAMERON 0x0810 |
@@ -296,9 +299,16 @@ | |||
296 | #define USB_VENDOR_ID_KBGEAR 0x084e | 299 | #define USB_VENDOR_ID_KBGEAR 0x084e |
297 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 | 300 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
298 | 301 | ||
302 | #define USB_VENDOR_ID_KENSINGTON 0x047d | ||
303 | #define USB_DEVICE_ID_KS_SLIMBLADE 0x2041 | ||
304 | |||
299 | #define USB_VENDOR_ID_KWORLD 0x1b80 | 305 | #define USB_VENDOR_ID_KWORLD 0x1b80 |
300 | #define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 | 306 | #define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 |
301 | 307 | ||
308 | #define USB_VENDOR_ID_KYE 0x0458 | ||
309 | #define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 | ||
310 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 | ||
311 | |||
302 | #define USB_VENDOR_ID_LABTEC 0x1020 | 312 | #define USB_VENDOR_ID_LABTEC 0x1020 |
303 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 | 313 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 |
304 | 314 | ||
@@ -318,9 +328,6 @@ | |||
318 | #define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 | 328 | #define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 |
319 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 | 329 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 |
320 | 330 | ||
321 | #define USB_VENDOR_ID_KENSINGTON 0x047d | ||
322 | #define USB_DEVICE_ID_KS_SLIMBLADE 0x2041 | ||
323 | |||
324 | #define USB_VENDOR_ID_LOGITECH 0x046d | 331 | #define USB_VENDOR_ID_LOGITECH 0x046d |
325 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 | 332 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 |
326 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 | 333 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 |
@@ -376,23 +383,23 @@ | |||
376 | #define USB_VENDOR_ID_MONTEREY 0x0566 | 383 | #define USB_VENDOR_ID_MONTEREY 0x0566 |
377 | #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 | 384 | #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 |
378 | 385 | ||
386 | #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 | ||
387 | #define USB_DEVICE_ID_N_S_HARMONY 0xc359 | ||
388 | |||
389 | #define USB_VENDOR_ID_NATSU 0x08b7 | ||
390 | #define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001 | ||
391 | |||
379 | #define USB_VENDOR_ID_NCR 0x0404 | 392 | #define USB_VENDOR_ID_NCR 0x0404 |
380 | #define USB_DEVICE_ID_NCR_FIRST 0x0300 | 393 | #define USB_DEVICE_ID_NCR_FIRST 0x0300 |
381 | #define USB_DEVICE_ID_NCR_LAST 0x03ff | 394 | #define USB_DEVICE_ID_NCR_LAST 0x03ff |
382 | 395 | ||
383 | #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 | ||
384 | #define USB_DEVICE_ID_N_S_HARMONY 0xc359 | ||
385 | |||
386 | #define USB_VENDOR_ID_NATSU 0x08b7 | ||
387 | #define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001 | ||
388 | |||
389 | #define USB_VENDOR_ID_NEC 0x073e | 396 | #define USB_VENDOR_ID_NEC 0x073e |
390 | #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 | 397 | #define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 |
391 | 398 | ||
392 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 | 399 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 |
393 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 | 400 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 |
394 | 401 | ||
395 | #define USB_VENDOR_ID_NTRIG 0x1b96 | 402 | #define USB_VENDOR_ID_NTRIG 0x1b96 |
396 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 | 403 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 |
397 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 | 404 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 |
398 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004 | 405 | #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004 |
@@ -427,7 +434,7 @@ | |||
427 | #define USB_VENDOR_ID_PETALYNX 0x18b1 | 434 | #define USB_VENDOR_ID_PETALYNX 0x18b1 |
428 | #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 | 435 | #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 |
429 | 436 | ||
430 | #define USB_VENDOR_ID_PHILIPS 0x0471 | 437 | #define USB_VENDOR_ID_PHILIPS 0x0471 |
431 | #define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617 | 438 | #define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617 |
432 | 439 | ||
433 | #define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 | 440 | #define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 |
@@ -439,16 +446,16 @@ | |||
439 | #define USB_VENDOR_ID_PRODIGE 0x05af | 446 | #define USB_VENDOR_ID_PRODIGE 0x05af |
440 | #define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 | 447 | #define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 |
441 | 448 | ||
449 | #define USB_VENDOR_ID_QUANTA 0x0408 | ||
450 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000 | ||
451 | #define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001 | ||
452 | |||
442 | #define USB_VENDOR_ID_ROCCAT 0x1e7d | 453 | #define USB_VENDOR_ID_ROCCAT 0x1e7d |
443 | #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced | 454 | #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced |
444 | 455 | ||
445 | #define USB_VENDOR_ID_SAITEK 0x06a3 | 456 | #define USB_VENDOR_ID_SAITEK 0x06a3 |
446 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 | 457 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 |
447 | 458 | ||
448 | #define USB_VENDOR_ID_QUANTA 0x0408 | ||
449 | #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000 | ||
450 | #define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001 | ||
451 | |||
452 | #define USB_VENDOR_ID_SAMSUNG 0x0419 | 459 | #define USB_VENDOR_ID_SAMSUNG 0x0419 |
453 | #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 | 460 | #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 |
454 | #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 | 461 | #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 |
@@ -472,20 +479,20 @@ | |||
472 | 479 | ||
473 | #define USB_VENDOR_ID_THRUSTMASTER 0x044f | 480 | #define USB_VENDOR_ID_THRUSTMASTER 0x044f |
474 | 481 | ||
475 | #define USB_VENDOR_ID_TOUCHPACK 0x1bfd | ||
476 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 | ||
477 | |||
478 | #define USB_VENDOR_ID_TOPMAX 0x0663 | 482 | #define USB_VENDOR_ID_TOPMAX 0x0663 |
479 | #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 | 483 | #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 |
480 | 484 | ||
481 | #define USB_VENDOR_ID_TOPSEED 0x0766 | 485 | #define USB_VENDOR_ID_TOPSEED 0x0766 |
482 | #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 | 486 | #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 |
483 | 487 | ||
488 | #define USB_VENDOR_ID_TOUCHPACK 0x1bfd | ||
489 | #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 | ||
490 | |||
484 | #define USB_VENDOR_ID_TURBOX 0x062a | 491 | #define USB_VENDOR_ID_TURBOX 0x062a |
485 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 | 492 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 |
486 | 493 | ||
487 | #define USB_VENDOR_ID_TWINHAN 0x6253 | 494 | #define USB_VENDOR_ID_TWINHAN 0x6253 |
488 | #define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 | 495 | #define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 |
489 | 496 | ||
490 | #define USB_VENDOR_ID_UCLOGIC 0x5543 | 497 | #define USB_VENDOR_ID_UCLOGIC 0x5543 |
491 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 | 498 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 |
@@ -522,9 +529,5 @@ | |||
522 | #define USB_VENDOR_ID_ZYDACRON 0x13EC | 529 | #define USB_VENDOR_ID_ZYDACRON 0x13EC |
523 | #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 | 530 | #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 |
524 | 531 | ||
525 | #define USB_VENDOR_ID_KYE 0x0458 | ||
526 | #define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 | ||
527 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 | ||
528 | |||
529 | 532 | ||
530 | #endif | 533 | #endif |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 7a0d2e4661a1..6b10e5afe770 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -301,6 +301,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
301 | 301 | ||
302 | case HID_UP_DIGITIZER: | 302 | case HID_UP_DIGITIZER: |
303 | switch (usage->hid & 0xff) { | 303 | switch (usage->hid & 0xff) { |
304 | case 0x00: /* Undefined */ | ||
305 | goto ignore; | ||
306 | |||
304 | case 0x30: /* TipPressure */ | 307 | case 0x30: /* TipPressure */ |
305 | if (!test_bit(BTN_TOUCH, input->keybit)) { | 308 | if (!test_bit(BTN_TOUCH, input->keybit)) { |
306 | device->quirks |= HID_QUIRK_NOTOUCH; | 309 | device->quirks |= HID_QUIRK_NOTOUCH; |
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index 7aabf65c48ef..346f0e34987e 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c | |||
@@ -127,6 +127,26 @@ static const struct fb_var_screeninfo picolcdfb_var = { | |||
127 | .height = 26, | 127 | .height = 26, |
128 | .bits_per_pixel = 1, | 128 | .bits_per_pixel = 1, |
129 | .grayscale = 1, | 129 | .grayscale = 1, |
130 | .red = { | ||
131 | .offset = 0, | ||
132 | .length = 1, | ||
133 | .msb_right = 0, | ||
134 | }, | ||
135 | .green = { | ||
136 | .offset = 0, | ||
137 | .length = 1, | ||
138 | .msb_right = 0, | ||
139 | }, | ||
140 | .blue = { | ||
141 | .offset = 0, | ||
142 | .length = 1, | ||
143 | .msb_right = 0, | ||
144 | }, | ||
145 | .transp = { | ||
146 | .offset = 0, | ||
147 | .length = 0, | ||
148 | .msb_right = 0, | ||
149 | }, | ||
130 | }; | 150 | }; |
131 | #endif /* CONFIG_HID_PICOLCD_FB */ | 151 | #endif /* CONFIG_HID_PICOLCD_FB */ |
132 | 152 | ||
@@ -188,6 +208,7 @@ struct picolcd_data { | |||
188 | /* Framebuffer stuff */ | 208 | /* Framebuffer stuff */ |
189 | u8 fb_update_rate; | 209 | u8 fb_update_rate; |
190 | u8 fb_bpp; | 210 | u8 fb_bpp; |
211 | u8 fb_force; | ||
191 | u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */ | 212 | u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */ |
192 | u8 *fb_bitmap; /* framebuffer */ | 213 | u8 *fb_bitmap; /* framebuffer */ |
193 | struct fb_info *fb_info; | 214 | struct fb_info *fb_info; |
@@ -346,7 +367,7 @@ static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp, | |||
346 | const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32; | 367 | const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32; |
347 | for (i = 0; i < 64; i++) { | 368 | for (i = 0; i < 64; i++) { |
348 | tdata[i] <<= 1; | 369 | tdata[i] <<= 1; |
349 | tdata[i] |= (bdata[i/8] >> (7 - i % 8)) & 0x01; | 370 | tdata[i] |= (bdata[i/8] >> (i % 8)) & 0x01; |
350 | } | 371 | } |
351 | } | 372 | } |
352 | } else if (bpp == 8) { | 373 | } else if (bpp == 8) { |
@@ -399,13 +420,10 @@ static int picolcd_fb_reset(struct picolcd_data *data, int clear) | |||
399 | 420 | ||
400 | if (data->fb_bitmap) { | 421 | if (data->fb_bitmap) { |
401 | if (clear) { | 422 | if (clear) { |
402 | memset(data->fb_vbitmap, 0xff, PICOLCDFB_SIZE); | 423 | memset(data->fb_vbitmap, 0, PICOLCDFB_SIZE); |
403 | memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp); | 424 | memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp); |
404 | } else { | ||
405 | /* invert 1 byte in each tile to force resend */ | ||
406 | for (i = 0; i < PICOLCDFB_SIZE; i += 64) | ||
407 | data->fb_vbitmap[i] = ~data->fb_vbitmap[i]; | ||
408 | } | 425 | } |
426 | data->fb_force = 1; | ||
409 | } | 427 | } |
410 | 428 | ||
411 | /* schedule first output of framebuffer */ | 429 | /* schedule first output of framebuffer */ |
@@ -421,6 +439,9 @@ static void picolcd_fb_update(struct picolcd_data *data) | |||
421 | int chip, tile, n; | 439 | int chip, tile, n; |
422 | unsigned long flags; | 440 | unsigned long flags; |
423 | 441 | ||
442 | if (!data) | ||
443 | return; | ||
444 | |||
424 | spin_lock_irqsave(&data->lock, flags); | 445 | spin_lock_irqsave(&data->lock, flags); |
425 | if (!(data->status & PICOLCD_READY_FB)) { | 446 | if (!(data->status & PICOLCD_READY_FB)) { |
426 | spin_unlock_irqrestore(&data->lock, flags); | 447 | spin_unlock_irqrestore(&data->lock, flags); |
@@ -440,14 +461,18 @@ static void picolcd_fb_update(struct picolcd_data *data) | |||
440 | for (chip = 0; chip < 4; chip++) | 461 | for (chip = 0; chip < 4; chip++) |
441 | for (tile = 0; tile < 8; tile++) | 462 | for (tile = 0; tile < 8; tile++) |
442 | if (picolcd_fb_update_tile(data->fb_vbitmap, | 463 | if (picolcd_fb_update_tile(data->fb_vbitmap, |
443 | data->fb_bitmap, data->fb_bpp, chip, tile)) { | 464 | data->fb_bitmap, data->fb_bpp, chip, tile) || |
465 | data->fb_force) { | ||
444 | n += 2; | 466 | n += 2; |
467 | if (!data->fb_info->par) | ||
468 | return; /* device lost! */ | ||
445 | if (n >= HID_OUTPUT_FIFO_SIZE / 2) { | 469 | if (n >= HID_OUTPUT_FIFO_SIZE / 2) { |
446 | usbhid_wait_io(data->hdev); | 470 | usbhid_wait_io(data->hdev); |
447 | n = 0; | 471 | n = 0; |
448 | } | 472 | } |
449 | picolcd_fb_send_tile(data->hdev, chip, tile); | 473 | picolcd_fb_send_tile(data->hdev, chip, tile); |
450 | } | 474 | } |
475 | data->fb_force = false; | ||
451 | if (n) | 476 | if (n) |
452 | usbhid_wait_io(data->hdev); | 477 | usbhid_wait_io(data->hdev); |
453 | } | 478 | } |
@@ -511,11 +536,23 @@ static int picolcd_fb_blank(int blank, struct fb_info *info) | |||
511 | static void picolcd_fb_destroy(struct fb_info *info) | 536 | static void picolcd_fb_destroy(struct fb_info *info) |
512 | { | 537 | { |
513 | struct picolcd_data *data = info->par; | 538 | struct picolcd_data *data = info->par; |
539 | u32 *ref_cnt = info->pseudo_palette; | ||
540 | int may_release; | ||
541 | |||
514 | info->par = NULL; | 542 | info->par = NULL; |
515 | if (data) | 543 | if (data) |
516 | data->fb_info = NULL; | 544 | data->fb_info = NULL; |
517 | fb_deferred_io_cleanup(info); | 545 | fb_deferred_io_cleanup(info); |
518 | framebuffer_release(info); | 546 | |
547 | ref_cnt--; | ||
548 | mutex_lock(&info->lock); | ||
549 | (*ref_cnt)--; | ||
550 | may_release = !ref_cnt; | ||
551 | mutex_unlock(&info->lock); | ||
552 | if (may_release) { | ||
553 | framebuffer_release(info); | ||
554 | vfree((u8 *)info->fix.smem_start); | ||
555 | } | ||
519 | } | 556 | } |
520 | 557 | ||
521 | static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 558 | static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
@@ -526,29 +563,37 @@ static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *i | |||
526 | /* only allow 1/8 bit depth (8-bit is grayscale) */ | 563 | /* only allow 1/8 bit depth (8-bit is grayscale) */ |
527 | *var = picolcdfb_var; | 564 | *var = picolcdfb_var; |
528 | var->activate = activate; | 565 | var->activate = activate; |
529 | if (bpp >= 8) | 566 | if (bpp >= 8) { |
530 | var->bits_per_pixel = 8; | 567 | var->bits_per_pixel = 8; |
531 | else | 568 | var->red.length = 8; |
569 | var->green.length = 8; | ||
570 | var->blue.length = 8; | ||
571 | } else { | ||
532 | var->bits_per_pixel = 1; | 572 | var->bits_per_pixel = 1; |
573 | var->red.length = 1; | ||
574 | var->green.length = 1; | ||
575 | var->blue.length = 1; | ||
576 | } | ||
533 | return 0; | 577 | return 0; |
534 | } | 578 | } |
535 | 579 | ||
536 | static int picolcd_set_par(struct fb_info *info) | 580 | static int picolcd_set_par(struct fb_info *info) |
537 | { | 581 | { |
538 | struct picolcd_data *data = info->par; | 582 | struct picolcd_data *data = info->par; |
539 | u8 *o_fb, *n_fb; | 583 | u8 *tmp_fb, *o_fb; |
584 | if (!data) | ||
585 | return -ENODEV; | ||
540 | if (info->var.bits_per_pixel == data->fb_bpp) | 586 | if (info->var.bits_per_pixel == data->fb_bpp) |
541 | return 0; | 587 | return 0; |
542 | /* switch between 1/8 bit depths */ | 588 | /* switch between 1/8 bit depths */ |
543 | if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8) | 589 | if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8) |
544 | return -EINVAL; | 590 | return -EINVAL; |
545 | 591 | ||
546 | o_fb = data->fb_bitmap; | 592 | o_fb = data->fb_bitmap; |
547 | n_fb = vmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel); | 593 | tmp_fb = kmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel, GFP_KERNEL); |
548 | if (!n_fb) | 594 | if (!tmp_fb) |
549 | return -ENOMEM; | 595 | return -ENOMEM; |
550 | 596 | ||
551 | fb_deferred_io_cleanup(info); | ||
552 | /* translate FB content to new bits-per-pixel */ | 597 | /* translate FB content to new bits-per-pixel */ |
553 | if (info->var.bits_per_pixel == 1) { | 598 | if (info->var.bits_per_pixel == 1) { |
554 | int i, b; | 599 | int i, b; |
@@ -558,24 +603,87 @@ static int picolcd_set_par(struct fb_info *info) | |||
558 | p <<= 1; | 603 | p <<= 1; |
559 | p |= o_fb[i*8+b] ? 0x01 : 0x00; | 604 | p |= o_fb[i*8+b] ? 0x01 : 0x00; |
560 | } | 605 | } |
606 | tmp_fb[i] = p; | ||
561 | } | 607 | } |
608 | memcpy(o_fb, tmp_fb, PICOLCDFB_SIZE); | ||
562 | info->fix.visual = FB_VISUAL_MONO01; | 609 | info->fix.visual = FB_VISUAL_MONO01; |
563 | info->fix.line_length = PICOLCDFB_WIDTH / 8; | 610 | info->fix.line_length = PICOLCDFB_WIDTH / 8; |
564 | } else { | 611 | } else { |
565 | int i; | 612 | int i; |
613 | memcpy(tmp_fb, o_fb, PICOLCDFB_SIZE); | ||
566 | for (i = 0; i < PICOLCDFB_SIZE * 8; i++) | 614 | for (i = 0; i < PICOLCDFB_SIZE * 8; i++) |
567 | n_fb[i] = o_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00; | 615 | o_fb[i] = tmp_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00; |
568 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 616 | info->fix.visual = FB_VISUAL_DIRECTCOLOR; |
569 | info->fix.line_length = PICOLCDFB_WIDTH; | 617 | info->fix.line_length = PICOLCDFB_WIDTH; |
570 | } | 618 | } |
571 | 619 | ||
572 | data->fb_bitmap = n_fb; | 620 | kfree(tmp_fb); |
573 | data->fb_bpp = info->var.bits_per_pixel; | 621 | data->fb_bpp = info->var.bits_per_pixel; |
574 | info->screen_base = (char __force __iomem *)n_fb; | 622 | return 0; |
575 | info->fix.smem_start = (unsigned long)n_fb; | 623 | } |
576 | info->fix.smem_len = PICOLCDFB_SIZE*data->fb_bpp; | 624 | |
577 | fb_deferred_io_init(info); | 625 | /* Do refcounting on our FB and cleanup per worker if FB is |
578 | vfree(o_fb); | 626 | * closed after unplug of our device |
627 | * (fb_release holds info->lock and still touches info after | ||
628 | * we return so we can't release it immediately. | ||
629 | */ | ||
630 | struct picolcd_fb_cleanup_item { | ||
631 | struct fb_info *info; | ||
632 | struct picolcd_fb_cleanup_item *next; | ||
633 | }; | ||
634 | static struct picolcd_fb_cleanup_item *fb_pending; | ||
635 | DEFINE_SPINLOCK(fb_pending_lock); | ||
636 | |||
637 | static void picolcd_fb_do_cleanup(struct work_struct *data) | ||
638 | { | ||
639 | struct picolcd_fb_cleanup_item *item; | ||
640 | unsigned long flags; | ||
641 | |||
642 | do { | ||
643 | spin_lock_irqsave(&fb_pending_lock, flags); | ||
644 | item = fb_pending; | ||
645 | fb_pending = item ? item->next : NULL; | ||
646 | spin_unlock_irqrestore(&fb_pending_lock, flags); | ||
647 | |||
648 | if (item) { | ||
649 | u8 *fb = (u8 *)item->info->fix.smem_start; | ||
650 | /* make sure we do not race against fb core when | ||
651 | * releasing */ | ||
652 | mutex_lock(&item->info->lock); | ||
653 | mutex_unlock(&item->info->lock); | ||
654 | framebuffer_release(item->info); | ||
655 | vfree(fb); | ||
656 | } | ||
657 | } while (item); | ||
658 | } | ||
659 | |||
660 | DECLARE_WORK(picolcd_fb_cleanup, picolcd_fb_do_cleanup); | ||
661 | |||
662 | static int picolcd_fb_open(struct fb_info *info, int u) | ||
663 | { | ||
664 | u32 *ref_cnt = info->pseudo_palette; | ||
665 | ref_cnt--; | ||
666 | |||
667 | (*ref_cnt)++; | ||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | static int picolcd_fb_release(struct fb_info *info, int u) | ||
672 | { | ||
673 | u32 *ref_cnt = info->pseudo_palette; | ||
674 | ref_cnt--; | ||
675 | |||
676 | (*ref_cnt)++; | ||
677 | if (!*ref_cnt) { | ||
678 | unsigned long flags; | ||
679 | struct picolcd_fb_cleanup_item *item = (struct picolcd_fb_cleanup_item *)ref_cnt; | ||
680 | item--; | ||
681 | spin_lock_irqsave(&fb_pending_lock, flags); | ||
682 | item->next = fb_pending; | ||
683 | fb_pending = item; | ||
684 | spin_unlock_irqrestore(&fb_pending_lock, flags); | ||
685 | schedule_work(&picolcd_fb_cleanup); | ||
686 | } | ||
579 | return 0; | 687 | return 0; |
580 | } | 688 | } |
581 | 689 | ||
@@ -583,6 +691,8 @@ static int picolcd_set_par(struct fb_info *info) | |||
583 | static struct fb_ops picolcdfb_ops = { | 691 | static struct fb_ops picolcdfb_ops = { |
584 | .owner = THIS_MODULE, | 692 | .owner = THIS_MODULE, |
585 | .fb_destroy = picolcd_fb_destroy, | 693 | .fb_destroy = picolcd_fb_destroy, |
694 | .fb_open = picolcd_fb_open, | ||
695 | .fb_release = picolcd_fb_release, | ||
586 | .fb_read = fb_sys_read, | 696 | .fb_read = fb_sys_read, |
587 | .fb_write = picolcd_fb_write, | 697 | .fb_write = picolcd_fb_write, |
588 | .fb_blank = picolcd_fb_blank, | 698 | .fb_blank = picolcd_fb_blank, |
@@ -660,11 +770,12 @@ static int picolcd_init_framebuffer(struct picolcd_data *data) | |||
660 | { | 770 | { |
661 | struct device *dev = &data->hdev->dev; | 771 | struct device *dev = &data->hdev->dev; |
662 | struct fb_info *info = NULL; | 772 | struct fb_info *info = NULL; |
663 | int error = -ENOMEM; | 773 | int i, error = -ENOMEM; |
664 | u8 *fb_vbitmap = NULL; | 774 | u8 *fb_vbitmap = NULL; |
665 | u8 *fb_bitmap = NULL; | 775 | u8 *fb_bitmap = NULL; |
776 | u32 *palette; | ||
666 | 777 | ||
667 | fb_bitmap = vmalloc(PICOLCDFB_SIZE*picolcdfb_var.bits_per_pixel); | 778 | fb_bitmap = vmalloc(PICOLCDFB_SIZE*8); |
668 | if (fb_bitmap == NULL) { | 779 | if (fb_bitmap == NULL) { |
669 | dev_err(dev, "can't get a free page for framebuffer\n"); | 780 | dev_err(dev, "can't get a free page for framebuffer\n"); |
670 | goto err_nomem; | 781 | goto err_nomem; |
@@ -678,18 +789,29 @@ static int picolcd_init_framebuffer(struct picolcd_data *data) | |||
678 | 789 | ||
679 | data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT; | 790 | data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT; |
680 | data->fb_defio = picolcd_fb_defio; | 791 | data->fb_defio = picolcd_fb_defio; |
681 | info = framebuffer_alloc(0, dev); | 792 | /* The extra memory is: |
793 | * - struct picolcd_fb_cleanup_item | ||
794 | * - u32 for ref_count | ||
795 | * - 256*u32 for pseudo_palette | ||
796 | */ | ||
797 | info = framebuffer_alloc(257 * sizeof(u32) + sizeof(struct picolcd_fb_cleanup_item), dev); | ||
682 | if (info == NULL) { | 798 | if (info == NULL) { |
683 | dev_err(dev, "failed to allocate a framebuffer\n"); | 799 | dev_err(dev, "failed to allocate a framebuffer\n"); |
684 | goto err_nomem; | 800 | goto err_nomem; |
685 | } | 801 | } |
686 | 802 | ||
803 | palette = info->par + sizeof(struct picolcd_fb_cleanup_item); | ||
804 | *palette = 1; | ||
805 | palette++; | ||
806 | for (i = 0; i < 256; i++) | ||
807 | palette[i] = i > 0 && i < 16 ? 0xff : 0; | ||
808 | info->pseudo_palette = palette; | ||
687 | info->fbdefio = &data->fb_defio; | 809 | info->fbdefio = &data->fb_defio; |
688 | info->screen_base = (char __force __iomem *)fb_bitmap; | 810 | info->screen_base = (char __force __iomem *)fb_bitmap; |
689 | info->fbops = &picolcdfb_ops; | 811 | info->fbops = &picolcdfb_ops; |
690 | info->var = picolcdfb_var; | 812 | info->var = picolcdfb_var; |
691 | info->fix = picolcdfb_fix; | 813 | info->fix = picolcdfb_fix; |
692 | info->fix.smem_len = PICOLCDFB_SIZE; | 814 | info->fix.smem_len = PICOLCDFB_SIZE*8; |
693 | info->fix.smem_start = (unsigned long)fb_bitmap; | 815 | info->fix.smem_start = (unsigned long)fb_bitmap; |
694 | info->par = data; | 816 | info->par = data; |
695 | info->flags = FBINFO_FLAG_DEFAULT; | 817 | info->flags = FBINFO_FLAG_DEFAULT; |
@@ -707,18 +829,20 @@ static int picolcd_init_framebuffer(struct picolcd_data *data) | |||
707 | dev_err(dev, "failed to create sysfs attributes\n"); | 829 | dev_err(dev, "failed to create sysfs attributes\n"); |
708 | goto err_cleanup; | 830 | goto err_cleanup; |
709 | } | 831 | } |
832 | fb_deferred_io_init(info); | ||
710 | data->fb_info = info; | 833 | data->fb_info = info; |
711 | error = register_framebuffer(info); | 834 | error = register_framebuffer(info); |
712 | if (error) { | 835 | if (error) { |
713 | dev_err(dev, "failed to register framebuffer\n"); | 836 | dev_err(dev, "failed to register framebuffer\n"); |
714 | goto err_sysfs; | 837 | goto err_sysfs; |
715 | } | 838 | } |
716 | fb_deferred_io_init(info); | ||
717 | /* schedule first output of framebuffer */ | 839 | /* schedule first output of framebuffer */ |
840 | data->fb_force = 1; | ||
718 | schedule_delayed_work(&info->deferred_work, 0); | 841 | schedule_delayed_work(&info->deferred_work, 0); |
719 | return 0; | 842 | return 0; |
720 | 843 | ||
721 | err_sysfs: | 844 | err_sysfs: |
845 | fb_deferred_io_cleanup(info); | ||
722 | device_remove_file(dev, &dev_attr_fb_update_rate); | 846 | device_remove_file(dev, &dev_attr_fb_update_rate); |
723 | err_cleanup: | 847 | err_cleanup: |
724 | data->fb_vbitmap = NULL; | 848 | data->fb_vbitmap = NULL; |
@@ -737,19 +861,17 @@ static void picolcd_exit_framebuffer(struct picolcd_data *data) | |||
737 | { | 861 | { |
738 | struct fb_info *info = data->fb_info; | 862 | struct fb_info *info = data->fb_info; |
739 | u8 *fb_vbitmap = data->fb_vbitmap; | 863 | u8 *fb_vbitmap = data->fb_vbitmap; |
740 | u8 *fb_bitmap = data->fb_bitmap; | ||
741 | 864 | ||
742 | if (!info) | 865 | if (!info) |
743 | return; | 866 | return; |
744 | 867 | ||
868 | info->par = NULL; | ||
869 | device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate); | ||
870 | unregister_framebuffer(info); | ||
745 | data->fb_vbitmap = NULL; | 871 | data->fb_vbitmap = NULL; |
746 | data->fb_bitmap = NULL; | 872 | data->fb_bitmap = NULL; |
747 | data->fb_bpp = 0; | 873 | data->fb_bpp = 0; |
748 | data->fb_info = NULL; | 874 | data->fb_info = NULL; |
749 | device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate); | ||
750 | fb_deferred_io_cleanup(info); | ||
751 | unregister_framebuffer(info); | ||
752 | vfree(fb_bitmap); | ||
753 | kfree(fb_vbitmap); | 875 | kfree(fb_vbitmap); |
754 | } | 876 | } |
755 | 877 | ||
@@ -2566,6 +2688,13 @@ static void picolcd_remove(struct hid_device *hdev) | |||
2566 | spin_lock_irqsave(&data->lock, flags); | 2688 | spin_lock_irqsave(&data->lock, flags); |
2567 | data->status |= PICOLCD_FAILED; | 2689 | data->status |= PICOLCD_FAILED; |
2568 | spin_unlock_irqrestore(&data->lock, flags); | 2690 | spin_unlock_irqrestore(&data->lock, flags); |
2691 | #ifdef CONFIG_HID_PICOLCD_FB | ||
2692 | /* short-circuit FB as early as possible in order to | ||
2693 | * avoid long delays if we host console. | ||
2694 | */ | ||
2695 | if (data->fb_info) | ||
2696 | data->fb_info->par = NULL; | ||
2697 | #endif | ||
2569 | 2698 | ||
2570 | picolcd_exit_devfs(data); | 2699 | picolcd_exit_devfs(data); |
2571 | device_remove_file(&hdev->dev, &dev_attr_operation_mode); | 2700 | device_remove_file(&hdev->dev, &dev_attr_operation_mode); |
@@ -2623,6 +2752,10 @@ static int __init picolcd_init(void) | |||
2623 | static void __exit picolcd_exit(void) | 2752 | static void __exit picolcd_exit(void) |
2624 | { | 2753 | { |
2625 | hid_unregister_driver(&picolcd_driver); | 2754 | hid_unregister_driver(&picolcd_driver); |
2755 | #ifdef CONFIG_HID_PICOLCD_FB | ||
2756 | flush_scheduled_work(); | ||
2757 | WARN_ON(fb_pending); | ||
2758 | #endif | ||
2626 | } | 2759 | } |
2627 | 2760 | ||
2628 | module_init(picolcd_init); | 2761 | module_init(picolcd_init); |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 3ccd47850677..47d70c523d93 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -46,7 +46,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, | |||
46 | { | 46 | { |
47 | struct hidraw_list *list = file->private_data; | 47 | struct hidraw_list *list = file->private_data; |
48 | int ret = 0, len; | 48 | int ret = 0, len; |
49 | char *report; | ||
50 | DECLARE_WAITQUEUE(wait, current); | 49 | DECLARE_WAITQUEUE(wait, current); |
51 | 50 | ||
52 | mutex_lock(&list->read_mutex); | 51 | mutex_lock(&list->read_mutex); |
@@ -84,7 +83,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, | |||
84 | if (ret) | 83 | if (ret) |
85 | goto out; | 84 | goto out; |
86 | 85 | ||
87 | report = list->buffer[list->tail].value; | ||
88 | len = list->buffer[list->tail].len > count ? | 86 | len = list->buffer[list->tail].len > count ? |
89 | count : list->buffer[list->tail].len; | 87 | count : list->buffer[list->tail].len; |
90 | 88 | ||