Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
9931753b
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看板
提交
9931753b
编写于
4月 05, 2018
作者:
J
Jiri Kosina
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-4.17/wacom' into for-linus
Pull support for 3rd generation Intuos BT device
上级
e2d39e0f
7ba8fc09
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
179 addition
and
48 deletion
+179
-48
drivers/hid/wacom_wac.c
drivers/hid/wacom_wac.c
+176
-47
drivers/hid/wacom_wac.h
drivers/hid/wacom_wac.h
+3
-1
未找到文件。
drivers/hid/wacom_wac.c
浏览文件 @
9931753b
...
...
@@ -1202,15 +1202,24 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
static
void
wacom_intuos_pro2_bt_pen
(
struct
wacom_wac
*
wacom
)
{
const
int
pen_frame_len
=
14
;
const
int
pen_frames
=
7
;
int
pen_frame_len
,
pen_frames
;
struct
input_dev
*
pen_input
=
wacom
->
pen_input
;
unsigned
char
*
data
=
wacom
->
data
;
int
i
;
wacom
->
serial
[
0
]
=
get_unaligned_le64
(
&
data
[
99
]);
wacom
->
id
[
0
]
=
get_unaligned_le16
(
&
data
[
107
]);
if
(
wacom
->
features
.
type
==
INTUOSP2_BT
)
{
wacom
->
serial
[
0
]
=
get_unaligned_le64
(
&
data
[
99
]);
wacom
->
id
[
0
]
=
get_unaligned_le16
(
&
data
[
107
]);
pen_frame_len
=
14
;
pen_frames
=
7
;
}
else
{
wacom
->
serial
[
0
]
=
get_unaligned_le64
(
&
data
[
33
]);
wacom
->
id
[
0
]
=
get_unaligned_le16
(
&
data
[
41
]);
pen_frame_len
=
8
;
pen_frames
=
4
;
}
if
(
wacom
->
serial
[
0
]
>>
52
==
1
)
{
/* Add back in missing bits of ID for non-USI pens */
wacom
->
id
[
0
]
|=
(
wacom
->
serial
[
0
]
>>
32
)
&
0xFFFFF
;
...
...
@@ -1227,21 +1236,35 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
continue
;
if
(
range
)
{
/* Fix rotation alignment: userspace expects zero at left */
int16_t
rotation
=
(
int16_t
)
get_unaligned_le16
(
&
frame
[
9
]);
rotation
+=
1800
/
4
;
if
(
rotation
>
899
)
rotation
-=
1800
;
input_report_abs
(
pen_input
,
ABS_X
,
get_unaligned_le16
(
&
frame
[
1
]));
input_report_abs
(
pen_input
,
ABS_Y
,
get_unaligned_le16
(
&
frame
[
3
]));
input_report_abs
(
pen_input
,
ABS_TILT_X
,
(
char
)
frame
[
7
]);
input_report_abs
(
pen_input
,
ABS_TILT_Y
,
(
char
)
frame
[
8
]);
input_report_abs
(
pen_input
,
ABS_Z
,
rotation
);
input_report_abs
(
pen_input
,
ABS_WHEEL
,
get_unaligned_le16
(
&
frame
[
11
]));
if
(
wacom
->
features
.
type
==
INTUOSP2_BT
)
{
/* Fix rotation alignment: userspace expects zero at left */
int16_t
rotation
=
(
int16_t
)
get_unaligned_le16
(
&
frame
[
9
]);
rotation
+=
1800
/
4
;
if
(
rotation
>
899
)
rotation
-=
1800
;
input_report_abs
(
pen_input
,
ABS_TILT_X
,
(
char
)
frame
[
7
]);
input_report_abs
(
pen_input
,
ABS_TILT_Y
,
(
char
)
frame
[
8
]);
input_report_abs
(
pen_input
,
ABS_Z
,
rotation
);
input_report_abs
(
pen_input
,
ABS_WHEEL
,
get_unaligned_le16
(
&
frame
[
11
]));
}
}
input_report_abs
(
pen_input
,
ABS_PRESSURE
,
get_unaligned_le16
(
&
frame
[
5
]));
input_report_abs
(
pen_input
,
ABS_DISTANCE
,
range
?
frame
[
13
]
:
wacom
->
features
.
distance_max
);
if
(
wacom
->
features
.
type
==
INTUOSP2_BT
)
{
input_report_abs
(
pen_input
,
ABS_DISTANCE
,
range
?
frame
[
13
]
:
wacom
->
features
.
distance_max
);
}
else
{
input_report_abs
(
pen_input
,
ABS_DISTANCE
,
range
?
frame
[
7
]
:
wacom
->
features
.
distance_max
);
}
input_report_key
(
pen_input
,
BTN_TOUCH
,
frame
[
0
]
&
0x01
);
input_report_key
(
pen_input
,
BTN_STYLUS
,
frame
[
0
]
&
0x02
);
...
...
@@ -1357,20 +1380,52 @@ static void wacom_intuos_pro2_bt_battery(struct wacom_wac *wacom)
battery_status
,
chg
,
1
,
chg
);
}
static
void
wacom_intuos_gen3_bt_pad
(
struct
wacom_wac
*
wacom
)
{
struct
input_dev
*
pad_input
=
wacom
->
pad_input
;
unsigned
char
*
data
=
wacom
->
data
;
int
buttons
=
data
[
44
];
wacom_report_numbered_buttons
(
pad_input
,
4
,
buttons
);
input_report_key
(
pad_input
,
wacom
->
tool
[
1
],
buttons
?
1
:
0
);
input_report_abs
(
pad_input
,
ABS_MISC
,
buttons
?
PAD_DEVICE_ID
:
0
);
input_event
(
pad_input
,
EV_MSC
,
MSC_SERIAL
,
0xffffffff
);
input_sync
(
pad_input
);
}
static
void
wacom_intuos_gen3_bt_battery
(
struct
wacom_wac
*
wacom
)
{
unsigned
char
*
data
=
wacom
->
data
;
bool
chg
=
data
[
45
]
&
0x80
;
int
battery_status
=
data
[
45
]
&
0x7F
;
wacom_notify_battery
(
wacom
,
WACOM_POWER_SUPPLY_STATUS_AUTO
,
battery_status
,
chg
,
1
,
chg
);
}
static
int
wacom_intuos_pro2_bt_irq
(
struct
wacom_wac
*
wacom
,
size_t
len
)
{
unsigned
char
*
data
=
wacom
->
data
;
if
(
data
[
0
]
!=
0x80
)
{
if
(
data
[
0
]
!=
0x80
&&
data
[
0
]
!=
0x81
)
{
dev_dbg
(
wacom
->
pen_input
->
dev
.
parent
,
"%s: received unknown report #%d
\n
"
,
__func__
,
data
[
0
]);
return
0
;
}
wacom_intuos_pro2_bt_pen
(
wacom
);
wacom_intuos_pro2_bt_touch
(
wacom
);
wacom_intuos_pro2_bt_pad
(
wacom
);
wacom_intuos_pro2_bt_battery
(
wacom
);
if
(
wacom
->
features
.
type
==
INTUOSP2_BT
)
{
wacom_intuos_pro2_bt_touch
(
wacom
);
wacom_intuos_pro2_bt_pad
(
wacom
);
wacom_intuos_pro2_bt_battery
(
wacom
);
}
else
{
wacom_intuos_gen3_bt_pad
(
wacom
);
wacom_intuos_gen3_bt_battery
(
wacom
);
}
return
0
;
}
...
...
@@ -1660,7 +1715,8 @@ int wacom_equivalent_usage(int usage)
usage
==
WACOM_HID_WD_TOUCHSTRIP
||
usage
==
WACOM_HID_WD_TOUCHSTRIP2
||
usage
==
WACOM_HID_WD_TOUCHRING
||
usage
==
WACOM_HID_WD_TOUCHRINGSTATUS
)
{
usage
==
WACOM_HID_WD_TOUCHRINGSTATUS
||
usage
==
WACOM_HID_WD_REPORT_VALID
)
{
return
usage
;
}
...
...
@@ -2017,7 +2073,7 @@ static void wacom_wac_pad_pre_report(struct hid_device *hdev,
}
static
void
wacom_wac_pad_report
(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
)
struct
hid_report
*
report
,
struct
hid_field
*
field
)
{
struct
wacom
*
wacom
=
hid_get_drvdata
(
hdev
);
struct
wacom_wac
*
wacom_wac
=
&
wacom
->
wacom_wac
;
...
...
@@ -2025,7 +2081,7 @@ static void wacom_wac_pad_report(struct hid_device *hdev,
bool
active
=
wacom_wac
->
hid_data
.
inrange_state
!=
0
;
/* report prox for expresskey events */
if
((
wacom_equivalent_usage
(
report
->
field
[
0
]
->
physical
)
==
HID_DG_TABLETFUNCTIONKEY
)
&&
if
((
wacom_equivalent_usage
(
field
->
physical
)
==
HID_DG_TABLETFUNCTIONKEY
)
&&
wacom_wac
->
hid_data
.
pad_input_event_flag
)
{
input_event
(
input
,
EV_ABS
,
ABS_MISC
,
active
?
PAD_DEVICE_ID
:
0
);
input_sync
(
input
);
...
...
@@ -2144,6 +2200,9 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
struct
input_dev
*
input
=
wacom_wac
->
pen_input
;
unsigned
equivalent_usage
=
wacom_equivalent_usage
(
usage
->
hid
);
if
(
wacom_wac
->
is_invalid_bt_frame
)
return
;
switch
(
equivalent_usage
)
{
case
HID_GD_Z
:
/*
...
...
@@ -2240,6 +2299,9 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
features
->
offset_bottom
);
features
->
offset_bottom
=
value
;
return
;
case
WACOM_HID_WD_REPORT_VALID
:
wacom_wac
->
is_invalid_bt_frame
=
!
value
;
return
;
}
/* send pen events only when touch is up or forced out
...
...
@@ -2258,6 +2320,10 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
static
void
wacom_wac_pen_pre_report
(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
)
{
struct
wacom
*
wacom
=
hid_get_drvdata
(
hdev
);
struct
wacom_wac
*
wacom_wac
=
&
wacom
->
wacom_wac
;
wacom_wac
->
is_invalid_bt_frame
=
false
;
return
;
}
...
...
@@ -2270,6 +2336,9 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
bool
range
=
wacom_wac
->
hid_data
.
inrange_state
;
bool
sense
=
wacom_wac
->
hid_data
.
sense_state
;
if
(
wacom_wac
->
is_invalid_bt_frame
)
return
;
if
(
!
wacom_wac
->
tool
[
0
]
&&
range
)
{
/* first in range */
/* Going into range select tool */
if
(
wacom_wac
->
hid_data
.
invert_state
)
...
...
@@ -2572,11 +2641,13 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
wacom_wac_finger_event
(
hdev
,
field
,
usage
,
value
);
}
static
void
wacom_report_events
(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
)
static
void
wacom_report_events
(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
,
int
collection_index
,
int
field_index
)
{
int
r
;
for
(
r
=
0
;
r
<
report
->
maxfield
;
r
++
)
{
for
(
r
=
field_index
;
r
<
report
->
maxfield
;
r
++
)
{
struct
hid_field
*
field
;
unsigned
count
,
n
;
...
...
@@ -2586,30 +2657,23 @@ static void wacom_report_events(struct hid_device *hdev, struct hid_report *repo
if
(
!
(
HID_MAIN_ITEM_VARIABLE
&
field
->
flags
))
continue
;
for
(
n
=
0
;
n
<
count
;
n
++
)
wacom_wac_event
(
hdev
,
field
,
&
field
->
usage
[
n
],
field
->
value
[
n
]);
for
(
n
=
0
;
n
<
count
;
n
++
)
{
if
(
field
->
usage
[
n
].
collection_index
==
collection_index
)
wacom_wac_event
(
hdev
,
field
,
&
field
->
usage
[
n
],
field
->
value
[
n
]);
else
return
;
}
}
}
void
wacom_wac_report
(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
)
static
int
wacom_wac_collection
(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
,
int
collection_index
,
struct
hid_field
*
field
,
int
field_index
)
{
struct
wacom
*
wacom
=
hid_get_drvdata
(
hdev
);
struct
wacom_wac
*
wacom_wac
=
&
wacom
->
wacom_wac
;
struct
hid_field
*
field
=
report
->
field
[
0
];
if
(
wacom_wac
->
features
.
type
!=
HID_GENERIC
)
return
;
wacom_wac_battery_pre_report
(
hdev
,
report
);
if
(
WACOM_PAD_FIELD
(
field
)
&&
wacom
->
wacom_wac
.
pad_input
)
wacom_wac_pad_pre_report
(
hdev
,
report
);
else
if
(
WACOM_PEN_FIELD
(
field
)
&&
wacom
->
wacom_wac
.
pen_input
)
wacom_wac_pen_pre_report
(
hdev
,
report
);
else
if
(
WACOM_FINGER_FIELD
(
field
)
&&
wacom
->
wacom_wac
.
touch_input
)
wacom_wac_finger_pre_report
(
hdev
,
report
);
wacom_report_events
(
hdev
,
report
);
wacom_report_events
(
hdev
,
report
,
collection_index
,
field_index
);
/*
* Non-input reports may be sent prior to the device being
...
...
@@ -2619,16 +2683,63 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
* processing functions.
*/
if
(
report
->
type
!=
HID_INPUT_REPORT
)
return
;
wacom_wac_battery_report
(
hdev
,
report
);
return
-
1
;
if
(
WACOM_PAD_FIELD
(
field
)
&&
wacom
->
wacom_wac
.
pad_input
)
wacom_wac_pad_report
(
hdev
,
report
);
wacom_wac_pad_report
(
hdev
,
report
,
field
);
else
if
(
WACOM_PEN_FIELD
(
field
)
&&
wacom
->
wacom_wac
.
pen_input
)
wacom_wac_pen_report
(
hdev
,
report
);
else
if
(
WACOM_FINGER_FIELD
(
field
)
&&
wacom
->
wacom_wac
.
touch_input
)
wacom_wac_finger_report
(
hdev
,
report
);
return
0
;
}
void
wacom_wac_report
(
struct
hid_device
*
hdev
,
struct
hid_report
*
report
)
{
struct
wacom
*
wacom
=
hid_get_drvdata
(
hdev
);
struct
wacom_wac
*
wacom_wac
=
&
wacom
->
wacom_wac
;
struct
hid_field
*
field
;
bool
pad_in_hid_field
=
false
,
pen_in_hid_field
=
false
,
finger_in_hid_field
=
false
;
int
r
;
int
prev_collection
=
-
1
;
if
(
wacom_wac
->
features
.
type
!=
HID_GENERIC
)
return
;
for
(
r
=
0
;
r
<
report
->
maxfield
;
r
++
)
{
field
=
report
->
field
[
r
];
if
(
WACOM_PAD_FIELD
(
field
))
pad_in_hid_field
=
true
;
if
(
WACOM_PEN_FIELD
(
field
))
pen_in_hid_field
=
true
;
if
(
WACOM_FINGER_FIELD
(
field
))
finger_in_hid_field
=
true
;
}
wacom_wac_battery_pre_report
(
hdev
,
report
);
if
(
pad_in_hid_field
&&
wacom
->
wacom_wac
.
pad_input
)
wacom_wac_pad_pre_report
(
hdev
,
report
);
if
(
pen_in_hid_field
&&
wacom
->
wacom_wac
.
pen_input
)
wacom_wac_pen_pre_report
(
hdev
,
report
);
if
(
finger_in_hid_field
&&
wacom
->
wacom_wac
.
touch_input
)
wacom_wac_finger_pre_report
(
hdev
,
report
);
for
(
r
=
0
;
r
<
report
->
maxfield
;
r
++
)
{
field
=
report
->
field
[
r
];
if
(
field
->
usage
[
0
].
collection_index
!=
prev_collection
)
{
if
(
wacom_wac_collection
(
hdev
,
report
,
field
->
usage
[
0
].
collection_index
,
field
,
r
)
<
0
)
return
;
prev_collection
=
field
->
usage
[
0
].
collection_index
;
}
}
wacom_wac_battery_report
(
hdev
,
report
);
}
static
int
wacom_bpt_touch
(
struct
wacom_wac
*
wacom
)
...
...
@@ -3093,6 +3204,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
break
;
case
INTUOSP2_BT
:
case
INTUOSHT3_BT
:
sync
=
wacom_intuos_pro2_bt_irq
(
wacom_wac
,
len
);
break
;
...
...
@@ -3272,6 +3384,12 @@ void wacom_setup_device_quirks(struct wacom *wacom)
features
->
quirks
|=
WACOM_QUIRK_BATTERY
;
}
if
(
features
->
type
==
INTUOSHT3_BT
)
{
features
->
device_type
|=
WACOM_DEVICETYPE_PEN
|
WACOM_DEVICETYPE_PAD
;
features
->
quirks
|=
WACOM_QUIRK_BATTERY
;
}
switch
(
features
->
type
)
{
case
PL
:
case
DTU
:
...
...
@@ -3466,7 +3584,9 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
case
BAMBOO_PT
:
case
BAMBOO_PEN
:
case
INTUOSHT2
:
if
(
features
->
type
==
INTUOSHT2
)
{
case
INTUOSHT3_BT
:
if
(
features
->
type
==
INTUOSHT2
||
features
->
type
==
INTUOSHT3_BT
)
{
wacom_setup_basic_pro_pen
(
wacom_wac
);
}
else
{
__clear_bit
(
ABS_MISC
,
input_dev
->
absbit
);
...
...
@@ -3887,6 +4007,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
input_set_abs_params
(
input_dev
,
ABS_WHEEL
,
0
,
71
,
0
,
0
);
break
;
case
INTUOSHT3_BT
:
case
HID_GENERIC
:
break
;
...
...
@@ -4415,6 +4536,12 @@ static const struct wacom_features wacom_features_0x360 =
static
const
struct
wacom_features
wacom_features_0x361
=
{
"Wacom Intuos Pro L"
,
62200
,
43200
,
8191
,
63
,
INTUOSP2_BT
,
WACOM_INTUOS3_RES
,
WACOM_INTUOS3_RES
,
9
,
.
touch_max
=
10
};
static
const
struct
wacom_features
wacom_features_0x377
=
{
"Wacom Intuos BT S"
,
15200
,
9500
,
4095
,
63
,
INTUOSHT3_BT
,
WACOM_INTUOS_RES
,
WACOM_INTUOS_RES
,
4
};
static
const
struct
wacom_features
wacom_features_0x379
=
{
"Wacom Intuos BT M"
,
21600
,
13500
,
4095
,
63
,
INTUOSHT3_BT
,
WACOM_INTUOS_RES
,
WACOM_INTUOS_RES
,
4
};
static
const
struct
wacom_features
wacom_features_0x37A
=
{
"Wacom One by Wacom S"
,
15200
,
9500
,
2047
,
63
,
BAMBOO_PEN
,
WACOM_INTUOS_RES
,
WACOM_INTUOS_RES
};
...
...
@@ -4589,6 +4716,8 @@ const struct hid_device_id wacom_ids[] = {
{
USB_DEVICE_WACOM
(
0x343
)
},
{
BT_DEVICE_WACOM
(
0x360
)
},
{
BT_DEVICE_WACOM
(
0x361
)
},
{
BT_DEVICE_WACOM
(
0x377
)
},
{
BT_DEVICE_WACOM
(
0x379
)
},
{
USB_DEVICE_WACOM
(
0x37A
)
},
{
USB_DEVICE_WACOM
(
0x37B
)
},
{
USB_DEVICE_WACOM
(
0x4001
)
},
...
...
drivers/hid/wacom_wac.h
浏览文件 @
9931753b
...
...
@@ -118,6 +118,7 @@
#define WACOM_HID_WD_TOUCHSTRIP2 (WACOM_HID_UP_WACOMDIGITIZER | 0x0137)
#define WACOM_HID_WD_TOUCHRING (WACOM_HID_UP_WACOMDIGITIZER | 0x0138)
#define WACOM_HID_WD_TOUCHRINGSTATUS (WACOM_HID_UP_WACOMDIGITIZER | 0x0139)
#define WACOM_HID_WD_REPORT_VALID (WACOM_HID_UP_WACOMDIGITIZER | 0x01d0)
#define WACOM_HID_WD_ACCELEROMETER_X (WACOM_HID_UP_WACOMDIGITIZER | 0x0401)
#define WACOM_HID_WD_ACCELEROMETER_Y (WACOM_HID_UP_WACOMDIGITIZER | 0x0402)
#define WACOM_HID_WD_ACCELEROMETER_Z (WACOM_HID_UP_WACOMDIGITIZER | 0x0403)
...
...
@@ -213,6 +214,7 @@ enum {
INTUOSPM
,
INTUOSPL
,
INTUOSP2_BT
,
INTUOSHT3_BT
,
WACOM_21UX2
,
WACOM_22HD
,
DTK
,
...
...
@@ -352,7 +354,7 @@ struct wacom_wac {
bool
has_mute_touch_switch
;
bool
has_mode_change
;
bool
is_direct_mode
;
bool
is_invalid_bt_frame
;
};
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录