Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
5099bc83
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
5099bc83
编写于
10月 23, 2018
作者:
J
Jiri Kosina
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-4.20/microsoft' into for-linus
Rumble support for Xbox One S
上级
276e7227
830e82aa
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
138 addition
and
5 deletion
+138
-5
drivers/hid/Kconfig
drivers/hid/Kconfig
+1
-0
drivers/hid/hid-ids.h
drivers/hid/hid-ids.h
+1
-0
drivers/hid/hid-microsoft.c
drivers/hid/hid-microsoft.c
+136
-5
未找到文件。
drivers/hid/Kconfig
浏览文件 @
5099bc83
...
...
@@ -609,6 +609,7 @@ config HID_MICROSOFT
tristate "Microsoft non-fully HID-compliant devices"
depends on HID
default !EXPERT
select INPUT_FF_MEMLESS
---help---
Support for Microsoft devices that are not fully compliant with HID standard.
...
...
drivers/hid/hid-ids.h
浏览文件 @
5099bc83
...
...
@@ -804,6 +804,7 @@
#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
#define USB_DEVICE_ID_MS_POWER_COVER 0x07da
#define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd
#define USB_VENDOR_ID_MOJO 0x8282
#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
...
...
drivers/hid/hid-microsoft.c
浏览文件 @
5099bc83
...
...
@@ -29,11 +29,41 @@
#define MS_NOGET BIT(4)
#define MS_DUPLICATE_USAGES BIT(5)
#define MS_SURFACE_DIAL BIT(6)
#define MS_QUIRK_FF BIT(7)
struct
ms_data
{
unsigned
long
quirks
;
struct
hid_device
*
hdev
;
struct
work_struct
ff_worker
;
__u8
strong
;
__u8
weak
;
void
*
output_report_dmabuf
;
};
#define XB1S_FF_REPORT 3
#define ENABLE_WEAK BIT(0)
#define ENABLE_STRONG BIT(1)
enum
{
MAGNITUDE_STRONG
=
2
,
MAGNITUDE_WEAK
,
MAGNITUDE_NUM
};
struct
xb1s_ff_report
{
__u8
report_id
;
__u8
enable
;
__u8
magnitude
[
MAGNITUDE_NUM
];
__u8
duration_10ms
;
__u8
start_delay_10ms
;
__u8
loop_count
;
}
__packed
;
static
__u8
*
ms_report_fixup
(
struct
hid_device
*
hdev
,
__u8
*
rdesc
,
unsigned
int
*
rsize
)
{
unsigned
long
quirks
=
(
unsigned
long
)
hid_get_drvdata
(
hdev
);
struct
ms_data
*
ms
=
hid_get_drvdata
(
hdev
);
unsigned
long
quirks
=
ms
->
quirks
;
/*
* Microsoft Wireless Desktop Receiver (Model 1028) has
...
...
@@ -159,7 +189,8 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
unsigned
long
quirks
=
(
unsigned
long
)
hid_get_drvdata
(
hdev
);
struct
ms_data
*
ms
=
hid_get_drvdata
(
hdev
);
unsigned
long
quirks
=
ms
->
quirks
;
if
(
quirks
&
MS_ERGONOMY
)
{
int
ret
=
ms_ergonomy_kb_quirk
(
hi
,
usage
,
bit
,
max
);
...
...
@@ -185,7 +216,8 @@ static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
unsigned
long
**
bit
,
int
*
max
)
{
unsigned
long
quirks
=
(
unsigned
long
)
hid_get_drvdata
(
hdev
);
struct
ms_data
*
ms
=
hid_get_drvdata
(
hdev
);
unsigned
long
quirks
=
ms
->
quirks
;
if
(
quirks
&
MS_DUPLICATE_USAGES
)
clear_bit
(
usage
->
code
,
*
bit
);
...
...
@@ -196,7 +228,8 @@ static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi,
static
int
ms_event
(
struct
hid_device
*
hdev
,
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
__s32
value
)
{
unsigned
long
quirks
=
(
unsigned
long
)
hid_get_drvdata
(
hdev
);
struct
ms_data
*
ms
=
hid_get_drvdata
(
hdev
);
unsigned
long
quirks
=
ms
->
quirks
;
struct
input_dev
*
input
;
if
(
!
(
hdev
->
claimed
&
HID_CLAIMED_INPUT
)
||
!
field
->
hidinput
||
...
...
@@ -251,12 +284,97 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
return
0
;
}
static
void
ms_ff_worker
(
struct
work_struct
*
work
)
{
struct
ms_data
*
ms
=
container_of
(
work
,
struct
ms_data
,
ff_worker
);
struct
hid_device
*
hdev
=
ms
->
hdev
;
struct
xb1s_ff_report
*
r
=
ms
->
output_report_dmabuf
;
int
ret
;
memset
(
r
,
0
,
sizeof
(
*
r
));
r
->
report_id
=
XB1S_FF_REPORT
;
r
->
enable
=
ENABLE_WEAK
|
ENABLE_STRONG
;
/*
* Specifying maximum duration and maximum loop count should
* cover maximum duration of a single effect, which is 65536
* ms
*/
r
->
duration_10ms
=
U8_MAX
;
r
->
loop_count
=
U8_MAX
;
r
->
magnitude
[
MAGNITUDE_STRONG
]
=
ms
->
strong
;
/* left actuator */
r
->
magnitude
[
MAGNITUDE_WEAK
]
=
ms
->
weak
;
/* right actuator */
ret
=
hid_hw_output_report
(
hdev
,
(
__u8
*
)
r
,
sizeof
(
*
r
));
if
(
ret
)
hid_warn
(
hdev
,
"failed to send FF report
\n
"
);
}
static
int
ms_play_effect
(
struct
input_dev
*
dev
,
void
*
data
,
struct
ff_effect
*
effect
)
{
struct
hid_device
*
hid
=
input_get_drvdata
(
dev
);
struct
ms_data
*
ms
=
hid_get_drvdata
(
hid
);
if
(
effect
->
type
!=
FF_RUMBLE
)
return
0
;
/*
* Magnitude is 0..100 so scale the 16-bit input here
*/
ms
->
strong
=
((
u32
)
effect
->
u
.
rumble
.
strong_magnitude
*
100
)
/
U16_MAX
;
ms
->
weak
=
((
u32
)
effect
->
u
.
rumble
.
weak_magnitude
*
100
)
/
U16_MAX
;
schedule_work
(
&
ms
->
ff_worker
);
return
0
;
}
static
int
ms_init_ff
(
struct
hid_device
*
hdev
)
{
struct
hid_input
*
hidinput
=
list_entry
(
hdev
->
inputs
.
next
,
struct
hid_input
,
list
);
struct
input_dev
*
input_dev
=
hidinput
->
input
;
struct
ms_data
*
ms
=
hid_get_drvdata
(
hdev
);
if
(
!
(
ms
->
quirks
&
MS_QUIRK_FF
))
return
0
;
ms
->
hdev
=
hdev
;
INIT_WORK
(
&
ms
->
ff_worker
,
ms_ff_worker
);
ms
->
output_report_dmabuf
=
devm_kzalloc
(
&
hdev
->
dev
,
sizeof
(
struct
xb1s_ff_report
),
GFP_KERNEL
);
if
(
ms
->
output_report_dmabuf
==
NULL
)
return
-
ENOMEM
;
input_set_capability
(
input_dev
,
EV_FF
,
FF_RUMBLE
);
return
input_ff_create_memless
(
input_dev
,
NULL
,
ms_play_effect
);
}
static
void
ms_remove_ff
(
struct
hid_device
*
hdev
)
{
struct
ms_data
*
ms
=
hid_get_drvdata
(
hdev
);
if
(
!
(
ms
->
quirks
&
MS_QUIRK_FF
))
return
;
cancel_work_sync
(
&
ms
->
ff_worker
);
}
static
int
ms_probe
(
struct
hid_device
*
hdev
,
const
struct
hid_device_id
*
id
)
{
unsigned
long
quirks
=
id
->
driver_data
;
struct
ms_data
*
ms
;
int
ret
;
hid_set_drvdata
(
hdev
,
(
void
*
)
quirks
);
ms
=
devm_kzalloc
(
&
hdev
->
dev
,
sizeof
(
*
ms
),
GFP_KERNEL
);
if
(
ms
==
NULL
)
return
-
ENOMEM
;
ms
->
quirks
=
quirks
;
hid_set_drvdata
(
hdev
,
ms
);
if
(
quirks
&
MS_NOGET
)
hdev
->
quirks
|=
HID_QUIRK_NOGET
;
...
...
@@ -277,11 +395,21 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto
err_free
;
}
ret
=
ms_init_ff
(
hdev
);
if
(
ret
)
hid_err
(
hdev
,
"could not initialize ff, continuing anyway"
);
return
0
;
err_free:
return
ret
;
}
static
void
ms_remove
(
struct
hid_device
*
hdev
)
{
hid_hw_stop
(
hdev
);
ms_remove_ff
(
hdev
);
}
static
const
struct
hid_device_id
ms_devices
[]
=
{
{
HID_USB_DEVICE
(
USB_VENDOR_ID_MICROSOFT
,
USB_DEVICE_ID_SIDEWINDER_GV
),
.
driver_data
=
MS_HIDINPUT
},
...
...
@@ -318,6 +446,8 @@ static const struct hid_device_id ms_devices[] = {
.
driver_data
=
MS_PRESENTER
},
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_MICROSOFT
,
0x091B
),
.
driver_data
=
MS_SURFACE_DIAL
},
{
HID_BLUETOOTH_DEVICE
(
USB_VENDOR_ID_MICROSOFT
,
USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER
),
.
driver_data
=
MS_QUIRK_FF
},
{
}
};
MODULE_DEVICE_TABLE
(
hid
,
ms_devices
);
...
...
@@ -330,6 +460,7 @@ static struct hid_driver ms_driver = {
.
input_mapped
=
ms_input_mapped
,
.
event
=
ms_event
,
.
probe
=
ms_probe
,
.
remove
=
ms_remove
,
};
module_hid_driver
(
ms_driver
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录