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 | ||
