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
fa1054a2
Commit
fa1054a2
authored
Apr 01, 2014
by
Jiri Kosina
Browse files
Options
Browse Files
Download
Plain Diff
Merge branches 'for-3.15/multitouch', 'for-3.15/sony' and 'for-3.15/uhid' into for-linus
parents
6cf8c85f
9abebedb
b95dd3ca
4522643a
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
233 additions
and
178 deletions
+233
-178
Documentation/hid/uhid.txt
Documentation/hid/uhid.txt
+11
-0
drivers/hid/hid-ids.h
drivers/hid/hid-ids.h
+3
-0
drivers/hid/hid-multitouch.c
drivers/hid/hid-multitouch.c
+104
-177
drivers/hid/hid-sony.c
drivers/hid/hid-sony.c
+11
-1
drivers/hid/uhid.c
drivers/hid/uhid.c
+78
-0
include/linux/hid.h
include/linux/hid.h
+3
-0
include/uapi/linux/uhid.h
include/uapi/linux/uhid.h
+23
-0
No files found.
Documentation/hid/uhid.txt
View file @
fa1054a2
...
...
@@ -93,6 +93,11 @@ the request was handled successfully.
event to the kernel. The payload is of type struct uhid_create_req and
contains information about your device. You can start I/O now.
UHID_CREATE2:
Same as UHID_CREATE, but the HID report descriptor data (rd_data) is an array
inside struct uhid_create2_req, instead of a pointer to a separate array.
Enables use from languages that don't support pointers, e.g. Python.
UHID_DESTROY:
This destroys the internal HID device. No further I/O will be accepted. There
may still be pending messages that you can receive with read() but no further
...
...
@@ -105,6 +110,12 @@ the request was handled successfully.
contains a data-payload. This is the raw data that you read from your device.
The kernel will parse the HID reports and react on it.
UHID_INPUT2:
Same as UHID_INPUT, but the data array is the last field of uhid_input2_req.
Enables userspace to write only the required bytes to kernel (ev.type +
ev.u.input2.size + the part of the data array that matters), instead of
the entire struct uhid_input2_req.
UHID_FEATURE_ANSWER:
If you receive a UHID_FEATURE request you must answer with this request. You
must copy the "id" field from the request into the answer. Set the "err" field
...
...
drivers/hid/hid-ids.h
View file @
fa1054a2
...
...
@@ -67,6 +67,9 @@
#define USB_VENDOR_ID_ALPS 0x0433
#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101
#define USB_VENDOR_ID_ANTON 0x1130
#define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101
#define USB_VENDOR_ID_APPLE 0x05ac
#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
...
...
drivers/hid/hid-multitouch.c
View file @
fa1054a2
...
...
@@ -68,6 +68,9 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_HOVERING (1 << 11)
#define MT_QUIRK_CONTACT_CNT_ACCURATE (1 << 12)
#define MT_INPUTMODE_TOUCHSCREEN 0x02
#define MT_INPUTMODE_TOUCHPAD 0x03
struct
mt_slot
{
__s32
x
,
y
,
cx
,
cy
,
p
,
w
,
h
;
__s32
contactid
;
/* the device ContactID assigned to this slot */
...
...
@@ -84,6 +87,7 @@ struct mt_class {
__s32
sn_pressure
;
/* Signal/noise ratio for pressure events */
__u8
maxcontacts
;
bool
is_indirect
;
/* true for touchpads */
bool
export_all_inputs
;
/* do not ignore mouse, keyboards, etc... */
};
struct
mt_fields
{
...
...
@@ -100,11 +104,11 @@ struct mt_device {
int
cc_value_index
;
/* contact count value index in the field */
unsigned
last_slot_field
;
/* the last field of a slot */
unsigned
mt_report_id
;
/* the report ID of the multitouch device */
unsigned
pen_report_id
;
/* the report ID of the pen device */
__s16
inputmode
;
/* InputMode HID feature, -1 if non-existent */
__s16
inputmode_index
;
/* InputMode HID feature index in the report */
__s16
maxcontact_report_id
;
/* Maximum Contact Number HID feature,
-1 if non-existent */
__u8
inputmode_value
;
/* InputMode HID feature value */
__u8
num_received
;
/* how many contacts we received */
__u8
num_expected
;
/* expected last contact index */
__u8
maxcontacts
;
...
...
@@ -128,16 +132,17 @@ static void mt_post_parse(struct mt_device *td);
#define MT_CLS_CONFIDENCE_MINUS_ONE 0x0005
#define MT_CLS_DUAL_INRANGE_CONTACTID 0x0006
#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0007
#define MT_CLS_DUAL_NSMU_CONTACTID 0x0008
/* reserved 0x0008 */
#define MT_CLS_INRANGE_CONTACTNUMBER 0x0009
#define MT_CLS_NSMU 0x000a
#define MT_CLS_DUAL_CONTACT_NUMBER 0x0010
#define MT_CLS_DUAL_CONTACT_ID 0x0011
/* reserved 0x0010 */
/* reserved 0x0011 */
#define MT_CLS_WIN_8 0x0012
#define MT_CLS_EXPORT_ALL_INPUTS 0x0013
/* vendor specific classes */
#define MT_CLS_3M 0x0101
#define MT_CLS_CYPRESS 0x0102
/* reserved 0x0102 */
#define MT_CLS_EGALAX 0x0103
#define MT_CLS_EGALAX_SERIAL 0x0104
#define MT_CLS_TOPSEED 0x0105
...
...
@@ -189,28 +194,18 @@ static struct mt_class mt_classes[] = {
.
quirks
=
MT_QUIRK_VALID_IS_INRANGE
|
MT_QUIRK_SLOT_IS_CONTACTNUMBER
,
.
maxcontacts
=
2
},
{
.
name
=
MT_CLS_DUAL_NSMU_CONTACTID
,
.
quirks
=
MT_QUIRK_NOT_SEEN_MEANS_UP
|
MT_QUIRK_SLOT_IS_CONTACTID
,
.
maxcontacts
=
2
},
{
.
name
=
MT_CLS_INRANGE_CONTACTNUMBER
,
.
quirks
=
MT_QUIRK_VALID_IS_INRANGE
|
MT_QUIRK_SLOT_IS_CONTACTNUMBER
},
{
.
name
=
MT_CLS_DUAL_CONTACT_NUMBER
,
.
quirks
=
MT_QUIRK_ALWAYS_VALID
|
MT_QUIRK_CONTACT_CNT_ACCURATE
|
MT_QUIRK_SLOT_IS_CONTACTNUMBER
,
.
maxcontacts
=
2
},
{
.
name
=
MT_CLS_DUAL_CONTACT_ID
,
.
quirks
=
MT_QUIRK_ALWAYS_VALID
|
MT_QUIRK_CONTACT_CNT_ACCURATE
|
MT_QUIRK_SLOT_IS_CONTACTID
,
.
maxcontacts
=
2
},
{
.
name
=
MT_CLS_WIN_8
,
.
quirks
=
MT_QUIRK_ALWAYS_VALID
|
MT_QUIRK_IGNORE_DUPLICATES
|
MT_QUIRK_HOVERING
|
MT_QUIRK_CONTACT_CNT_ACCURATE
},
{
.
name
=
MT_CLS_EXPORT_ALL_INPUTS
,
.
quirks
=
MT_QUIRK_ALWAYS_VALID
|
MT_QUIRK_CONTACT_CNT_ACCURATE
,
.
export_all_inputs
=
true
},
/*
* vendor specific classes
...
...
@@ -223,10 +218,6 @@ static struct mt_class mt_classes[] = {
.
sn_height
=
128
,
.
maxcontacts
=
60
,
},
{
.
name
=
MT_CLS_CYPRESS
,
.
quirks
=
MT_QUIRK_NOT_SEEN_MEANS_UP
|
MT_QUIRK_CYPRESS
,
.
maxcontacts
=
10
},
{
.
name
=
MT_CLS_EGALAX
,
.
quirks
=
MT_QUIRK_SLOT_IS_CONTACTID
|
MT_QUIRK_VALID_IS_INRANGE
,
...
...
@@ -360,45 +351,6 @@ static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
f
->
usages
[
f
->
length
++
]
=
usage
->
hid
;
}
static
int
mt_pen_input_mapping
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
struct
mt_device
*
td
=
hid_get_drvdata
(
hdev
);
td
->
pen_report_id
=
field
->
report
->
id
;
return
0
;
}
static
int
mt_pen_input_mapped
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
return
0
;
}
static
int
mt_pen_event
(
struct
hid_device
*
hid
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
__s32
value
)
{
/* let hid-input handle it */
return
0
;
}
static
void
mt_pen_report
(
struct
hid_device
*
hid
,
struct
hid_report
*
report
)
{
struct
hid_field
*
field
=
report
->
field
[
0
];
input_sync
(
field
->
hidinput
->
input
);
}
static
void
mt_pen_input_configured
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
)
{
/* force BTN_STYLUS to allow tablet matching in udev */
__set_bit
(
BTN_STYLUS
,
hi
->
input
->
keybit
);
}
static
int
mt_touch_input_mapping
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
...
...
@@ -415,8 +367,10 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
* Model touchscreens providing buttons as touchpads.
*/
if
(
field
->
application
==
HID_DG_TOUCHPAD
||
(
usage
->
hid
&
HID_USAGE_PAGE
)
==
HID_UP_BUTTON
)
(
usage
->
hid
&
HID_USAGE_PAGE
)
==
HID_UP_BUTTON
)
{
td
->
mt_flags
|=
INPUT_MT_POINTER
;
td
->
inputmode_value
=
MT_INPUTMODE_TOUCHPAD
;
}
if
(
usage
->
usage_index
)
prev_usage
=
&
field
->
usage
[
usage
->
usage_index
-
1
];
...
...
@@ -776,28 +730,52 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
/* Only map fields from TouchScreen or TouchPad collections.
* We need to ignore fields that belong to other collections
* such as Mouse that might have the same GenericDesktop usages. */
if
(
field
->
application
!=
HID_DG_TOUCHSCREEN
&&
struct
mt_device
*
td
=
hid_get_drvdata
(
hdev
);
/*
* If mtclass.export_all_inputs is not set, only map fields from
* TouchScreen or TouchPad collections. We need to ignore fields
* that belong to other collections such as Mouse that might have
* the same GenericDesktop usages.
*/
if
(
!
td
->
mtclass
.
export_all_inputs
&&
field
->
application
!=
HID_DG_TOUCHSCREEN
&&
field
->
application
!=
HID_DG_PEN
&&
field
->
application
!=
HID_DG_TOUCHPAD
)
return
-
1
;
/*
* some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
* for the stylus.
*/
if
(
field
->
physical
==
HID_DG_STYLUS
)
return
mt_pen_input_mapping
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
)
;
return
0
;
return
mt_touch_input_mapping
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
);
if
(
field
->
application
==
HID_DG_TOUCHSCREEN
||
field
->
application
==
HID_DG_TOUCHPAD
)
return
mt_touch_input_mapping
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
);
/* let hid-core decide for the others */
return
0
;
}
static
int
mt_input_mapped
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
/*
* some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
* for the stylus.
*/
if
(
field
->
physical
==
HID_DG_STYLUS
)
return
mt_pen_input_mapped
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
)
;
return
0
;
return
mt_touch_input_mapped
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
);
if
(
field
->
application
==
HID_DG_TOUCHSCREEN
||
field
->
application
==
HID_DG_TOUCHPAD
)
return
mt_touch_input_mapped
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
);
/* let hid-core decide for the others */
return
0
;
}
static
int
mt_event
(
struct
hid_device
*
hid
,
struct
hid_field
*
field
,
...
...
@@ -808,25 +786,22 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
if
(
field
->
report
->
id
==
td
->
mt_report_id
)
return
mt_touch_event
(
hid
,
field
,
usage
,
value
);
if
(
field
->
report
->
id
==
td
->
pen_report_id
)
return
mt_pen_event
(
hid
,
field
,
usage
,
value
);
/* ignore other reports */
return
1
;
return
0
;
}
static
void
mt_report
(
struct
hid_device
*
hid
,
struct
hid_report
*
report
)
{
struct
mt_device
*
td
=
hid_get_drvdata
(
hid
);
struct
hid_field
*
field
=
report
->
field
[
0
];
if
(
!
(
hid
->
claimed
&
HID_CLAIMED_INPUT
))
return
;
if
(
report
->
id
==
td
->
mt_report_id
)
mt_touch_report
(
hid
,
report
);
return
mt_touch_report
(
hid
,
report
);
if
(
report
->
id
==
td
->
pen_report_id
)
mt_pen_report
(
hid
,
repor
t
);
if
(
field
&&
field
->
hidinput
&&
field
->
hidinput
->
input
)
input_sync
(
field
->
hidinput
->
inpu
t
);
}
static
void
mt_set_input_mode
(
struct
hid_device
*
hdev
)
...
...
@@ -841,7 +816,7 @@ static void mt_set_input_mode(struct hid_device *hdev)
re
=
&
(
hdev
->
report_enum
[
HID_FEATURE_REPORT
]);
r
=
re
->
report_id_hash
[
td
->
inputmode
];
if
(
r
)
{
r
->
field
[
0
]
->
value
[
td
->
inputmode_index
]
=
0x02
;
r
->
field
[
0
]
->
value
[
td
->
inputmode_index
]
=
td
->
inputmode_value
;
hid_hw_request
(
hdev
,
r
,
HID_REQ_SET_REPORT
);
}
}
...
...
@@ -907,13 +882,49 @@ static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
struct
mt_device
*
td
=
hid_get_drvdata
(
hdev
);
char
*
name
;
const
char
*
suffix
=
NULL
;
struct
hid_field
*
field
=
hi
->
report
->
field
[
0
];
if
(
hi
->
report
->
id
==
td
->
mt_report_id
)
mt_touch_input_configured
(
hdev
,
hi
);
/*
* some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
* for the stylus. Check this first, and then rely on the application
* field.
*/
if
(
hi
->
report
->
field
[
0
]
->
physical
==
HID_DG_STYLUS
)
{
suffix
=
"Pen"
;
mt_pen_input_configured
(
hdev
,
hi
);
/* force BTN_STYLUS to allow tablet matching in udev */
__set_bit
(
BTN_STYLUS
,
hi
->
input
->
keybit
);
}
else
{
switch
(
field
->
application
)
{
case
HID_GD_KEYBOARD
:
suffix
=
"Keyboard"
;
break
;
case
HID_GD_KEYPAD
:
suffix
=
"Keypad"
;
break
;
case
HID_GD_MOUSE
:
suffix
=
"Mouse"
;
break
;
case
HID_DG_STYLUS
:
suffix
=
"Pen"
;
/* force BTN_STYLUS to allow tablet matching in udev */
__set_bit
(
BTN_STYLUS
,
hi
->
input
->
keybit
);
break
;
case
HID_DG_TOUCHSCREEN
:
/* we do not set suffix = "Touchscreen" */
break
;
case
HID_GD_SYSTEM_CONTROL
:
suffix
=
"System Control"
;
break
;
case
HID_CP_CONSUMER_CONTROL
:
suffix
=
"Consumer Control"
;
break
;
default:
suffix
=
"UNKNOWN"
;
break
;
}
}
if
(
suffix
)
{
...
...
@@ -973,9 +984,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
td
->
mtclass
=
*
mtclass
;
td
->
inputmode
=
-
1
;
td
->
maxcontact_report_id
=
-
1
;
td
->
inputmode_value
=
MT_INPUTMODE_TOUCHSCREEN
;
td
->
cc_index
=
-
1
;
td
->
mt_report_id
=
-
1
;
td
->
pen_report_id
=
-
1
;
hid_set_drvdata
(
hdev
,
td
);
td
->
fields
=
devm_kzalloc
(
&
hdev
->
dev
,
sizeof
(
struct
mt_fields
),
...
...
@@ -1034,6 +1045,12 @@ static void mt_remove(struct hid_device *hdev)
hid_hw_stop
(
hdev
);
}
/*
* This list contains only:
* - VID/PID of products not working with the default multitouch handling
* - 2 generic rules.
* So there is no point in adding here any device with MT_CLS_DEFAULT.
*/
static
const
struct
hid_device_id
mt_devices
[]
=
{
/* 3M panels */
...
...
@@ -1047,15 +1064,12 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE
(
USB_VENDOR_ID_3M
,
USB_DEVICE_ID_3M3266
)
},
/* A
ctionStar panel
s */
{
.
driver_data
=
MT_CLS_
NSMU
,
MT_USB_DEVICE
(
USB_VENDOR_ID_A
CTIONSTAR
,
USB_DEVICE_ID_A
CTIONSTAR_1011
)
},
/* A
nton device
s */
{
.
driver_data
=
MT_CLS_
EXPORT_ALL_INPUTS
,
MT_USB_DEVICE
(
USB_VENDOR_ID_A
NTON
,
USB_DEVICE_ID_A
NTON_TOUCH_PAD
)
},
/* Atmel panels */
{
.
driver_data
=
MT_CLS_SERIAL
,
MT_USB_DEVICE
(
USB_VENDOR_ID_ATMEL
,
USB_DEVICE_ID_ATMEL_MULTITOUCH
)
},
{
.
driver_data
=
MT_CLS_SERIAL
,
MT_USB_DEVICE
(
USB_VENDOR_ID_ATMEL
,
USB_DEVICE_ID_ATMEL_MXT_DIGITIZER
)
},
...
...
@@ -1064,16 +1078,11 @@ static const struct hid_device_id mt_devices[] = {
{
.
driver_data
=
MT_CLS_NSMU
,
MT_USB_DEVICE
(
USB_VENDOR_ID_BAANTO
,
USB_DEVICE_ID_BAANTO_MT_190W2
)
},
/* Cando panels */
{
.
driver_data
=
MT_CLS_DUAL_INRANGE_CONTACTNUMBER
,
MT_USB_DEVICE
(
USB_VENDOR_ID_CANDO
,
USB_DEVICE_ID_CANDO_MULTI_TOUCH
)
},
{
.
driver_data
=
MT_CLS_DUAL_CONTACT_NUMBER
,
MT_USB_DEVICE
(
USB_VENDOR_ID_CANDO
,
USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1
)
},
{
.
driver_data
=
MT_CLS_DUAL_INRANGE_CONTACTNUMBER
,
MT_USB_DEVICE
(
USB_VENDOR_ID_CANDO
,
USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6
)
},
{
.
driver_data
=
MT_CLS_DUAL_INRANGE_CONTACTNUMBER
,
MT_USB_DEVICE
(
USB_VENDOR_ID_CANDO
,
USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6
)
},
...
...
@@ -1088,16 +1097,6 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE
(
USB_VENDOR_ID_CVTOUCH
,
USB_DEVICE_ID_CVTOUCH_SCREEN
)
},
/* Cypress panel */
{
.
driver_data
=
MT_CLS_CYPRESS
,
HID_USB_DEVICE
(
USB_VENDOR_ID_CYPRESS
,
USB_DEVICE_ID_CYPRESS_TRUETOUCH
)
},
/* Data Modul easyMaxTouch */
{
.
driver_data
=
MT_CLS_DEFAULT
,
MT_USB_DEVICE
(
USB_VENDOR_ID_DATA_MODUL
,
USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH
)
},
/* eGalax devices (resistive) */
{
.
driver_data
=
MT_CLS_EGALAX
,
MT_USB_DEVICE
(
USB_VENDOR_ID_DWAV
,
...
...
@@ -1156,11 +1155,6 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE
(
USB_VENDOR_ID_DWAV
,
USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001
)
},
/* Elo TouchSystems IntelliTouch Plus panel */
{
.
driver_data
=
MT_CLS_DUAL_CONTACT_ID
,
MT_USB_DEVICE
(
USB_VENDOR_ID_ELO
,
USB_DEVICE_ID_ELO_TS2515
)
},
/* Flatfrog Panels */
{
.
driver_data
=
MT_CLS_FLATFROG
,
MT_USB_DEVICE
(
USB_VENDOR_ID_FLATFROG
,
...
...
@@ -1209,37 +1203,11 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE
(
USB_VENDOR_ID_HANVON_ALT
,
USB_DEVICE_ID_HANVON_ALT_MULTITOUCH
)
},
/* Ideacom panel */
{
.
driver_data
=
MT_CLS_SERIAL
,
MT_USB_DEVICE
(
USB_VENDOR_ID_IDEACOM
,
USB_DEVICE_ID_IDEACOM_IDC6650
)
},
{
.
driver_data
=
MT_CLS_SERIAL
,
MT_USB_DEVICE
(
USB_VENDOR_ID_IDEACOM
,
USB_DEVICE_ID_IDEACOM_IDC6651
)
},
/* Ilitek dual touch panel */
{
.
driver_data
=
MT_CLS_NSMU
,
MT_USB_DEVICE
(
USB_VENDOR_ID_ILITEK
,
USB_DEVICE_ID_ILITEK_MULTITOUCH
)
},
/* IRTOUCH panels */
{
.
driver_data
=
MT_CLS_DUAL_INRANGE_CONTACTID
,
MT_USB_DEVICE
(
USB_VENDOR_ID_IRTOUCHSYSTEMS
,
USB_DEVICE_ID_IRTOUCH_INFRARED_USB
)
},
/* LG Display panels */
{
.
driver_data
=
MT_CLS_DEFAULT
,
MT_USB_DEVICE
(
USB_VENDOR_ID_LG
,
USB_DEVICE_ID_LG_MULTITOUCH
)
},
/* Lumio panels */
{
.
driver_data
=
MT_CLS_CONFIDENCE_MINUS_ONE
,
MT_USB_DEVICE
(
USB_VENDOR_ID_LUMIO
,
USB_DEVICE_ID_CRYSTALTOUCH
)
},
{
.
driver_data
=
MT_CLS_CONFIDENCE_MINUS_ONE
,
MT_USB_DEVICE
(
USB_VENDOR_ID_LUMIO
,
USB_DEVICE_ID_CRYSTALTOUCH_DUAL
)
},
/* MosArt panels */
{
.
driver_data
=
MT_CLS_CONFIDENCE_MINUS_ONE
,
MT_USB_DEVICE
(
USB_VENDOR_ID_ASUS
,
...
...
@@ -1251,11 +1219,6 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE
(
USB_VENDOR_ID_TURBOX
,
USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART
)
},
/* Nexio panels */
{
.
driver_data
=
MT_CLS_DEFAULT
,
MT_USB_DEVICE
(
USB_VENDOR_ID_NEXIO
,
USB_DEVICE_ID_NEXIO_MULTITOUCH_420
)},
/* Panasonic panels */
{
.
driver_data
=
MT_CLS_PANASONIC
,
MT_USB_DEVICE
(
USB_VENDOR_ID_PANASONIC
,
...
...
@@ -1269,11 +1232,6 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE
(
USB_VENDOR_ID_NOVATEK
,
USB_DEVICE_ID_NOVATEK_PCT
)
},
/* PenMount panels */
{
.
driver_data
=
MT_CLS_CONFIDENCE
,
MT_USB_DEVICE
(
USB_VENDOR_ID_PENMOUNT
,
USB_DEVICE_ID_PENMOUNT_PCI
)
},
/* PixArt optical touch screen */
{
.
driver_data
=
MT_CLS_INRANGE_CONTACTNUMBER
,
MT_USB_DEVICE
(
USB_VENDOR_ID_PIXART
,
...
...
@@ -1286,45 +1244,19 @@ static const struct hid_device_id mt_devices[] = {
USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2
)
},
/* PixCir-based panels */
{
.
driver_data
=
MT_CLS_DUAL_INRANGE_CONTACTID
,
MT_USB_DEVICE
(
USB_VENDOR_ID_HANVON
,
USB_DEVICE_ID_HANVON_MULTITOUCH
)
},
{
.
driver_data
=
MT_CLS_DUAL_INRANGE_CONTACTID
,
MT_USB_DEVICE
(
USB_VENDOR_ID_CANDO
,
USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH
)
},
/* Quanta-based panels */
{
.
driver_data
=
MT_CLS_CONFIDENCE_CONTACT_ID
,
MT_USB_DEVICE
(
USB_VENDOR_ID_QUANTA
,
USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH
)
},
{
.
driver_data
=
MT_CLS_CONFIDENCE_CONTACT_ID
,
MT_USB_DEVICE
(
USB_VENDOR_ID_QUANTA
,
USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001
)
},
{
.
driver_data
=
MT_CLS_CONFIDENCE_CONTACT_ID
,
MT_USB_DEVICE
(
USB_VENDOR_ID_QUANTA
,
USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008
)
},
/* SiS panels */
{
.
driver_data
=
MT_CLS_DEFAULT
,
HID_USB_DEVICE
(
USB_VENDOR_ID_SIS_TOUCH
,
USB_DEVICE_ID_SIS9200_TOUCH
)
},
{
.
driver_data
=
MT_CLS_DEFAULT
,
HID_USB_DEVICE
(
USB_VENDOR_ID_SIS_TOUCH
,
USB_DEVICE_ID_SIS817_TOUCH
)
},
{
.
driver_data
=
MT_CLS_DEFAULT
,
HID_USB_DEVICE
(
USB_VENDOR_ID_SIS_TOUCH
,
USB_DEVICE_ID_SIS1030_TOUCH
)
},
/* Stantum panels */
{
.
driver_data
=
MT_CLS_CONFIDENCE
,
MT_USB_DEVICE
(
USB_VENDOR_ID_STANTUM
,
USB_DEVICE_ID_MTP
)},
{
.
driver_data
=
MT_CLS_CONFIDENCE
,
MT_USB_DEVICE
(
USB_VENDOR_ID_STANTUM_STM
,
USB_DEVICE_ID_MTP_STM
)},
{
.
driver_data
=
MT_CLS_DEFAULT
,
MT_USB_DEVICE
(
USB_VENDOR_ID_STANTUM_SITRONIX
,
USB_DEVICE_ID_MTP_SITRONIX
)},
/* TopSeed panels */
{
.
driver_data
=
MT_CLS_TOPSEED
,
...
...
@@ -1383,11 +1315,6 @@ static const struct hid_device_id mt_devices[] = {
MT_USB_DEVICE
(
USB_VENDOR_ID_XIROKU
,
USB_DEVICE_ID_XIROKU_CSR2
)
},
/* Zytronic panels */
{
.
driver_data
=
MT_CLS_SERIAL
,
MT_USB_DEVICE
(
USB_VENDOR_ID_ZYTRONIC
,
USB_DEVICE_ID_ZYTRONIC_ZXY100
)
},
/* Generic MT device */
{
HID_DEVICE
(
HID_BUS_ANY
,
HID_GROUP_MULTITOUCH
,
HID_ANY_ID
,
HID_ANY_ID
)
},
...
...
drivers/hid/hid-sony.c
View file @
fa1054a2
...
...
@@ -863,7 +863,7 @@ static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size)
battery_capacity
=
sixaxis_battery_capacity
[
index
];
battery_charging
=
0
;
}
cable_state
=
!
(
(
rd
[
31
]
>>
4
)
&
0x01
);
cable_state
=
!
(
rd
[
31
]
&
0x04
);
spin_lock_irqsave
(
&
sc
->
lock
,
flags
);
sc
->
cable_state
=
cable_state
;
...
...
@@ -1632,11 +1632,21 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
sc
->
worker_initialized
=
1
;
INIT_WORK
(
&
sc
->
state_worker
,
sixaxis_state_worker
);
}
else
if
(
sc
->
quirks
&
SIXAXIS_CONTROLLER_BT
)
{
/*
* The Sixaxis wants output reports sent on the ctrl endpoint
* when connected via Bluetooth.
*/
hdev
->
quirks
|=
HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP
;
ret
=
sixaxis_set_operational_bt
(
hdev
);
sc
->
worker_initialized
=
1
;
INIT_WORK
(
&
sc
->
state_worker
,
sixaxis_state_worker
);
}
else
if
(
sc
->
quirks
&
DUALSHOCK4_CONTROLLER
)
{
if
(
sc
->
quirks
&
DUALSHOCK4_CONTROLLER_BT
)
{
/*
* The DualShock 4 wants output reports sent on the ctrl
* endpoint when connected via Bluetooth.
*/
hdev
->
quirks
|=
HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP
;
ret
=
dualshock4_set_operational_bt
(
hdev
);
if
(
ret
<
0
)
{
hid_err
(
hdev
,
"failed to set the Dualshock 4 operational mode
\n
"
);
...
...
drivers/hid/uhid.c
View file @
fa1054a2
...
...
@@ -428,6 +428,67 @@ static int uhid_dev_create(struct uhid_device *uhid,
return
ret
;
}
static
int
uhid_dev_create2
(
struct
uhid_device
*
uhid
,
const
struct
uhid_event
*
ev
)
{
struct
hid_device
*
hid
;
int
ret
;
if
(
uhid
->
running
)
return
-
EALREADY
;
uhid
->
rd_size
=
ev
->
u
.
create2
.
rd_size
;
if
(
uhid
->
rd_size
<=
0
||
uhid
->
rd_size
>
HID_MAX_DESCRIPTOR_SIZE
)
return
-
EINVAL
;
uhid
->
rd_data
=
kmalloc
(
uhid
->
rd_size
,
GFP_KERNEL
);
if
(
!
uhid
->
rd_data
)
return
-
ENOMEM
;
memcpy
(
uhid
->
rd_data
,
ev
->
u
.
create2
.
rd_data
,
uhid
->
rd_size
);
hid
=
hid_allocate_device
();
if
(
IS_ERR
(
hid
))
{
ret
=
PTR_ERR
(
hid
);
goto
err_free
;
}
strncpy
(
hid
->
name
,
ev
->
u
.
create2
.
name
,
127
);
hid
->
name
[
127
]
=
0
;
strncpy
(
hid
->
phys
,
ev
->
u
.
create2
.
phys
,
63
);
hid
->
phys
[
63
]
=
0
;
strncpy
(
hid
->
uniq
,
ev
->
u
.
create2
.
uniq
,
63
);
hid
->
uniq
[
63
]
=
0
;
hid
->
ll_driver
=
&
uhid_hid_driver
;
hid
->
bus
=
ev
->
u
.
create2
.
bus
;
hid
->
vendor
=
ev
->
u
.
create2
.
vendor
;
hid
->
product
=
ev
->
u
.
create2
.
product
;
hid
->
version
=
ev
->
u
.
create2
.
version
;
hid
->
country
=
ev
->
u
.
create2
.
country
;
hid
->
driver_data
=
uhid
;
hid
->
dev
.
parent
=
uhid_misc
.
this_device
;
uhid
->
hid
=
hid
;
uhid
->
running
=
true
;
ret
=
hid_add_device
(
hid
);
if
(
ret
)
{
hid_err
(
hid
,
"Cannot register HID device
\n
"
);
goto
err_hid
;
}
return
0
;
err_hid:
hid_destroy_device
(
hid
);
uhid
->
hid
=
NULL
;
uhid
->
running
=
false
;
err_free:
kfree
(
uhid
->
rd_data
);
return
ret
;
}
static
int
uhid_dev_destroy
(
struct
uhid_device
*
uhid
)
{
if
(
!
uhid
->
running
)
...
...
@@ -456,6 +517,17 @@ static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev)
return
0
;
}
static
int
uhid_dev_input2
(
struct
uhid_device
*
uhid
,
struct
uhid_event
*
ev
)
{
if
(
!
uhid
->
running
)
return
-
EINVAL
;
hid_input_report
(
uhid
->
hid
,
HID_INPUT_REPORT
,
ev
->
u
.
input2
.
data
,
min_t
(
size_t
,
ev
->
u
.
input2
.
size
,
UHID_DATA_MAX
),
0
);
return
0
;
}
static
int
uhid_dev_feature_answer
(
struct
uhid_device
*
uhid
,
struct
uhid_event
*
ev
)
{
...
...
@@ -592,12 +664,18 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
case
UHID_CREATE
:
ret
=
uhid_dev_create
(
uhid
,
&
uhid
->
input_buf
);
break
;
case
UHID_CREATE2
:
ret
=
uhid_dev_create2
(
uhid
,
&
uhid
->
input_buf
);
break
;
case
UHID_DESTROY
:
ret
=
uhid_dev_destroy
(
uhid
);
break
;
case
UHID_INPUT
:
ret
=
uhid_dev_input
(
uhid
,
&
uhid
->
input_buf
);
break
;
case
UHID_INPUT2
:
ret
=
uhid_dev_input2
(
uhid
,
&
uhid
->
input_buf
);
break
;
case
UHID_FEATURE_ANSWER
:
ret
=
uhid_dev_feature_answer
(
uhid
,
&
uhid
->
input_buf
);
break
;
...
...
include/linux/hid.h
View file @
fa1054a2
...
...
@@ -201,6 +201,7 @@ struct hid_item {
#define HID_GD_VBRZ 0x00010045
#define HID_GD_VNO 0x00010046
#define HID_GD_FEATURE 0x00010047
#define HID_GD_SYSTEM_CONTROL 0x00010080
#define HID_GD_UP 0x00010090
#define HID_GD_DOWN 0x00010091
#define HID_GD_RIGHT 0x00010092
...
...
@@ -208,6 +209,8 @@ struct hid_item {
#define HID_DC_BATTERYSTRENGTH 0x00060020
#define HID_CP_CONSUMER_CONTROL 0x000c0001
#define HID_DG_DIGITIZER 0x000d0001
#define HID_DG_PEN 0x000d0002
#define HID_DG_LIGHTPEN 0x000d0003
...
...
include/uapi/linux/uhid.h
View file @
fa1054a2
...
...
@@ -21,6 +21,7 @@
#include <linux/input.h>
#include <linux/types.h>
#include <linux/hid.h>
enum
uhid_event_type
{
UHID_CREATE
,
...
...
@@ -34,6 +35,8 @@ enum uhid_event_type {
UHID_INPUT
,
UHID_FEATURE
,
UHID_FEATURE_ANSWER
,
UHID_CREATE2
,
UHID_INPUT2
,
};
struct
uhid_create_req
{
...
...
@@ -50,6 +53,19 @@ struct uhid_create_req {
__u32
country
;
}
__attribute__
((
__packed__
));
struct
uhid_create2_req
{
__u8
name
[
128
];
__u8
phys
[
64
];
__u8
uniq
[
64
];
__u16
rd_size
;
__u16
bus
;
__u32
vendor
;
__u32
product
;
__u32
version
;
__u32
country
;
__u8
rd_data
[
HID_MAX_DESCRIPTOR_SIZE
];
}
__attribute__
((
__packed__
));
#define UHID_DATA_MAX 4096
enum
uhid_report_type
{
...
...
@@ -63,6 +79,11 @@ struct uhid_input_req {
__u16
size
;
}
__attribute__
((
__packed__
));
struct
uhid_input2_req
{
__u16
size
;
__u8
data
[
UHID_DATA_MAX
];
}
__attribute__
((
__packed__
));
struct
uhid_output_req
{
__u8
data
[
UHID_DATA_MAX
];
__u16
size
;
...
...
@@ -100,6 +121,8 @@ struct uhid_event {
struct
uhid_output_ev_req
output_ev
;
struct
uhid_feature_req
feature
;
struct
uhid_feature_answer_req
feature_answer
;
struct
uhid_create2_req
create2
;
struct
uhid_input2_req
input2
;
}
u
;
}
__attribute__
((
__packed__
));
...
...
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