Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
91167e19
L
linux
项目概览
xiphi1978
/
linux
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
91167e19
编写于
8月 14, 2014
作者:
D
Dmitry Torokhov
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'next' into for-linus
Prepare second round of input updates for 3.17.
上级
a6b48699
3361a976
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
459 addition
and
201 deletion
+459
-201
drivers/input/input-mt.c
drivers/input/input-mt.c
+27
-11
drivers/input/joystick/xpad.c
drivers/input/joystick/xpad.c
+157
-17
drivers/input/keyboard/cap1106.c
drivers/input/keyboard/cap1106.c
+7
-1
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.c
+69
-3
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/atmel_mxt_ts.c
+198
-168
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/edt-ft5x06.c
+0
-1
include/linux/input/mt.h
include/linux/input/mt.h
+1
-0
未找到文件。
drivers/input/input-mt.c
浏览文件 @
91167e19
...
...
@@ -236,6 +236,31 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
}
EXPORT_SYMBOL
(
input_mt_report_pointer_emulation
);
/**
* input_mt_drop_unused() - Inactivate slots not seen in this frame
* @dev: input device with allocated MT slots
*
* Lift all slots not seen since the last call to this function.
*/
void
input_mt_drop_unused
(
struct
input_dev
*
dev
)
{
struct
input_mt
*
mt
=
dev
->
mt
;
int
i
;
if
(
!
mt
)
return
;
for
(
i
=
0
;
i
<
mt
->
num_slots
;
i
++
)
{
if
(
!
input_mt_is_used
(
mt
,
&
mt
->
slots
[
i
]))
{
input_mt_slot
(
dev
,
i
);
input_event
(
dev
,
EV_ABS
,
ABS_MT_TRACKING_ID
,
-
1
);
}
}
mt
->
frame
++
;
}
EXPORT_SYMBOL
(
input_mt_drop_unused
);
/**
* input_mt_sync_frame() - synchronize mt frame
* @dev: input device with allocated MT slots
...
...
@@ -247,27 +272,18 @@ EXPORT_SYMBOL(input_mt_report_pointer_emulation);
void
input_mt_sync_frame
(
struct
input_dev
*
dev
)
{
struct
input_mt
*
mt
=
dev
->
mt
;
struct
input_mt_slot
*
s
;
bool
use_count
=
false
;
if
(
!
mt
)
return
;
if
(
mt
->
flags
&
INPUT_MT_DROP_UNUSED
)
{
for
(
s
=
mt
->
slots
;
s
!=
mt
->
slots
+
mt
->
num_slots
;
s
++
)
{
if
(
input_mt_is_used
(
mt
,
s
))
continue
;
input_mt_slot
(
dev
,
s
-
mt
->
slots
);
input_event
(
dev
,
EV_ABS
,
ABS_MT_TRACKING_ID
,
-
1
);
}
}
if
(
mt
->
flags
&
INPUT_MT_DROP_UNUSED
)
input_mt_drop_unused
(
dev
);
if
((
mt
->
flags
&
INPUT_MT_POINTER
)
&&
!
(
mt
->
flags
&
INPUT_MT_SEMI_MT
))
use_count
=
true
;
input_mt_report_pointer_emulation
(
dev
,
use_count
);
mt
->
frame
++
;
}
EXPORT_SYMBOL
(
input_mt_sync_frame
);
...
...
drivers/input/joystick/xpad.c
浏览文件 @
91167e19
...
...
@@ -95,7 +95,8 @@
#define XTYPE_XBOX 0
#define XTYPE_XBOX360 1
#define XTYPE_XBOX360W 2
#define XTYPE_UNKNOWN 3
#define XTYPE_XBOXONE 3
#define XTYPE_UNKNOWN 4
static
bool
dpad_to_buttons
;
module_param
(
dpad_to_buttons
,
bool
,
S_IRUGO
);
...
...
@@ -121,6 +122,7 @@ static const struct xpad_device {
{
0x045e
,
0x0287
,
"Microsoft Xbox Controller S"
,
0
,
XTYPE_XBOX
},
{
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
,
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
},
...
...
@@ -231,10 +233,12 @@ static const signed short xpad_abs_triggers[] = {
-
1
};
/* Xbox 360 has a vendor-specific class, so we cannot match it with only
/*
* Xbox 360 has a vendor-specific class, so we cannot match it with only
* USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
* match against vendor id as well. Wired Xbox 360 devices have protocol 1,
* wireless controllers have protocol 129. */
* wireless controllers have protocol 129.
*/
#define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \
.match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
.idVendor = (vend), \
...
...
@@ -245,9 +249,20 @@ static const signed short xpad_abs_triggers[] = {
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) }
/* The Xbox One controller uses subclass 71 and protocol 208. */
#define XPAD_XBOXONE_VENDOR_PROTOCOL(vend, pr) \
.match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
.idVendor = (vend), \
.bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
.bInterfaceSubClass = 71, \
.bInterfaceProtocol = (pr)
#define XPAD_XBOXONE_VENDOR(vend) \
{ XPAD_XBOXONE_VENDOR_PROTOCOL(vend, 208) }
static
struct
usb_device_id
xpad_table
[]
=
{
{
USB_INTERFACE_INFO
(
'X'
,
'B'
,
0
)
},
/* X-Box USB-IF not approved class */
XPAD_XBOX360_VENDOR
(
0x045e
),
/* Microsoft X-Box 360 controllers */
XPAD_XBOXONE_VENDOR
(
0x045e
),
/* Microsoft X-Box One controllers */
XPAD_XBOX360_VENDOR
(
0x046d
),
/* Logitech X-Box 360 style controllers */
XPAD_XBOX360_VENDOR
(
0x0738
),
/* Mad Catz X-Box 360 controllers */
{
USB_DEVICE
(
0x0738
,
0x4540
)
},
/* Mad Catz Beat Pad */
...
...
@@ -278,12 +293,10 @@ struct usb_xpad {
struct
urb
*
bulk_out
;
unsigned
char
*
bdata
;
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
struct
urb
*
irq_out
;
/* urb for interrupt out report */
unsigned
char
*
odata
;
/* output data */
dma_addr_t
odata_dma
;
struct
mutex
odata_mutex
;
#endif
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
struct
xpad_led
*
led
;
...
...
@@ -470,6 +483,105 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
xpad360_process_packet
(
xpad
,
cmd
,
&
data
[
4
]);
}
/*
* xpadone_process_buttons
*
* Process a button update packet from an Xbox one controller.
*/
static
void
xpadone_process_buttons
(
struct
usb_xpad
*
xpad
,
struct
input_dev
*
dev
,
unsigned
char
*
data
)
{
/* menu/view buttons */
input_report_key
(
dev
,
BTN_START
,
data
[
4
]
&
0x04
);
input_report_key
(
dev
,
BTN_SELECT
,
data
[
4
]
&
0x08
);
/* buttons A,B,X,Y */
input_report_key
(
dev
,
BTN_A
,
data
[
4
]
&
0x10
);
input_report_key
(
dev
,
BTN_B
,
data
[
4
]
&
0x20
);
input_report_key
(
dev
,
BTN_X
,
data
[
4
]
&
0x40
);
input_report_key
(
dev
,
BTN_Y
,
data
[
4
]
&
0x80
);
/* digital pad */
if
(
xpad
->
mapping
&
MAP_DPAD_TO_BUTTONS
)
{
/* dpad as buttons (left, right, up, down) */
input_report_key
(
dev
,
BTN_TRIGGER_HAPPY1
,
data
[
5
]
&
0x04
);
input_report_key
(
dev
,
BTN_TRIGGER_HAPPY2
,
data
[
5
]
&
0x08
);
input_report_key
(
dev
,
BTN_TRIGGER_HAPPY3
,
data
[
5
]
&
0x01
);
input_report_key
(
dev
,
BTN_TRIGGER_HAPPY4
,
data
[
5
]
&
0x02
);
}
else
{
input_report_abs
(
dev
,
ABS_HAT0X
,
!!
(
data
[
5
]
&
0x08
)
-
!!
(
data
[
5
]
&
0x04
));
input_report_abs
(
dev
,
ABS_HAT0Y
,
!!
(
data
[
5
]
&
0x02
)
-
!!
(
data
[
5
]
&
0x01
));
}
/* TL/TR */
input_report_key
(
dev
,
BTN_TL
,
data
[
5
]
&
0x10
);
input_report_key
(
dev
,
BTN_TR
,
data
[
5
]
&
0x20
);
/* stick press left/right */
input_report_key
(
dev
,
BTN_THUMBL
,
data
[
5
]
&
0x40
);
input_report_key
(
dev
,
BTN_THUMBR
,
data
[
5
]
&
0x80
);
if
(
!
(
xpad
->
mapping
&
MAP_STICKS_TO_NULL
))
{
/* left stick */
input_report_abs
(
dev
,
ABS_X
,
(
__s16
)
le16_to_cpup
((
__le16
*
)(
data
+
10
)));
input_report_abs
(
dev
,
ABS_Y
,
~
(
__s16
)
le16_to_cpup
((
__le16
*
)(
data
+
12
)));
/* right stick */
input_report_abs
(
dev
,
ABS_RX
,
(
__s16
)
le16_to_cpup
((
__le16
*
)(
data
+
14
)));
input_report_abs
(
dev
,
ABS_RY
,
~
(
__s16
)
le16_to_cpup
((
__le16
*
)(
data
+
16
)));
}
/* triggers left/right */
if
(
xpad
->
mapping
&
MAP_TRIGGERS_TO_BUTTONS
)
{
input_report_key
(
dev
,
BTN_TL2
,
(
__u16
)
le16_to_cpup
((
__le16
*
)(
data
+
6
)));
input_report_key
(
dev
,
BTN_TR2
,
(
__u16
)
le16_to_cpup
((
__le16
*
)(
data
+
8
)));
}
else
{
input_report_abs
(
dev
,
ABS_Z
,
(
__u16
)
le16_to_cpup
((
__le16
*
)(
data
+
6
)));
input_report_abs
(
dev
,
ABS_RZ
,
(
__u16
)
le16_to_cpup
((
__le16
*
)(
data
+
8
)));
}
input_sync
(
dev
);
}
/*
* xpadone_process_packet
*
* Completes a request by converting the data into events for the
* input subsystem. This version is for the Xbox One controller.
*
* The report format was gleaned from
* https://github.com/kylelemons/xbox/blob/master/xbox.go
*/
static
void
xpadone_process_packet
(
struct
usb_xpad
*
xpad
,
u16
cmd
,
unsigned
char
*
data
)
{
struct
input_dev
*
dev
=
xpad
->
dev
;
switch
(
data
[
0
])
{
case
0x20
:
xpadone_process_buttons
(
xpad
,
dev
,
data
);
break
;
case
0x07
:
/* the xbox button has its own special report */
input_report_key
(
dev
,
BTN_MODE
,
data
[
4
]
&
0x01
);
input_sync
(
dev
);
break
;
}
}
static
void
xpad_irq_in
(
struct
urb
*
urb
)
{
struct
usb_xpad
*
xpad
=
urb
->
context
;
...
...
@@ -502,6 +614,9 @@ static void xpad_irq_in(struct urb *urb)
case
XTYPE_XBOX360W
:
xpad360w_process_packet
(
xpad
,
0
,
xpad
->
idata
);
break
;
case
XTYPE_XBOXONE
:
xpadone_process_packet
(
xpad
,
0
,
xpad
->
idata
);
break
;
default:
xpad_process_packet
(
xpad
,
0
,
xpad
->
idata
);
}
...
...
@@ -535,7 +650,6 @@ static void xpad_bulk_out(struct urb *urb)
}
}
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
static
void
xpad_irq_out
(
struct
urb
*
urb
)
{
struct
usb_xpad
*
xpad
=
urb
->
context
;
...
...
@@ -573,6 +687,7 @@ static void xpad_irq_out(struct urb *urb)
static
int
xpad_init_output
(
struct
usb_interface
*
intf
,
struct
usb_xpad
*
xpad
)
{
struct
usb_endpoint_descriptor
*
ep_irq_out
;
int
ep_irq_out_idx
;
int
error
;
if
(
xpad
->
xtype
==
XTYPE_UNKNOWN
)
...
...
@@ -593,7 +708,10 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
goto
fail2
;
}
ep_irq_out
=
&
intf
->
cur_altsetting
->
endpoint
[
1
].
desc
;
/* Xbox One controller has in/out endpoints swapped. */
ep_irq_out_idx
=
xpad
->
xtype
==
XTYPE_XBOXONE
?
0
:
1
;
ep_irq_out
=
&
intf
->
cur_altsetting
->
endpoint
[
ep_irq_out_idx
].
desc
;
usb_fill_int_urb
(
xpad
->
irq_out
,
xpad
->
udev
,
usb_sndintpipe
(
xpad
->
udev
,
ep_irq_out
->
bEndpointAddress
),
xpad
->
odata
,
XPAD_PKT_LEN
,
...
...
@@ -621,11 +739,6 @@ static void xpad_deinit_output(struct usb_xpad *xpad)
xpad
->
odata
,
xpad
->
odata_dma
);
}
}
#else
static
int
xpad_init_output
(
struct
usb_interface
*
intf
,
struct
usb_xpad
*
xpad
)
{
return
0
;
}
static
void
xpad_deinit_output
(
struct
usb_xpad
*
xpad
)
{}
static
void
xpad_stop_output
(
struct
usb_xpad
*
xpad
)
{}
#endif
#ifdef CONFIG_JOYSTICK_XPAD_FF
static
int
xpad_play_effect
(
struct
input_dev
*
dev
,
void
*
data
,
struct
ff_effect
*
effect
)
...
...
@@ -692,7 +805,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
static
int
xpad_init_ff
(
struct
usb_xpad
*
xpad
)
{
if
(
xpad
->
xtype
==
XTYPE_UNKNOWN
)
if
(
xpad
->
xtype
==
XTYPE_UNKNOWN
||
xpad
->
xtype
==
XTYPE_XBOXONE
)
return
0
;
input_set_capability
(
xpad
->
dev
,
EV_FF
,
FF_RUMBLE
);
...
...
@@ -801,6 +914,14 @@ static int xpad_open(struct input_dev *dev)
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
);
}
return
0
;
}
...
...
@@ -816,6 +937,7 @@ static void xpad_close(struct input_dev *dev)
static
void
xpad_set_up_abs
(
struct
input_dev
*
input_dev
,
signed
short
abs
)
{
struct
usb_xpad
*
xpad
=
input_get_drvdata
(
input_dev
);
set_bit
(
abs
,
input_dev
->
absbit
);
switch
(
abs
)
{
...
...
@@ -827,7 +949,10 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
break
;
case
ABS_Z
:
case
ABS_RZ
:
/* the triggers (if mapped to axes) */
input_set_abs_params
(
input_dev
,
abs
,
0
,
255
,
0
,
0
);
if
(
xpad
->
xtype
==
XTYPE_XBOXONE
)
input_set_abs_params
(
input_dev
,
abs
,
0
,
1023
,
0
,
0
);
else
input_set_abs_params
(
input_dev
,
abs
,
0
,
255
,
0
,
0
);
break
;
case
ABS_HAT0X
:
case
ABS_HAT0Y
:
/* the d-pad (only if dpad is mapped to axes */
...
...
@@ -842,6 +967,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
struct
usb_xpad
*
xpad
;
struct
input_dev
*
input_dev
;
struct
usb_endpoint_descriptor
*
ep_irq_in
;
int
ep_irq_in_idx
;
int
i
,
error
;
for
(
i
=
0
;
xpad_device
[
i
].
idVendor
;
i
++
)
{
...
...
@@ -850,6 +976,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
break
;
}
if
(
xpad_device
[
i
].
xtype
==
XTYPE_XBOXONE
&&
intf
->
cur_altsetting
->
desc
.
bInterfaceNumber
!=
0
)
{
/*
* The Xbox One controller lists three interfaces all with the
* same interface class, subclass and protocol. Differentiate by
* interface number.
*/
return
-
ENODEV
;
}
xpad
=
kzalloc
(
sizeof
(
struct
usb_xpad
),
GFP_KERNEL
);
input_dev
=
input_allocate_device
();
if
(
!
xpad
||
!
input_dev
)
{
...
...
@@ -920,7 +1056,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
__set_bit
(
xpad_common_btn
[
i
],
input_dev
->
keybit
);
/* set up model-specific ones */
if
(
xpad
->
xtype
==
XTYPE_XBOX360
||
xpad
->
xtype
==
XTYPE_XBOX360W
)
{
if
(
xpad
->
xtype
==
XTYPE_XBOX360
||
xpad
->
xtype
==
XTYPE_XBOX360W
||
xpad
->
xtype
==
XTYPE_XBOXONE
)
{
for
(
i
=
0
;
xpad360_btn
[
i
]
>=
0
;
i
++
)
__set_bit
(
xpad360_btn
[
i
],
input_dev
->
keybit
);
}
else
{
...
...
@@ -933,7 +1070,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
__set_bit
(
xpad_btn_pad
[
i
],
input_dev
->
keybit
);
}
else
{
for
(
i
=
0
;
xpad_abs_pad
[
i
]
>=
0
;
i
++
)
xpad_set_up_abs
(
input_dev
,
xpad_abs_pad
[
i
]);
xpad_set_up_abs
(
input_dev
,
xpad_abs_pad
[
i
]);
}
if
(
xpad
->
mapping
&
MAP_TRIGGERS_TO_BUTTONS
)
{
...
...
@@ -956,7 +1093,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
if
(
error
)
goto
fail5
;
ep_irq_in
=
&
intf
->
cur_altsetting
->
endpoint
[
0
].
desc
;
/* Xbox One controller has in/out endpoints swapped. */
ep_irq_in_idx
=
xpad
->
xtype
==
XTYPE_XBOXONE
?
1
:
0
;
ep_irq_in
=
&
intf
->
cur_altsetting
->
endpoint
[
ep_irq_in_idx
].
desc
;
usb_fill_int_urb
(
xpad
->
irq_in
,
udev
,
usb_rcvintpipe
(
udev
,
ep_irq_in
->
bEndpointAddress
),
xpad
->
idata
,
XPAD_PKT_LEN
,
xpad_irq_in
,
...
...
drivers/input/keyboard/cap1106.c
浏览文件 @
91167e19
...
...
@@ -64,7 +64,7 @@ struct cap1106_priv {
struct
input_dev
*
idev
;
/* config */
unsigned
in
t
keycodes
[
CAP1106_NUM_CHN
];
unsigned
shor
t
keycodes
[
CAP1106_NUM_CHN
];
};
static
const
struct
reg_default
cap1106_reg_defaults
[]
=
{
...
...
@@ -272,6 +272,12 @@ static int cap1106_i2c_probe(struct i2c_client *i2c_client,
for
(
i
=
0
;
i
<
CAP1106_NUM_CHN
;
i
++
)
__set_bit
(
priv
->
keycodes
[
i
],
priv
->
idev
->
keybit
);
__clear_bit
(
KEY_RESERVED
,
priv
->
idev
->
keybit
);
priv
->
idev
->
keycode
=
priv
->
keycodes
;
priv
->
idev
->
keycodesize
=
sizeof
(
priv
->
keycodes
[
0
]);
priv
->
idev
->
keycodemax
=
ARRAY_SIZE
(
priv
->
keycodes
);
priv
->
idev
->
id
.
vendor
=
CAP1106_MANUFACTURER_ID
;
priv
->
idev
->
id
.
product
=
CAP1106_PRODUCT_ID
;
priv
->
idev
->
id
.
version
=
rev
;
...
...
drivers/input/mouse/synaptics.c
浏览文件 @
91167e19
...
...
@@ -117,6 +117,9 @@ void synaptics_reset(struct psmouse *psmouse)
}
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
static
bool
cr48_profile_sensor
;
struct
min_max_quirk
{
const
char
*
const
*
pnp_ids
;
int
x_min
,
x_max
,
y_min
,
y_max
;
...
...
@@ -1152,6 +1155,42 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse,
priv
->
agm_pending
=
false
;
}
static
void
synaptics_profile_sensor_process
(
struct
psmouse
*
psmouse
,
struct
synaptics_hw_state
*
sgm
,
int
num_fingers
)
{
struct
input_dev
*
dev
=
psmouse
->
dev
;
struct
synaptics_data
*
priv
=
psmouse
->
private
;
struct
synaptics_hw_state
*
hw
[
2
]
=
{
sgm
,
&
priv
->
agm
};
struct
input_mt_pos
pos
[
2
];
int
slot
[
2
],
nsemi
,
i
;
nsemi
=
clamp_val
(
num_fingers
,
0
,
2
);
for
(
i
=
0
;
i
<
nsemi
;
i
++
)
{
pos
[
i
].
x
=
hw
[
i
]
->
x
;
pos
[
i
].
y
=
synaptics_invert_y
(
hw
[
i
]
->
y
);
}
input_mt_assign_slots
(
dev
,
slot
,
pos
,
nsemi
);
for
(
i
=
0
;
i
<
nsemi
;
i
++
)
{
input_mt_slot
(
dev
,
slot
[
i
]);
input_mt_report_slot_state
(
dev
,
MT_TOOL_FINGER
,
true
);
input_report_abs
(
dev
,
ABS_MT_POSITION_X
,
pos
[
i
].
x
);
input_report_abs
(
dev
,
ABS_MT_POSITION_Y
,
pos
[
i
].
y
);
input_report_abs
(
dev
,
ABS_MT_PRESSURE
,
hw
[
i
]
->
z
);
}
input_mt_drop_unused
(
dev
);
input_mt_report_pointer_emulation
(
dev
,
false
);
input_mt_report_finger_count
(
dev
,
num_fingers
);
synaptics_report_buttons
(
psmouse
,
sgm
);
input_sync
(
dev
);
}
/*
* called for each full received packet from the touchpad
*/
...
...
@@ -1215,6 +1254,11 @@ static void synaptics_process_packet(struct psmouse *psmouse)
finger_width
=
0
;
}
if
(
cr48_profile_sensor
)
{
synaptics_profile_sensor_process
(
psmouse
,
&
hw
,
num_fingers
);
return
;
}
if
(
SYN_CAP_ADV_GESTURE
(
priv
->
ext_cap_0c
))
synaptics_report_semi_mt_data
(
dev
,
&
hw
,
&
priv
->
agm
,
num_fingers
);
...
...
@@ -1360,6 +1404,9 @@ static void set_input_params(struct psmouse *psmouse,
set_abs_position_params
(
dev
,
priv
,
ABS_X
,
ABS_Y
);
input_set_abs_params
(
dev
,
ABS_PRESSURE
,
0
,
255
,
0
,
0
);
if
(
cr48_profile_sensor
)
input_set_abs_params
(
dev
,
ABS_MT_PRESSURE
,
0
,
255
,
0
,
0
);
if
(
SYN_CAP_IMAGE_SENSOR
(
priv
->
ext_cap_0c
))
{
set_abs_position_params
(
dev
,
priv
,
ABS_MT_POSITION_X
,
ABS_MT_POSITION_Y
);
...
...
@@ -1371,11 +1418,16 @@ static void set_input_params(struct psmouse *psmouse,
__set_bit
(
BTN_TOOL_QUADTAP
,
dev
->
keybit
);
__set_bit
(
BTN_TOOL_QUINTTAP
,
dev
->
keybit
);
}
else
if
(
SYN_CAP_ADV_GESTURE
(
priv
->
ext_cap_0c
))
{
/* Non-image sensors with AGM use semi-mt */
__set_bit
(
INPUT_PROP_SEMI_MT
,
dev
->
propbit
);
input_mt_init_slots
(
dev
,
2
,
0
);
set_abs_position_params
(
dev
,
priv
,
ABS_MT_POSITION_X
,
ABS_MT_POSITION_Y
);
/*
* Profile sensor in CR-48 tracks contacts reasonably well,
* other non-image sensors with AGM use semi-mt.
*/
input_mt_init_slots
(
dev
,
2
,
INPUT_MT_POINTER
|
(
cr48_profile_sensor
?
INPUT_MT_TRACK
:
INPUT_MT_SEMI_MT
));
}
if
(
SYN_CAP_PALMDETECT
(
priv
->
capabilities
))
...
...
@@ -1577,10 +1629,24 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = {
{
}
};
static
const
struct
dmi_system_id
__initconst
cr48_dmi_table
[]
=
{
#if defined(CONFIG_DMI) && defined(CONFIG_X86)
{
/* Cr-48 Chromebook (Codename Mario) */
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"IEC"
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"Mario"
),
},
},
#endif
{
}
};
void
__init
synaptics_module_init
(
void
)
{
impaired_toshiba_kbc
=
dmi_check_system
(
toshiba_dmi_table
);
broken_olpc_ec
=
dmi_check_system
(
olpc_dmi_table
);
cr48_profile_sensor
=
dmi_check_system
(
cr48_dmi_table
);
}
static
int
__synaptics_init
(
struct
psmouse
*
psmouse
,
bool
absolute_mode
)
...
...
drivers/input/touchscreen/atmel_mxt_ts.c
浏览文件 @
91167e19
...
...
@@ -359,7 +359,6 @@ static int mxt_bootloader_read(struct mxt_data *data,
msg
.
buf
=
val
;
ret
=
i2c_transfer
(
data
->
client
->
adapter
,
&
msg
,
1
);
if
(
ret
==
1
)
{
ret
=
0
;
}
else
{
...
...
@@ -414,6 +413,7 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry)
case
0x5b
:
bootloader
=
appmode
-
0x26
;
break
;
default:
dev_err
(
&
data
->
client
->
dev
,
"Appmode i2c address 0x%02x not found
\n
"
,
...
...
@@ -425,20 +425,20 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry)
return
0
;
}
static
int
mxt_probe_bootloader
(
struct
mxt_data
*
data
,
bool
retry
)
static
int
mxt_probe_bootloader
(
struct
mxt_data
*
data
,
bool
alt_address
)
{
struct
device
*
dev
=
&
data
->
client
->
dev
;
int
ret
;
int
error
;
u8
val
;
bool
crc_failure
;
ret
=
mxt_lookup_bootloader_address
(
data
,
retry
);
if
(
ret
)
return
ret
;
error
=
mxt_lookup_bootloader_address
(
data
,
alt_address
);
if
(
error
)
return
error
;
ret
=
mxt_bootloader_read
(
data
,
&
val
,
1
);
if
(
ret
)
return
ret
;
error
=
mxt_bootloader_read
(
data
,
&
val
,
1
);
if
(
error
)
return
error
;
/* Check app crc fail mode */
crc_failure
=
(
val
&
~
MXT_BOOT_STATUS_MASK
)
==
MXT_APP_CRC_FAIL
;
...
...
@@ -1064,6 +1064,137 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, off_t end_off)
return
crc
;
}
static
int
mxt_prepare_cfg_mem
(
struct
mxt_data
*
data
,
const
struct
firmware
*
cfg
,
unsigned
int
data_pos
,
unsigned
int
cfg_start_ofs
,
u8
*
config_mem
,
size_t
config_mem_size
)
{
struct
device
*
dev
=
&
data
->
client
->
dev
;
struct
mxt_object
*
object
;
unsigned
int
type
,
instance
,
size
,
byte_offset
;
int
offset
;
int
ret
;
int
i
;
u16
reg
;
u8
val
;
while
(
data_pos
<
cfg
->
size
)
{
/* Read type, instance, length */
ret
=
sscanf
(
cfg
->
data
+
data_pos
,
"%x %x %x%n"
,
&
type
,
&
instance
,
&
size
,
&
offset
);
if
(
ret
==
0
)
{
/* EOF */
break
;
}
else
if
(
ret
!=
3
)
{
dev_err
(
dev
,
"Bad format: failed to parse object
\n
"
);
return
-
EINVAL
;
}
data_pos
+=
offset
;
object
=
mxt_get_object
(
data
,
type
);
if
(
!
object
)
{
/* Skip object */
for
(
i
=
0
;
i
<
size
;
i
++
)
{
ret
=
sscanf
(
cfg
->
data
+
data_pos
,
"%hhx%n"
,
&
val
,
&
offset
);
if
(
ret
!=
1
)
{
dev_err
(
dev
,
"Bad format in T%d at %d
\n
"
,
type
,
i
);
return
-
EINVAL
;
}
data_pos
+=
offset
;
}
continue
;
}
if
(
size
>
mxt_obj_size
(
object
))
{
/*
* Either we are in fallback mode due to wrong
* config or config from a later fw version,
* or the file is corrupt or hand-edited.
*/
dev_warn
(
dev
,
"Discarding %zu byte(s) in T%u
\n
"
,
size
-
mxt_obj_size
(
object
),
type
);
}
else
if
(
mxt_obj_size
(
object
)
>
size
)
{
/*
* If firmware is upgraded, new bytes may be added to
* end of objects. It is generally forward compatible
* to zero these bytes - previous behaviour will be
* retained. However this does invalidate the CRC and
* will force fallback mode until the configuration is
* updated. We warn here but do nothing else - the
* malloc has zeroed the entire configuration.
*/
dev_warn
(
dev
,
"Zeroing %zu byte(s) in T%d
\n
"
,
mxt_obj_size
(
object
)
-
size
,
type
);
}
if
(
instance
>=
mxt_obj_instances
(
object
))
{
dev_err
(
dev
,
"Object instances exceeded!
\n
"
);
return
-
EINVAL
;
}
reg
=
object
->
start_address
+
mxt_obj_size
(
object
)
*
instance
;
for
(
i
=
0
;
i
<
size
;
i
++
)
{
ret
=
sscanf
(
cfg
->
data
+
data_pos
,
"%hhx%n"
,
&
val
,
&
offset
);
if
(
ret
!=
1
)
{
dev_err
(
dev
,
"Bad format in T%d at %d
\n
"
,
type
,
i
);
return
-
EINVAL
;
}
data_pos
+=
offset
;
if
(
i
>
mxt_obj_size
(
object
))
continue
;
byte_offset
=
reg
+
i
-
cfg_start_ofs
;
if
(
byte_offset
>=
0
&&
byte_offset
<
config_mem_size
)
{
*
(
config_mem
+
byte_offset
)
=
val
;
}
else
{
dev_err
(
dev
,
"Bad object: reg:%d, T%d, ofs=%d
\n
"
,
reg
,
object
->
type
,
byte_offset
);
return
-
EINVAL
;
}
}
}
return
0
;
}
static
int
mxt_upload_cfg_mem
(
struct
mxt_data
*
data
,
unsigned
int
cfg_start
,
u8
*
config_mem
,
size_t
config_mem_size
)
{
unsigned
int
byte_offset
=
0
;
int
error
;
/* Write configuration as blocks */
while
(
byte_offset
<
config_mem_size
)
{
unsigned
int
size
=
config_mem_size
-
byte_offset
;
if
(
size
>
MXT_MAX_BLOCK_WRITE
)
size
=
MXT_MAX_BLOCK_WRITE
;
error
=
__mxt_write_reg
(
data
->
client
,
cfg_start
+
byte_offset
,
size
,
config_mem
+
byte_offset
);
if
(
error
)
{
dev_err
(
&
data
->
client
->
dev
,
"Config write error, ret=%d
\n
"
,
error
);
return
error
;
}
byte_offset
+=
size
;
}
return
0
;
}
/*
* mxt_update_cfg - download configuration to chip
*
...
...
@@ -1087,26 +1218,20 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
{
struct
device
*
dev
=
&
data
->
client
->
dev
;
struct
mxt_info
cfg_info
;
struct
mxt_object
*
object
;
int
ret
;
int
offset
;
int
data_pos
;
int
byte_offset
;
int
i
;
int
cfg_start_ofs
;
u32
info_crc
,
config_crc
,
calculated_crc
;
u8
*
config_mem
;
size_t
config_mem_size
;
unsigned
int
type
,
instance
,
size
;
u8
val
;
u16
reg
;
mxt_update_crc
(
data
,
MXT_COMMAND_REPORTALL
,
1
);
if
(
strncmp
(
cfg
->
data
,
MXT_CFG_MAGIC
,
strlen
(
MXT_CFG_MAGIC
)))
{
dev_err
(
dev
,
"Unrecognised config file
\n
"
);
ret
=
-
EINVAL
;
goto
release
;
return
-
EINVAL
;
}
data_pos
=
strlen
(
MXT_CFG_MAGIC
);
...
...
@@ -1118,8 +1243,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
&
offset
);
if
(
ret
!=
1
)
{
dev_err
(
dev
,
"Bad format
\n
"
);
ret
=
-
EINVAL
;
goto
release
;
return
-
EINVAL
;
}
data_pos
+=
offset
;
...
...
@@ -1127,30 +1251,26 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
if
(
cfg_info
.
family_id
!=
data
->
info
.
family_id
)
{
dev_err
(
dev
,
"Family ID mismatch!
\n
"
);
ret
=
-
EINVAL
;
goto
release
;
return
-
EINVAL
;
}
if
(
cfg_info
.
variant_id
!=
data
->
info
.
variant_id
)
{
dev_err
(
dev
,
"Variant ID mismatch!
\n
"
);
ret
=
-
EINVAL
;
goto
release
;
return
-
EINVAL
;
}
/* Read CRCs */
ret
=
sscanf
(
cfg
->
data
+
data_pos
,
"%x%n"
,
&
info_crc
,
&
offset
);
if
(
ret
!=
1
)
{
dev_err
(
dev
,
"Bad format: failed to parse Info CRC
\n
"
);
ret
=
-
EINVAL
;
goto
release
;
return
-
EINVAL
;
}
data_pos
+=
offset
;
ret
=
sscanf
(
cfg
->
data
+
data_pos
,
"%x%n"
,
&
config_crc
,
&
offset
);
if
(
ret
!=
1
)
{
dev_err
(
dev
,
"Bad format: failed to parse Config CRC
\n
"
);
ret
=
-
EINVAL
;
goto
release
;
return
-
EINVAL
;
}
data_pos
+=
offset
;
...
...
@@ -1166,8 +1286,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
}
else
if
(
config_crc
==
data
->
config_crc
)
{
dev_dbg
(
dev
,
"Config CRC 0x%06X: OK
\n
"
,
data
->
config_crc
);
ret
=
0
;
goto
release
;
return
0
;
}
else
{
dev_info
(
dev
,
"Config CRC 0x%06X: does not match file 0x%06X
\n
"
,
data
->
config_crc
,
config_crc
);
...
...
@@ -1186,93 +1305,13 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
config_mem
=
kzalloc
(
config_mem_size
,
GFP_KERNEL
);
if
(
!
config_mem
)
{
dev_err
(
dev
,
"Failed to allocate memory
\n
"
);
ret
=
-
ENOMEM
;
goto
release
;
return
-
ENOMEM
;
}
while
(
data_pos
<
cfg
->
size
)
{
/* Read type, instance, length */
ret
=
sscanf
(
cfg
->
data
+
data_pos
,
"%x %x %x%n"
,
&
type
,
&
instance
,
&
size
,
&
offset
);
if
(
ret
==
0
)
{
/* EOF */
break
;
}
else
if
(
ret
!=
3
)
{
dev_err
(
dev
,
"Bad format: failed to parse object
\n
"
);
ret
=
-
EINVAL
;
goto
release_mem
;
}
data_pos
+=
offset
;
object
=
mxt_get_object
(
data
,
type
);
if
(
!
object
)
{
/* Skip object */
for
(
i
=
0
;
i
<
size
;
i
++
)
{
ret
=
sscanf
(
cfg
->
data
+
data_pos
,
"%hhx%n"
,
&
val
,
&
offset
);
data_pos
+=
offset
;
}
continue
;
}
if
(
size
>
mxt_obj_size
(
object
))
{
/*
* Either we are in fallback mode due to wrong
* config or config from a later fw version,
* or the file is corrupt or hand-edited.
*/
dev_warn
(
dev
,
"Discarding %zu byte(s) in T%u
\n
"
,
size
-
mxt_obj_size
(
object
),
type
);
}
else
if
(
mxt_obj_size
(
object
)
>
size
)
{
/*
* If firmware is upgraded, new bytes may be added to
* end of objects. It is generally forward compatible
* to zero these bytes - previous behaviour will be
* retained. However this does invalidate the CRC and
* will force fallback mode until the configuration is
* updated. We warn here but do nothing else - the
* malloc has zeroed the entire configuration.
*/
dev_warn
(
dev
,
"Zeroing %zu byte(s) in T%d
\n
"
,
mxt_obj_size
(
object
)
-
size
,
type
);
}
if
(
instance
>=
mxt_obj_instances
(
object
))
{
dev_err
(
dev
,
"Object instances exceeded!
\n
"
);
ret
=
-
EINVAL
;
goto
release_mem
;
}
reg
=
object
->
start_address
+
mxt_obj_size
(
object
)
*
instance
;
for
(
i
=
0
;
i
<
size
;
i
++
)
{
ret
=
sscanf
(
cfg
->
data
+
data_pos
,
"%hhx%n"
,
&
val
,
&
offset
);
if
(
ret
!=
1
)
{
dev_err
(
dev
,
"Bad format in T%d
\n
"
,
type
);
ret
=
-
EINVAL
;
goto
release_mem
;
}
data_pos
+=
offset
;
if
(
i
>
mxt_obj_size
(
object
))
continue
;
byte_offset
=
reg
+
i
-
cfg_start_ofs
;
if
((
byte_offset
>=
0
)
&&
(
byte_offset
<=
config_mem_size
))
{
*
(
config_mem
+
byte_offset
)
=
val
;
}
else
{
dev_err
(
dev
,
"Bad object: reg:%d, T%d, ofs=%d
\n
"
,
reg
,
object
->
type
,
byte_offset
);
ret
=
-
EINVAL
;
goto
release_mem
;
}
}
}
ret
=
mxt_prepare_cfg_mem
(
data
,
cfg
,
data_pos
,
cfg_start_ofs
,
config_mem
,
config_mem_size
);
if
(
ret
)
goto
release_mem
;
/* Calculate crc of the received configs (not the raw config file) */
if
(
data
->
T7_address
<
cfg_start_ofs
)
{
...
...
@@ -1286,28 +1325,14 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
data
->
T7_address
-
cfg_start_ofs
,
config_mem_size
);
if
(
config_crc
>
0
&&
(
config_crc
!=
calculated_crc
)
)
if
(
config_crc
>
0
&&
config_crc
!=
calculated_crc
)
dev_warn
(
dev
,
"Config CRC error, calculated=%06X, file=%06X
\n
"
,
calculated_crc
,
config_crc
);
/* Write configuration as blocks */
byte_offset
=
0
;
while
(
byte_offset
<
config_mem_size
)
{
size
=
config_mem_size
-
byte_offset
;
if
(
size
>
MXT_MAX_BLOCK_WRITE
)
size
=
MXT_MAX_BLOCK_WRITE
;
ret
=
__mxt_write_reg
(
data
->
client
,
cfg_start_ofs
+
byte_offset
,
size
,
config_mem
+
byte_offset
);
if
(
ret
!=
0
)
{
dev_err
(
dev
,
"Config write error, ret=%d
\n
"
,
ret
);
goto
release_mem
;
}
byte_offset
+=
size
;
}
ret
=
mxt_upload_cfg_mem
(
data
,
cfg_start_ofs
,
config_mem
,
config_mem_size
);
if
(
ret
)
goto
release_mem
;
mxt_update_crc
(
data
,
MXT_COMMAND_BACKUPNV
,
MXT_BACKUP_VALUE
);
...
...
@@ -1319,8 +1344,6 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
release_mem:
kfree
(
config_mem
);
release:
release_firmware
(
cfg
);
return
ret
;
}
...
...
@@ -1422,10 +1445,12 @@ static int mxt_get_object_table(struct mxt_data *data)
switch
(
object
->
type
)
{
case
MXT_GEN_MESSAGE_T5
:
if
(
data
->
info
.
family_id
==
0x80
)
{
if
(
data
->
info
.
family_id
==
0x80
&&
data
->
info
.
version
<
0x20
)
{
/*
* On mXT224 read and discard unused CRC byte
* otherwise DMA reads are misaligned
* On mXT224 firmware versions prior to V2.0
* read and discard unused CRC byte otherwise
* DMA reads are misaligned.
*/
data
->
T5_msg_size
=
mxt_obj_size
(
object
);
}
else
{
...
...
@@ -1433,6 +1458,7 @@ static int mxt_get_object_table(struct mxt_data *data)
data
->
T5_msg_size
=
mxt_obj_size
(
object
)
-
1
;
}
data
->
T5_address
=
object
->
start_address
;
break
;
case
MXT_GEN_COMMAND_T6
:
data
->
T6_reportid
=
min_id
;
data
->
T6_address
=
object
->
start_address
;
...
...
@@ -1638,46 +1664,45 @@ static int mxt_configure_objects(struct mxt_data *data,
static
void
mxt_config_cb
(
const
struct
firmware
*
cfg
,
void
*
ctx
)
{
mxt_configure_objects
(
ctx
,
cfg
);
release_firmware
(
cfg
);
}
static
int
mxt_initialize
(
struct
mxt_data
*
data
)
{
struct
i2c_client
*
client
=
data
->
client
;
int
recovery_attempts
=
0
;
int
error
;
bool
alt_bootloader_addr
=
false
;
bool
retry
=
false
;
retry_info:
error
=
mxt_get_info
(
data
);
if
(
error
)
{
retry_bootloader:
error
=
mxt_probe_bootloader
(
data
,
alt_bootloader_addr
);
while
(
1
)
{
error
=
mxt_get_info
(
data
);
if
(
!
error
)
break
;
/* Check bootloader state */
error
=
mxt_probe_bootloader
(
data
,
false
);
if
(
error
)
{
if
(
alt_bootloader_addr
)
{
dev_info
(
&
client
->
dev
,
"Trying alternate bootloader address
\n
"
);
error
=
mxt_probe_bootloader
(
data
,
true
);
if
(
error
)
{
/* Chip is not in appmode or bootloader mode */
return
error
;
}
}
dev_info
(
&
client
->
dev
,
"Trying alternate bootloader address
\n
"
);
alt_bootloader_addr
=
true
;
goto
retry_bootloader
;
}
else
{
if
(
retry
)
{
dev_err
(
&
client
->
dev
,
"Could not recover from bootloader mode
\n
"
);
/*
* We can reflash from this state, so do not
* abort init
*/
data
->
in_bootloader
=
true
;
return
0
;
}
/* Attempt to exit bootloader into app mode */
mxt_send_bootloader_cmd
(
data
,
false
);
msleep
(
MXT_FW_RESET_TIME
);
retry
=
true
;
goto
retry_info
;
/* OK, we are in bootloader, see if we can recover */
if
(
++
recovery_attempts
>
1
)
{
dev_err
(
&
client
->
dev
,
"Could not recover from bootloader mode
\n
"
);
/*
* We can reflash from this state, so do not
* abort initialization.
*/
data
->
in_bootloader
=
true
;
return
0
;
}
/* Attempt to exit bootloader into app mode */
mxt_send_bootloader_cmd
(
data
,
false
);
msleep
(
MXT_FW_RESET_TIME
);
}
/* Get object table information */
...
...
@@ -1687,13 +1712,18 @@ static int mxt_initialize(struct mxt_data *data)
return
error
;
}
mxt_acquire_irq
(
data
);
error
=
mxt_acquire_irq
(
data
);
if
(
error
)
goto
err_free_object_table
;
request_firmware_nowait
(
THIS_MODULE
,
true
,
MXT_CFG_NAME
,
&
data
->
client
->
dev
,
GFP_KERNEL
,
data
,
mxt_config_cb
);
error
=
request_firmware_nowait
(
THIS_MODULE
,
true
,
MXT_CFG_NAME
,
&
client
->
dev
,
GFP_KERNEL
,
data
,
mxt_config_cb
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"Failed to invoke firmware loader: %d
\n
"
,
error
);
goto
err_free_object_table
;
}
return
0
;
...
...
drivers/input/touchscreen/edt-ft5x06.c
浏览文件 @
91167e19
...
...
@@ -262,7 +262,6 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
case
M06
:
wrbuf
[
0
]
=
tsdata
->
factory_mode
?
0xf3
:
0xfc
;
wrbuf
[
1
]
=
tsdata
->
factory_mode
?
addr
&
0x7f
:
addr
&
0x3f
;
wrbuf
[
1
]
=
tsdata
->
factory_mode
?
addr
&
0x7f
:
addr
&
0x3f
;
wrbuf
[
2
]
=
value
;
wrbuf
[
3
]
=
wrbuf
[
0
]
^
wrbuf
[
1
]
^
wrbuf
[
2
];
return
edt_ft5x06_ts_readwrite
(
tsdata
->
client
,
4
,
...
...
include/linux/input/mt.h
浏览文件 @
91167e19
...
...
@@ -105,6 +105,7 @@ void input_mt_report_slot_state(struct input_dev *dev,
void
input_mt_report_finger_count
(
struct
input_dev
*
dev
,
int
count
);
void
input_mt_report_pointer_emulation
(
struct
input_dev
*
dev
,
bool
use_count
);
void
input_mt_drop_unused
(
struct
input_dev
*
dev
);
void
input_mt_sync_frame
(
struct
input_dev
*
dev
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录