Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
b26a95d4
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
b26a95d4
编写于
1月 21, 2016
作者:
D
Dmitry Torokhov
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'next' into for-linus
Prepare second round of input updates for 4.5 merge window.
上级
009f7738
809d9516
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
456 addition
and
210 deletion
+456
-210
Documentation/devicetree/bindings/input/gpio-keys.txt
Documentation/devicetree/bindings/input/gpio-keys.txt
+1
-0
drivers/input/joystick/xpad.c
drivers/input/joystick/xpad.c
+425
-166
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/gpio_keys.c
+4
-2
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/atmel_mxt_ts.c
+26
-42
未找到文件。
Documentation/devicetree/bindings/input/gpio-keys.txt
浏览文件 @
b26a95d4
...
...
@@ -6,6 +6,7 @@ Required properties:
Optional properties:
- autorepeat: Boolean, Enable auto repeat feature of Linux input
subsystem.
- label: String, name of the input device.
Each button (key) is represented as a sub-node of "gpio-keys":
Subnode properties:
...
...
drivers/input/joystick/xpad.c
浏览文件 @
b26a95d4
...
...
@@ -76,10 +76,13 @@
*/
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/rcupdate.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/module.h>
#include <linux/usb/input.h>
#include <linux/usb/quirks.h>
#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
#define DRIVER_DESC "X-Box pad driver"
...
...
@@ -125,7 +128,7 @@ static const struct xpad_device {
{
0x045e
,
0x0289
,
"Microsoft X-Box pad v2 (US)"
,
0
,
XTYPE_XBOX
},
{
0x045e
,
0x028e
,
"Microsoft X-Box 360 pad"
,
0
,
XTYPE_XBOX360
},
{
0x045e
,
0x02d1
,
"Microsoft X-Box One pad"
,
0
,
XTYPE_XBOXONE
},
{
0x045e
,
0x02dd
,
"Microsoft X-Box One pad (
Covert Forces
)"
,
0
,
XTYPE_XBOXONE
},
{
0x045e
,
0x02dd
,
"Microsoft X-Box One pad (
Firmware 2015
)"
,
0
,
XTYPE_XBOXONE
},
{
0x045e
,
0x0291
,
"Xbox 360 Wireless Receiver (XBOX)"
,
MAP_DPAD_TO_BUTTONS
,
XTYPE_XBOX360W
},
{
0x045e
,
0x0719
,
"Xbox 360 Wireless Receiver"
,
MAP_DPAD_TO_BUTTONS
,
XTYPE_XBOX360W
},
{
0x044f
,
0x0f07
,
"Thrustmaster, Inc. Controller"
,
0
,
XTYPE_XBOX
},
...
...
@@ -317,21 +320,42 @@ static struct usb_device_id xpad_table[] = {
MODULE_DEVICE_TABLE
(
usb
,
xpad_table
);
struct
xpad_output_packet
{
u8
data
[
XPAD_PKT_LEN
];
u8
len
;
bool
pending
;
};
#define XPAD_OUT_CMD_IDX 0
#define XPAD_OUT_FF_IDX 1
#define XPAD_OUT_LED_IDX (1 + IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF))
#define XPAD_NUM_OUT_PACKETS (1 + \
IS_ENABLED(CONFIG_JOYSTICK_XPAD_FF) + \
IS_ENABLED(CONFIG_JOYSTICK_XPAD_LEDS))
struct
usb_xpad
{
struct
input_dev
*
dev
;
/* input device interface */
struct
input_dev
__rcu
*
x360w_dev
;
struct
usb_device
*
udev
;
/* usb device */
struct
usb_interface
*
intf
;
/* usb interface */
int
pad_present
;
bool
pad_present
;
bool
input_created
;
struct
urb
*
irq_in
;
/* urb for interrupt in report */
unsigned
char
*
idata
;
/* input data */
dma_addr_t
idata_dma
;
struct
urb
*
irq_out
;
/* urb for interrupt out report */
struct
usb_anchor
irq_out_anchor
;
bool
irq_out_active
;
/* we must not use an active URB */
u8
odata_serial
;
/* serial number for xbox one protocol */
unsigned
char
*
odata
;
/* output data */
dma_addr_t
odata_dma
;
struct
mutex
odata_mutex
;
spinlock_t
odata_lock
;
struct
xpad_output_packet
out_packets
[
XPAD_NUM_OUT_PACKETS
];
int
last_out_packet
;
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
struct
xpad_led
*
led
;
...
...
@@ -343,8 +367,12 @@ struct usb_xpad {
int
xtype
;
/* type of xbox device */
int
pad_nr
;
/* the order x360 pads were attached */
const
char
*
name
;
/* name of the device */
struct
work_struct
work
;
/* init/remove device from callback */
};
static
int
xpad_init_input
(
struct
usb_xpad
*
xpad
);
static
void
xpad_deinit_input
(
struct
usb_xpad
*
xpad
);
/*
* xpad_process_packet
*
...
...
@@ -424,11 +452,9 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
* http://www.free60.org/wiki/Gamepad
*/
static
void
xpad360_process_packet
(
struct
usb_xpad
*
xpad
,
static
void
xpad360_process_packet
(
struct
usb_xpad
*
xpad
,
struct
input_dev
*
dev
,
u16
cmd
,
unsigned
char
*
data
)
{
struct
input_dev
*
dev
=
xpad
->
dev
;
/* digital pad */
if
(
xpad
->
mapping
&
MAP_DPAD_TO_BUTTONS
)
{
/* dpad as buttons (left, right, up, down) */
...
...
@@ -495,7 +521,30 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
input_sync
(
dev
);
}
static
void
xpad_identify_controller
(
struct
usb_xpad
*
xpad
);
static
void
xpad_presence_work
(
struct
work_struct
*
work
)
{
struct
usb_xpad
*
xpad
=
container_of
(
work
,
struct
usb_xpad
,
work
);
int
error
;
if
(
xpad
->
pad_present
)
{
error
=
xpad_init_input
(
xpad
);
if
(
error
)
{
/* complain only, not much else we can do here */
dev_err
(
&
xpad
->
dev
->
dev
,
"unable to init device: %d
\n
"
,
error
);
}
else
{
rcu_assign_pointer
(
xpad
->
x360w_dev
,
xpad
->
dev
);
}
}
else
{
RCU_INIT_POINTER
(
xpad
->
x360w_dev
,
NULL
);
synchronize_rcu
();
/*
* Now that we are sure xpad360w_process_packet is not
* using input device we can get rid of it.
*/
xpad_deinit_input
(
xpad
);
}
}
/*
* xpad360w_process_packet
...
...
@@ -513,24 +562,28 @@ static void xpad_identify_controller(struct usb_xpad *xpad);
*/
static
void
xpad360w_process_packet
(
struct
usb_xpad
*
xpad
,
u16
cmd
,
unsigned
char
*
data
)
{
struct
input_dev
*
dev
;
bool
present
;
/* Presence change */
if
(
data
[
0
]
&
0x08
)
{
if
(
data
[
1
]
&
0x80
)
{
xpad
->
pad_present
=
1
;
/*
* Light up the segment corresponding to
* controller number.
*/
xpad_identify_controller
(
xpad
);
}
else
xpad
->
pad_present
=
0
;
present
=
(
data
[
1
]
&
0x80
)
!=
0
;
if
(
xpad
->
pad_present
!=
present
)
{
xpad
->
pad_present
=
present
;
schedule_work
(
&
xpad
->
work
);
}
}
/* Valid pad data */
if
(
!
(
data
[
1
]
&
0x1
)
)
if
(
data
[
1
]
!=
0x1
)
return
;
xpad360_process_packet
(
xpad
,
cmd
,
&
data
[
4
]);
rcu_read_lock
();
dev
=
rcu_dereference
(
xpad
->
x360w_dev
);
if
(
dev
)
xpad360_process_packet
(
xpad
,
dev
,
cmd
,
&
data
[
4
]);
rcu_read_unlock
();
}
/*
...
...
@@ -659,7 +712,7 @@ static void xpad_irq_in(struct urb *urb)
switch
(
xpad
->
xtype
)
{
case
XTYPE_XBOX360
:
xpad360_process_packet
(
xpad
,
0
,
xpad
->
idata
);
xpad360_process_packet
(
xpad
,
xpad
->
dev
,
0
,
xpad
->
idata
);
break
;
case
XTYPE_XBOX360W
:
xpad360w_process_packet
(
xpad
,
0
,
xpad
->
idata
);
...
...
@@ -678,18 +731,73 @@ static void xpad_irq_in(struct urb *urb)
__func__
,
retval
);
}
/* Callers must hold xpad->odata_lock spinlock */
static
bool
xpad_prepare_next_out_packet
(
struct
usb_xpad
*
xpad
)
{
struct
xpad_output_packet
*
pkt
,
*
packet
=
NULL
;
int
i
;
for
(
i
=
0
;
i
<
XPAD_NUM_OUT_PACKETS
;
i
++
)
{
if
(
++
xpad
->
last_out_packet
>=
XPAD_NUM_OUT_PACKETS
)
xpad
->
last_out_packet
=
0
;
pkt
=
&
xpad
->
out_packets
[
xpad
->
last_out_packet
];
if
(
pkt
->
pending
)
{
dev_dbg
(
&
xpad
->
intf
->
dev
,
"%s - found pending output packet %d
\n
"
,
__func__
,
xpad
->
last_out_packet
);
packet
=
pkt
;
break
;
}
}
if
(
packet
)
{
memcpy
(
xpad
->
odata
,
packet
->
data
,
packet
->
len
);
xpad
->
irq_out
->
transfer_buffer_length
=
packet
->
len
;
return
true
;
}
return
false
;
}
/* Callers must hold xpad->odata_lock spinlock */
static
int
xpad_try_sending_next_out_packet
(
struct
usb_xpad
*
xpad
)
{
int
error
;
if
(
!
xpad
->
irq_out_active
&&
xpad_prepare_next_out_packet
(
xpad
))
{
usb_anchor_urb
(
xpad
->
irq_out
,
&
xpad
->
irq_out_anchor
);
error
=
usb_submit_urb
(
xpad
->
irq_out
,
GFP_ATOMIC
);
if
(
error
)
{
dev_err
(
&
xpad
->
intf
->
dev
,
"%s - usb_submit_urb failed with result %d
\n
"
,
__func__
,
error
);
usb_unanchor_urb
(
xpad
->
irq_out
);
return
-
EIO
;
}
xpad
->
irq_out_active
=
true
;
}
return
0
;
}
static
void
xpad_irq_out
(
struct
urb
*
urb
)
{
struct
usb_xpad
*
xpad
=
urb
->
context
;
struct
device
*
dev
=
&
xpad
->
intf
->
dev
;
int
retval
,
status
;
int
status
=
urb
->
status
;
int
error
;
unsigned
long
flags
;
s
tatus
=
urb
->
status
;
s
pin_lock_irqsave
(
&
xpad
->
odata_lock
,
flags
)
;
switch
(
status
)
{
case
0
:
/* success */
return
;
xpad
->
out_packets
[
xpad
->
last_out_packet
].
pending
=
false
;
xpad
->
irq_out_active
=
xpad_prepare_next_out_packet
(
xpad
);
break
;
case
-
ECONNRESET
:
case
-
ENOENT
:
...
...
@@ -697,19 +805,28 @@ static void xpad_irq_out(struct urb *urb)
/* this urb is terminated, clean up */
dev_dbg
(
dev
,
"%s - urb shutting down with status: %d
\n
"
,
__func__
,
status
);
return
;
xpad
->
irq_out_active
=
false
;
break
;
default:
dev_dbg
(
dev
,
"%s - nonzero urb status received: %d
\n
"
,
__func__
,
status
);
goto
exit
;
break
;
}
exit:
retval
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
retval
)
dev_err
(
dev
,
"%s - usb_submit_urb failed with result %d
\n
"
,
__func__
,
retval
);
if
(
xpad
->
irq_out_active
)
{
usb_anchor_urb
(
urb
,
&
xpad
->
irq_out_anchor
);
error
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
if
(
error
)
{
dev_err
(
dev
,
"%s - usb_submit_urb failed with result %d
\n
"
,
__func__
,
error
);
usb_unanchor_urb
(
urb
);
xpad
->
irq_out_active
=
false
;
}
}
spin_unlock_irqrestore
(
&
xpad
->
odata_lock
,
flags
);
}
static
int
xpad_init_output
(
struct
usb_interface
*
intf
,
struct
usb_xpad
*
xpad
)
...
...
@@ -721,6 +838,8 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
if
(
xpad
->
xtype
==
XTYPE_UNKNOWN
)
return
0
;
init_usb_anchor
(
&
xpad
->
irq_out_anchor
);
xpad
->
odata
=
usb_alloc_coherent
(
xpad
->
udev
,
XPAD_PKT_LEN
,
GFP_KERNEL
,
&
xpad
->
odata_dma
);
if
(
!
xpad
->
odata
)
{
...
...
@@ -728,7 +847,7 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
goto
fail1
;
}
mutex_init
(
&
xpad
->
odata_mutex
);
spin_lock_init
(
&
xpad
->
odata_lock
);
xpad
->
irq_out
=
usb_alloc_urb
(
0
,
GFP_KERNEL
);
if
(
!
xpad
->
irq_out
)
{
...
...
@@ -755,8 +874,14 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
static
void
xpad_stop_output
(
struct
usb_xpad
*
xpad
)
{
if
(
xpad
->
xtype
!=
XTYPE_UNKNOWN
)
usb_kill_urb
(
xpad
->
irq_out
);
if
(
xpad
->
xtype
!=
XTYPE_UNKNOWN
)
{
if
(
!
usb_wait_anchor_empty_timeout
(
&
xpad
->
irq_out_anchor
,
5000
))
{
dev_warn
(
&
xpad
->
intf
->
dev
,
"timed out waiting for output URB to complete, killing
\n
"
);
usb_kill_anchored_urbs
(
&
xpad
->
irq_out_anchor
);
}
}
}
static
void
xpad_deinit_output
(
struct
usb_xpad
*
xpad
)
...
...
@@ -770,27 +895,60 @@ static void xpad_deinit_output(struct usb_xpad *xpad)
static
int
xpad_inquiry_pad_presence
(
struct
usb_xpad
*
xpad
)
{
struct
xpad_output_packet
*
packet
=
&
xpad
->
out_packets
[
XPAD_OUT_CMD_IDX
];
unsigned
long
flags
;
int
retval
;
mutex_lock
(
&
xpad
->
odata_mutex
);
spin_lock_irqsave
(
&
xpad
->
odata_lock
,
flags
);
packet
->
data
[
0
]
=
0x08
;
packet
->
data
[
1
]
=
0x00
;
packet
->
data
[
2
]
=
0x0F
;
packet
->
data
[
3
]
=
0xC0
;
packet
->
data
[
4
]
=
0x00
;
packet
->
data
[
5
]
=
0x00
;
packet
->
data
[
6
]
=
0x00
;
packet
->
data
[
7
]
=
0x00
;
packet
->
data
[
8
]
=
0x00
;
packet
->
data
[
9
]
=
0x00
;
packet
->
data
[
10
]
=
0x00
;
packet
->
data
[
11
]
=
0x00
;
packet
->
len
=
12
;
packet
->
pending
=
true
;
/* Reset the sequence so we send out presence first */
xpad
->
last_out_packet
=
-
1
;
retval
=
xpad_try_sending_next_out_packet
(
xpad
);
spin_unlock_irqrestore
(
&
xpad
->
odata_lock
,
flags
);
xpad
->
odata
[
0
]
=
0x08
;
xpad
->
odata
[
1
]
=
0x00
;
xpad
->
odata
[
2
]
=
0x0F
;
xpad
->
odata
[
3
]
=
0xC0
;
xpad
->
odata
[
4
]
=
0x00
;
xpad
->
odata
[
5
]
=
0x00
;
xpad
->
odata
[
6
]
=
0x00
;
xpad
->
odata
[
7
]
=
0x00
;
xpad
->
odata
[
8
]
=
0x00
;
xpad
->
odata
[
9
]
=
0x00
;
xpad
->
odata
[
10
]
=
0x00
;
xpad
->
odata
[
11
]
=
0x00
;
xpad
->
irq_out
->
transfer_buffer_length
=
12
;
return
retval
;
}
static
int
xpad_start_xbox_one
(
struct
usb_xpad
*
xpad
)
{
struct
xpad_output_packet
*
packet
=
&
xpad
->
out_packets
[
XPAD_OUT_CMD_IDX
];
unsigned
long
flags
;
int
retval
;
retval
=
usb_submit_urb
(
xpad
->
irq_out
,
GFP_KERNEL
);
spin_lock_irqsave
(
&
xpad
->
odata_lock
,
flags
);
mutex_unlock
(
&
xpad
->
odata_mutex
);
/* Xbox one controller needs to be initialized. */
packet
->
data
[
0
]
=
0x05
;
packet
->
data
[
1
]
=
0x20
;
packet
->
data
[
2
]
=
xpad
->
odata_serial
++
;
/* packet serial */
packet
->
data
[
3
]
=
0x01
;
/* rumble bit enable? */
packet
->
data
[
4
]
=
0x00
;
packet
->
len
=
5
;
packet
->
pending
=
true
;
/* Reset the sequence so we send out start packet first */
xpad
->
last_out_packet
=
-
1
;
retval
=
xpad_try_sending_next_out_packet
(
xpad
);
spin_unlock_irqrestore
(
&
xpad
->
odata_lock
,
flags
);
return
retval
;
}
...
...
@@ -799,8 +957,11 @@ static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
static
int
xpad_play_effect
(
struct
input_dev
*
dev
,
void
*
data
,
struct
ff_effect
*
effect
)
{
struct
usb_xpad
*
xpad
=
input_get_drvdata
(
dev
);
struct
xpad_output_packet
*
packet
=
&
xpad
->
out_packets
[
XPAD_OUT_FF_IDX
];
__u16
strong
;
__u16
weak
;
int
retval
;
unsigned
long
flags
;
if
(
effect
->
type
!=
FF_RUMBLE
)
return
0
;
...
...
@@ -808,69 +969,81 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
strong
=
effect
->
u
.
rumble
.
strong_magnitude
;
weak
=
effect
->
u
.
rumble
.
weak_magnitude
;
spin_lock_irqsave
(
&
xpad
->
odata_lock
,
flags
);
switch
(
xpad
->
xtype
)
{
case
XTYPE_XBOX
:
xpad
->
odata
[
0
]
=
0x00
;
xpad
->
odata
[
1
]
=
0x06
;
xpad
->
odata
[
2
]
=
0x00
;
xpad
->
odata
[
3
]
=
strong
/
256
;
/* left actuator */
xpad
->
odata
[
4
]
=
0x00
;
xpad
->
odata
[
5
]
=
weak
/
256
;
/* right actuator */
xpad
->
irq_out
->
transfer_buffer_length
=
6
;
packet
->
data
[
0
]
=
0x00
;
packet
->
data
[
1
]
=
0x06
;
packet
->
data
[
2
]
=
0x00
;
packet
->
data
[
3
]
=
strong
/
256
;
/* left actuator */
packet
->
data
[
4
]
=
0x00
;
packet
->
data
[
5
]
=
weak
/
256
;
/* right actuator */
packet
->
len
=
6
;
packet
->
pending
=
true
;
break
;
case
XTYPE_XBOX360
:
xpad
->
odata
[
0
]
=
0x00
;
xpad
->
odata
[
1
]
=
0x08
;
xpad
->
odata
[
2
]
=
0x00
;
xpad
->
odata
[
3
]
=
strong
/
256
;
/* left actuator? */
xpad
->
odata
[
4
]
=
weak
/
256
;
/* right actuator? */
xpad
->
odata
[
5
]
=
0x00
;
xpad
->
odata
[
6
]
=
0x00
;
xpad
->
odata
[
7
]
=
0x00
;
xpad
->
irq_out
->
transfer_buffer_length
=
8
;
packet
->
data
[
0
]
=
0x00
;
packet
->
data
[
1
]
=
0x08
;
packet
->
data
[
2
]
=
0x00
;
packet
->
data
[
3
]
=
strong
/
256
;
/* left actuator? */
packet
->
data
[
4
]
=
weak
/
256
;
/* right actuator? */
packet
->
data
[
5
]
=
0x00
;
packet
->
data
[
6
]
=
0x00
;
packet
->
data
[
7
]
=
0x00
;
packet
->
len
=
8
;
packet
->
pending
=
true
;
break
;
case
XTYPE_XBOX360W
:
xpad
->
odata
[
0
]
=
0x00
;
xpad
->
odata
[
1
]
=
0x01
;
xpad
->
odata
[
2
]
=
0x0F
;
xpad
->
odata
[
3
]
=
0xC0
;
xpad
->
odata
[
4
]
=
0x00
;
xpad
->
odata
[
5
]
=
strong
/
256
;
xpad
->
odata
[
6
]
=
weak
/
256
;
xpad
->
odata
[
7
]
=
0x00
;
xpad
->
odata
[
8
]
=
0x00
;
xpad
->
odata
[
9
]
=
0x00
;
xpad
->
odata
[
10
]
=
0x00
;
xpad
->
odata
[
11
]
=
0x00
;
xpad
->
irq_out
->
transfer_buffer_length
=
12
;
packet
->
data
[
0
]
=
0x00
;
packet
->
data
[
1
]
=
0x01
;
packet
->
data
[
2
]
=
0x0F
;
packet
->
data
[
3
]
=
0xC0
;
packet
->
data
[
4
]
=
0x00
;
packet
->
data
[
5
]
=
strong
/
256
;
packet
->
data
[
6
]
=
weak
/
256
;
packet
->
data
[
7
]
=
0x00
;
packet
->
data
[
8
]
=
0x00
;
packet
->
data
[
9
]
=
0x00
;
packet
->
data
[
10
]
=
0x00
;
packet
->
data
[
11
]
=
0x00
;
packet
->
len
=
12
;
packet
->
pending
=
true
;
break
;
case
XTYPE_XBOXONE
:
xpad
->
odata
[
0
]
=
0x09
;
/* activate rumble */
xpad
->
odata
[
1
]
=
0x08
;
xpad
->
odata
[
2
]
=
0x00
;
xpad
->
odata
[
3
]
=
0x08
;
/* continuous effect */
xpad
->
odata
[
4
]
=
0x00
;
/* simple rumble mode */
xpad
->
odata
[
5
]
=
0x03
;
/* L and R actuator only */
xpad
->
odata
[
6
]
=
0x00
;
/* TODO: LT actuator */
xpad
->
odata
[
7
]
=
0x00
;
/* TODO: RT actuator */
xpad
->
odata
[
8
]
=
strong
/
256
;
/* left actuator */
xpad
->
odata
[
9
]
=
weak
/
256
;
/* right actuator */
xpad
->
odata
[
10
]
=
0x80
;
/* length of pulse */
xpad
->
odata
[
11
]
=
0x00
;
/* stop period of pulse */
xpad
->
irq_out
->
transfer_buffer_length
=
12
;
packet
->
data
[
0
]
=
0x09
;
/* activate rumble */
packet
->
data
[
1
]
=
0x08
;
packet
->
data
[
2
]
=
xpad
->
odata_serial
++
;
packet
->
data
[
3
]
=
0x08
;
/* continuous effect */
packet
->
data
[
4
]
=
0x00
;
/* simple rumble mode */
packet
->
data
[
5
]
=
0x03
;
/* L and R actuator only */
packet
->
data
[
6
]
=
0x00
;
/* TODO: LT actuator */
packet
->
data
[
7
]
=
0x00
;
/* TODO: RT actuator */
packet
->
data
[
8
]
=
strong
/
512
;
/* left actuator */
packet
->
data
[
9
]
=
weak
/
512
;
/* right actuator */
packet
->
data
[
10
]
=
0x80
;
/* length of pulse */
packet
->
data
[
11
]
=
0x00
;
/* stop period of pulse */
packet
->
data
[
12
]
=
0x00
;
packet
->
len
=
13
;
packet
->
pending
=
true
;
break
;
default:
dev_dbg
(
&
xpad
->
dev
->
dev
,
"%s - rumble command sent to unsupported xpad type: %d
\n
"
,
__func__
,
xpad
->
xtype
);
return
-
EINVAL
;
retval
=
-
EINVAL
;
goto
out
;
}
return
usb_submit_urb
(
xpad
->
irq_out
,
GFP_ATOMIC
);
retval
=
xpad_try_sending_next_out_packet
(
xpad
);
out:
spin_unlock_irqrestore
(
&
xpad
->
odata_lock
,
flags
);
return
retval
;
}
static
int
xpad_init_ff
(
struct
usb_xpad
*
xpad
)
...
...
@@ -921,36 +1094,44 @@ struct xpad_led {
*/
static
void
xpad_send_led_command
(
struct
usb_xpad
*
xpad
,
int
command
)
{
struct
xpad_output_packet
*
packet
=
&
xpad
->
out_packets
[
XPAD_OUT_LED_IDX
];
unsigned
long
flags
;
command
%=
16
;
mutex_lock
(
&
xpad
->
odata_mutex
);
spin_lock_irqsave
(
&
xpad
->
odata_lock
,
flags
);
switch
(
xpad
->
xtype
)
{
case
XTYPE_XBOX360
:
xpad
->
odata
[
0
]
=
0x01
;
xpad
->
odata
[
1
]
=
0x03
;
xpad
->
odata
[
2
]
=
command
;
xpad
->
irq_out
->
transfer_buffer_length
=
3
;
packet
->
data
[
0
]
=
0x01
;
packet
->
data
[
1
]
=
0x03
;
packet
->
data
[
2
]
=
command
;
packet
->
len
=
3
;
packet
->
pending
=
true
;
break
;
case
XTYPE_XBOX360W
:
xpad
->
odata
[
0
]
=
0x00
;
xpad
->
odata
[
1
]
=
0x00
;
xpad
->
odata
[
2
]
=
0x08
;
xpad
->
odata
[
3
]
=
0x40
+
command
;
xpad
->
odata
[
4
]
=
0x00
;
xpad
->
odata
[
5
]
=
0x00
;
xpad
->
odata
[
6
]
=
0x00
;
xpad
->
odata
[
7
]
=
0x00
;
xpad
->
odata
[
8
]
=
0x00
;
xpad
->
odata
[
9
]
=
0x00
;
xpad
->
odata
[
10
]
=
0x00
;
xpad
->
odata
[
11
]
=
0x00
;
xpad
->
irq_out
->
transfer_buffer_length
=
12
;
packet
->
data
[
0
]
=
0x00
;
packet
->
data
[
1
]
=
0x00
;
packet
->
data
[
2
]
=
0x08
;
packet
->
data
[
3
]
=
0x40
+
command
;
packet
->
data
[
4
]
=
0x00
;
packet
->
data
[
5
]
=
0x00
;
packet
->
data
[
6
]
=
0x00
;
packet
->
data
[
7
]
=
0x00
;
packet
->
data
[
8
]
=
0x00
;
packet
->
data
[
9
]
=
0x00
;
packet
->
data
[
10
]
=
0x00
;
packet
->
data
[
11
]
=
0x00
;
packet
->
len
=
12
;
packet
->
pending
=
true
;
break
;
}
usb_submit_urb
(
xpad
->
irq_out
,
GFP_KERNEL
);
mutex_unlock
(
&
xpad
->
odata_mutex
);
xpad_try_sending_next_out_packet
(
xpad
);
spin_unlock_irqrestore
(
&
xpad
->
odata_lock
,
flags
);
}
/*
...
...
@@ -959,7 +1140,7 @@ static void xpad_send_led_command(struct usb_xpad *xpad, int command)
*/
static
void
xpad_identify_controller
(
struct
usb_xpad
*
xpad
)
{
xpad_send_led_command
(
xpad
,
(
xpad
->
pad_nr
%
4
)
+
2
);
led_set_brightness
(
&
xpad
->
led
->
led_cdev
,
(
xpad
->
pad_nr
%
4
)
+
2
);
}
static
void
xpad_led_set
(
struct
led_classdev
*
led_cdev
,
...
...
@@ -1001,14 +1182,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
if
(
error
)
goto
err_free_id
;
if
(
xpad
->
xtype
==
XTYPE_XBOX360
)
{
/*
* Light up the segment corresponding to controller
* number on wired devices. On wireless we'll do that
* when they respond to "presence" packet.
*/
xpad_identify_controller
(
xpad
);
}
xpad_identify_controller
(
xpad
);
return
0
;
...
...
@@ -1036,37 +1210,73 @@ static void xpad_led_disconnect(struct usb_xpad *xpad) { }
static
void
xpad_identify_controller
(
struct
usb_xpad
*
xpad
)
{
}
#endif
static
int
xpad_
open
(
struct
input_dev
*
dev
)
static
int
xpad_
start_input
(
struct
usb_xpad
*
xpad
)
{
struct
usb_xpad
*
xpad
=
input_get_drvdata
(
dev
);
/* URB was submitted in probe */
if
(
xpad
->
xtype
==
XTYPE_XBOX360W
)
return
0
;
int
error
;
xpad
->
irq_in
->
dev
=
xpad
->
udev
;
if
(
usb_submit_urb
(
xpad
->
irq_in
,
GFP_KERNEL
))
return
-
EIO
;
if
(
xpad
->
xtype
==
XTYPE_XBOXONE
)
{
/* Xbox one controller needs to be initialized. */
xpad
->
odata
[
0
]
=
0x05
;
xpad
->
odata
[
1
]
=
0x20
;
xpad
->
irq_out
->
transfer_buffer_length
=
2
;
return
usb_submit_urb
(
xpad
->
irq_out
,
GFP_KERNEL
);
error
=
xpad_start_xbox_one
(
xpad
);
if
(
error
)
{
usb_kill_urb
(
xpad
->
irq_in
)
;
return
error
;
}
}
return
0
;
}
static
void
xpad_
close
(
struct
input_dev
*
dev
)
static
void
xpad_
stop_input
(
struct
usb_xpad
*
xpad
)
{
struct
usb_xpad
*
xpad
=
input_get_drvdata
(
dev
);
usb_kill_urb
(
xpad
->
irq_in
);
}
static
int
xpad360w_start_input
(
struct
usb_xpad
*
xpad
)
{
int
error
;
if
(
xpad
->
xtype
!=
XTYPE_XBOX360W
)
error
=
usb_submit_urb
(
xpad
->
irq_in
,
GFP_KERNEL
);
if
(
error
)
return
-
EIO
;
/*
* Send presence packet.
* This will force the controller to resend connection packets.
* This is useful in the case we activate the module after the
* adapter has been plugged in, as it won't automatically
* send us info about the controllers.
*/
error
=
xpad_inquiry_pad_presence
(
xpad
);
if
(
error
)
{
usb_kill_urb
(
xpad
->
irq_in
);
return
error
;
}
xpad_stop_output
(
xpad
);
return
0
;
}
static
void
xpad360w_stop_input
(
struct
usb_xpad
*
xpad
)
{
usb_kill_urb
(
xpad
->
irq_in
);
/* Make sure we are done with presence work if it was scheduled */
flush_work
(
&
xpad
->
work
);
}
static
int
xpad_open
(
struct
input_dev
*
dev
)
{
struct
usb_xpad
*
xpad
=
input_get_drvdata
(
dev
);
return
xpad_start_input
(
xpad
);
}
static
void
xpad_close
(
struct
input_dev
*
dev
)
{
struct
usb_xpad
*
xpad
=
input_get_drvdata
(
dev
);
xpad_stop_input
(
xpad
);
}
static
void
xpad_set_up_abs
(
struct
input_dev
*
input_dev
,
signed
short
abs
)
...
...
@@ -1097,8 +1307,11 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
static
void
xpad_deinit_input
(
struct
usb_xpad
*
xpad
)
{
xpad_led_disconnect
(
xpad
);
input_unregister_device
(
xpad
->
dev
);
if
(
xpad
->
input_created
)
{
xpad
->
input_created
=
false
;
xpad_led_disconnect
(
xpad
);
input_unregister_device
(
xpad
->
dev
);
}
}
static
int
xpad_init_input
(
struct
usb_xpad
*
xpad
)
...
...
@@ -1118,8 +1331,10 @@ static int xpad_init_input(struct usb_xpad *xpad)
input_set_drvdata
(
input_dev
,
xpad
);
input_dev
->
open
=
xpad_open
;
input_dev
->
close
=
xpad_close
;
if
(
xpad
->
xtype
!=
XTYPE_XBOX360W
)
{
input_dev
->
open
=
xpad_open
;
input_dev
->
close
=
xpad_close
;
}
__set_bit
(
EV_KEY
,
input_dev
->
evbit
);
...
...
@@ -1181,6 +1396,7 @@ static int xpad_init_input(struct usb_xpad *xpad)
if
(
error
)
goto
err_disconnect_led
;
xpad
->
input_created
=
true
;
return
0
;
err_disconnect_led:
...
...
@@ -1241,6 +1457,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad
->
mapping
=
xpad_device
[
i
].
mapping
;
xpad
->
xtype
=
xpad_device
[
i
].
xtype
;
xpad
->
name
=
xpad_device
[
i
].
name
;
INIT_WORK
(
&
xpad
->
work
,
xpad_presence_work
);
if
(
xpad
->
xtype
==
XTYPE_UNKNOWN
)
{
if
(
intf
->
cur_altsetting
->
desc
.
bInterfaceClass
==
USB_CLASS_VENDOR_SPEC
)
{
...
...
@@ -1277,10 +1494,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
usb_set_intfdata
(
intf
,
xpad
);
error
=
xpad_init_input
(
xpad
);
if
(
error
)
goto
err_deinit_output
;
if
(
xpad
->
xtype
==
XTYPE_XBOX360W
)
{
/*
* Submit the int URB immediately rather than waiting for open
...
...
@@ -1289,28 +1502,24 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
* exactly the message that a controller has arrived that
* we're waiting for.
*/
xpad
->
irq_in
->
dev
=
xpad
->
udev
;
error
=
usb_submit_urb
(
xpad
->
irq_in
,
GFP_KERNEL
);
error
=
xpad360w_start_input
(
xpad
);
if
(
error
)
goto
err_deinit_input
;
goto
err_deinit_output
;
/*
*
Send presence packet.
*
This will force the controller to resend connection packets.
*
This is useful in the case we activate the module after th
e
*
adapter has been plugged in, as it won't automatically
*
send us info about the controllers
.
*
Wireless controllers require RESET_RESUME to work properly
*
after suspend. Ideally this quirk should be in usb core
*
quirk list, but we have too many vendors producing thes
e
*
controllers and we'd need to maintain 2 identical lists
*
here in this driver and in usb core
.
*/
error
=
xpad_inquiry_pad_presence
(
xpad
);
udev
->
quirks
|=
USB_QUIRK_RESET_RESUME
;
}
else
{
error
=
xpad_init_input
(
xpad
);
if
(
error
)
goto
err_
kill_in_urb
;
goto
err_
deinit_output
;
}
return
0
;
err_kill_in_urb:
usb_kill_urb
(
xpad
->
irq_in
);
err_deinit_input:
xpad_deinit_input
(
xpad
);
err_deinit_output:
xpad_deinit_output
(
xpad
);
err_free_in_urb:
...
...
@@ -1320,19 +1529,24 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
err_free_mem:
kfree
(
xpad
);
return
error
;
}
static
void
xpad_disconnect
(
struct
usb_interface
*
intf
)
{
struct
usb_xpad
*
xpad
=
usb_get_intfdata
(
intf
);
struct
usb_xpad
*
xpad
=
usb_get_intfdata
(
intf
);
if
(
xpad
->
xtype
==
XTYPE_XBOX360W
)
xpad360w_stop_input
(
xpad
);
xpad_deinit_input
(
xpad
);
xpad_deinit_output
(
xpad
);
if
(
xpad
->
xtype
==
XTYPE_XBOX360W
)
{
usb_kill_urb
(
xpad
->
irq_in
);
}
/*
* Now that both input device and LED device are gone we can
* stop output URB.
*/
xpad_stop_output
(
xpad
);
xpad_deinit_output
(
xpad
);
usb_free_urb
(
xpad
->
irq_in
);
usb_free_coherent
(
xpad
->
udev
,
XPAD_PKT_LEN
,
...
...
@@ -1343,10 +1557,55 @@ static void xpad_disconnect(struct usb_interface *intf)
usb_set_intfdata
(
intf
,
NULL
);
}
static
int
xpad_suspend
(
struct
usb_interface
*
intf
,
pm_message_t
message
)
{
struct
usb_xpad
*
xpad
=
usb_get_intfdata
(
intf
);
struct
input_dev
*
input
=
xpad
->
dev
;
if
(
xpad
->
xtype
==
XTYPE_XBOX360W
)
{
/*
* Wireless controllers always listen to input so
* they are notified when controller shows up
* or goes away.
*/
xpad360w_stop_input
(
xpad
);
}
else
{
mutex_lock
(
&
input
->
mutex
);
if
(
input
->
users
)
xpad_stop_input
(
xpad
);
mutex_unlock
(
&
input
->
mutex
);
}
xpad_stop_output
(
xpad
);
return
0
;
}
static
int
xpad_resume
(
struct
usb_interface
*
intf
)
{
struct
usb_xpad
*
xpad
=
usb_get_intfdata
(
intf
);
struct
input_dev
*
input
=
xpad
->
dev
;
int
retval
=
0
;
if
(
xpad
->
xtype
==
XTYPE_XBOX360W
)
{
retval
=
xpad360w_start_input
(
xpad
);
}
else
{
mutex_lock
(
&
input
->
mutex
);
if
(
input
->
users
)
retval
=
xpad_start_input
(
xpad
);
mutex_unlock
(
&
input
->
mutex
);
}
return
retval
;
}
static
struct
usb_driver
xpad_driver
=
{
.
name
=
"xpad"
,
.
probe
=
xpad_probe
,
.
disconnect
=
xpad_disconnect
,
.
suspend
=
xpad_suspend
,
.
resume
=
xpad_resume
,
.
reset_resume
=
xpad_resume
,
.
id_table
=
xpad_table
,
};
...
...
drivers/input/keyboard/gpio_keys.c
浏览文件 @
b26a95d4
...
...
@@ -630,7 +630,7 @@ gpio_keys_get_devtree_pdata(struct device *dev)
if
(
!
node
)
return
ERR_PTR
(
-
ENODEV
);
nbuttons
=
of_get_child_count
(
node
);
nbuttons
=
of_get_
available_
child_count
(
node
);
if
(
nbuttons
==
0
)
return
ERR_PTR
(
-
ENODEV
);
...
...
@@ -645,8 +645,10 @@ gpio_keys_get_devtree_pdata(struct device *dev)
pdata
->
rep
=
!!
of_get_property
(
node
,
"autorepeat"
,
NULL
);
of_property_read_string
(
node
,
"label"
,
&
pdata
->
name
);
i
=
0
;
for_each_child_of_node
(
node
,
pp
)
{
for_each_
available_
child_of_node
(
node
,
pp
)
{
enum
of_gpio_flags
flags
;
button
=
&
pdata
->
buttons
[
i
++
];
...
...
drivers/input/touchscreen/atmel_mxt_ts.c
浏览文件 @
b26a95d4
...
...
@@ -113,8 +113,8 @@ struct t7_config {
#define MXT_T9_DETECT (1 << 7)
struct
t9_range
{
u
16
x
;
u
16
y
;
__le
16
x
;
__le
16
y
;
}
__packed
;
/* MXT_TOUCH_MULTI_T9 orient */
...
...
@@ -216,6 +216,7 @@ struct mxt_data {
unsigned
int
irq
;
unsigned
int
max_x
;
unsigned
int
max_y
;
bool
xy_switch
;
bool
in_bootloader
;
u16
mem_size
;
u8
t100_aux_ampl
;
...
...
@@ -1665,8 +1666,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
if
(
error
)
return
error
;
le16_to_cpus
(
&
range
.
x
);
le16_to_cpus
(
&
range
.
y
);
data
->
max_x
=
get_unaligned_le16
(
&
range
.
x
);
data
->
max_y
=
get_unaligned_le16
(
&
range
.
y
);
error
=
__mxt_read_reg
(
client
,
object
->
start_address
+
MXT_T9_ORIENT
,
...
...
@@ -1674,23 +1675,7 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
if
(
error
)
return
error
;
/* Handle default values */
if
(
range
.
x
==
0
)
range
.
x
=
1023
;
if
(
range
.
y
==
0
)
range
.
y
=
1023
;
if
(
orient
&
MXT_T9_ORIENT_SWITCH
)
{
data
->
max_x
=
range
.
y
;
data
->
max_y
=
range
.
x
;
}
else
{
data
->
max_x
=
range
.
x
;
data
->
max_y
=
range
.
y
;
}
dev_dbg
(
&
client
->
dev
,
"Touchscreen size X%uY%u
\n
"
,
data
->
max_x
,
data
->
max_y
);
data
->
xy_switch
=
orient
&
MXT_T9_ORIENT_SWITCH
;
return
0
;
}
...
...
@@ -1708,13 +1693,14 @@ static int mxt_read_t100_config(struct mxt_data *data)
if
(
!
object
)
return
-
EINVAL
;
/* read touchscreen dimensions */
error
=
__mxt_read_reg
(
client
,
object
->
start_address
+
MXT_T100_XRANGE
,
sizeof
(
range_x
),
&
range_x
);
if
(
error
)
return
error
;
le16_to_cpus
(
&
range_x
);
data
->
max_x
=
get_unaligned_le16
(
&
range_x
);
error
=
__mxt_read_reg
(
client
,
object
->
start_address
+
MXT_T100_YRANGE
,
...
...
@@ -1722,36 +1708,24 @@ static int mxt_read_t100_config(struct mxt_data *data)
if
(
error
)
return
error
;
le16_to_cpus
(
&
range_y
);
data
->
max_y
=
get_unaligned_le16
(
&
range_y
);
/* read orientation config */
error
=
__mxt_read_reg
(
client
,
object
->
start_address
+
MXT_T100_CFG1
,
1
,
&
cfg
);
if
(
error
)
return
error
;
data
->
xy_switch
=
cfg
&
MXT_T100_CFG_SWITCHXY
;
/* allocate aux bytes */
error
=
__mxt_read_reg
(
client
,
object
->
start_address
+
MXT_T100_TCHAUX
,
1
,
&
tchaux
);
if
(
error
)
return
error
;
/* Handle default values */
if
(
range_x
==
0
)
range_x
=
1023
;
if
(
range_y
==
0
)
range_y
=
1023
;
if
(
cfg
&
MXT_T100_CFG_SWITCHXY
)
{
data
->
max_x
=
range_y
;
data
->
max_y
=
range_x
;
}
else
{
data
->
max_x
=
range_x
;
data
->
max_y
=
range_y
;
}
/* allocate aux bytes */
aux
=
6
;
if
(
tchaux
&
MXT_T100_TCHAUX_VECT
)
...
...
@@ -1767,9 +1741,6 @@ static int mxt_read_t100_config(struct mxt_data *data)
"T100 aux mappings vect:%u ampl:%u area:%u
\n
"
,
data
->
t100_aux_vect
,
data
->
t100_aux_ampl
,
data
->
t100_aux_area
);
dev_info
(
&
client
->
dev
,
"T100 Touchscreen size X%uY%u
\n
"
,
data
->
max_x
,
data
->
max_y
);
return
0
;
}
...
...
@@ -1828,6 +1799,19 @@ static int mxt_initialize_input_device(struct mxt_data *data)
return
-
EINVAL
;
}
/* Handle default values and orientation switch */
if
(
data
->
max_x
==
0
)
data
->
max_x
=
1023
;
if
(
data
->
max_y
==
0
)
data
->
max_y
=
1023
;
if
(
data
->
xy_switch
)
swap
(
data
->
max_x
,
data
->
max_y
);
dev_info
(
dev
,
"Touchscreen size X%uY%u
\n
"
,
data
->
max_x
,
data
->
max_y
);
/* Register input device */
input_dev
=
input_allocate_device
();
if
(
!
input_dev
)
{
dev_err
(
dev
,
"Failed to allocate memory
\n
"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录