Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
7426ef52
Commit
7426ef52
authored
May 19, 2010
by
Jiri Kosina
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'upstream' into for-linus
Conflicts: drivers/hid/hid-wacom.c
parents
537b60d1
a8ab5d58
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
679 additions
and
79 deletions
+679
-79
Documentation/ABI/testing/sysfs-wacom
Documentation/ABI/testing/sysfs-wacom
+10
-0
drivers/hid/Kconfig
drivers/hid/Kconfig
+17
-2
drivers/hid/Makefile
drivers/hid/Makefile
+1
-0
drivers/hid/hid-3m-pct.c
drivers/hid/hid-3m-pct.c
+28
-3
drivers/hid/hid-core.c
drivers/hid/hid-core.c
+13
-10
drivers/hid/hid-ids.h
drivers/hid/hid-ids.h
+12
-0
drivers/hid/hid-lg.c
drivers/hid/hid-lg.c
+9
-0
drivers/hid/hid-samsung.c
drivers/hid/hid-samsung.c
+83
-12
drivers/hid/hid-topseed.c
drivers/hid/hid-topseed.c
+24
-14
drivers/hid/hid-wacom.c
drivers/hid/hid-wacom.c
+204
-25
drivers/hid/hid-zydacron.c
drivers/hid/hid-zydacron.c
+237
-0
drivers/hid/hidraw.c
drivers/hid/hidraw.c
+1
-1
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-core.c
+36
-12
drivers/hid/usbhid/hid-quirks.c
drivers/hid/usbhid/hid-quirks.c
+1
-0
drivers/hid/usbhid/usbkbd.c
drivers/hid/usbhid/usbkbd.c
+1
-0
include/linux/hid.h
include/linux/hid.h
+2
-0
No files found.
Documentation/ABI/testing/sysfs-wacom
0 → 100644
View file @
7426ef52
What: /sys/class/hidraw/hidraw*/device/speed
Date: April 2010
Kernel Version: 2.6.35
Contact: linux-bluetooth@vger.kernel.org
Description:
The /sys/class/hidraw/hidraw*/device/speed file controls
reporting speed of wacom bluetooth tablet. Reading from
this file returns 1 if tablet reports in high speed mode
or 0 otherwise. Writing to this file one of these values
switches reporting speed.
drivers/hid/Kconfig
View file @
7426ef52
...
...
@@ -273,7 +273,7 @@ config HID_SAMSUNG
depends on USB_HID
default !EMBEDDED
---help---
Support for Samsung InfraRed remote control.
Support for Samsung InfraRed remote control
or keyboards
.
config HID_SONY
tristate "Sony" if EMBEDDED
...
...
@@ -332,7 +332,7 @@ config HID_TOPSEED
depends on USB_HID
default !EMBEDDED
---help---
Say Y if you have a TopSeed Cyberlink remote control.
Say Y if you have a TopSeed Cyberlink
or BTC Emprex
remote control.
config HID_THRUSTMASTER
tristate "ThrustMaster devices support" if EMBEDDED
...
...
@@ -357,6 +357,14 @@ config HID_WACOM
---help---
Support for Wacom Graphire Bluetooth tablet.
config HID_WACOM_POWER_SUPPLY
bool "Wacom Bluetooth devices power supply status support"
depends on HID_WACOM
select POWER_SUPPLY
---help---
Say Y here if you want to enable power supply status monitoring for
Wacom Bluetooth devices.
config HID_ZEROPLUS
tristate "Zeroplus based game controller support" if EMBEDDED
depends on USB_HID
...
...
@@ -372,6 +380,13 @@ config ZEROPLUS_FF
Say Y here if you have a Zeroplus based game controller and want
to have force feedback support for it.
config HID_ZYDACRON
tristate "Zydacron remote control support" if EMBEDDED
depends on USB_HID
default !EMBEDDED
---help---
Support for Zydacron remote control.
endmenu
endif # HID_SUPPORT
drivers/hid/Makefile
View file @
7426ef52
...
...
@@ -54,6 +54,7 @@ obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
obj-$(CONFIG_HID_TOPSEED)
+=
hid-topseed.o
obj-$(CONFIG_HID_TWINHAN)
+=
hid-twinhan.o
obj-$(CONFIG_HID_ZEROPLUS)
+=
hid-zpff.o
obj-$(CONFIG_HID_ZYDACRON)
+=
hid-zydacron.o
obj-$(CONFIG_HID_WACOM)
+=
hid-wacom.o
obj-$(CONFIG_USB_HID)
+=
usbhid/
...
...
drivers/hid/hid-3m-pct.c
View file @
7426ef52
/*
* HID driver for 3M PCT multitouch panels
*
* Copyright (c) 2009 Stephane Chatty <chatty@enac.fr>
* Copyright (c) 2009
-2010
Stephane Chatty <chatty@enac.fr>
*
*/
...
...
@@ -25,7 +25,7 @@ MODULE_LICENSE("GPL");
#include "hid-ids.h"
struct
mmm_finger
{
__s32
x
,
y
;
__s32
x
,
y
,
w
,
h
;
__u8
rank
;
bool
touch
,
valid
;
};
...
...
@@ -82,7 +82,18 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
/* touchscreen emulation */
hid_map_usage
(
hi
,
usage
,
bit
,
max
,
EV_KEY
,
BTN_TOUCH
);
return
1
;
case
HID_DG_WIDTH
:
hid_map_usage
(
hi
,
usage
,
bit
,
max
,
EV_ABS
,
ABS_MT_TOUCH_MAJOR
);
return
1
;
case
HID_DG_HEIGHT
:
hid_map_usage
(
hi
,
usage
,
bit
,
max
,
EV_ABS
,
ABS_MT_TOUCH_MINOR
);
input_set_abs_params
(
hi
->
input
,
ABS_MT_ORIENTATION
,
1
,
1
,
0
,
0
);
return
1
;
case
HID_DG_CONTACTID
:
field
->
logical_maximum
=
59
;
hid_map_usage
(
hi
,
usage
,
bit
,
max
,
EV_ABS
,
ABS_MT_TRACKING_ID
);
return
1
;
...
...
@@ -128,9 +139,15 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
/* this finger is just placeholder data, ignore */
}
else
if
(
f
->
touch
)
{
/* this finger is on the screen */
int
wide
=
(
f
->
w
>
f
->
h
);
input_event
(
input
,
EV_ABS
,
ABS_MT_TRACKING_ID
,
i
);
input_event
(
input
,
EV_ABS
,
ABS_MT_POSITION_X
,
f
->
x
);
input_event
(
input
,
EV_ABS
,
ABS_MT_POSITION_Y
,
f
->
y
);
input_event
(
input
,
EV_ABS
,
ABS_MT_ORIENTATION
,
wide
);
input_event
(
input
,
EV_ABS
,
ABS_MT_TOUCH_MAJOR
,
wide
?
f
->
w
:
f
->
h
);
input_event
(
input
,
EV_ABS
,
ABS_MT_TOUCH_MINOR
,
wide
?
f
->
h
:
f
->
w
);
input_mt_sync
(
input
);
/*
* touchscreen emulation: maintain the age rank
...
...
@@ -197,6 +214,14 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
case
HID_DG_CONFIDENCE
:
md
->
valid
=
value
;
break
;
case
HID_DG_WIDTH
:
if
(
md
->
valid
)
md
->
f
[
md
->
curid
].
w
=
value
;
break
;
case
HID_DG_HEIGHT
:
if
(
md
->
valid
)
md
->
f
[
md
->
curid
].
h
=
value
;
break
;
case
HID_DG_CONTACTID
:
if
(
md
->
valid
)
{
md
->
curid
=
value
;
...
...
@@ -255,6 +280,7 @@ static void mmm_remove(struct hid_device *hdev)
static
const
struct
hid_device_id
mmm_devices
[]
=
{
{
HID_USB_DEVICE
(
USB_VENDOR_ID_3M
,
USB_DEVICE_ID_3M1968
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_3M
,
USB_DEVICE_ID_3M2256
)
},
{
}
};
MODULE_DEVICE_TABLE
(
hid
,
mmm_devices
);
...
...
@@ -287,5 +313,4 @@ static void __exit mmm_exit(void)
module_init
(
mmm_init
);
module_exit
(
mmm_exit
);
MODULE_LICENSE
(
"GPL"
);
drivers/hid/hid-core.c
View file @
7426ef52
...
...
@@ -653,10 +653,9 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
if
(
device
->
driver
->
report_fixup
)
device
->
driver
->
report_fixup
(
device
,
start
,
size
);
device
->
rdesc
=
km
alloc
(
size
,
GFP_KERNEL
);
device
->
rdesc
=
km
emdup
(
start
,
size
,
GFP_KERNEL
);
if
(
device
->
rdesc
==
NULL
)
return
-
ENOMEM
;
memcpy
(
device
->
rdesc
,
start
,
size
);
device
->
rsize
=
size
;
parser
=
vmalloc
(
sizeof
(
struct
hid_parser
));
...
...
@@ -940,13 +939,8 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
unsigned
count
=
field
->
report_count
;
unsigned
offset
=
field
->
report_offset
;
unsigned
size
=
field
->
report_size
;
unsigned
bitsused
=
offset
+
count
*
size
;
unsigned
n
;
/* make sure the unused bits in the last byte are zeros */
if
(
count
>
0
&&
size
>
0
&&
(
bitsused
%
8
)
!=
0
)
data
[(
bitsused
-
1
)
/
8
]
&=
(
1
<<
(
bitsused
%
8
))
-
1
;
for
(
n
=
0
;
n
<
count
;
n
++
)
{
if
(
field
->
logical_minimum
<
0
)
/* signed values */
implement
(
data
,
offset
+
n
*
size
,
size
,
s32ton
(
field
->
value
[
n
],
size
));
...
...
@@ -966,6 +960,7 @@ void hid_output_report(struct hid_report *report, __u8 *data)
if
(
report
->
id
>
0
)
*
data
++
=
report
->
id
;
memset
(
data
,
0
,
((
report
->
size
-
1
)
>>
3
)
+
1
);
for
(
n
=
0
;
n
<
report
->
maxfield
;
n
++
)
hid_output_field
(
report
->
field
[
n
],
data
);
}
...
...
@@ -1167,6 +1162,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
unsigned
int
i
;
int
len
;
if
(
hdev
->
quirks
&
HID_QUIRK_HIDDEV_FORCE
)
connect_mask
|=
(
HID_CONNECT_HIDDEV_FORCE
|
HID_CONNECT_HIDDEV
);
if
(
hdev
->
bus
!=
BUS_USB
)
connect_mask
&=
~
HID_CONNECT_HIDDEV
;
if
(
hid_hiddev
(
hdev
))
...
...
@@ -1246,6 +1243,7 @@ EXPORT_SYMBOL_GPL(hid_disconnect);
/* a list of devices for which there is a specialized driver on HID bus */
static
const
struct
hid_device_id
hid_blacklist
[]
=
{
{
HID_USB_DEVICE
(
USB_VENDOR_ID_3M
,
USB_DEVICE_ID_3M1968
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_3M
,
USB_DEVICE_ID_3M2256
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_A4TECH
,
USB_DEVICE_ID_A4TECH_WCP32PU
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_A4TECH
,
USB_DEVICE_ID_A4TECH_X5_005D
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_APPLE
,
USB_DEVICE_ID_APPLE_ATV_IRCONTROL
)
},
...
...
@@ -1290,6 +1288,7 @@ static const struct hid_device_id hid_blacklist[] = {
{
HID_USB_DEVICE
(
USB_VENDOR_ID_APPLE
,
USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_APPLE
,
USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_BELKIN
,
USB_DEVICE_ID_FLIP_KVM
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_BTC
,
USB_DEVICE_ID_BTC_EMPREX_REMOTE
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_CHERRY
,
USB_DEVICE_ID_CHERRY_CYMOTION
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_CHERRY
,
USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_CHICONY
,
USB_DEVICE_ID_CHICONY_TACTICAL_PAD
)
},
...
...
@@ -1343,6 +1342,7 @@ static const struct hid_device_id hid_blacklist[] = {
{
HID_USB_DEVICE
(
USB_VENDOR_ID_QUANTA
,
USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_QUANTA
,
USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_SAMSUNG
,
USB_DEVICE_ID_SAMSUNG_IR_REMOTE
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_SAMSUNG
,
USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_SONY
,
USB_DEVICE_ID_SONY_PS3_CONTROLLER
)
},
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_SONY
,
USB_DEVICE_ID_SONY_PS3_CONTROLLER
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_SONY
,
USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE
)
},
...
...
@@ -1359,8 +1359,10 @@ static const struct hid_device_id hid_blacklist[] = {
{
HID_USB_DEVICE
(
USB_VENDOR_ID_TWINHAN
,
USB_DEVICE_ID_TWINHAN_IR_REMOTE
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_WISEGROUP
,
USB_DEVICE_ID_SMARTJOY_PLUS
)
},
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH
)
},
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_ZEROPLUS
,
0x0005
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_ZEROPLUS
,
0x0030
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_ZYDACRON
,
USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL
)
},
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_MICROSOFT
,
USB_DEVICE_ID_MS_PRESENTER_8K_BT
)
},
{
}
...
...
@@ -1757,7 +1759,7 @@ int hid_add_device(struct hid_device *hdev)
/* we need to kill them here, otherwise they will stay allocated to
* wait for coming driver */
if
(
hid_ignore
(
hdev
))
if
(
!
(
hdev
->
quirks
&
HID_QUIRK_NO_IGNORE
)
&&
hid_ignore
(
hdev
))
return
-
ENODEV
;
/* XXX hack, any other cleaner solution after the driver core
...
...
@@ -1765,11 +1767,12 @@ int hid_add_device(struct hid_device *hdev)
dev_set_name
(
&
hdev
->
dev
,
"%04X:%04X:%04X.%04X"
,
hdev
->
bus
,
hdev
->
vendor
,
hdev
->
product
,
atomic_inc_return
(
&
id
));
hid_debug_register
(
hdev
,
dev_name
(
&
hdev
->
dev
));
ret
=
device_add
(
&
hdev
->
dev
);
if
(
!
ret
)
hdev
->
status
|=
HID_STAT_ADDED
;
hid_debug_register
(
hdev
,
dev_name
(
&
hdev
->
dev
)
);
else
hid_debug_unregister
(
hdev
);
return
ret
;
}
...
...
drivers/hid/hid-ids.h
View file @
7426ef52
...
...
@@ -20,6 +20,7 @@
#define USB_VENDOR_ID_3M 0x0596
#define USB_DEVICE_ID_3M1968 0x0500
#define USB_DEVICE_ID_3M2256 0x0502
#define USB_VENDOR_ID_A4TECH 0x09da
#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
...
...
@@ -123,6 +124,9 @@
#define USB_VENDOR_ID_BERKSHIRE 0x0c98
#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
#define USB_VENDOR_ID_BTC 0x046e
#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
#define USB_VENDOR_ID_CH 0x068e
#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2
#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4
...
...
@@ -171,6 +175,9 @@
#define USB_VENDOR_ID_DRAGONRISE 0x0079
#define USB_VENDOR_ID_EGALAX 0x0EEF
#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
#define USB_VENDOR_ID_ELO 0x04E7
#define USB_DEVICE_ID_ELO_TS2700 0x0020
...
...
@@ -409,6 +416,7 @@
#define USB_VENDOR_ID_SAMSUNG 0x0419
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
#define USB_VENDOR_ID_SONY 0x054c
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
...
...
@@ -457,6 +465,7 @@
#define USB_VENDOR_ID_WACOM 0x056a
#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0xbd
#define USB_VENDOR_ID_WISEGROUP 0x0925
#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005
...
...
@@ -475,6 +484,9 @@
#define USB_VENDOR_ID_ZEROPLUS 0x0c12
#define USB_VENDOR_ID_ZYDACRON 0x13EC
#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
#define USB_VENDOR_ID_KYE 0x0458
#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
...
...
drivers/hid/hid-lg.c
View file @
7426ef52
...
...
@@ -126,6 +126,9 @@ static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
case
0x1004
:
lg_map_key_clear
(
KEY_VIDEO
);
break
;
case
0x1005
:
lg_map_key_clear
(
KEY_AUDIO
);
break
;
case
0x100a
:
lg_map_key_clear
(
KEY_DOCUMENTS
);
break
;
/* The following two entries are Playlist 1 and 2 on the MX3200 */
case
0x100f
:
lg_map_key_clear
(
KEY_FN_1
);
break
;
case
0x1010
:
lg_map_key_clear
(
KEY_FN_2
);
break
;
case
0x1011
:
lg_map_key_clear
(
KEY_PREVIOUSSONG
);
break
;
case
0x1012
:
lg_map_key_clear
(
KEY_NEXTSONG
);
break
;
case
0x1013
:
lg_map_key_clear
(
KEY_CAMERA
);
break
;
...
...
@@ -137,6 +140,7 @@ static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
case
0x1019
:
lg_map_key_clear
(
KEY_PROG1
);
break
;
case
0x101a
:
lg_map_key_clear
(
KEY_PROG2
);
break
;
case
0x101b
:
lg_map_key_clear
(
KEY_PROG3
);
break
;
case
0x101c
:
lg_map_key_clear
(
KEY_CYCLEWINDOWS
);
break
;
case
0x101f
:
lg_map_key_clear
(
KEY_ZOOMIN
);
break
;
case
0x1020
:
lg_map_key_clear
(
KEY_ZOOMOUT
);
break
;
case
0x1021
:
lg_map_key_clear
(
KEY_ZOOMRESET
);
break
;
...
...
@@ -147,6 +151,11 @@ static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
case
0x1029
:
lg_map_key_clear
(
KEY_SHUFFLE
);
break
;
case
0x102a
:
lg_map_key_clear
(
KEY_BACK
);
break
;
case
0x102b
:
lg_map_key_clear
(
KEY_CYCLEWINDOWS
);
break
;
case
0x102d
:
lg_map_key_clear
(
KEY_WWW
);
break
;
/* The following two are 'Start/answer call' and 'End/reject call'
on the MX3200 */
case
0x1031
:
lg_map_key_clear
(
KEY_OK
);
break
;
case
0x1032
:
lg_map_key_clear
(
KEY_CANCEL
);
break
;
case
0x1041
:
lg_map_key_clear
(
KEY_BATTERY
);
break
;
case
0x1042
:
lg_map_key_clear
(
KEY_WORDPROCESSOR
);
break
;
case
0x1043
:
lg_map_key_clear
(
KEY_SPREADSHEET
);
break
;
...
...
drivers/hid/hid-samsung.c
View file @
7426ef52
...
...
@@ -7,6 +7,18 @@
* Copyright (c) 2006-2007 Jiri Kosina
* Copyright (c) 2007 Paul Walmsley
* Copyright (c) 2008 Jiri Slaby
* Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>
*
*
* This driver supports several HID devices:
*
* [0419:0001] Samsung IrDA remote controller (reports as Cypress USB Mouse).
* various hid report fixups for different variants.
*
* [0419:0600] Creative Desktop Wireless 6000 keyboard/mouse combo
* several key mappings used from the consumer usage page
* deviate from the USB HUT 1.12 standard.
*
*/
/*
...
...
@@ -17,14 +29,13 @@
*/
#include <linux/device.h>
#include <linux/usb.h>
#include <linux/hid.h>
#include <linux/module.h>
#include "hid-ids.h"
/*
* Samsung IrDA remote controller (reports as Cypress USB Mouse).
*
* There are several variants for 0419:0001:
*
* 1. 184 byte report descriptor
...
...
@@ -43,21 +54,21 @@
* 4. 171 byte report descriptor
* Report #3 has an array field with logical range 0..1 instead of 1..3.
*/
static
inline
void
samsung_dev_trace
(
struct
hid_device
*
hdev
,
static
inline
void
samsung_
irda_
dev_trace
(
struct
hid_device
*
hdev
,
unsigned
int
rsize
)
{
dev_info
(
&
hdev
->
dev
,
"fixing up Samsung IrDA %d byte report "
"descriptor
\n
"
,
rsize
);
}
static
void
samsung_report_fixup
(
struct
hid_device
*
hdev
,
__u8
*
rdesc
,
static
void
samsung_
irda_
report_fixup
(
struct
hid_device
*
hdev
,
__u8
*
rdesc
,
unsigned
int
rsize
)
{
if
(
rsize
==
184
&&
rdesc
[
175
]
==
0x25
&&
rdesc
[
176
]
==
0x40
&&
rdesc
[
177
]
==
0x75
&&
rdesc
[
178
]
==
0x30
&&
rdesc
[
179
]
==
0x95
&&
rdesc
[
180
]
==
0x01
&&
rdesc
[
182
]
==
0x40
)
{
samsung_dev_trace
(
hdev
,
184
);
samsung_
irda_
dev_trace
(
hdev
,
184
);
rdesc
[
176
]
=
0xff
;
rdesc
[
178
]
=
0x08
;
rdesc
[
180
]
=
0x06
;
...
...
@@ -65,24 +76,80 @@ static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
}
else
if
(
rsize
==
203
&&
rdesc
[
192
]
==
0x15
&&
rdesc
[
193
]
==
0x0
&&
rdesc
[
194
]
==
0x25
&&
rdesc
[
195
]
==
0x12
)
{
samsung_dev_trace
(
hdev
,
203
);
samsung_
irda_
dev_trace
(
hdev
,
203
);
rdesc
[
193
]
=
0x1
;
rdesc
[
195
]
=
0xf
;
}
else
if
(
rsize
==
135
&&
rdesc
[
124
]
==
0x15
&&
rdesc
[
125
]
==
0x0
&&
rdesc
[
126
]
==
0x25
&&
rdesc
[
127
]
==
0x11
)
{
samsung_dev_trace
(
hdev
,
135
);
samsung_
irda_
dev_trace
(
hdev
,
135
);
rdesc
[
125
]
=
0x1
;
rdesc
[
127
]
=
0xe
;
}
else
if
(
rsize
==
171
&&
rdesc
[
160
]
==
0x15
&&
rdesc
[
161
]
==
0x0
&&
rdesc
[
162
]
==
0x25
&&
rdesc
[
163
]
==
0x01
)
{
samsung_dev_trace
(
hdev
,
171
);
samsung_
irda_
dev_trace
(
hdev
,
171
);
rdesc
[
161
]
=
0x1
;
rdesc
[
163
]
=
0x3
;
}
}
#define samsung_kbd_mouse_map_key_clear(c) \
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
static
int
samsung_kbd_mouse_input_mapping
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
struct
usb_interface
*
intf
=
to_usb_interface
(
hdev
->
dev
.
parent
);
unsigned
short
ifnum
=
intf
->
cur_altsetting
->
desc
.
bInterfaceNumber
;
if
(
1
!=
ifnum
||
HID_UP_CONSUMER
!=
(
usage
->
hid
&
HID_USAGE_PAGE
))
return
0
;
dbg_hid
(
"samsung wireless keyboard/mouse input mapping event [0x%x]
\n
"
,
usage
->
hid
&
HID_USAGE
);
switch
(
usage
->
hid
&
HID_USAGE
)
{
/* report 2 */
case
0x183
:
samsung_kbd_mouse_map_key_clear
(
KEY_MEDIA
);
break
;
case
0x195
:
samsung_kbd_mouse_map_key_clear
(
KEY_EMAIL
);
break
;
case
0x196
:
samsung_kbd_mouse_map_key_clear
(
KEY_CALC
);
break
;
case
0x197
:
samsung_kbd_mouse_map_key_clear
(
KEY_COMPUTER
);
break
;
case
0x22b
:
samsung_kbd_mouse_map_key_clear
(
KEY_SEARCH
);
break
;
case
0x22c
:
samsung_kbd_mouse_map_key_clear
(
KEY_WWW
);
break
;
case
0x22d
:
samsung_kbd_mouse_map_key_clear
(
KEY_BACK
);
break
;
case
0x22e
:
samsung_kbd_mouse_map_key_clear
(
KEY_FORWARD
);
break
;
case
0x22f
:
samsung_kbd_mouse_map_key_clear
(
KEY_FAVORITES
);
break
;
case
0x230
:
samsung_kbd_mouse_map_key_clear
(
KEY_REFRESH
);
break
;
case
0x231
:
samsung_kbd_mouse_map_key_clear
(
KEY_STOP
);
break
;
default:
return
0
;
}
return
1
;
}
static
void
samsung_report_fixup
(
struct
hid_device
*
hdev
,
__u8
*
rdesc
,
unsigned
int
rsize
)
{
if
(
USB_DEVICE_ID_SAMSUNG_IR_REMOTE
==
hdev
->
product
)
samsung_irda_report_fixup
(
hdev
,
rdesc
,
rsize
);
}
static
int
samsung_input_mapping
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
int
ret
=
0
;
if
(
USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE
==
hdev
->
product
)
ret
=
samsung_kbd_mouse_input_mapping
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
);
return
ret
;
}
static
int
samsung_probe
(
struct
hid_device
*
hdev
,
const
struct
hid_device_id
*
id
)
{
...
...
@@ -95,10 +162,12 @@ static int samsung_probe(struct hid_device *hdev,
goto
err_free
;
}
if
(
hdev
->
rsize
==
184
)
{
/* disable hidinput, force hiddev */
cmask
=
(
cmask
&
~
HID_CONNECT_HIDINPUT
)
|
HID_CONNECT_HIDDEV_FORCE
;
if
(
USB_DEVICE_ID_SAMSUNG_IR_REMOTE
==
hdev
->
product
)
{
if
(
hdev
->
rsize
==
184
)
{
/* disable hidinput, force hiddev */
cmask
=
(
cmask
&
~
HID_CONNECT_HIDINPUT
)
|
HID_CONNECT_HIDDEV_FORCE
;
}
}
ret
=
hid_hw_start
(
hdev
,
cmask
);
...
...
@@ -114,6 +183,7 @@ static int samsung_probe(struct hid_device *hdev,
static
const
struct
hid_device_id
samsung_devices
[]
=
{
{
HID_USB_DEVICE
(
USB_VENDOR_ID_SAMSUNG
,
USB_DEVICE_ID_SAMSUNG_IR_REMOTE
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_SAMSUNG
,
USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE
)
},
{
}
};
MODULE_DEVICE_TABLE
(
hid
,
samsung_devices
);
...
...
@@ -122,6 +192,7 @@ static struct hid_driver samsung_driver = {
.
name
=
"samsung"
,
.
id_table
=
samsung_devices
,
.
report_fixup
=
samsung_report_fixup
,
.
input_mapping
=
samsung_input_mapping
,
.
probe
=
samsung_probe
,
};
...
...
drivers/hid/hid-topseed.c
View file @
7426ef52
...
...
@@ -3,6 +3,9 @@
*
* Copyright (c) 2008 Lev Babiev
* based on hid-cherry driver
*
* Modified to also support BTC "Emprex 3009URF III Vista MCE Remote" by
* Wayne Thomas 2010.
*/
/*
...
...
@@ -24,23 +27,29 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
if
((
usage
->
hid
&
HID_USAGE_PAGE
)
!=
0x0ffbc0000
)
if
((
usage
->
hid
&
HID_USAGE_PAGE
)
!=
HID_UP_LOGIVENDOR
)
return
0
;
switch
(
usage
->
hid
&
HID_USAGE
)
{
case
0x00d
:
ts_map_key_clear
(
KEY_HOME
);
break
;
case
0x024
:
ts_map_key_clear
(
KEY_MENU
);
break
;
case
0x025
:
ts_map_key_clear
(
KEY_TV
);
break
;
case
0x048
:
ts_map_key_clear
(
KEY_RED
);
break
;
case
0x047
:
ts_map_key_clear
(
KEY_GREEN
);
break
;
case
0x049
:
ts_map_key_clear
(
KEY_YELLOW
);
break
;
case
0x04a
:
ts_map_key_clear
(
KEY_BLUE
);
break
;
case
0x04b
:
ts_map_key_clear
(
KEY_ANGLE
);
break
;
case
0x04c
:
ts_map_key_clear
(
KEY_LANGUAGE
);
break
;
case
0x04d
:
ts_map_key_clear
(
KEY_SUBTITLE
);
break
;
case
0x031
:
ts_map_key_clear
(
KEY_AUDIO
);
break
;
case
0x032
:
ts_map_key_clear
(
KEY_TEXT
);
break
;
case
0x033
:
ts_map_key_clear
(
KEY_CHANNEL
);
break
;
case
0x00d
:
ts_map_key_clear
(
KEY_MEDIA
);
break
;
case
0x024
:
ts_map_key_clear
(
KEY_MENU
);
break
;
case
0x025
:
ts_map_key_clear
(
KEY_TV
);
break
;
case
0x031
:
ts_map_key_clear
(
KEY_AUDIO
);
break
;
case
0x032
:
ts_map_key_clear
(
KEY_TEXT
);
break
;
case
0x033
:
ts_map_key_clear
(
KEY_CHANNEL
);
break
;
case
0x047
:
ts_map_key_clear
(
KEY_MP3
);
break
;
case
0x048
:
ts_map_key_clear
(
KEY_TV2
);
break
;
case
0x049
:
ts_map_key_clear
(
KEY_CAMERA
);
break
;
case
0x04a
:
ts_map_key_clear
(
KEY_VIDEO
);
break
;
case
0x04b
:
ts_map_key_clear
(
KEY_ANGLE
);
break
;
case
0x04c
:
ts_map_key_clear
(
KEY_LANGUAGE
);
break
;
case
0x04d
:
ts_map_key_clear
(
KEY_SUBTITLE
);
break
;
case
0x050
:
ts_map_key_clear
(
KEY_RADIO
);
break
;
case
0x05a
:
ts_map_key_clear
(
KEY_TEXT
);
break
;
case
0x05b
:
ts_map_key_clear
(
KEY_RED
);
break
;
case
0x05c
:
ts_map_key_clear
(
KEY_GREEN
);
break
;
case
0x05d
:
ts_map_key_clear
(
KEY_YELLOW
);
break
;
case
0x05e
:
ts_map_key_clear
(
KEY_BLUE
);
break
;
default:
return
0
;
}
...
...
@@ -50,6 +59,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
static
const
struct
hid_device_id
ts_devices
[]
=
{
{
HID_USB_DEVICE
(
USB_VENDOR_ID_TOPSEED
,
USB_DEVICE_ID_TOPSEED_CYBERLINK
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_BTC
,
USB_DEVICE_ID_BTC_EMPREX_REMOTE
)
},
{
}
};
MODULE_DEVICE_TABLE
(
hid
,
ts_devices
);
...
...
drivers/hid/hid-wacom.c
View file @
7426ef52
...
...
@@ -22,14 +22,159 @@
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/slab.h>
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
#include <linux/power_supply.h>
#endif
#include "hid-ids.h"
struct
wacom_data
{
__u16
tool
;
unsigned
char
butstate
;
unsigned
char
high_speed
;
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
int
battery_capacity
;
struct
power_supply
battery
;
struct
power_supply
ac
;
#endif
};
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
/*percent of battery capacity, 0 means AC online*/
static
unsigned
short
batcap
[
8
]
=
{
1
,
15
,
25
,
35
,
50
,
70
,
100
,
0
};
static
enum
power_supply_property
wacom_battery_props
[]
=
{
POWER_SUPPLY_PROP_PRESENT
,
POWER_SUPPLY_PROP_CAPACITY
};
static
enum
power_supply_property
wacom_ac_props
[]
=
{
POWER_SUPPLY_PROP_PRESENT
,
POWER_SUPPLY_PROP_ONLINE
};
static
int
wacom_battery_get_property
(
struct
power_supply
*
psy
,
enum
power_supply_property
psp
,
union
power_supply_propval
*
val
)
{
struct
wacom_data
*
wdata
=
container_of
(
psy
,
struct
wacom_data
,
battery
);
int
power_state
=
batcap
[
wdata
->
battery_capacity
];
int
ret
=
0
;
switch
(
psp
)
{
case
POWER_SUPPLY_PROP_PRESENT
:
val
->
intval
=
1
;
break
;
case
POWER_SUPPLY_PROP_CAPACITY
:
/* show 100% battery capacity when charging */
if
(
power_state
==
0
)
val
->
intval
=
100
;
else
val
->
intval
=
power_state
;
break
;
default:
ret
=
-
EINVAL
;
break
;
}
return
ret
;
}
static
int
wacom_ac_get_property
(
struct
power_supply
*
psy
,
enum
power_supply_property
psp
,
union
power_supply_propval
*
val
)
{
struct
wacom_data
*
wdata
=
container_of
(
psy
,
struct
wacom_data
,
ac
);
int
power_state
=
batcap
[
wdata
->
battery_capacity
];
int
ret
=
0
;
switch
(
psp
)
{
case
POWER_SUPPLY_PROP_PRESENT
:
/* fall through */
case
POWER_SUPPLY_PROP_ONLINE
:
if
(
power_state
==
0
)
val
->
intval
=
1
;
else
val
->
intval
=
0
;
break
;
default:
ret
=
-
EINVAL
;
break
;
}
return
ret
;
}
#endif
static
void
wacom_poke
(
struct
hid_device
*
hdev
,
u8
speed
)
{
struct
wacom_data
*
wdata
=
hid_get_drvdata
(
hdev
);
int
limit
,
ret
;
char
rep_data
[
2
];
rep_data
[
0
]
=
0x03
;
rep_data
[
1
]
=
0x00
;
limit
=
3
;
do
{
ret
=
hdev
->
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
}
while
(
ret
<
0
&&
limit
--
>
0
);
if
(
ret
>=
0
)
{
if
(
speed
==
0
)
rep_data
[
0
]
=
0x05
;
else
rep_data
[
0
]
=
0x06
;
rep_data
[
1
]
=
0x00
;
limit
=
3
;
do
{
ret
=
hdev
->
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
}
while
(
ret
<
0
&&
limit
--
>
0
);
if
(
ret
>=
0
)
{
wdata
->
high_speed
=
speed
;
return
;
}
}
/*
* Note that if the raw queries fail, it's not a hard failure and it
* is safe to continue
*/
dev_warn
(
&
hdev
->
dev
,
"failed to poke device, command %d, err %d
\n
"
,
rep_data
[
0
],
ret
);
return
;
}
static
ssize_t
wacom_show_speed
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
wacom_data
*
wdata
=
dev_get_drvdata
(
dev
);
return
snprintf
(
buf
,
PAGE_SIZE
,
"%i
\n
"
,
wdata
->
high_speed
);
}
static
ssize_t
wacom_store_speed
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
hid_device
*
hdev
=
container_of
(
dev
,
struct
hid_device
,
dev
);
int
new_speed
;
if
(
sscanf
(
buf
,
"%1d"
,
&
new_speed
)
!=
1
)
return
-
EINVAL
;
if
(
new_speed
==
0
||
new_speed
==
1
)
{
wacom_poke
(
hdev
,
new_speed
);
return
strnlen
(
buf
,
PAGE_SIZE
);
}
else
return
-
EINVAL
;
}
static
DEVICE_ATTR
(
speed
,
S_IRUGO
|
S_IWUGO
,
wacom_show_speed
,
wacom_store_speed
);
static
int
wacom_raw_event
(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
,
u8
*
raw_data
,
int
size
)
{
...
...
@@ -148,6 +293,12 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
input_sync
(
input
);
}
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
/* Store current battery capacity */
rw
=
(
data
[
7
]
>>
2
&
0x07
);
if
(
rw
!=
wdata
->
battery_capacity
)
wdata
->
battery_capacity
=
rw
;
#endif
return
1
;
}
...
...
@@ -157,9 +308,7 @@ static int wacom_probe(struct hid_device *hdev,
struct
hid_input
*
hidinput
;
struct
input_dev
*
input
;
struct
wacom_data
*
wdata
;
char
rep_data
[
2
];
int
ret
;
int
limit
;
wdata
=
kzalloc
(
sizeof
(
*
wdata
),
GFP_KERNEL
);
if
(
wdata
==
NULL
)
{
...
...
@@ -182,31 +331,53 @@ static int wacom_probe(struct hid_device *hdev,
goto
err_free
;
}
/*
* Note that if the raw queries fail, it's not a hard failure and it
* is safe to continue
*/
ret
=
device_create_file
(
&
hdev
->
dev
,
&
dev_attr_speed
);
if
(
ret
)
dev_warn
(
&
hdev
->
dev
,
"can't create sysfs speed attribute err: %d
\n
"
,
ret
);
/* Set Wacom mode2 */
rep_data
[
0
]
=
0x03
;
rep_data
[
1
]
=
0x00
;
limit
=
3
;
do
{
ret
=
hdev
->
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
}
while
(
ret
<
0
&&
limit
--
>
0
);
if
(
ret
<
0
)
dev_warn
(
&
hdev
->
dev
,
"failed to poke device #1, %d
\n
"
,
ret
);
/* Set Wacom mode 2 with high reporting speed */
wacom_poke
(
hdev
,
1
);
/* 0x06 - high reporting speed, 0x05 - low speed */
rep_data
[
0
]
=
0x06
;
rep_data
[
1
]
=
0x00
;
limit
=
3
;
do
{
ret
=
hdev
->
hid_output_raw_report
(
hdev
,
rep_data
,
2
,
HID_FEATURE_REPORT
);
}
while
(
ret
<
0
&&
limit
--
>
0
);
if
(
ret
<
0
)
dev_warn
(
&
hdev
->
dev
,
"failed to poke device #2, %d
\n
"
,
ret
);
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
wdata
->
battery
.
properties
=
wacom_battery_props
;
wdata
->
battery
.
num_properties
=
ARRAY_SIZE
(
wacom_battery_props
);
wdata
->
battery
.
get_property
=
wacom_battery_get_property
;
wdata
->
battery
.
name
=
"wacom_battery"
;
wdata
->
battery
.
type
=
POWER_SUPPLY_TYPE_BATTERY
;
wdata
->
battery
.
use_for_apm
=
0
;
ret
=
power_supply_register
(
&
hdev
->
dev
,
&
wdata
->
battery
);
if
(
ret
)
{
dev_warn
(
&
hdev
->
dev
,
"can't create sysfs battery attribute, err: %d
\n
"
,
ret
);
/*
* battery attribute is not critical for the tablet, but if it
* failed then there is no need to create ac attribute
*/
goto
move_on
;
}
wdata
->
ac
.
properties
=
wacom_ac_props
;
wdata
->
ac
.
num_properties
=
ARRAY_SIZE
(
wacom_ac_props
);
wdata
->
ac
.
get_property
=
wacom_ac_get_property
;
wdata
->
ac
.
name
=
"wacom_ac"
;
wdata
->
ac
.
type
=
POWER_SUPPLY_TYPE_MAINS
;
wdata
->
ac
.
use_for_apm
=
0
;
ret
=
power_supply_register
(
&
hdev
->
dev
,
&
wdata
->
ac
);
if
(
ret
)
{
dev_warn
(
&
hdev
->
dev
,
"can't create ac battery attribute, err: %d
\n
"
,
ret
);
/*
* ac attribute is not critical for the tablet, but if it
* failed then we don't want to battery attribute to exist
*/
power_supply_unregister
(
&
wdata
->
battery
);
}
move_on:
#endif
hidinput
=
list_entry
(
hdev
->
inputs
.
next
,
struct
hid_input
,
list
);
input
=
hidinput
->
input
;
...
...
@@ -251,13 +422,21 @@ static int wacom_probe(struct hid_device *hdev,
static
void
wacom_remove
(
struct
hid_device
*
hdev
)
{
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
struct
wacom_data
*
wdata
=
hid_get_drvdata
(
hdev
);
#endif
hid_hw_stop
(
hdev
);
#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
power_supply_unregister
(
&
wdata
->
battery
);
power_supply_unregister
(
&
wdata
->
ac
);
#endif
kfree
(
hid_get_drvdata
(
hdev
));
}
static
const
struct
hid_device_id
wacom_devices
[]
=
{
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH
)
},
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_WACOM
,
USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH
)
},
{
}
};
MODULE_DEVICE_TABLE
(
hid
,
wacom_devices
);
...
...
drivers/hid/hid-zydacron.c
0 → 100644
View file @
7426ef52
/*
* HID driver for zydacron remote control
*
* Copyright (c) 2010 Don Prince <dhprince.devel@yahoo.co.uk>
*/
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*/
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
#include "hid-ids.h"
struct
zc_device
{
struct
input_dev
*
input_ep81
;
unsigned
short
last_key
[
4
];
};
/*
* Zydacron remote control has an invalid HID report descriptor,
* that needs fixing before we can parse it.
*/
static
void
zc_report_fixup
(
struct
hid_device
*
hdev
,
__u8
*
rdesc
,
unsigned
int
rsize
)
{
if
(
rsize
>=
253
&&
rdesc
[
0x96
]
==
0xbc
&&
rdesc
[
0x97
]
==
0xff
&&
rdesc
[
0xca
]
==
0xbc
&&
rdesc
[
0xcb
]
==
0xff
&&
rdesc
[
0xe1
]
==
0xbc
&&
rdesc
[
0xe2
]
==
0xff
)
{
dev_info
(
&
hdev
->
dev
,
"fixing up zydacron remote control report "
"descriptor
\n
"
);
rdesc
[
0x96
]
=
rdesc
[
0xca
]
=
rdesc
[
0xe1
]
=
0x0c
;
rdesc
[
0x97
]
=
rdesc
[
0xcb
]
=
rdesc
[
0xe2
]
=
0x00
;
}
}
#define zc_map_key_clear(c) \
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
static
int
zc_input_mapping
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
int
i
;
struct
zc_device
*
zc
=
hid_get_drvdata
(
hdev
);
zc
->
input_ep81
=
hi
->
input
;
if
((
usage
->
hid
&
HID_USAGE_PAGE
)
!=
HID_UP_CONSUMER
)
return
0
;
dbg_hid
(
"zynacron input mapping event [0x%x]
\n
"
,
usage
->
hid
&
HID_USAGE
);
switch
(
usage
->
hid
&
HID_USAGE
)
{
/* report 2 */
case
0x10
:
zc_map_key_clear
(
KEY_MODE
);
break
;
case
0x30
:
zc_map_key_clear
(
KEY_SCREEN
);
break
;
case
0x70
:
zc_map_key_clear
(
KEY_INFO
);
break
;
/* report 3 */
case
0x04
:
zc_map_key_clear
(
KEY_RADIO
);
break
;
/* report 4 */
case
0x0d
:
zc_map_key_clear
(
KEY_PVR
);
break
;
case
0x25
:
zc_map_key_clear
(
KEY_TV
);
break
;
case
0x47
:
zc_map_key_clear
(
KEY_AUDIO
);
break
;
case
0x49
:
zc_map_key_clear
(
KEY_AUX
);
break
;
case
0x4a
:
zc_map_key_clear
(
KEY_VIDEO
);
break
;
case
0x48
:
zc_map_key_clear
(
KEY_DVD
);
break
;
case
0x24
:
zc_map_key_clear
(
KEY_MENU
);
break
;
case
0x32
:
zc_map_key_clear
(
KEY_TEXT
);
break
;
default:
return
0
;
}
for
(
i
=
0
;
i
<
4
;
i
++
)
zc
->
last_key
[
i
]
=
0
;
return
1
;
}
static
int
zc_raw_event
(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
,
u8
*
data
,
int
size
)
{
struct
zc_device
*
zc
=
hid_get_drvdata
(
hdev
);
int
ret
=
0
;
unsigned
key
;
unsigned
short
index
;
if
(
report
->
id
==
data
[
0
])
{
/* break keys */
for
(
index
=
0
;
index
<
4
;
index
++
)
{
key
=
zc
->
last_key
[
index
];
if
(
key
)
{
input_event
(
zc
->
input_ep81
,
EV_KEY
,
key
,
0
);
zc
->
last_key
[
index
]
=
0
;
}
}
key
=
0
;
switch
(
report
->
id
)
{
case
0x02
:
case
0x03
:
switch
(
data
[
1
])
{
case
0x10
:
key
=
KEY_MODE
;
index
=
0
;
break
;
case
0x30
:
key
=
KEY_SCREEN
;
index
=
1
;
break
;
case
0x70
:
key
=
KEY_INFO
;
index
=
2
;
break
;
case
0x04
:
key
=
KEY_RADIO
;
index
=
3
;
break
;
}
if
(
key
)
{
input_event
(
zc
->
input_ep81
,
EV_KEY
,
key
,
1
);
zc
->
last_key
[
index
]
=
key
;
}
ret
=
1
;
break
;
}
}
return
ret
;
}
static
int
zc_probe
(
struct
hid_device
*
hdev
,
const
struct
hid_device_id
*
id
)
{
int
ret
;
struct
zc_device
*
zc
;
zc
=
kzalloc
(
sizeof
(
*
zc
),
GFP_KERNEL
);
if
(
zc
==
NULL
)
{
dev_err
(
&
hdev
->
dev
,
"zydacron: can't alloc descriptor
\n
"
);
return
-
ENOMEM
;
}
hid_set_drvdata
(
hdev
,
zc
);
ret
=
hid_parse
(
hdev
);
if
(
ret
)
{
dev_err
(
&
hdev
->
dev
,
"zydacron: parse failed
\n
"
);
goto
err_free
;
}
ret
=
hid_hw_start
(
hdev
,
HID_CONNECT_DEFAULT
);
if
(
ret
)
{
dev_err
(
&
hdev
->
dev
,
"zydacron: hw start failed
\n
"
);
goto
err_free
;
}
return
0
;
err_free:
kfree
(
zc
);
return
ret
;
}
static
void
zc_remove
(
struct
hid_device
*
hdev
)
{
struct
zc_device
*
zc
=
hid_get_drvdata
(
hdev
);
hid_hw_stop
(
hdev
);
if
(
NULL
!=
zc
)
kfree
(
zc
);
}
static
const
struct
hid_device_id
zc_devices
[]
=
{
{
HID_USB_DEVICE
(
USB_VENDOR_ID_ZYDACRON
,
USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL
)
},
{
}
};
MODULE_DEVICE_TABLE
(
hid
,
zc_devices
);
static
struct
hid_driver
zc_driver
=
{
.
name
=
"zydacron"
,
.
id_table
=
zc_devices
,
.
report_fixup
=
zc_report_fixup
,
.
input_mapping
=
zc_input_mapping
,
.
raw_event
=
zc_raw_event
,
.
probe
=
zc_probe
,
.
remove
=
zc_remove
,
};
static
int
__init
zc_init
(
void
)
{
return
hid_register_driver
(
&
zc_driver
);
}
static
void
__exit
zc_exit
(
void
)
{
hid_unregister_driver
(
&
zc_driver
);
}
module_init
(
zc_init
);
module_exit
(
zc_exit
);
MODULE_LICENSE
(
"GPL"
);
drivers/hid/hidraw.c
View file @
7426ef52
...
...
@@ -311,7 +311,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
-
EFAULT
:
len
;
break
;
}
}
}
ret
=
-
ENOTTY
;
}
...
...
drivers/hid/usbhid/hid-core.c
View file @
7426ef52
...
...
@@ -807,16 +807,36 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
struct
usb_host_interface
*
interface
=
intf
->
cur_altsetting
;
int
ret
;
ret
=
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
HID_REQ_SET_REPORT
,
USB_DIR_OUT
|
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
((
report_type
+
1
)
<<
8
)
|
*
buf
,
interface
->
desc
.
bInterfaceNumber
,
buf
+
1
,
count
-
1
,
USB_CTRL_SET_TIMEOUT
);
/* count also the report id */
if
(
ret
>
0
)
ret
++
;
if
(
usbhid
->
urbout
)
{
int
actual_length
;
int
skipped_report_id
=
0
;
if
(
buf
[
0
]
==
0x0
)
{
/* Don't send the Report ID */
buf
++
;
count
--
;
skipped_report_id
=
1
;
}
ret
=
usb_interrupt_msg
(
dev
,
usbhid
->
urbout
->
pipe
,
buf
,
count
,
&
actual_length
,
USB_CTRL_SET_TIMEOUT
);
/* return the number of bytes transferred */
if
(
ret
==
0
)
{
ret
=
actual_length
;
/* count also the report id */
if
(
skipped_report_id
)
ret
++
;
}
}
else
{
ret
=
usb_control_msg
(
dev
,
usb_sndctrlpipe
(
dev
,
0
),
HID_REQ_SET_REPORT
,
USB_DIR_OUT
|
USB_TYPE_CLASS
|
USB_RECIP_INTERFACE
,
((
report_type
+
1
)
<<
8
)
|
*
buf
,
interface
->
desc
.
bInterfaceNumber
,
buf
+
1
,
count
-
1
,
USB_CTRL_SET_TIMEOUT
);
/* count also the report id */
if
(
ret
>
0
)
ret
++
;
}
return
ret
;
}
...
...
@@ -1019,12 +1039,15 @@ static int usbhid_start(struct hid_device *hid)
/* Some keyboards don't work until their LEDs have been set.
* Since BIOSes do set the LEDs, it must be safe for any device
* that supports the keyboard boot protocol.
* In addition, enable remote wakeup by default for all keyboard
* devices supporting the boot protocol.
*/
if
(
interface
->
desc
.
bInterfaceSubClass
==
USB_INTERFACE_SUBCLASS_BOOT
&&
interface
->
desc
.
bInterfaceProtocol
==
USB_INTERFACE_PROTOCOL_KEYBOARD
)
USB_INTERFACE_PROTOCOL_KEYBOARD
)
{
usbhid_set_leds
(
hid
);
device_set_wakeup_enable
(
&
dev
->
dev
,
1
);
}
return
0
;
fail:
...
...
@@ -1133,6 +1156,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
hid
->
vendor
=
le16_to_cpu
(
dev
->
descriptor
.
idVendor
);
hid
->
product
=
le16_to_cpu
(
dev
->
descriptor
.
idProduct
);
hid
->
name
[
0
]
=
0
;
hid
->
quirks
=
usbhid_lookup_quirk
(
hid
->
vendor
,
hid
->
product
);
if
(
intf
->
cur_altsetting
->
desc
.
bInterfaceProtocol
==
USB_INTERFACE_PROTOCOL_MOUSE
)
hid
->
type
=
HID_TYPE_USBMOUSE
;
...
...
drivers/hid/usbhid/hid-quirks.c
View file @
7426ef52
...
...
@@ -33,6 +33,7 @@ static const struct hid_blacklist {
{
USB_VENDOR_ID_AASHIMA
,
USB_DEVICE_ID_AASHIMA_PREDATOR
,
HID_QUIRK_BADPAD
},
{
USB_VENDOR_ID_ALPS
,
USB_DEVICE_ID_IBM_GAMEPAD
,
HID_QUIRK_BADPAD
},
{
USB_VENDOR_ID_CHIC
,
USB_DEVICE_ID_CHIC_GAMEPAD
,
HID_QUIRK_BADPAD
},
{
USB_VENDOR_ID_EGALAX
,
USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER
,
HID_QUIRK_MULTI_INPUT
},
{
USB_VENDOR_ID_HAPP
,
USB_DEVICE_ID_UGCI_DRIVING
,
HID_QUIRK_BADPAD
|
HID_QUIRK_MULTI_INPUT
},
{
USB_VENDOR_ID_HAPP
,
USB_DEVICE_ID_UGCI_FLYING
,
HID_QUIRK_BADPAD
|
HID_QUIRK_MULTI_INPUT
},
{
USB_VENDOR_ID_HAPP
,
USB_DEVICE_ID_UGCI_FIGHTING
,
HID_QUIRK_BADPAD
|
HID_QUIRK_MULTI_INPUT
},
...
...
drivers/hid/usbhid/usbkbd.c
View file @
7426ef52
...
...
@@ -313,6 +313,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
goto
fail2
;
usb_set_intfdata
(
iface
,
kbd
);
device_set_wakeup_enable
(
&
dev
->
dev
,
1
);
return
0
;
fail2:
...
...
include/linux/hid.h
View file @
7426ef52
...
...
@@ -308,11 +308,13 @@ struct hid_item {
#define HID_QUIRK_NOTOUCH 0x00000002
#define HID_QUIRK_IGNORE 0x00000004
#define HID_QUIRK_NOGET 0x00000008
#define HID_QUIRK_HIDDEV_FORCE 0x00000010
#define HID_QUIRK_BADPAD 0x00000020
#define HID_QUIRK_MULTI_INPUT 0x00000040
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
#define HID_QUIRK_NO_INIT_REPORTS 0x20000000
#define HID_QUIRK_NO_IGNORE 0x40000000
/*
* This is the global environment of the parser. This information is
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment