Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
72c16d9a
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
72c16d9a
编写于
4月 30, 2013
作者:
J
Jiri Kosina
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-3.10/mt-hybrid-finger-pen' into for-linus
Conflicts: drivers/hid/hid-multitouch.c
上级
4f5a8104
fb4d8d98
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
255 addition
and
60 deletion
+255
-60
drivers/hid/hid-input.c
drivers/hid/hid-input.c
+77
-0
drivers/hid/hid-multitouch.c
drivers/hid/hid-multitouch.c
+177
-60
include/linux/hid.h
include/linux/hid.h
+1
-0
未找到文件。
drivers/hid/hid-input.c
浏览文件 @
72c16d9a
...
...
@@ -1198,6 +1198,67 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
return
hidinput
;
}
static
bool
hidinput_has_been_populated
(
struct
hid_input
*
hidinput
)
{
int
i
;
unsigned
long
r
=
0
;
for
(
i
=
0
;
i
<
BITS_TO_LONGS
(
EV_CNT
);
i
++
)
r
|=
hidinput
->
input
->
evbit
[
i
];
for
(
i
=
0
;
i
<
BITS_TO_LONGS
(
KEY_CNT
);
i
++
)
r
|=
hidinput
->
input
->
keybit
[
i
];
for
(
i
=
0
;
i
<
BITS_TO_LONGS
(
REL_CNT
);
i
++
)
r
|=
hidinput
->
input
->
relbit
[
i
];
for
(
i
=
0
;
i
<
BITS_TO_LONGS
(
ABS_CNT
);
i
++
)
r
|=
hidinput
->
input
->
absbit
[
i
];
for
(
i
=
0
;
i
<
BITS_TO_LONGS
(
MSC_CNT
);
i
++
)
r
|=
hidinput
->
input
->
mscbit
[
i
];
for
(
i
=
0
;
i
<
BITS_TO_LONGS
(
LED_CNT
);
i
++
)
r
|=
hidinput
->
input
->
ledbit
[
i
];
for
(
i
=
0
;
i
<
BITS_TO_LONGS
(
SND_CNT
);
i
++
)
r
|=
hidinput
->
input
->
sndbit
[
i
];
for
(
i
=
0
;
i
<
BITS_TO_LONGS
(
FF_CNT
);
i
++
)
r
|=
hidinput
->
input
->
ffbit
[
i
];
for
(
i
=
0
;
i
<
BITS_TO_LONGS
(
SW_CNT
);
i
++
)
r
|=
hidinput
->
input
->
swbit
[
i
];
return
!!
r
;
}
static
void
hidinput_cleanup_hidinput
(
struct
hid_device
*
hid
,
struct
hid_input
*
hidinput
)
{
struct
hid_report
*
report
;
int
i
,
k
;
list_del
(
&
hidinput
->
list
);
input_free_device
(
hidinput
->
input
);
for
(
k
=
HID_INPUT_REPORT
;
k
<=
HID_OUTPUT_REPORT
;
k
++
)
{
if
(
k
==
HID_OUTPUT_REPORT
&&
hid
->
quirks
&
HID_QUIRK_SKIP_OUTPUT_REPORTS
)
continue
;
list_for_each_entry
(
report
,
&
hid
->
report_enum
[
k
].
report_list
,
list
)
{
for
(
i
=
0
;
i
<
report
->
maxfield
;
i
++
)
if
(
report
->
field
[
i
]
->
hidinput
==
hidinput
)
report
->
field
[
i
]
->
hidinput
=
NULL
;
}
}
kfree
(
hidinput
);
}
/*
* Register the input device; print a message.
* Configure the input layer interface
...
...
@@ -1249,6 +1310,10 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
hidinput_configure_usage
(
hidinput
,
report
->
field
[
i
],
report
->
field
[
i
]
->
usage
+
j
);
if
((
hid
->
quirks
&
HID_QUIRK_NO_EMPTY_INPUT
)
&&
!
hidinput_has_been_populated
(
hidinput
))
continue
;
if
(
hid
->
quirks
&
HID_QUIRK_MULTI_INPUT
)
{
/* This will leave hidinput NULL, so that it
* allocates another one if we have more inputs on
...
...
@@ -1265,6 +1330,18 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
}
}
if
(
hidinput
&&
(
hid
->
quirks
&
HID_QUIRK_NO_EMPTY_INPUT
)
&&
!
hidinput_has_been_populated
(
hidinput
))
{
/* no need to register an input device not populated */
hidinput_cleanup_hidinput
(
hid
,
hidinput
);
hidinput
=
NULL
;
}
if
(
list_empty
(
&
hid
->
inputs
))
{
hid_err
(
hid
,
"No inputs registered, leaving
\n
"
);
goto
out_unwind
;
}
if
(
hidinput
)
{
if
(
drv
->
input_configured
)
drv
->
input_configured
(
hid
,
hidinput
);
...
...
drivers/hid/hid-multitouch.c
浏览文件 @
72c16d9a
...
...
@@ -44,6 +44,7 @@
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/input/mt.h>
#include <linux/string.h>
MODULE_AUTHOR
(
"Stephane Chatty <chatty@enac.fr>"
);
...
...
@@ -97,9 +98,9 @@ struct mt_device {
multitouch fields */
int
cc_index
;
/* contact count field index in the report */
int
cc_value_index
;
/* contact count value index in the field */
unsigned
last_field_index
;
/* last field index of the report */
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 */
__s8
inputmode
;
/* InputMode HID feature, -1 if non-existent */
__s8
inputmode_index
;
/* InputMode HID feature index in the report */
__s8
maxcontact_report_id
;
/* Maximum Contact Number HID feature,
...
...
@@ -115,6 +116,9 @@ struct mt_device {
unsigned
mt_flags
;
/* flags to pass to input-mt */
};
static
void
mt_post_parse_default_settings
(
struct
mt_device
*
td
);
static
void
mt_post_parse
(
struct
mt_device
*
td
);
/* classes of device behavior */
#define MT_CLS_DEFAULT 0x0001
...
...
@@ -257,6 +261,14 @@ static struct mt_class mt_classes[] = {
{
}
};
static
void
mt_free_input_name
(
struct
hid_input
*
hi
)
{
struct
hid_device
*
hdev
=
hi
->
report
->
device
;
if
(
hi
->
input
->
name
!=
hdev
->
name
)
kfree
(
hi
->
input
->
name
);
}
static
ssize_t
mt_show_quirks
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
...
...
@@ -365,7 +377,53 @@ static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
f
->
usages
[
f
->
length
++
]
=
usage
->
hid
;
}
static
int
mt_input_mapping
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
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
)
{
char
*
name
=
kzalloc
(
strlen
(
hi
->
input
->
name
)
+
5
,
GFP_KERNEL
);
if
(
name
)
{
sprintf
(
name
,
"%s Pen"
,
hi
->
input
->
name
);
mt_free_input_name
(
hi
);
hi
->
input
->
name
=
name
;
}
/* 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
)
{
...
...
@@ -374,13 +432,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
int
code
;
struct
hid_usage
*
prev_usage
=
NULL
;
/* 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
)
td
->
mt_flags
|=
INPUT_MT_DIRECT
;
else
if
(
field
->
application
!=
HID_DG_TOUCHPAD
)
return
0
;
/*
* Model touchscreens providing buttons as touchpads.
...
...
@@ -389,12 +442,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
(
usage
->
hid
&
HID_USAGE_PAGE
)
==
HID_UP_BUTTON
)
td
->
mt_flags
|=
INPUT_MT_POINTER
;
/* eGalax devices provide a Digitizer.Stylus input which overrides
* the correct Digitizers.Finger X/Y ranges.
* Let's just ignore this input. */
if
(
field
->
physical
==
HID_DG_STYLUS
)
return
-
1
;
if
(
usage
->
usage_index
)
prev_usage
=
&
field
->
usage
[
usage
->
usage_index
-
1
];
...
...
@@ -416,7 +463,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
}
mt_store_field
(
usage
,
td
,
hi
);
td
->
last_field_index
=
field
->
index
;
return
1
;
case
HID_GD_Y
:
if
(
prev_usage
&&
(
prev_usage
->
hid
==
usage
->
hid
))
{
...
...
@@ -432,7 +478,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
}
mt_store_field
(
usage
,
td
,
hi
);
td
->
last_field_index
=
field
->
index
;
return
1
;
}
return
0
;
...
...
@@ -447,21 +492,17 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
ABS_MT_DISTANCE
,
0
,
1
,
0
,
0
);
}
mt_store_field
(
usage
,
td
,
hi
);
td
->
last_field_index
=
field
->
index
;
return
1
;
case
HID_DG_CONFIDENCE
:
mt_store_field
(
usage
,
td
,
hi
);
td
->
last_field_index
=
field
->
index
;
return
1
;
case
HID_DG_TIPSWITCH
:
hid_map_usage
(
hi
,
usage
,
bit
,
max
,
EV_KEY
,
BTN_TOUCH
);
input_set_capability
(
hi
->
input
,
EV_KEY
,
BTN_TOUCH
);
mt_store_field
(
usage
,
td
,
hi
);
td
->
last_field_index
=
field
->
index
;
return
1
;
case
HID_DG_CONTACTID
:
mt_store_field
(
usage
,
td
,
hi
);
td
->
last_field_index
=
field
->
index
;
td
->
touches_by_report
++
;
td
->
mt_report_id
=
field
->
report
->
id
;
return
1
;
...
...
@@ -472,7 +513,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
set_abs
(
hi
->
input
,
ABS_MT_TOUCH_MAJOR
,
field
,
cls
->
sn_width
);
mt_store_field
(
usage
,
td
,
hi
);
td
->
last_field_index
=
field
->
index
;
return
1
;
case
HID_DG_HEIGHT
:
hid_map_usage
(
hi
,
usage
,
bit
,
max
,
...
...
@@ -484,7 +524,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
ABS_MT_ORIENTATION
,
0
,
1
,
0
,
0
);
}
mt_store_field
(
usage
,
td
,
hi
);
td
->
last_field_index
=
field
->
index
;
return
1
;
case
HID_DG_TIPPRESSURE
:
hid_map_usage
(
hi
,
usage
,
bit
,
max
,
...
...
@@ -492,17 +531,14 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
set_abs
(
hi
->
input
,
ABS_MT_PRESSURE
,
field
,
cls
->
sn_pressure
);
mt_store_field
(
usage
,
td
,
hi
);
td
->
last_field_index
=
field
->
index
;
return
1
;
case
HID_DG_CONTACTCOUNT
:
td
->
cc_index
=
field
->
index
;
td
->
cc_value_index
=
usage
->
usage_index
;
td
->
last_field_index
=
field
->
index
;
return
1
;
case
HID_DG_CONTACTMAX
:
/* we don't set td->last_slot_field as contactcount and
* contact max are global to the report */
td
->
last_field_index
=
field
->
index
;
return
-
1
;
case
HID_DG_TOUCH
:
/* Legacy devices use TIPSWITCH and not TOUCH.
...
...
@@ -526,7 +562,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
return
0
;
}
static
int
mt_input_mapped
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
static
int
mt_
touch_
input_mapped
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
...
...
@@ -617,7 +653,7 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input)
td
->
num_received
=
0
;
}
static
int
mt_event
(
struct
hid_device
*
hid
,
struct
hid_field
*
field
,
static
int
mt_
touch_
event
(
struct
hid_device
*
hid
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
__s32
value
)
{
/* we will handle the hidinput part later, now remains hiddev */
...
...
@@ -691,29 +727,19 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
if
(
usage
->
usage_index
+
1
==
field
->
report_count
)
{
/* we only take into account the last report. */
if
(
usage
->
hid
==
td
->
last_slot_field
)
mt_complete_slot
(
td
,
input
);
if
(
field
->
index
==
td
->
last_field_index
&&
td
->
num_received
>=
td
->
num_expected
)
mt_sync_frame
(
td
,
field
->
hidinput
->
input
);
mt_complete_slot
(
td
,
field
->
hidinput
->
input
);
}
}
}
static
void
mt_report
(
struct
hid_device
*
hid
,
struct
hid_report
*
report
)
static
void
mt_
touch_
report
(
struct
hid_device
*
hid
,
struct
hid_report
*
report
)
{
struct
mt_device
*
td
=
hid_get_drvdata
(
hid
);
struct
hid_field
*
field
;
unsigned
count
;
int
r
,
n
;
if
(
report
->
id
!=
td
->
mt_report_id
)
return
;
if
(
!
(
hid
->
claimed
&
HID_CLAIMED_INPUT
))
return
;
/*
* Includes multi-packet support where subsequent
* packets are sent with zero contactcount.
...
...
@@ -736,6 +762,91 @@ static void mt_report(struct hid_device *hid, struct hid_report *report)
mt_process_mt_event
(
hid
,
field
,
&
field
->
usage
[
n
],
field
->
value
[
n
]);
}
if
(
td
->
num_received
>=
td
->
num_expected
)
mt_sync_frame
(
td
,
report
->
field
[
0
]
->
hidinput
->
input
);
}
static
void
mt_touch_input_configured
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
)
{
struct
mt_device
*
td
=
hid_get_drvdata
(
hdev
);
struct
mt_class
*
cls
=
&
td
->
mtclass
;
struct
input_dev
*
input
=
hi
->
input
;
if
(
!
td
->
maxcontacts
)
td
->
maxcontacts
=
MT_DEFAULT_MAXCONTACT
;
mt_post_parse
(
td
);
if
(
td
->
serial_maybe
)
mt_post_parse_default_settings
(
td
);
if
(
cls
->
is_indirect
)
td
->
mt_flags
|=
INPUT_MT_POINTER
;
if
(
cls
->
quirks
&
MT_QUIRK_NOT_SEEN_MEANS_UP
)
td
->
mt_flags
|=
INPUT_MT_DROP_UNUSED
;
input_mt_init_slots
(
input
,
td
->
maxcontacts
,
td
->
mt_flags
);
td
->
mt_flags
=
0
;
}
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
&&
field
->
application
!=
HID_DG_PEN
&&
field
->
application
!=
HID_DG_TOUCHPAD
)
return
-
1
;
if
(
field
->
physical
==
HID_DG_STYLUS
)
return
mt_pen_input_mapping
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
);
return
mt_touch_input_mapping
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
);
}
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
)
{
if
(
field
->
physical
==
HID_DG_STYLUS
)
return
mt_pen_input_mapped
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
);
return
mt_touch_input_mapped
(
hdev
,
hi
,
field
,
usage
,
bit
,
max
);
}
static
int
mt_event
(
struct
hid_device
*
hid
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
__s32
value
)
{
struct
mt_device
*
td
=
hid_get_drvdata
(
hid
);
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
;
}
static
void
mt_report
(
struct
hid_device
*
hid
,
struct
hid_report
*
report
)
{
struct
mt_device
*
td
=
hid_get_drvdata
(
hid
);
if
(
!
(
hid
->
claimed
&
HID_CLAIMED_INPUT
))
return
;
if
(
report
->
id
==
td
->
mt_report_id
)
mt_touch_report
(
hid
,
report
);
if
(
report
->
id
==
td
->
pen_report_id
)
mt_pen_report
(
hid
,
report
);
}
static
void
mt_set_input_mode
(
struct
hid_device
*
hdev
)
...
...
@@ -812,32 +923,18 @@ static void mt_post_parse(struct mt_device *td)
}
static
void
mt_input_configured
(
struct
hid_device
*
hdev
,
struct
hid_input
*
hi
)
{
struct
mt_device
*
td
=
hid_get_drvdata
(
hdev
);
struct
mt_class
*
cls
=
&
td
->
mtclass
;
struct
input_dev
*
input
=
hi
->
input
;
char
*
name
=
kstrdup
(
hdev
->
name
,
GFP_KERNEL
);
/* Only initialize slots for MT input devices */
if
(
!
test_bit
(
ABS_MT_POSITION_X
,
input
->
absbit
))
return
;
if
(
name
)
hi
->
input
->
name
=
name
;
if
(
!
td
->
maxcontacts
)
td
->
maxcontacts
=
MT_DEFAULT_MAXCONTACT
;
if
(
hi
->
report
->
id
==
td
->
mt_report_id
)
mt_touch_input_configured
(
hdev
,
hi
)
;
mt_post_parse
(
td
);
if
(
td
->
serial_maybe
)
mt_post_parse_default_settings
(
td
);
if
(
cls
->
is_indirect
)
td
->
mt_flags
|=
INPUT_MT_POINTER
;
if
(
cls
->
quirks
&
MT_QUIRK_NOT_SEEN_MEANS_UP
)
td
->
mt_flags
|=
INPUT_MT_DROP_UNUSED
;
input_mt_init_slots
(
input
,
td
->
maxcontacts
,
td
->
mt_flags
);
td
->
mt_flags
=
0
;
if
(
hi
->
report
->
id
==
td
->
pen_report_id
)
mt_pen_input_configured
(
hdev
,
hi
);
}
static
int
mt_probe
(
struct
hid_device
*
hdev
,
const
struct
hid_device_id
*
id
)
...
...
@@ -845,6 +942,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
int
ret
,
i
;
struct
mt_device
*
td
;
struct
mt_class
*
mtclass
=
mt_classes
;
/* MT_CLS_DEFAULT */
struct
hid_input
*
hi
;
for
(
i
=
0
;
mt_classes
[
i
].
name
;
i
++
)
{
if
(
id
->
driver_data
==
mt_classes
[
i
].
name
)
{
...
...
@@ -858,6 +956,14 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
*/
hdev
->
quirks
|=
HID_QUIRK_NO_INPUT_SYNC
;
/*
* This allows the driver to handle different input sensors
* that emits events through different reports on the same HID
* device.
*/
hdev
->
quirks
|=
HID_QUIRK_MULTI_INPUT
;
hdev
->
quirks
|=
HID_QUIRK_NO_EMPTY_INPUT
;
td
=
kzalloc
(
sizeof
(
struct
mt_device
),
GFP_KERNEL
);
if
(
!
td
)
{
dev_err
(
&
hdev
->
dev
,
"cannot allocate multitouch data
\n
"
);
...
...
@@ -867,6 +973,8 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
td
->
inputmode
=
-
1
;
td
->
maxcontact_report_id
=
-
1
;
td
->
cc_index
=
-
1
;
td
->
mt_report_id
=
-
1
;
td
->
pen_report_id
=
-
1
;
hid_set_drvdata
(
hdev
,
td
);
td
->
fields
=
kzalloc
(
sizeof
(
struct
mt_fields
),
GFP_KERNEL
);
...
...
@@ -885,7 +993,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
ret
=
hid_hw_start
(
hdev
,
HID_CONNECT_DEFAULT
);
if
(
ret
)
goto
fail
;
goto
hid_
fail
;
ret
=
sysfs_create_group
(
&
hdev
->
dev
.
kobj
,
&
mt_attribute_group
);
...
...
@@ -897,6 +1005,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
return
0
;
hid_fail:
list_for_each_entry
(
hi
,
&
hdev
->
inputs
,
list
)
mt_free_input_name
(
hi
);
fail:
kfree
(
td
->
fields
);
kfree
(
td
);
...
...
@@ -926,8 +1037,14 @@ static int mt_resume(struct hid_device *hdev)
static
void
mt_remove
(
struct
hid_device
*
hdev
)
{
struct
mt_device
*
td
=
hid_get_drvdata
(
hdev
);
struct
hid_input
*
hi
;
sysfs_remove_group
(
&
hdev
->
dev
.
kobj
,
&
mt_attribute_group
);
hid_hw_stop
(
hdev
);
list_for_each_entry
(
hi
,
&
hdev
->
inputs
,
list
)
mt_free_input_name
(
hi
);
kfree
(
td
);
hid_set_drvdata
(
hdev
,
NULL
);
}
...
...
include/linux/hid.h
浏览文件 @
72c16d9a
...
...
@@ -282,6 +282,7 @@ struct hid_item {
#define HID_QUIRK_BADPAD 0x00000020
#define HID_QUIRK_MULTI_INPUT 0x00000040
#define HID_QUIRK_HIDINPUT_FORCE 0x00000080
#define HID_QUIRK_NO_EMPTY_INPUT 0x00000100
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
#define HID_QUIRK_NO_INIT_REPORTS 0x20000000
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录