Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
48853389
Commit
48853389
authored
Apr 21, 2015
by
Dmitry Torokhov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next' into for-linus
Prepare second round of updates for 4.1 merge window.
parents
85a36858
c9eeb508
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
806 additions
and
42 deletions
+806
-42
Documentation/input/alps.txt
Documentation/input/alps.txt
+7
-2
MAINTAINERS
MAINTAINERS
+8
-0
drivers/input/ff-core.c
drivers/input/ff-core.c
+4
-6
drivers/input/joystick/xpad.c
drivers/input/joystick/xpad.c
+20
-1
drivers/input/keyboard/lm8333.c
drivers/input/keyboard/lm8333.c
+2
-2
drivers/input/mouse/Kconfig
drivers/input/mouse/Kconfig
+12
-0
drivers/input/mouse/Makefile
drivers/input/mouse/Makefile
+1
-0
drivers/input/mouse/cyapa.c
drivers/input/mouse/cyapa.c
+2
-2
drivers/input/mouse/elan_i2c.h
drivers/input/mouse/elan_i2c.h
+3
-0
drivers/input/mouse/elan_i2c_core.c
drivers/input/mouse/elan_i2c_core.c
+25
-13
drivers/input/mouse/elan_i2c_i2c.c
drivers/input/mouse/elan_i2c_i2c.c
+25
-2
drivers/input/mouse/elan_i2c_smbus.c
drivers/input/mouse/elan_i2c_smbus.c
+10
-2
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse-base.c
+17
-0
drivers/input/mouse/psmouse.h
drivers/input/mouse/psmouse.h
+1
-0
drivers/input/mouse/vmmouse.c
drivers/input/mouse/vmmouse.c
+508
-0
drivers/input/mouse/vmmouse.h
drivers/input/mouse/vmmouse.h
+30
-0
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/atmel_mxt_ts.c
+130
-11
drivers/input/touchscreen/elants_i2c.c
drivers/input/touchscreen/elants_i2c.c
+1
-1
No files found.
Documentation/input/alps.txt
View file @
48853389
...
@@ -94,6 +94,10 @@ PS/2 packet format
...
@@ -94,6 +94,10 @@ PS/2 packet format
Note that the device never signals overflow condition.
Note that the device never signals overflow condition.
For protocol version 2 devices when the trackpoint is used, and no fingers
are on the touchpad, the M R L bits signal the combined status of both the
pointingstick and touchpad buttons.
ALPS Absolute Mode - Protocol Version 1
ALPS Absolute Mode - Protocol Version 1
--------------------------------------
--------------------------------------
...
@@ -107,7 +111,7 @@ ALPS Absolute Mode - Protocol Version 1
...
@@ -107,7 +111,7 @@ ALPS Absolute Mode - Protocol Version 1
ALPS Absolute Mode - Protocol Version 2
ALPS Absolute Mode - Protocol Version 2
---------------------------------------
---------------------------------------
byte 0: 1 ? ? ? 1
? ? ?
byte 0: 1 ? ? ? 1
PSM PSR PSL
byte 1: 0 x6 x5 x4 x3 x2 x1 x0
byte 1: 0 x6 x5 x4 x3 x2 x1 x0
byte 2: 0 x10 x9 x8 x7 ? fin ges
byte 2: 0 x10 x9 x8 x7 ? fin ges
byte 3: 0 y9 y8 y7 1 M R L
byte 3: 0 y9 y8 y7 1 M R L
...
@@ -115,7 +119,8 @@ ALPS Absolute Mode - Protocol Version 2
...
@@ -115,7 +119,8 @@ ALPS Absolute Mode - Protocol Version 2
byte 5: 0 z6 z5 z4 z3 z2 z1 z0
byte 5: 0 z6 z5 z4 z3 z2 z1 z0
Protocol Version 2 DualPoint devices send standard PS/2 mouse packets for
Protocol Version 2 DualPoint devices send standard PS/2 mouse packets for
the DualPoint Stick.
the DualPoint Stick. For non interleaved dualpoint devices the pointingstick
buttons get reported separately in the PSM, PSR and PSL bits.
Dualpoint device -- interleaved packet format
Dualpoint device -- interleaved packet format
---------------------------------------------
---------------------------------------------
...
...
MAINTAINERS
View file @
48853389
...
@@ -10530,6 +10530,14 @@ L: linux-kernel@vger.kernel.org
...
@@ -10530,6 +10530,14 @@ L: linux-kernel@vger.kernel.org
S: Maintained
S: Maintained
F: drivers/misc/vmw_balloon.c
F: drivers/misc/vmw_balloon.c
VMWARE VMMOUSE SUBDRIVER
M: "VMware Graphics" <linux-graphics-maintainer@vmware.com>
M: "VMware, Inc." <pv-drivers@vmware.com>
L: linux-input@vger.kernel.org
S: Maintained
F: drivers/input/mouse/vmmouse.c
F: drivers/input/mouse/vmmouse.h
VMWARE VMXNET3 ETHERNET DRIVER
VMWARE VMXNET3 ETHERNET DRIVER
M: Shreyas Bhatewara <sbhatewara@vmware.com>
M: Shreyas Bhatewara <sbhatewara@vmware.com>
M: "VMware, Inc." <pv-drivers@vmware.com>
M: "VMware, Inc." <pv-drivers@vmware.com>
...
...
drivers/input/ff-core.c
View file @
48853389
...
@@ -23,8 +23,6 @@
...
@@ -23,8 +23,6 @@
/* #define DEBUG */
/* #define DEBUG */
#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt
#include <linux/input.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/mutex.h>
...
@@ -116,7 +114,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
...
@@ -116,7 +114,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
if
(
effect
->
type
<
FF_EFFECT_MIN
||
effect
->
type
>
FF_EFFECT_MAX
||
if
(
effect
->
type
<
FF_EFFECT_MIN
||
effect
->
type
>
FF_EFFECT_MAX
||
!
test_bit
(
effect
->
type
,
dev
->
ffbit
))
{
!
test_bit
(
effect
->
type
,
dev
->
ffbit
))
{
pr_debug
(
"invalid or not supported effect type in upload
\n
"
);
dev_dbg
(
&
dev
->
dev
,
"invalid or not supported effect type in upload
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -124,7 +122,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
...
@@ -124,7 +122,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
(
effect
->
u
.
periodic
.
waveform
<
FF_WAVEFORM_MIN
||
(
effect
->
u
.
periodic
.
waveform
<
FF_WAVEFORM_MIN
||
effect
->
u
.
periodic
.
waveform
>
FF_WAVEFORM_MAX
||
effect
->
u
.
periodic
.
waveform
>
FF_WAVEFORM_MAX
||
!
test_bit
(
effect
->
u
.
periodic
.
waveform
,
dev
->
ffbit
)))
{
!
test_bit
(
effect
->
u
.
periodic
.
waveform
,
dev
->
ffbit
)))
{
pr_debug
(
"invalid or not supported wave form in upload
\n
"
);
dev_dbg
(
&
dev
->
dev
,
"invalid or not supported wave form in upload
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -246,7 +244,7 @@ static int flush_effects(struct input_dev *dev, struct file *file)
...
@@ -246,7 +244,7 @@ static int flush_effects(struct input_dev *dev, struct file *file)
struct
ff_device
*
ff
=
dev
->
ff
;
struct
ff_device
*
ff
=
dev
->
ff
;
int
i
;
int
i
;
pr_debug
(
"flushing now
\n
"
);
dev_dbg
(
&
dev
->
dev
,
"flushing now
\n
"
);
mutex_lock
(
&
ff
->
mutex
);
mutex_lock
(
&
ff
->
mutex
);
...
@@ -316,7 +314,7 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects)
...
@@ -316,7 +314,7 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects)
int
i
;
int
i
;
if
(
!
max_effects
)
{
if
(
!
max_effects
)
{
pr_err
(
"cannot allocate device without any effects
\n
"
);
dev_err
(
&
dev
->
dev
,
"cannot allocate device without any effects
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
...
drivers/input/joystick/xpad.c
View file @
48853389
...
@@ -31,12 +31,14 @@
...
@@ -31,12 +31,14 @@
* - the iForce driver drivers/char/joystick/iforce.c
* - the iForce driver drivers/char/joystick/iforce.c
* - the skeleton-driver drivers/usb/usb-skeleton.c
* - the skeleton-driver drivers/usb/usb-skeleton.c
* - Xbox 360 information http://www.free60.org/wiki/Gamepad
* - Xbox 360 information http://www.free60.org/wiki/Gamepad
* - Xbox One information https://github.com/quantus/xbox-one-controller-protocol
*
*
* Thanks to:
* Thanks to:
* - ITO Takayuki for providing essential xpad information on his website
* - ITO Takayuki for providing essential xpad information on his website
* - Vojtech Pavlik - iforce driver / input subsystem
* - Vojtech Pavlik - iforce driver / input subsystem
* - Greg Kroah-Hartman - usb-skeleton driver
* - Greg Kroah-Hartman - usb-skeleton driver
* - XBOX Linux project - extra USB id's
* - XBOX Linux project - extra USB id's
* - Pekka Pöyry (quantus) - Xbox One controller reverse engineering
*
*
* TODO:
* TODO:
* - fine tune axes (especially trigger axes)
* - fine tune axes (especially trigger axes)
...
@@ -828,6 +830,23 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
...
@@ -828,6 +830,23 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
return
usb_submit_urb
(
xpad
->
irq_out
,
GFP_ATOMIC
);
return
usb_submit_urb
(
xpad
->
irq_out
,
GFP_ATOMIC
);
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
;
return
usb_submit_urb
(
xpad
->
irq_out
,
GFP_ATOMIC
);
default:
default:
dev_dbg
(
&
xpad
->
dev
->
dev
,
dev_dbg
(
&
xpad
->
dev
->
dev
,
"%s - rumble command sent to unsupported xpad type: %d
\n
"
,
"%s - rumble command sent to unsupported xpad type: %d
\n
"
,
...
@@ -841,7 +860,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
...
@@ -841,7 +860,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
static
int
xpad_init_ff
(
struct
usb_xpad
*
xpad
)
static
int
xpad_init_ff
(
struct
usb_xpad
*
xpad
)
{
{
if
(
xpad
->
xtype
==
XTYPE_UNKNOWN
||
xpad
->
xtype
==
XTYPE_XBOXONE
)
if
(
xpad
->
xtype
==
XTYPE_UNKNOWN
)
return
0
;
return
0
;
input_set_capability
(
xpad
->
dev
,
EV_FF
,
FF_RUMBLE
);
input_set_capability
(
xpad
->
dev
,
EV_FF
,
FF_RUMBLE
);
...
...
drivers/input/keyboard/lm8333.c
View file @
48853389
/*
/*
* LM8333 keypad driver
* LM8333 keypad driver
* Copyright (C) 2012 Wolfram Sang, Pengutronix <
w.sang
@pengutronix.de>
* Copyright (C) 2012 Wolfram Sang, Pengutronix <
kernel
@pengutronix.de>
*
*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
...
@@ -231,6 +231,6 @@ static struct i2c_driver lm8333_driver = {
...
@@ -231,6 +231,6 @@ static struct i2c_driver lm8333_driver = {
};
};
module_i2c_driver
(
lm8333_driver
);
module_i2c_driver
(
lm8333_driver
);
MODULE_AUTHOR
(
"Wolfram Sang <
w.sang
@pengutronix.de>"
);
MODULE_AUTHOR
(
"Wolfram Sang <
kernel
@pengutronix.de>"
);
MODULE_DESCRIPTION
(
"LM8333 keyboard driver"
);
MODULE_DESCRIPTION
(
"LM8333 keyboard driver"
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/input/mouse/Kconfig
View file @
48853389
...
@@ -149,6 +149,18 @@ config MOUSE_PS2_FOCALTECH
...
@@ -149,6 +149,18 @@ config MOUSE_PS2_FOCALTECH
If unsure, say Y.
If unsure, say Y.
config MOUSE_PS2_VMMOUSE
bool "Virtual mouse (vmmouse)"
depends on MOUSE_PS2 && X86 && HYPERVISOR_GUEST
help
Say Y here if you are running under control of VMware hypervisor
(ESXi, Workstation or Fusion). Also make sure that when you enable
this option, you remove the xf86-input-vmmouse user-space driver
or upgrade it to at least xf86-input-vmmouse 13.0.1, which doesn't
load in the presence of an in-kernel vmmouse driver.
If unsure, say N.
config MOUSE_SERIAL
config MOUSE_SERIAL
tristate "Serial mouse"
tristate "Serial mouse"
select SERIO
select SERIO
...
...
drivers/input/mouse/Makefile
View file @
48853389
...
@@ -36,6 +36,7 @@ psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o
...
@@ -36,6 +36,7 @@ psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT)
+=
trackpoint.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT)
+=
trackpoint.o
psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT)
+=
touchkit_ps2.o
psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT)
+=
touchkit_ps2.o
psmouse-$(CONFIG_MOUSE_PS2_CYPRESS)
+=
cypress_ps2.o
psmouse-$(CONFIG_MOUSE_PS2_CYPRESS)
+=
cypress_ps2.o
psmouse-$(CONFIG_MOUSE_PS2_VMMOUSE)
+=
vmmouse.o
elan_i2c-objs
:=
elan_i2c_core.o
elan_i2c-objs
:=
elan_i2c_core.o
elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_I2C)
+=
elan_i2c_i2c.o
elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_I2C)
+=
elan_i2c_i2c.o
...
...
drivers/input/mouse/cyapa.c
View file @
48853389
...
@@ -723,7 +723,7 @@ static ssize_t cyapa_update_suspend_scanrate(struct device *dev,
...
@@ -723,7 +723,7 @@ static ssize_t cyapa_update_suspend_scanrate(struct device *dev,
}
else
if
(
sysfs_streq
(
buf
,
OFF_MODE_NAME
))
{
}
else
if
(
sysfs_streq
(
buf
,
OFF_MODE_NAME
))
{
cyapa
->
suspend_power_mode
=
PWR_MODE_OFF
;
cyapa
->
suspend_power_mode
=
PWR_MODE_OFF
;
}
else
if
(
!
kstrtou16
(
buf
,
10
,
&
sleep_time
))
{
}
else
if
(
!
kstrtou16
(
buf
,
10
,
&
sleep_time
))
{
cyapa
->
suspend_sleep_time
=
m
ax
_t
(
u16
,
sleep_time
,
1000
);
cyapa
->
suspend_sleep_time
=
m
in
_t
(
u16
,
sleep_time
,
1000
);
cyapa
->
suspend_power_mode
=
cyapa
->
suspend_power_mode
=
cyapa_sleep_time_to_pwr_cmd
(
cyapa
->
suspend_sleep_time
);
cyapa_sleep_time_to_pwr_cmd
(
cyapa
->
suspend_sleep_time
);
}
else
{
}
else
{
...
@@ -840,7 +840,7 @@ static ssize_t cyapa_update_rt_suspend_scanrate(struct device *dev,
...
@@ -840,7 +840,7 @@ static ssize_t cyapa_update_rt_suspend_scanrate(struct device *dev,
if
(
error
)
if
(
error
)
return
error
;
return
error
;
cyapa
->
runtime_suspend_sleep_time
=
m
ax
_t
(
u16
,
time
,
1000
);
cyapa
->
runtime_suspend_sleep_time
=
m
in
_t
(
u16
,
time
,
1000
);
cyapa
->
runtime_suspend_power_mode
=
cyapa
->
runtime_suspend_power_mode
=
cyapa_sleep_time_to_pwr_cmd
(
cyapa
->
runtime_suspend_sleep_time
);
cyapa_sleep_time_to_pwr_cmd
(
cyapa
->
runtime_suspend_sleep_time
);
...
...
drivers/input/mouse/elan_i2c.h
View file @
48853389
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
#define ETP_ENABLE_CALIBRATE 0x0002
#define ETP_ENABLE_CALIBRATE 0x0002
#define ETP_DISABLE_CALIBRATE 0x0000
#define ETP_DISABLE_CALIBRATE 0x0000
#define ETP_DISABLE_POWER 0x0001
#define ETP_DISABLE_POWER 0x0001
#define ETP_PRESSURE_OFFSET 25
/* IAP Firmware handling */
/* IAP Firmware handling */
#define ETP_FW_NAME "elan_i2c.bin"
#define ETP_FW_NAME "elan_i2c.bin"
...
@@ -79,6 +80,8 @@ struct elan_transport_ops {
...
@@ -79,6 +80,8 @@ struct elan_transport_ops {
struct
completion
*
reset_done
);
struct
completion
*
reset_done
);
int
(
*
get_report
)(
struct
i2c_client
*
client
,
u8
*
report
);
int
(
*
get_report
)(
struct
i2c_client
*
client
,
u8
*
report
);
int
(
*
get_pressure_adjustment
)(
struct
i2c_client
*
client
,
int
*
adjustment
);
};
};
extern
const
struct
elan_transport_ops
elan_smbus_ops
,
elan_i2c_ops
;
extern
const
struct
elan_transport_ops
elan_smbus_ops
,
elan_i2c_ops
;
...
...
drivers/input/mouse/elan_i2c_core.c
View file @
48853389
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
* Copyright (c) 2013 ELAN Microelectronics Corp.
* Copyright (c) 2013 ELAN Microelectronics Corp.
*
*
* Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
* Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
* Version: 1.5.
6
* Version: 1.5.
7
*
*
* Based on cyapa driver:
* Based on cyapa driver:
* copyright (c) 2011-2012 Cypress Semiconductor, Inc.
* copyright (c) 2011-2012 Cypress Semiconductor, Inc.
...
@@ -40,8 +40,7 @@
...
@@ -40,8 +40,7 @@
#include "elan_i2c.h"
#include "elan_i2c.h"
#define DRIVER_NAME "elan_i2c"
#define DRIVER_NAME "elan_i2c"
#define ELAN_DRIVER_VERSION "1.5.6"
#define ELAN_DRIVER_VERSION "1.5.7"
#define ETP_PRESSURE_OFFSET 25
#define ETP_MAX_PRESSURE 255
#define ETP_MAX_PRESSURE 255
#define ETP_FWIDTH_REDUCE 90
#define ETP_FWIDTH_REDUCE 90
#define ETP_FINGER_WIDTH 15
#define ETP_FINGER_WIDTH 15
...
@@ -53,6 +52,7 @@
...
@@ -53,6 +52,7 @@
#define ETP_REPORT_ID_OFFSET 2
#define ETP_REPORT_ID_OFFSET 2
#define ETP_TOUCH_INFO_OFFSET 3
#define ETP_TOUCH_INFO_OFFSET 3
#define ETP_FINGER_DATA_OFFSET 4
#define ETP_FINGER_DATA_OFFSET 4
#define ETP_HOVER_INFO_OFFSET 30
#define ETP_MAX_REPORT_LEN 34
#define ETP_MAX_REPORT_LEN 34
/* The main device structure */
/* The main device structure */
...
@@ -81,7 +81,7 @@ struct elan_tp_data {
...
@@ -81,7 +81,7 @@ struct elan_tp_data {
u8
sm_version
;
u8
sm_version
;
u8
iap_version
;
u8
iap_version
;
u16
fw_checksum
;
u16
fw_checksum
;
int
pressure_adjustment
;
u8
mode
;
u8
mode
;
bool
irq_wake
;
bool
irq_wake
;
...
@@ -229,6 +229,11 @@ static int elan_query_device_info(struct elan_tp_data *data)
...
@@ -229,6 +229,11 @@ static int elan_query_device_info(struct elan_tp_data *data)
if
(
error
)
if
(
error
)
return
error
;
return
error
;
error
=
data
->
ops
->
get_pressure_adjustment
(
data
->
client
,
&
data
->
pressure_adjustment
);
if
(
error
)
return
error
;
return
0
;
return
0
;
}
}
...
@@ -721,13 +726,13 @@ static const struct attribute_group *elan_sysfs_groups[] = {
...
@@ -721,13 +726,13 @@ static const struct attribute_group *elan_sysfs_groups[] = {
*/
*/
static
void
elan_report_contact
(
struct
elan_tp_data
*
data
,
static
void
elan_report_contact
(
struct
elan_tp_data
*
data
,
int
contact_num
,
bool
contact_valid
,
int
contact_num
,
bool
contact_valid
,
u8
*
finger_data
)
bool
hover_event
,
u8
*
finger_data
)
{
{
struct
input_dev
*
input
=
data
->
input
;
struct
input_dev
*
input
=
data
->
input
;
unsigned
int
pos_x
,
pos_y
;
unsigned
int
pos_x
,
pos_y
;
unsigned
int
pressure
,
mk_x
,
mk_y
;
unsigned
int
pressure
,
mk_x
,
mk_y
;
unsigned
int
area_x
,
area_y
,
major
,
minor
,
new_pressure
;
unsigned
int
area_x
,
area_y
,
major
,
minor
;
unsigned
int
scaled_pressure
;
if
(
contact_valid
)
{
if
(
contact_valid
)
{
pos_x
=
((
finger_data
[
0
]
&
0xf0
)
<<
4
)
|
pos_x
=
((
finger_data
[
0
]
&
0xf0
)
<<
4
)
|
...
@@ -756,15 +761,18 @@ static void elan_report_contact(struct elan_tp_data *data,
...
@@ -756,15 +761,18 @@ static void elan_report_contact(struct elan_tp_data *data,
major
=
max
(
area_x
,
area_y
);
major
=
max
(
area_x
,
area_y
);
minor
=
min
(
area_x
,
area_y
);
minor
=
min
(
area_x
,
area_y
);
new_pressure
=
pressure
+
ETP_PRESSURE_OFFSET
;
scaled_pressure
=
pressure
+
data
->
pressure_adjustment
;
if
(
new_pressure
>
ETP_MAX_PRESSURE
)
new_pressure
=
ETP_MAX_PRESSURE
;
if
(
scaled_pressure
>
ETP_MAX_PRESSURE
)
scaled_pressure
=
ETP_MAX_PRESSURE
;
input_mt_slot
(
input
,
contact_num
);
input_mt_slot
(
input
,
contact_num
);
input_mt_report_slot_state
(
input
,
MT_TOOL_FINGER
,
true
);
input_mt_report_slot_state
(
input
,
MT_TOOL_FINGER
,
true
);
input_report_abs
(
input
,
ABS_MT_POSITION_X
,
pos_x
);
input_report_abs
(
input
,
ABS_MT_POSITION_X
,
pos_x
);
input_report_abs
(
input
,
ABS_MT_POSITION_Y
,
data
->
max_y
-
pos_y
);
input_report_abs
(
input
,
ABS_MT_POSITION_Y
,
data
->
max_y
-
pos_y
);
input_report_abs
(
input
,
ABS_MT_PRESSURE
,
new_pressure
);
input_report_abs
(
input
,
ABS_MT_DISTANCE
,
hover_event
);
input_report_abs
(
input
,
ABS_MT_PRESSURE
,
hover_event
?
0
:
scaled_pressure
);
input_report_abs
(
input
,
ABS_TOOL_WIDTH
,
mk_x
);
input_report_abs
(
input
,
ABS_TOOL_WIDTH
,
mk_x
);
input_report_abs
(
input
,
ABS_MT_TOUCH_MAJOR
,
major
);
input_report_abs
(
input
,
ABS_MT_TOUCH_MAJOR
,
major
);
input_report_abs
(
input
,
ABS_MT_TOUCH_MINOR
,
minor
);
input_report_abs
(
input
,
ABS_MT_TOUCH_MINOR
,
minor
);
...
@@ -780,11 +788,14 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
...
@@ -780,11 +788,14 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
u8
*
finger_data
=
&
packet
[
ETP_FINGER_DATA_OFFSET
];
u8
*
finger_data
=
&
packet
[
ETP_FINGER_DATA_OFFSET
];
int
i
;
int
i
;
u8
tp_info
=
packet
[
ETP_TOUCH_INFO_OFFSET
];
u8
tp_info
=
packet
[
ETP_TOUCH_INFO_OFFSET
];
bool
contact_valid
;
u8
hover_info
=
packet
[
ETP_HOVER_INFO_OFFSET
];
bool
contact_valid
,
hover_event
;
hover_event
=
hover_info
&
0x40
;
for
(
i
=
0
;
i
<
ETP_MAX_FINGERS
;
i
++
)
{
for
(
i
=
0
;
i
<
ETP_MAX_FINGERS
;
i
++
)
{
contact_valid
=
tp_info
&
(
1U
<<
(
3
+
i
));
contact_valid
=
tp_info
&
(
1U
<<
(
3
+
i
));
elan_report_contact
(
data
,
i
,
contact_valid
,
finger_data
);
elan_report_contact
(
data
,
i
,
contact_valid
,
hover_event
,
finger_data
);
if
(
contact_valid
)
if
(
contact_valid
)
finger_data
+=
ETP_FINGER_DATA_LEN
;
finger_data
+=
ETP_FINGER_DATA_LEN
;
...
@@ -878,6 +889,7 @@ static int elan_setup_input_device(struct elan_tp_data *data)
...
@@ -878,6 +889,7 @@ static int elan_setup_input_device(struct elan_tp_data *data)
ETP_FINGER_WIDTH
*
max_width
,
0
,
0
);
ETP_FINGER_WIDTH
*
max_width
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_MT_TOUCH_MINOR
,
0
,
input_set_abs_params
(
input
,
ABS_MT_TOUCH_MINOR
,
0
,
ETP_FINGER_WIDTH
*
min_width
,
0
,
0
);
ETP_FINGER_WIDTH
*
min_width
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_MT_DISTANCE
,
0
,
1
,
0
,
0
);
data
->
input
=
input
;
data
->
input
=
input
;
...
...
drivers/input/mouse/elan_i2c_i2c.c
View file @
48853389
...
@@ -41,6 +41,7 @@
...
@@ -41,6 +41,7 @@
#define ETP_I2C_MAX_X_AXIS_CMD 0x0106
#define ETP_I2C_MAX_X_AXIS_CMD 0x0106
#define ETP_I2C_MAX_Y_AXIS_CMD 0x0107
#define ETP_I2C_MAX_Y_AXIS_CMD 0x0107
#define ETP_I2C_RESOLUTION_CMD 0x0108
#define ETP_I2C_RESOLUTION_CMD 0x0108
#define ETP_I2C_PRESSURE_CMD 0x010A
#define ETP_I2C_IAP_VERSION_CMD 0x0110
#define ETP_I2C_IAP_VERSION_CMD 0x0110
#define ETP_I2C_SET_CMD 0x0300
#define ETP_I2C_SET_CMD 0x0300
#define ETP_I2C_POWER_CMD 0x0307
#define ETP_I2C_POWER_CMD 0x0307
...
@@ -364,8 +365,29 @@ static int elan_i2c_get_num_traces(struct i2c_client *client,
...
@@ -364,8 +365,29 @@ static int elan_i2c_get_num_traces(struct i2c_client *client,
return
error
;
return
error
;
}
}
*
x_traces
=
val
[
0
]
-
1
;
*
x_traces
=
val
[
0
];
*
y_traces
=
val
[
1
]
-
1
;
*
y_traces
=
val
[
1
];
return
0
;
}
static
int
elan_i2c_get_pressure_adjustment
(
struct
i2c_client
*
client
,
int
*
adjustment
)
{
int
error
;
u8
val
[
3
];
error
=
elan_i2c_read_cmd
(
client
,
ETP_I2C_PRESSURE_CMD
,
val
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"failed to get pressure format: %d
\n
"
,
error
);
return
error
;
}
if
((
val
[
0
]
>>
4
)
&
0x1
)
*
adjustment
=
0
;
else
*
adjustment
=
ETP_PRESSURE_OFFSET
;
return
0
;
return
0
;
}
}
...
@@ -602,6 +624,7 @@ const struct elan_transport_ops elan_i2c_ops = {
...
@@ -602,6 +624,7 @@ const struct elan_transport_ops elan_i2c_ops = {
.
get_sm_version
=
elan_i2c_get_sm_version
,
.
get_sm_version
=
elan_i2c_get_sm_version
,
.
get_product_id
=
elan_i2c_get_product_id
,
.
get_product_id
=
elan_i2c_get_product_id
,
.
get_checksum
=
elan_i2c_get_checksum
,
.
get_checksum
=
elan_i2c_get_checksum
,
.
get_pressure_adjustment
=
elan_i2c_get_pressure_adjustment
,
.
get_max
=
elan_i2c_get_max
,
.
get_max
=
elan_i2c_get_max
,
.
get_resolution
=
elan_i2c_get_resolution
,
.
get_resolution
=
elan_i2c_get_resolution
,
...
...
drivers/input/mouse/elan_i2c_smbus.c
View file @
48853389
...
@@ -268,12 +268,19 @@ static int elan_smbus_get_num_traces(struct i2c_client *client,
...
@@ -268,12 +268,19 @@ static int elan_smbus_get_num_traces(struct i2c_client *client,
return
error
;
return
error
;
}
}
*
x_traces
=
val
[
1
]
-
1
;
*
x_traces
=
val
[
1
];
*
y_traces
=
val
[
2
]
-
1
;
*
y_traces
=
val
[
2
];
return
0
;
return
0
;
}
}
static
int
elan_smbus_get_pressure_adjustment
(
struct
i2c_client
*
client
,
int
*
adjustment
)
{
*
adjustment
=
ETP_PRESSURE_OFFSET
;
return
0
;
}
static
int
elan_smbus_iap_get_mode
(
struct
i2c_client
*
client
,
static
int
elan_smbus_iap_get_mode
(
struct
i2c_client
*
client
,
enum
tp_mode
*
mode
)
enum
tp_mode
*
mode
)
{
{
...
@@ -497,6 +504,7 @@ const struct elan_transport_ops elan_smbus_ops = {
...
@@ -497,6 +504,7 @@ const struct elan_transport_ops elan_smbus_ops = {
.
get_sm_version
=
elan_smbus_get_sm_version
,
.
get_sm_version
=
elan_smbus_get_sm_version
,
.
get_product_id
=
elan_smbus_get_product_id
,
.
get_product_id
=
elan_smbus_get_product_id
,
.
get_checksum
=
elan_smbus_get_checksum
,
.
get_checksum
=
elan_smbus_get_checksum
,
.
get_pressure_adjustment
=
elan_smbus_get_pressure_adjustment
,
.
get_max
=
elan_smbus_get_max
,
.
get_max
=
elan_smbus_get_max
,
.
get_resolution
=
elan_smbus_get_resolution
,
.
get_resolution
=
elan_smbus_get_resolution
,
...
...
drivers/input/mouse/psmouse-base.c
View file @
48853389
...
@@ -36,6 +36,7 @@
...
@@ -36,6 +36,7 @@
#include "sentelic.h"
#include "sentelic.h"
#include "cypress_ps2.h"
#include "cypress_ps2.h"
#include "focaltech.h"
#include "focaltech.h"
#include "vmmouse.h"
#define DRIVER_DESC "PS/2 mouse driver"
#define DRIVER_DESC "PS/2 mouse driver"
...
@@ -790,6 +791,13 @@ static int psmouse_extensions(struct psmouse *psmouse,
...
@@ -790,6 +791,13 @@ static int psmouse_extensions(struct psmouse *psmouse,
}
}
}
}
if
(
psmouse_do_detect
(
vmmouse_detect
,
psmouse
,
set_properties
)
==
0
)
{
if
(
max_proto
>
PSMOUSE_IMEX
)
{
if
(
!
set_properties
||
vmmouse_init
(
psmouse
)
==
0
)
return
PSMOUSE_VMMOUSE
;
}
}
/*
/*
* Try Kensington ThinkingMouse (we try first, because synaptics probe
* Try Kensington ThinkingMouse (we try first, because synaptics probe
* upsets the thinkingmouse).
* upsets the thinkingmouse).
...
@@ -1112,6 +1120,15 @@ static const struct psmouse_protocol psmouse_protocols[] = {
...
@@ -1112,6 +1120,15 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.
detect
=
focaltech_detect
,
.
detect
=
focaltech_detect
,
.
init
=
focaltech_init
,
.
init
=
focaltech_init
,
},
},
#endif
#ifdef CONFIG_MOUSE_PS2_VMMOUSE
{
.
type
=
PSMOUSE_VMMOUSE
,
.
name
=
VMMOUSE_PSNAME
,
.
alias
=
"vmmouse"
,
.
detect
=
vmmouse_detect
,
.
init
=
vmmouse_init
,
},
#endif
#endif
{
{
.
type
=
PSMOUSE_AUTO
,
.
type
=
PSMOUSE_AUTO
,
...
...
drivers/input/mouse/psmouse.h
View file @
48853389
...
@@ -103,6 +103,7 @@ enum psmouse_type {
...
@@ -103,6 +103,7 @@ enum psmouse_type {
PSMOUSE_SYNAPTICS_RELATIVE
,
PSMOUSE_SYNAPTICS_RELATIVE
,
PSMOUSE_CYPRESS
,
PSMOUSE_CYPRESS
,
PSMOUSE_FOCALTECH
,
PSMOUSE_FOCALTECH
,
PSMOUSE_VMMOUSE
,
PSMOUSE_AUTO
/* This one should always be last */
PSMOUSE_AUTO
/* This one should always be last */
};
};
...
...
drivers/input/mouse/vmmouse.c
0 → 100644
View file @
48853389
/*
* Driver for Virtual PS/2 Mouse on VMware and QEMU hypervisors.
*
* Copyright (C) 2014, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* Twin device code is hugely inspired by the ALPS driver.
* Authors:
* Dmitry Torokhov <dmitry.torokhov@gmail.com>
* Thomas Hellstrom <thellstrom@vmware.com>
*/
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/libps2.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <asm/hypervisor.h>
#include "psmouse.h"
#include "vmmouse.h"
#define VMMOUSE_PROTO_MAGIC 0x564D5868U
#define VMMOUSE_PROTO_PORT 0x5658
/*
* Main commands supported by the vmmouse hypervisor port.
*/
#define VMMOUSE_PROTO_CMD_GETVERSION 10
#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA 39
#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS 40
#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND 41
#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT 86
/*
* Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND
*/
#define VMMOUSE_CMD_ENABLE 0x45414552U
#define VMMOUSE_CMD_DISABLE 0x000000f5U
#define VMMOUSE_CMD_REQUEST_RELATIVE 0x4c455252U
#define VMMOUSE_CMD_REQUEST_ABSOLUTE 0x53424152U
#define VMMOUSE_ERROR 0xffff0000U
#define VMMOUSE_VERSION_ID 0x3442554aU
#define VMMOUSE_RELATIVE_PACKET 0x00010000U
#define VMMOUSE_LEFT_BUTTON 0x20
#define VMMOUSE_RIGHT_BUTTON 0x10
#define VMMOUSE_MIDDLE_BUTTON 0x08
/*
* VMMouse Restrict command
*/
#define VMMOUSE_RESTRICT_ANY 0x00
#define VMMOUSE_RESTRICT_CPL0 0x01
#define VMMOUSE_RESTRICT_IOPL 0x02
#define VMMOUSE_MAX_X 0xFFFF
#define VMMOUSE_MAX_Y 0xFFFF
#define VMMOUSE_VENDOR "VMware"
#define VMMOUSE_NAME "VMMouse"
/**
* struct vmmouse_data - private data structure for the vmmouse driver
*
* @abs_dev: "Absolute" device used to report absolute mouse movement.
* @phys: Physical path for the absolute device.
* @dev_name: Name attribute name for the absolute device.
*/
struct
vmmouse_data
{
struct
input_dev
*
abs_dev
;
char
phys
[
32
];
char
dev_name
[
128
];
};
/**
* Hypervisor-specific bi-directional communication channel
* implementing the vmmouse protocol. Should never execute on
* bare metal hardware.
*/
#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \
({ \
unsigned long __dummy1, __dummy2; \
__asm__ __volatile__ ("inl %%dx" : \
"=a"(out1), \
"=b"(out2), \
"=c"(out3), \
"=d"(out4), \
"=S"(__dummy1), \
"=D"(__dummy2) : \
"a"(VMMOUSE_PROTO_MAGIC), \
"b"(in1), \
"c"(VMMOUSE_PROTO_CMD_##cmd), \
"d"(VMMOUSE_PROTO_PORT) : \
"memory"); \
})
/**
* vmmouse_report_button - report button state on the correct input device
*
* @psmouse: Pointer to the psmouse struct
* @abs_dev: The absolute input device
* @rel_dev: The relative input device
* @pref_dev: The preferred device for reporting
* @code: Button code
* @value: Button value
*
* Report @value and @code on @pref_dev, unless the button is already
* pressed on the other device, in which case the state is reported on that
* device.
*/
static
void
vmmouse_report_button
(
struct
psmouse
*
psmouse
,
struct
input_dev
*
abs_dev
,
struct
input_dev
*
rel_dev
,
struct
input_dev
*
pref_dev
,
unsigned
int
code
,
int
value
)
{
if
(
test_bit
(
code
,
abs_dev
->
key
))
pref_dev
=
abs_dev
;
else
if
(
test_bit
(
code
,
rel_dev
->
key
))
pref_dev
=
rel_dev
;
input_report_key
(
pref_dev
,
code
,
value
);
}
/**
* vmmouse_report_events - process events on the vmmouse communications channel
*
* @psmouse: Pointer to the psmouse struct
*
* This function pulls events from the vmmouse communications channel and
* reports them on the correct (absolute or relative) input device. When the
* communications channel is drained, or if we've processed more than 255
* psmouse commands, the function returns PSMOUSE_FULL_PACKET. If there is a
* host- or synchronization error, the function returns PSMOUSE_BAD_DATA in
* the hope that the caller will reset the communications channel.
*/
static
psmouse_ret_t
vmmouse_report_events
(
struct
psmouse
*
psmouse
)
{
struct
input_dev
*
rel_dev
=
psmouse
->
dev
;
struct
vmmouse_data
*
priv
=
psmouse
->
private
;
struct
input_dev
*
abs_dev
=
priv
->
abs_dev
;
struct
input_dev
*
pref_dev
;
u32
status
,
x
,
y
,
z
;
u32
dummy1
,
dummy2
,
dummy3
;
unsigned
int
queue_length
;
unsigned
int
count
=
255
;
while
(
count
--
)
{
/* See if we have motion data. */
VMMOUSE_CMD
(
ABSPOINTER_STATUS
,
0
,
status
,
dummy1
,
dummy2
,
dummy3
);
if
((
status
&
VMMOUSE_ERROR
)
==
VMMOUSE_ERROR
)
{
psmouse_err
(
psmouse
,
"failed to fetch status data
\n
"
);
/*
* After a few attempts this will result in
* reconnect.
*/
return
PSMOUSE_BAD_DATA
;
}
queue_length
=
status
&
0xffff
;
if
(
queue_length
==
0
)
break
;
if
(
queue_length
%
4
)
{
psmouse_err
(
psmouse
,
"invalid queue length
\n
"
);
return
PSMOUSE_BAD_DATA
;
}
/* Now get it */
VMMOUSE_CMD
(
ABSPOINTER_DATA
,
4
,
status
,
x
,
y
,
z
);
/*
* And report what we've got. Prefer to report button
* events on the same device where we report motion events.
* This doesn't work well with the mouse wheel, though. See
* below. Ideally we would want to report that on the
* preferred device as well.
*/
if
(
status
&
VMMOUSE_RELATIVE_PACKET
)
{
pref_dev
=
rel_dev
;
input_report_rel
(
rel_dev
,
REL_X
,
(
s32
)
x
);
input_report_rel
(
rel_dev
,
REL_Y
,
-
(
s32
)
y
);
}
else
{
pref_dev
=
abs_dev
;
input_report_abs
(
abs_dev
,
ABS_X
,
x
);
input_report_abs
(
abs_dev
,
ABS_Y
,
y
);
}
/* Xorg seems to ignore wheel events on absolute devices */
input_report_rel
(
rel_dev
,
REL_WHEEL
,
-
(
s8
)((
u8
)
z
));
vmmouse_report_button
(
psmouse
,
abs_dev
,
rel_dev
,
pref_dev
,
BTN_LEFT
,
status
&
VMMOUSE_LEFT_BUTTON
);
vmmouse_report_button
(
psmouse
,
abs_dev
,
rel_dev
,
pref_dev
,
BTN_RIGHT
,
status
&
VMMOUSE_RIGHT_BUTTON
);
vmmouse_report_button
(
psmouse
,
abs_dev
,
rel_dev
,
pref_dev
,
BTN_MIDDLE
,
status
&
VMMOUSE_MIDDLE_BUTTON
);
input_sync
(
abs_dev
);
input_sync
(
rel_dev
);
}
return
PSMOUSE_FULL_PACKET
;
}
/**
* vmmouse_process_byte - process data on the ps/2 channel
*
* @psmouse: Pointer to the psmouse struct
*
* When the ps/2 channel indicates that there is vmmouse data available,
* call vmmouse channel processing. Otherwise, continue to accept bytes. If
* there is a synchronization or communication data error, return
* PSMOUSE_BAD_DATA in the hope that the caller will reset the mouse.
*/
static
psmouse_ret_t
vmmouse_process_byte
(
struct
psmouse
*
psmouse
)
{
unsigned
char
*
packet
=
psmouse
->
packet
;
switch
(
psmouse
->
pktcnt
)
{
case
1
:
return
(
packet
[
0
]
&
0x8
)
==
0x8
?
PSMOUSE_GOOD_DATA
:
PSMOUSE_BAD_DATA
;
case
2
:
return
PSMOUSE_GOOD_DATA
;
default:
return
vmmouse_report_events
(
psmouse
);
}
}
/**
* vmmouse_disable - Disable vmmouse
*
* @psmouse: Pointer to the psmouse struct
*
* Tries to disable vmmouse mode.
*/
static
void
vmmouse_disable
(
struct
psmouse
*
psmouse
)
{
u32
status
;
u32
dummy1
,
dummy2
,
dummy3
,
dummy4
;
VMMOUSE_CMD
(
ABSPOINTER_COMMAND
,
VMMOUSE_CMD_DISABLE
,
dummy1
,
dummy2
,
dummy3
,
dummy4
);
VMMOUSE_CMD
(
ABSPOINTER_STATUS
,
0
,
status
,
dummy1
,
dummy2
,
dummy3
);
if
((
status
&
VMMOUSE_ERROR
)
!=
VMMOUSE_ERROR
)
psmouse_warn
(
psmouse
,
"failed to disable vmmouse device
\n
"
);
}
/**
* vmmouse_enable - Enable vmmouse and request absolute mode.
*
* @psmouse: Pointer to the psmouse struct
*
* Tries to enable vmmouse mode. Performs basic checks and requests
* absolute vmmouse mode.
* Returns 0 on success, -ENODEV on failure.
*/
static
int
vmmouse_enable
(
struct
psmouse
*
psmouse
)
{
u32
status
,
version
;
u32
dummy1
,
dummy2
,
dummy3
,
dummy4
;
/*
* Try enabling the device. If successful, we should be able to
* read valid version ID back from it.
*/
VMMOUSE_CMD
(
ABSPOINTER_COMMAND
,
VMMOUSE_CMD_ENABLE
,
dummy1
,
dummy2
,
dummy3
,
dummy4
);
/*
* See if version ID can be retrieved.
*/
VMMOUSE_CMD
(
ABSPOINTER_STATUS
,
0
,
status
,
dummy1
,
dummy2
,
dummy3
);
if
((
status
&
0x0000ffff
)
==
0
)
{
psmouse_dbg
(
psmouse
,
"empty flags - assuming no device
\n
"
);
return
-
ENXIO
;
}
VMMOUSE_CMD
(
ABSPOINTER_DATA
,
1
/* single item */
,
version
,
dummy1
,
dummy2
,
dummy3
);
if
(
version
!=
VMMOUSE_VERSION_ID
)
{
psmouse_dbg
(
psmouse
,
"Unexpected version value: %u vs %u
\n
"
,
(
unsigned
)
version
,
VMMOUSE_VERSION_ID
);
vmmouse_disable
(
psmouse
);
return
-
ENXIO
;
}
/*
* Restrict ioport access, if possible.
*/
VMMOUSE_CMD
(
ABSPOINTER_RESTRICT
,
VMMOUSE_RESTRICT_CPL0
,
dummy1
,
dummy2
,
dummy3
,
dummy4
);
VMMOUSE_CMD
(
ABSPOINTER_COMMAND
,
VMMOUSE_CMD_REQUEST_ABSOLUTE
,
dummy1
,
dummy2
,
dummy3
,
dummy4
);
return
0
;
}
/*
* Array of supported hypervisors.
*/
static
const
struct
hypervisor_x86
*
vmmouse_supported_hypervisors
[]
=
{
&
x86_hyper_vmware
,
#ifdef CONFIG_KVM_GUEST
&
x86_hyper_kvm
,
#endif
};
/**
* vmmouse_check_hypervisor - Check if we're running on a supported hypervisor
*/
static
bool
vmmouse_check_hypervisor
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
vmmouse_supported_hypervisors
);
i
++
)
if
(
vmmouse_supported_hypervisors
[
i
]
==
x86_hyper
)
return
true
;
return
false
;
}
/**
* vmmouse_detect - Probe whether vmmouse is available
*
* @psmouse: Pointer to the psmouse struct
* @set_properties: Whether to set psmouse name and vendor
*
* Returns 0 if vmmouse channel is available. Negative error code if not.
*/
int
vmmouse_detect
(
struct
psmouse
*
psmouse
,
bool
set_properties
)
{
u32
response
,
version
,
dummy1
,
dummy2
;
if
(
!
vmmouse_check_hypervisor
())
{
psmouse_dbg
(
psmouse
,
"VMMouse not running on supported hypervisor.
\n
"
);
return
-
ENXIO
;
}
if
(
!
request_region
(
VMMOUSE_PROTO_PORT
,
4
,
"vmmouse"
))
{
psmouse_dbg
(
psmouse
,
"VMMouse port in use.
\n
"
);
return
-
EBUSY
;
}
/* Check if the device is present */
response
=
~
VMMOUSE_PROTO_MAGIC
;
VMMOUSE_CMD
(
GETVERSION
,
0
,
version
,
response
,
dummy1
,
dummy2
);
if
(
response
!=
VMMOUSE_PROTO_MAGIC
||
version
==
0xffffffffU
)
{
release_region
(
VMMOUSE_PROTO_PORT
,
4
);
return
-
ENXIO
;
}
if
(
set_properties
)
{
psmouse
->
vendor
=
VMMOUSE_VENDOR
;
psmouse
->
name
=
VMMOUSE_NAME
;
psmouse
->
model
=
version
;
}
release_region
(
VMMOUSE_PROTO_PORT
,
4
);
return
0
;
}
/**
* vmmouse_disconnect - Take down vmmouse driver
*
* @psmouse: Pointer to the psmouse struct
*
* Takes down vmmouse driver and frees resources set up in vmmouse_init().
*/
static
void
vmmouse_disconnect
(
struct
psmouse
*
psmouse
)
{
struct
vmmouse_data
*
priv
=
psmouse
->
private
;
vmmouse_disable
(
psmouse
);
psmouse_reset
(
psmouse
);
input_unregister_device
(
priv
->
abs_dev
);
kfree
(
priv
);
release_region
(
VMMOUSE_PROTO_PORT
,
4
);
}
/**
* vmmouse_reconnect - Reset the ps/2 - and vmmouse connections
*
* @psmouse: Pointer to the psmouse struct
*
* Attempts to reset the mouse connections. Returns 0 on success and
* -1 on failure.
*/
static
int
vmmouse_reconnect
(
struct
psmouse
*
psmouse
)
{
int
error
;
psmouse_reset
(
psmouse
);
vmmouse_disable
(
psmouse
);
error
=
vmmouse_enable
(
psmouse
);
if
(
error
)
{
psmouse_err
(
psmouse
,
"Unable to re-enable mouse when reconnecting, err: %d
\n
"
,
error
);
return
error
;
}
return
0
;
}
/**
* vmmouse_init - Initialize the vmmouse driver
*
* @psmouse: Pointer to the psmouse struct
*
* Requests the device and tries to enable vmmouse mode.
* If successful, sets up the input device for relative movement events.
* It also allocates another input device and sets it up for absolute motion
* events. Returns 0 on success and -1 on failure.
*/
int
vmmouse_init
(
struct
psmouse
*
psmouse
)
{
struct
vmmouse_data
*
priv
;
struct
input_dev
*
rel_dev
=
psmouse
->
dev
,
*
abs_dev
;
int
error
;
if
(
!
request_region
(
VMMOUSE_PROTO_PORT
,
4
,
"vmmouse"
))
{
psmouse_dbg
(
psmouse
,
"VMMouse port in use.
\n
"
);
return
-
EBUSY
;
}
psmouse_reset
(
psmouse
);
error
=
vmmouse_enable
(
psmouse
);
if
(
error
)
goto
release_region
;
priv
=
kzalloc
(
sizeof
(
*
priv
),
GFP_KERNEL
);
abs_dev
=
input_allocate_device
();
if
(
!
priv
||
!
abs_dev
)
{
error
=
-
ENOMEM
;
goto
init_fail
;
}
priv
->
abs_dev
=
abs_dev
;
psmouse
->
private
=
priv
;
input_set_capability
(
rel_dev
,
EV_REL
,
REL_WHEEL
);
/* Set up and register absolute device */
snprintf
(
priv
->
phys
,
sizeof
(
priv
->
phys
),
"%s/input1"
,
psmouse
->
ps2dev
.
serio
->
phys
);
/* Mimic name setup for relative device in psmouse-base.c */
snprintf
(
priv
->
dev_name
,
sizeof
(
priv
->
dev_name
),
"%s %s %s"
,
VMMOUSE_PSNAME
,
VMMOUSE_VENDOR
,
VMMOUSE_NAME
);
abs_dev
->
phys
=
priv
->
phys
;
abs_dev
->
name
=
priv
->
dev_name
;
abs_dev
->
id
.
bustype
=
BUS_I8042
;
abs_dev
->
id
.
vendor
=
0x0002
;
abs_dev
->
id
.
product
=
PSMOUSE_VMMOUSE
;
abs_dev
->
id
.
version
=
psmouse
->
model
;
abs_dev
->
dev
.
parent
=
&
psmouse
->
ps2dev
.
serio
->
dev
;
error
=
input_register_device
(
priv
->
abs_dev
);
if
(
error
)
goto
init_fail
;
/* Set absolute device capabilities */
input_set_capability
(
abs_dev
,
EV_KEY
,
BTN_LEFT
);
input_set_capability
(
abs_dev
,
EV_KEY
,
BTN_RIGHT
);
input_set_capability
(
abs_dev
,
EV_KEY
,
BTN_MIDDLE
);
input_set_capability
(
abs_dev
,
EV_ABS
,
ABS_X
);
input_set_capability
(
abs_dev
,
EV_ABS
,
ABS_Y
);
input_set_abs_params
(
abs_dev
,
ABS_X
,
0
,
VMMOUSE_MAX_X
,
0
,
0
);
input_set_abs_params
(
abs_dev
,
ABS_Y
,
0
,
VMMOUSE_MAX_Y
,
0
,
0
);
psmouse
->
protocol_handler
=
vmmouse_process_byte
;
psmouse
->
disconnect
=
vmmouse_disconnect
;
psmouse
->
reconnect
=
vmmouse_reconnect
;
return
0
;
init_fail:
vmmouse_disable
(
psmouse
);
psmouse_reset
(
psmouse
);
input_free_device
(
abs_dev
);
kfree
(
priv
);
psmouse
->
private
=
NULL
;
release_region:
release_region
(
VMMOUSE_PROTO_PORT
,
4
);
return
error
;
}
drivers/input/mouse/vmmouse.h
0 → 100644
View file @
48853389
/*
* Driver for Virtual PS/2 Mouse on VMware and QEMU hypervisors.
*
* Copyright (C) 2014, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#ifndef _VMMOUSE_H
#define _VMMOUSE_H
#ifdef CONFIG_MOUSE_PS2_VMMOUSE
#define VMMOUSE_PSNAME "VirtualPS/2"
int
vmmouse_detect
(
struct
psmouse
*
psmouse
,
bool
set_properties
);
int
vmmouse_init
(
struct
psmouse
*
psmouse
);
#else
static
inline
int
vmmouse_detect
(
struct
psmouse
*
psmouse
,
bool
set_properties
)
{
return
-
ENOSYS
;
}
static
inline
int
vmmouse_init
(
struct
psmouse
*
psmouse
)
{
return
-
ENOSYS
;
}
#endif
#endif
drivers/input/touchscreen/atmel_mxt_ts.c
View file @
48853389
...
@@ -14,6 +14,8 @@
...
@@ -14,6 +14,8 @@
*
*
*/
*/
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/completion.h>
#include <linux/completion.h>
...
@@ -2371,7 +2373,7 @@ static void mxt_input_close(struct input_dev *dev)
...
@@ -2371,7 +2373,7 @@ static void mxt_input_close(struct input_dev *dev)
}
}
#ifdef CONFIG_OF
#ifdef CONFIG_OF
static
struct
mxt_platform_data
*
mxt_parse_dt
(
struct
i2c_client
*
client
)
static
const
struct
mxt_platform_data
*
mxt_parse_dt
(
struct
i2c_client
*
client
)
{
{
struct
mxt_platform_data
*
pdata
;
struct
mxt_platform_data
*
pdata
;
u32
*
keymap
;
u32
*
keymap
;
...
@@ -2379,7 +2381,7 @@ static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
...
@@ -2379,7 +2381,7 @@ static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
int
proplen
,
i
,
ret
;
int
proplen
,
i
,
ret
;
if
(
!
client
->
dev
.
of_node
)
if
(
!
client
->
dev
.
of_node
)
return
ERR_PTR
(
-
ENO
DEV
);
return
ERR_PTR
(
-
ENO
ENT
);
pdata
=
devm_kzalloc
(
&
client
->
dev
,
sizeof
(
*
pdata
),
GFP_KERNEL
);
pdata
=
devm_kzalloc
(
&
client
->
dev
,
sizeof
(
*
pdata
),
GFP_KERNEL
);
if
(
!
pdata
)
if
(
!
pdata
)
...
@@ -2410,25 +2412,132 @@ static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
...
@@ -2410,25 +2412,132 @@ static struct mxt_platform_data *mxt_parse_dt(struct i2c_client *client)
return
pdata
;
return
pdata
;
}
}
#else
#else
static
struct
mxt_platform_data
*
mxt_parse_dt
(
struct
i2c_client
*
client
)
static
const
struct
mxt_platform_data
*
mxt_parse_dt
(
struct
i2c_client
*
client
)
{
{
dev_dbg
(
&
client
->
dev
,
"No platform data specified
\n
"
);
return
ERR_PTR
(
-
ENOENT
);
return
ERR_PTR
(
-
EINVAL
);
}
#endif
#ifdef CONFIG_ACPI
struct
mxt_acpi_platform_data
{
const
char
*
hid
;
struct
mxt_platform_data
pdata
;
};
static
unsigned
int
samus_touchpad_buttons
[]
=
{
KEY_RESERVED
,
KEY_RESERVED
,
KEY_RESERVED
,
BTN_LEFT
};
static
struct
mxt_acpi_platform_data
samus_platform_data
[]
=
{
{
/* Touchpad */
.
hid
=
"ATML0000"
,
.
pdata
=
{
.
t19_num_keys
=
ARRAY_SIZE
(
samus_touchpad_buttons
),
.
t19_keymap
=
samus_touchpad_buttons
,
},
},
{
/* Touchscreen */
.
hid
=
"ATML0001"
,
},
{
}
};
static
const
struct
dmi_system_id
mxt_dmi_table
[]
=
{
{
/* 2015 Google Pixel */
.
ident
=
"Chromebook Pixel 2"
,
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"GOOGLE"
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"Samus"
),
},
.
driver_data
=
samus_platform_data
,
},
{
}
};
static
const
struct
mxt_platform_data
*
mxt_parse_acpi
(
struct
i2c_client
*
client
)
{
struct
acpi_device
*
adev
;
const
struct
dmi_system_id
*
system_id
;
const
struct
mxt_acpi_platform_data
*
acpi_pdata
;
/*
* Ignore ACPI devices representing bootloader mode.
*
* This is a bit of a hack: Google Chromebook BIOS creates ACPI
* devices for both application and bootloader modes, but we are
* interested in application mode only (if device is in bootloader
* mode we'll end up switching into application anyway). So far
* application mode addresses were all above 0x40, so we'll use it
* as a threshold.
*/
if
(
client
->
addr
<
0x40
)
return
ERR_PTR
(
-
ENXIO
);
adev
=
ACPI_COMPANION
(
&
client
->
dev
);
if
(
!
adev
)
return
ERR_PTR
(
-
ENOENT
);
system_id
=
dmi_first_match
(
mxt_dmi_table
);
if
(
!
system_id
)
return
ERR_PTR
(
-
ENOENT
);
acpi_pdata
=
system_id
->
driver_data
;
if
(
!
acpi_pdata
)
return
ERR_PTR
(
-
ENOENT
);
while
(
acpi_pdata
->
hid
)
{
if
(
!
strcmp
(
acpi_device_hid
(
adev
),
acpi_pdata
->
hid
))
return
&
acpi_pdata
->
pdata
;
acpi_pdata
++
;
}
return
ERR_PTR
(
-
ENOENT
);
}
#else
static
const
struct
mxt_platform_data
*
mxt_parse_acpi
(
struct
i2c_client
*
client
)
{
return
ERR_PTR
(
-
ENOENT
);
}
}
#endif
#endif
static
const
struct
mxt_platform_data
*
mxt_get_platform_data
(
struct
i2c_client
*
client
)
{
const
struct
mxt_platform_data
*
pdata
;
pdata
=
dev_get_platdata
(
&
client
->
dev
);
if
(
pdata
)
return
pdata
;
pdata
=
mxt_parse_dt
(
client
);
if
(
!
IS_ERR
(
pdata
)
||
PTR_ERR
(
pdata
)
!=
-
ENOENT
)
return
pdata
;
pdata
=
mxt_parse_acpi
(
client
);
if
(
!
IS_ERR
(
pdata
)
||
PTR_ERR
(
pdata
)
!=
-
ENOENT
)
return
pdata
;
dev_err
(
&
client
->
dev
,
"No platform data specified
\n
"
);
return
ERR_PTR
(
-
EINVAL
);
}
static
int
mxt_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
static
int
mxt_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
{
{
struct
mxt_data
*
data
;
struct
mxt_data
*
data
;
const
struct
mxt_platform_data
*
pdata
;
const
struct
mxt_platform_data
*
pdata
;
int
error
;
int
error
;
pdata
=
dev_get_platdata
(
&
client
->
dev
);
pdata
=
mxt_get_platform_data
(
client
);
if
(
!
pdata
)
{
if
(
IS_ERR
(
pdata
))
pdata
=
mxt_parse_dt
(
client
);
return
PTR_ERR
(
pdata
);
if
(
IS_ERR
(
pdata
))
return
PTR_ERR
(
pdata
);
}
data
=
kzalloc
(
sizeof
(
struct
mxt_data
),
GFP_KERNEL
);
data
=
kzalloc
(
sizeof
(
struct
mxt_data
),
GFP_KERNEL
);
if
(
!
data
)
{
if
(
!
data
)
{
...
@@ -2536,6 +2645,15 @@ static const struct of_device_id mxt_of_match[] = {
...
@@ -2536,6 +2645,15 @@ static const struct of_device_id mxt_of_match[] = {
};
};
MODULE_DEVICE_TABLE
(
of
,
mxt_of_match
);
MODULE_DEVICE_TABLE
(
of
,
mxt_of_match
);
#ifdef CONFIG_ACPI
static
const
struct
acpi_device_id
mxt_acpi_id
[]
=
{
{
"ATML0000"
,
0
},
/* Touchpad */
{
"ATML0001"
,
0
},
/* Touchscreen */
{
}
};
MODULE_DEVICE_TABLE
(
acpi
,
mxt_acpi_id
);
#endif
static
const
struct
i2c_device_id
mxt_id
[]
=
{
static
const
struct
i2c_device_id
mxt_id
[]
=
{
{
"qt602240_ts"
,
0
},
{
"qt602240_ts"
,
0
},
{
"atmel_mxt_ts"
,
0
},
{
"atmel_mxt_ts"
,
0
},
...
@@ -2550,6 +2668,7 @@ static struct i2c_driver mxt_driver = {
...
@@ -2550,6 +2668,7 @@ static struct i2c_driver mxt_driver = {
.
name
=
"atmel_mxt_ts"
,
.
name
=
"atmel_mxt_ts"
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
of_match_table
=
of_match_ptr
(
mxt_of_match
),
.
of_match_table
=
of_match_ptr
(
mxt_of_match
),
.
acpi_match_table
=
ACPI_PTR
(
mxt_acpi_id
),
.
pm
=
&
mxt_pm_ops
,
.
pm
=
&
mxt_pm_ops
,
},
},
.
probe
=
mxt_probe
,
.
probe
=
mxt_probe
,
...
...
drivers/input/touchscreen/elants_i2c.c
View file @
48853389
...
@@ -699,7 +699,7 @@ static int elants_i2c_fw_update(struct elants_data *ts)
...
@@ -699,7 +699,7 @@ static int elants_i2c_fw_update(struct elants_data *ts)
char
*
fw_name
;
char
*
fw_name
;
int
error
;
int
error
;
fw_name
=
kasprintf
(
GFP_KERNEL
,
"elants_i2c_%4x.bin"
,
ts
->
hw_version
);
fw_name
=
kasprintf
(
GFP_KERNEL
,
"elants_i2c_%
0
4x.bin"
,
ts
->
hw_version
);
if
(
!
fw_name
)
if
(
!
fw_name
)
return
-
ENOMEM
;
return
-
ENOMEM
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment