Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input subsystem updates from Dmitry Torokhov: - a big update from Mauro converting input documentation to ReST format - Synaptics PS/2 is now aware of SMBus companion devices, which means that we can now use native RMI4 protocol to handle touchpads, instead of relying on legacy PS/2 mode. - we removed support from BMA180 accelerometer from input devices as it is now handled properly by IIO - update to TSC2007 to corretcly report pressure - other miscellaneous driver fixes. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (152 commits) Input: ar1021_i2c - use BIT to check for a bit Input: twl4030-pwrbutton - use input_set_capability() helper Input: twl4030-pwrbutton - use correct device for irq request Input: ar1021_i2c - enable touch mode during open Input: add uinput documentation dt-bindings: input: add bindings document for ar1021_i2c driver dt-bindings: input: rotary-encoder: fix typo Input: xen-kbdfront - add module parameter for setting resolution ARM: pxa/raumfeld: fix compile error in rotary controller resources Input: xpad - do not suggest writing to Dominic Input: xpad - don't use literal blocks inside footnotes Input: xpad - note that usb/devices is now at /sys/kernel/debug/ Input: docs - freshen up introduction Input: docs - split input docs into kernel- and user-facing Input: docs - note that MT-A protocol is obsolete Input: docs - update joystick documentation a bit Input: docs - remove disclaimer/GPL notice Input: fix "Game console" heading level in joystick documentation Input: rotary-encoder - remove references to platform data from docs Input: move documentation for Amiga CD32 ...
This commit is contained in:
Коммит
16a12fa9ae
|
@ -348,6 +348,8 @@ latex_documents = [
|
|||
'The kernel development community', 'manual'),
|
||||
('driver-api/index', 'driver-api.tex', 'The kernel driver API manual',
|
||||
'The kernel development community', 'manual'),
|
||||
('input/index', 'linux-input.tex', 'The Linux input driver subsystem',
|
||||
'The kernel development community', 'manual'),
|
||||
('kernel-documentation', 'kernel-documentation.tex', 'The Linux Kernel Documentation',
|
||||
'The kernel development community', 'manual'),
|
||||
('process/index', 'development-process.tex', 'Linux Kernel Development Documentation',
|
||||
|
|
|
@ -24,6 +24,8 @@ Optional Properties:
|
|||
- debounce-delay-ms: debounce interval in milliseconds
|
||||
- col-scan-delay-us: delay, measured in microseconds, that is needed
|
||||
before we can scan keypad after activating column gpio
|
||||
- drive-inactive-cols: drive inactive columns during scan,
|
||||
default is to turn inactive columns into inputs.
|
||||
|
||||
Example:
|
||||
matrix-keypad {
|
||||
|
|
|
@ -8,6 +8,7 @@ Required properties:
|
|||
|
||||
Optional properties:
|
||||
- amp-supply: phandle to a regulator that acts as an amplifier for the beeper
|
||||
- beeper-hz: bell frequency in Hz
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ PROPERTIES
|
|||
Value type: <string>
|
||||
Definition: must be one of:
|
||||
"qcom,pm8058-vib"
|
||||
"qcom,pm8916-vib"
|
||||
"qcom,pm8921-vib"
|
||||
|
||||
- reg:
|
||||
|
|
|
@ -12,7 +12,7 @@ Optional properties:
|
|||
- rotary-encoder,relative-axis: register a relative axis rather than an
|
||||
absolute one. Relative axis will only generate +1/-1 events on the input
|
||||
device, hence no steps need to be passed.
|
||||
- rotary-encoder,rollover: Automatic rollove when the rotary value becomes
|
||||
- rotary-encoder,rollover: Automatic rollover when the rotary value becomes
|
||||
greater than the specified steps or smaller than 0. For absolute axis only.
|
||||
- rotary-encoder,steps-per-period: Number of steps (stable states) per period.
|
||||
The values have the following meaning:
|
||||
|
|
|
@ -35,6 +35,7 @@ Optional properties:
|
|||
- adi,conversion-interval: : 0 : convert one time only
|
||||
1-255: 515us + val * 35us (up to 9.440ms)
|
||||
This property has to be a '/bits/ 8' value
|
||||
- gpio-controller : Switch AUX/VBAT/GPIO pin to GPIO mode
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -51,3 +52,21 @@ Example:
|
|||
adi,averaging = /bits/ 8 <1>;
|
||||
adi,conversion-interval = /bits/ 8 <255>;
|
||||
};
|
||||
|
||||
ad7879@1 {
|
||||
compatible = "adi,ad7879";
|
||||
spi-max-frequency = <5000000>;
|
||||
reg = <1>;
|
||||
spi-cpol;
|
||||
spi-cpha;
|
||||
gpio-controller;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
|
||||
touchscreen-max-pressure = <4096>;
|
||||
adi,resistance-plate-x = <120>;
|
||||
adi,first-conversion-delay = /bits/ 8 <3>;
|
||||
adi,acquisition-time = /bits/ 8 <1>;
|
||||
adi,median-filter-size = /bits/ 8 <2>;
|
||||
adi,averaging = /bits/ 8 <1>;
|
||||
adi,conversion-interval = /bits/ 8 <255>;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
* Microchip AR1020 and AR1021 touchscreen interface (I2C)
|
||||
|
||||
Required properties:
|
||||
- compatible : "microchip,ar1021-i2c"
|
||||
- reg : I2C slave address
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
- interrupts : touch controller interrupt
|
||||
|
||||
Example:
|
||||
|
||||
touchscreen@4d {
|
||||
compatible = "microchip,ar1021-i2c";
|
||||
reg = <0x4d>;
|
||||
interrupt-parent = <&gpio3>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
* MAXI MAX11801 Resistive touch screen controller with i2c interface
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "maxim,max11801"
|
||||
- reg: i2c slave address
|
||||
- interrupt-parent: the phandle for the interrupt controller
|
||||
- interrupts: touch controller interrupt
|
||||
|
||||
Example:
|
||||
|
||||
&i2c1 {
|
||||
max11801: touchscreen@48 {
|
||||
compatible = "maxim,max11801";
|
||||
reg = <0x48>;
|
||||
interrupt-parent = <&gpio3>;
|
||||
interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
};
|
|
@ -1,7 +1,12 @@
|
|||
* GSL 1680 touchscreen controller
|
||||
|
||||
Required properties:
|
||||
- compatible : "silead,gsl1680"
|
||||
- compatible : Must be one of the following, depending on the model:
|
||||
"silead,gsl1680"
|
||||
"silead,gsl1688"
|
||||
"silead,gsl3670"
|
||||
"silead,gsl3675"
|
||||
"silead,gsl3692"
|
||||
- reg : I2C slave address of the chip (0x40)
|
||||
- interrupt-parent : a phandle pointing to the interrupt controller
|
||||
serving the interrupt for this chip
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
I have written a small patch that let's me use my Amiga CD32
|
||||
joypad connected to the parallel port. Thought I'd share it with you so
|
||||
you can add it to the list of supported joysticks (hopefully someone will
|
||||
find it useful).
|
||||
|
||||
It needs the following wiring:
|
||||
|
||||
CD32 pad | Parallel port
|
||||
----------------------------
|
||||
1 (Up) | 2 (D0)
|
||||
2 (Down) | 3 (D1)
|
||||
3 (Left) | 4 (D2)
|
||||
4 (Right) | 5 (D3)
|
||||
5 (Fire3) | 14 (AUTOFD)
|
||||
6 (Fire1) | 17 (SELIN)
|
||||
7 (+5V) | 1 (STROBE)
|
||||
8 (Gnd) | 18 (Gnd)
|
||||
9 (Fire2) | 7 (D5)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8; mode: python -*-
|
||||
|
||||
project = "The Linux input driver subsystem"
|
||||
|
||||
tags.add("subproject")
|
||||
|
||||
latex_documents = [
|
||||
('index', 'linux-input.tex', project,
|
||||
'The kernel development community', 'manual'),
|
||||
]
|
|
@ -1,10 +1,11 @@
|
|||
----------------------
|
||||
ALPS Touchpad Protocol
|
||||
----------------------
|
||||
|
||||
Introduction
|
||||
------------
|
||||
Currently the ALPS touchpad driver supports seven protocol versions in use by
|
||||
ALPS touchpads, called versions 1, 2, 3, 4, 5, 6 and 7.
|
||||
ALPS touchpads, called versions 1, 2, 3, 4, 5, 6, 7 and 8.
|
||||
|
||||
Since roughly mid-2010 several new ALPS touchpads have been released and
|
||||
integrated into a variety of laptops and netbooks. These new touchpads
|
||||
|
@ -78,7 +79,7 @@ of the EC response.
|
|||
Packet Format
|
||||
-------------
|
||||
|
||||
In the following tables, the following notation is used.
|
||||
In the following tables, the following notation is used::
|
||||
|
||||
CAPITALS = stick, miniscules = touchpad
|
||||
|
||||
|
@ -88,6 +89,8 @@ extra buttons, stick buttons on a dualpoint, etc.
|
|||
PS/2 packet format
|
||||
------------------
|
||||
|
||||
::
|
||||
|
||||
byte 0: 0 0 YSGN XSGN 1 M R L
|
||||
byte 1: X7 X6 X5 X4 X3 X2 X1 X0
|
||||
byte 2: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
|
||||
|
@ -99,7 +102,9 @@ 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
|
||||
--------------------------------------
|
||||
---------------------------------------
|
||||
|
||||
::
|
||||
|
||||
byte 0: 1 0 0 0 1 x9 x8 x7
|
||||
byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
|
@ -111,6 +116,8 @@ ALPS Absolute Mode - Protocol Version 1
|
|||
ALPS Absolute Mode - Protocol Version 2
|
||||
---------------------------------------
|
||||
|
||||
::
|
||||
|
||||
byte 0: 1 ? ? ? 1 PSM PSR PSL
|
||||
byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
byte 2: 0 x10 x9 x8 x7 ? fin ges
|
||||
|
@ -127,6 +134,8 @@ and PSL bits.
|
|||
Dualpoint device -- interleaved packet format
|
||||
---------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
byte 0: 1 1 0 0 1 1 1 1
|
||||
byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
byte 2: 0 x10 x9 x8 x7 0 fin ges
|
||||
|
@ -149,7 +158,7 @@ ALPS protocol version 3 has three different packet formats. The first two are
|
|||
associated with touchpad events, and the third is associated with trackstick
|
||||
events.
|
||||
|
||||
The first type is the touchpad position packet.
|
||||
The first type is the touchpad position packet::
|
||||
|
||||
byte 0: 1 ? x1 x0 1 1 1 1
|
||||
byte 1: 0 x10 x9 x8 x7 x6 x5 x4
|
||||
|
@ -165,7 +174,7 @@ The second packet type contains bitmaps representing the x and y axes. In the
|
|||
bitmaps a given bit is set if there is a finger covering that position on the
|
||||
given axis. Thus the bitmap packet can be used for low-resolution multi-touch
|
||||
data, although finger tracking is not possible. This packet also encodes the
|
||||
number of contacts (f1 and f0 in the table below).
|
||||
number of contacts (f1 and f0 in the table below)::
|
||||
|
||||
byte 0: 1 1 x1 x0 1 1 1 1
|
||||
byte 1: 0 x8 x7 x6 x5 x4 x3 x2
|
||||
|
@ -178,7 +187,7 @@ This packet only appears after a position packet with the mt bit set, and
|
|||
usually only appears when there are two or more contacts (although
|
||||
occasionally it's seen with only a single contact).
|
||||
|
||||
The final v3 packet type is the trackstick packet.
|
||||
The final v3 packet type is the trackstick packet::
|
||||
|
||||
byte 0: 1 1 x7 y7 1 1 1 1
|
||||
byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
|
@ -190,7 +199,7 @@ The final v3 packet type is the trackstick packet.
|
|||
ALPS Absolute Mode - Protocol Version 4
|
||||
---------------------------------------
|
||||
|
||||
Protocol version 4 has an 8-byte packet format.
|
||||
Protocol version 4 has an 8-byte packet format::
|
||||
|
||||
byte 0: 1 ? x1 x0 1 1 1 1
|
||||
byte 1: 0 x10 x9 x8 x7 x6 x5 x4
|
||||
|
@ -203,7 +212,7 @@ Protocol version 4 has an 8-byte packet format.
|
|||
|
||||
The last two bytes represent a partial bitmap packet, with 3 full packets
|
||||
required to construct a complete bitmap packet. Once assembled, the 6-byte
|
||||
bitmap packet has the following format:
|
||||
bitmap packet has the following format::
|
||||
|
||||
byte 0: 0 1 x7 x6 x5 x4 x3 x2
|
||||
byte 1: 0 x1 x0 y4 y3 y2 y1 y0
|
||||
|
@ -238,7 +247,7 @@ decode. It uses the same alps_process_touchpad_packet_v3 call with a
|
|||
specialized decode_fields function pointer to correctly interpret the
|
||||
packets. This appears to only be used by the Dolphin devices.
|
||||
|
||||
For single-touch, the 6-byte packet format is:
|
||||
For single-touch, the 6-byte packet format is::
|
||||
|
||||
byte 0: 1 1 0 0 1 0 0 0
|
||||
byte 1: 0 x6 x5 x4 x3 x2 x1 x0
|
||||
|
@ -247,7 +256,7 @@ For single-touch, the 6-byte packet format is:
|
|||
byte 4: y10 y9 y8 y7 x10 x9 x8 x7
|
||||
byte 5: 0 z6 z5 z4 z3 z2 z1 z0
|
||||
|
||||
For mt, the format is:
|
||||
For mt, the format is::
|
||||
|
||||
byte 0: 1 1 1 n3 1 n2 n1 x24
|
||||
byte 1: 1 y7 y6 y5 y4 y3 y2 y1
|
||||
|
@ -259,7 +268,7 @@ For mt, the format is:
|
|||
ALPS Absolute Mode - Protocol Version 6
|
||||
---------------------------------------
|
||||
|
||||
For trackstick packet, the format is:
|
||||
For trackstick packet, the format is::
|
||||
|
||||
byte 0: 1 1 1 1 1 1 1 1
|
||||
byte 1: 0 X6 X5 X4 X3 X2 X1 X0
|
||||
|
@ -268,7 +277,7 @@ For trackstick packet, the format is:
|
|||
byte 4: Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0
|
||||
byte 5: 0 1 1 1 1 1 1 1
|
||||
|
||||
For touchpad packet, the format is:
|
||||
For touchpad packet, the format is::
|
||||
|
||||
byte 0: 1 1 1 1 1 1 1 1
|
||||
byte 1: 0 0 0 0 x3 x2 x1 x0
|
||||
|
@ -282,7 +291,7 @@ For touchpad packet, the format is:
|
|||
ALPS Absolute Mode - Protocol Version 7
|
||||
---------------------------------------
|
||||
|
||||
For trackstick packet, the format is:
|
||||
For trackstick packet, the format is::
|
||||
|
||||
byte 0: 0 1 0 0 1 0 0 0
|
||||
byte 1: 1 1 * * 1 M R L
|
||||
|
@ -291,7 +300,7 @@ For trackstick packet, the format is:
|
|||
byte 4: Y7 0 Y5 Y4 Y3 1 1 0
|
||||
byte 5: T&P 0 Z5 Z4 Z3 Z2 Z1 Z0
|
||||
|
||||
For touchpad packet, the format is:
|
||||
For touchpad packet, the format is::
|
||||
|
||||
packet-fmt b7 b6 b5 b4 b3 b2 b1 b0
|
||||
byte 0: TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0
|
||||
|
@ -328,7 +337,7 @@ Spoken by SS4 (73 03 14) and SS5 (73 03 28) hardware.
|
|||
|
||||
The packet type is given by the APD field, bits 4-5 of byte 3.
|
||||
|
||||
Touchpad packet (APD = 0x2):
|
||||
Touchpad packet (APD = 0x2)::
|
||||
|
||||
b7 b6 b5 b4 b3 b2 b1 b0
|
||||
byte 0: SWM SWR SWL 1 1 0 0 X7
|
||||
|
@ -340,7 +349,7 @@ Touchpad packet (APD = 0x2):
|
|||
|
||||
SWM, SWR, SWL: Middle, Right, and Left button states
|
||||
|
||||
Touchpad 1 Finger packet (APD = 0x0):
|
||||
Touchpad 1 Finger packet (APD = 0x0)::
|
||||
|
||||
b7 b6 b5 b4 b3 b2 b1 b0
|
||||
byte 0: SWM SWR SWL 1 1 X2 X1 X0
|
||||
|
@ -353,7 +362,7 @@ Touchpad 1 Finger packet (APD = 0x0):
|
|||
TAPF: ???
|
||||
LFB: ???
|
||||
|
||||
Touchpad 2 Finger packet (APD = 0x1):
|
||||
Touchpad 2 Finger packet (APD = 0x1)::
|
||||
|
||||
b7 b6 b5 b4 b3 b2 b1 b0
|
||||
byte 0: SWM SWR SWL 1 1 AX6 AX5 AX4
|
||||
|
@ -365,7 +374,7 @@ Touchpad 2 Finger packet (APD = 0x1):
|
|||
|
||||
CONT: A 3-or-4 Finger packet is to follow
|
||||
|
||||
Touchpad 3-or-4 Finger packet (APD = 0x3):
|
||||
Touchpad 3-or-4 Finger packet (APD = 0x3)::
|
||||
|
||||
b7 b6 b5 b4 b3 b2 b1 b0
|
||||
byte 0: SWM SWR SWL 1 1 AX6 AX5 AX4
|
|
@ -1,67 +1,101 @@
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Amiga joystick extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
Amiga 4-joystick parport extension
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Parallel port pins:
|
||||
|
||||
(2) - Up1 (6) - Up2
|
||||
(3) - Down1 (7) - Down2
|
||||
(4) - Left1 (8) - Left2
|
||||
(5) - Right1 (9) - Right2
|
||||
(13) - Fire1 (11) - Fire2
|
||||
(18) - Gnd1 (18) - Gnd2
|
||||
|
||||
===== ======== ==== ==========
|
||||
Pin Meaning Pin Meaning
|
||||
===== ======== ==== ==========
|
||||
2 Up1 6 Up2
|
||||
3 Down1 7 Down2
|
||||
4 Left1 8 Left2
|
||||
5 Right1 9 Right2
|
||||
13 Fire1 11 Fire2
|
||||
18 Gnd1 18 Gnd2
|
||||
===== ======== ==== ==========
|
||||
|
||||
Amiga digital joystick pinout
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
(1) - Up
|
||||
(2) - Down
|
||||
(3) - Left
|
||||
(4) - Right
|
||||
(5) - n/c
|
||||
(6) - Fire button
|
||||
(7) - +5V (50mA)
|
||||
(8) - Gnd
|
||||
(9) - Thumb button
|
||||
|
||||
=== ============
|
||||
Pin Meaning
|
||||
=== ============
|
||||
1 Up
|
||||
2 Down
|
||||
3 Left
|
||||
4 Right
|
||||
5 n/c
|
||||
6 Fire button
|
||||
7 +5V (50mA)
|
||||
8 Gnd
|
||||
9 Thumb button
|
||||
=== ============
|
||||
|
||||
Amiga mouse pinout
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
(1) - V-pulse
|
||||
(2) - H-pulse
|
||||
(3) - VQ-pulse
|
||||
(4) - HQ-pulse
|
||||
(5) - Middle button
|
||||
(6) - Left button
|
||||
(7) - +5V (50mA)
|
||||
(8) - Gnd
|
||||
(9) - Right button
|
||||
|
||||
=== ============
|
||||
Pin Meaning
|
||||
=== ============
|
||||
1 V-pulse
|
||||
2 H-pulse
|
||||
3 VQ-pulse
|
||||
4 HQ-pulse
|
||||
5 Middle button
|
||||
6 Left button
|
||||
7 +5V (50mA)
|
||||
8 Gnd
|
||||
9 Right button
|
||||
=== ============
|
||||
|
||||
Amiga analog joystick pinout
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
(1) - Top button
|
||||
(2) - Top2 button
|
||||
(3) - Trigger button
|
||||
(4) - Thumb button
|
||||
(5) - Analog X
|
||||
(6) - n/c
|
||||
(7) - +5V (50mA)
|
||||
(8) - Gnd
|
||||
(9) - Analog Y
|
||||
|
||||
=== ==============
|
||||
Pin Meaning
|
||||
=== ==============
|
||||
1 Top button
|
||||
2 Top2 button
|
||||
3 Trigger button
|
||||
4 Thumb button
|
||||
5 Analog X
|
||||
6 n/c
|
||||
7 +5V (50mA)
|
||||
8 Gnd
|
||||
9 Analog Y
|
||||
=== ==============
|
||||
|
||||
Amiga lightpen pinout
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
(1) - n/c
|
||||
(2) - n/c
|
||||
(3) - n/c
|
||||
(4) - n/c
|
||||
(5) - Touch button
|
||||
(6) - /Beamtrigger
|
||||
(7) - +5V (50mA)
|
||||
(8) - Gnd
|
||||
(9) - Stylus button
|
||||
|
||||
=== =============
|
||||
Pin Meaning
|
||||
=== =============
|
||||
1 n/c
|
||||
2 n/c
|
||||
3 n/c
|
||||
4 n/c
|
||||
5 Touch button
|
||||
6 /Beamtrigger
|
||||
7 +5V (50mA)
|
||||
8 Gnd
|
||||
9 Stylus button
|
||||
=== =============
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
======== === ==== ==== ====== ========================================
|
||||
NAME rev ADDR type chip Description
|
||||
======== === ==== ==== ====== ========================================
|
||||
JOY0DAT 00A R Denise Joystick-mouse 0 data (left vert, horiz)
|
||||
JOY1DAT 00C R Denise Joystick-mouse 1 data (right vert,horiz)
|
||||
======== === ==== ==== ====== ========================================
|
||||
|
||||
These addresses each read a 16 bit register. These in turn
|
||||
are loaded from the MDAT serial stream and are clocked in on
|
||||
|
@ -71,12 +105,17 @@ JOY1DAT 00C R Denise Joystick-mouse 1 data (right vert,horiz)
|
|||
controller ports (8 total) plus 8 miscellaneous control bits
|
||||
which are new for LISA and can be read in upper 8 bits of
|
||||
LISAID.
|
||||
Register bits are as follows:
|
||||
Mouse counter usage (pins 1,3 =Yclock, pins 2,4 =Xclock)
|
||||
|
||||
Register bits are as follows:
|
||||
|
||||
- Mouse counter usage (pins 1,3 =Yclock, pins 2,4 =Xclock)
|
||||
|
||||
======== === === === === === === === === ====== === === === === === === ===
|
||||
BIT# 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
|
||||
======== === === === === === === === === ====== === === === === === === ===
|
||||
JOY0DAT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 X7 X6 X5 X4 X3 X2 X1 X0
|
||||
JOY1DAT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 X7 X6 X5 X4 X3 X2 X1 X0
|
||||
======== === === === === === === === === ====== === === === === === === ===
|
||||
|
||||
0=LEFT CONTROLLER PAIR, 1=RIGHT CONTROLLER PAIR.
|
||||
(4 counters total). The bit usage for both left and right
|
||||
|
@ -86,14 +125,21 @@ JOY1DAT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 X7 X6 X5 X4 X3 X2 X1 X0
|
|||
|
||||
+-------------------+-----------------------------------------+
|
||||
| Serial | Bit Name | Description |
|
||||
+--------+----------+-----------------------------------------+
|
||||
+========+==========+=========================================+
|
||||
| 0 | M0H | JOY0DAT Horizontal Clock |
|
||||
+--------+----------+-----------------------------------------+
|
||||
| 1 | M0HQ | JOY0DAT Horizontal Clock (quadrature) |
|
||||
+--------+----------+-----------------------------------------+
|
||||
| 2 | M0V | JOY0DAT Vertical Clock |
|
||||
+--------+----------+-----------------------------------------+
|
||||
| 3 | M0VQ | JOY0DAT Vertical Clock (quadrature) |
|
||||
+--------+----------+-----------------------------------------+
|
||||
| 4 | M1V | JOY1DAT Horizontal Clock |
|
||||
+--------+----------+-----------------------------------------+
|
||||
| 5 | M1VQ | JOY1DAT Horizontal Clock (quadrature) |
|
||||
+--------+----------+-----------------------------------------+
|
||||
| 6 | M1V | JOY1DAT Vertical Clock |
|
||||
+--------+----------+-----------------------------------------+
|
||||
| 7 | M1VQ | JOY1DAT Vertical Clock (quadrature) |
|
||||
+--------+----------+-----------------------------------------+
|
||||
|
||||
|
@ -104,46 +150,65 @@ JOY1DAT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 X7 X6 X5 X4 X3 X2 X1 X0
|
|||
|
||||
+------------+------+---------------------------------+
|
||||
| Directions | Pin# | Counter bits |
|
||||
+------------+------+---------------------------------+
|
||||
+============+======+=================================+
|
||||
| Forward | 1 | Y1 xor Y0 (BIT#09 xor BIT#08) |
|
||||
+------------+------+---------------------------------+
|
||||
| Left | 3 | Y1 |
|
||||
+------------+------+---------------------------------+
|
||||
| Back | 2 | X1 xor X0 (BIT#01 xor BIT#00) |
|
||||
+------------+------+---------------------------------+
|
||||
| Right | 4 | X1 |
|
||||
+------------+------+---------------------------------+
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
======== === ==== ==== ====== =================================================
|
||||
NAME rev ADDR type chip Description
|
||||
======== === ==== ==== ====== =================================================
|
||||
JOYTEST 036 W Denise Write to all 4 joystick-mouse counters at once.
|
||||
======== === ==== ==== ====== =================================================
|
||||
|
||||
Mouse counter write test data:
|
||||
|
||||
========= === === === === === === === === ====== === === === === === === ===
|
||||
BIT# 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
|
||||
========= === === === === === === === === ====== === === === === === === ===
|
||||
JOYxDAT Y7 Y6 Y5 Y4 Y3 Y2 xx xx X7 X6 X5 X4 X3 X2 xx xx
|
||||
JOYxDAT Y7 Y6 Y5 Y4 Y3 Y2 xx xx X7 X6 X5 X4 X3 X2 xx xx
|
||||
========= === === === === === === === === ====== === === === === === === ===
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
======= === ==== ==== ====== ========================================
|
||||
NAME rev ADDR type chip Description
|
||||
======= === ==== ==== ====== ========================================
|
||||
POT0DAT h 012 R Paula Pot counter data left pair (vert, horiz)
|
||||
POT1DAT h 014 R Paula Pot counter data right pair (vert,horiz)
|
||||
======= === ==== ==== ====== ========================================
|
||||
|
||||
These addresses each read a pair of 8 bit pot counters.
|
||||
(4 counters total). The bit assignment for both
|
||||
addresses is shown below. The counters are stopped by signals
|
||||
from 2 controller connectors (left-right) with 2 pins each.
|
||||
|
||||
====== === === === === === === === === ====== === === === === === === ===
|
||||
BIT# 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
|
||||
====== === === === === === === === === ====== === === === === === === ===
|
||||
RIGHT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 X7 X6 X5 X4 X3 X2 X1 X0
|
||||
LEFT Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 X7 X6 X5 X4 X3 X2 X1 X0
|
||||
====== === === === === === === === === ====== === === === === === === ===
|
||||
|
||||
+--------------------------+-------+
|
||||
| CONNECTORS | PAULA |
|
||||
+-------+------+-----+-----+-------+
|
||||
| Loc. | Dir. | Sym | pin | pin |
|
||||
+-------+------+-----+-----+-------+
|
||||
+=======+======+=====+=====+=======+
|
||||
| RIGHT | Y | RX | 9 | 33 |
|
||||
+-------+------+-----+-----+-------+
|
||||
| RIGHT | X | RX | 5 | 32 |
|
||||
+-------+------+-----+-----+-------+
|
||||
| LEFT | Y | LY | 9 | 36 |
|
||||
+-------+------+-----+-----+-------+
|
||||
| LEFT | X | LX | 5 | 35 |
|
||||
+-------+------+-----+-----+-------+
|
||||
|
||||
|
@ -155,30 +220,44 @@ POT1DAT h 014 R Paula Pot counter data right pair (vert,horiz)
|
|||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
====== === ==== ==== ====== ================================================
|
||||
NAME rev ADDR type chip Description
|
||||
POTGO 034 W Paula Pot port (4 bit) bi-direction and data, and pot counter start.
|
||||
====== === ==== ==== ====== ================================================
|
||||
POTGO 034 W Paula Pot port (4 bit) bi-direction and data, and pot
|
||||
counter start.
|
||||
====== === ==== ==== ====== ================================================
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
====== === ==== ==== ====== ================================================
|
||||
NAME rev ADDR type chip Description
|
||||
====== === ==== ==== ====== ================================================
|
||||
POTINP 016 R Paula Pot pin data read
|
||||
====== === ==== ==== ====== ================================================
|
||||
|
||||
This register controls a 4 bit bi-direction I/O port
|
||||
that shares the same 4 pins as the 4 pot counters above.
|
||||
|
||||
+-------+----------+---------------------------------------------+
|
||||
| BIT# | FUNCTION | DESCRIPTION |
|
||||
+-------+----------+---------------------------------------------+
|
||||
+=======+==========+=============================================+
|
||||
| 15 | OUTRY | Output enable for Paula pin 33 |
|
||||
+-------+----------+---------------------------------------------+
|
||||
| 14 | DATRY | I/O data Paula pin 33 |
|
||||
+-------+----------+---------------------------------------------+
|
||||
| 13 | OUTRX | Output enable for Paula pin 32 |
|
||||
+-------+----------+---------------------------------------------+
|
||||
| 12 | DATRX | I/O data Paula pin 32 |
|
||||
+-------+----------+---------------------------------------------+
|
||||
| 11 | OUTLY | Out put enable for Paula pin 36 |
|
||||
+-------+----------+---------------------------------------------+
|
||||
| 10 | DATLY | I/O data Paula pin 36 |
|
||||
+-------+----------+---------------------------------------------+
|
||||
| 09 | OUTLX | Output enable for Paula pin 35 |
|
||||
+-------+----------+---------------------------------------------+
|
||||
| 08 | DATLX | I/O data Paula pin 35 |
|
||||
+-------+----------+---------------------------------------------+
|
||||
| 07-01 | X | Not used |
|
||||
+-------+----------+---------------------------------------------+
|
||||
| 00 | START | Start pots (dump capacitors,start counters) |
|
||||
+-------+----------+---------------------------------------------+
|
||||
|
||||
-------------------------------------------------------------------------------
|
|
@ -1,12 +1,17 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
----------------------------------
|
||||
Apple Touchpad Driver (appletouch)
|
||||
----------------------------------
|
||||
Copyright (C) 2005 Stelian Pop <stelian@popies.net>
|
||||
|
||||
:Copyright: |copy| 2005 Stelian Pop <stelian@popies.net>
|
||||
|
||||
appletouch is a Linux kernel driver for the USB touchpad found on post
|
||||
February 2005 and October 2005 Apple Aluminium Powerbooks.
|
||||
|
||||
This driver is derived from Johannes Berg's appletrackpad driver[1], but it has
|
||||
been improved in some areas:
|
||||
This driver is derived from Johannes Berg's appletrackpad driver [#f1]_,
|
||||
but it has been improved in some areas:
|
||||
|
||||
* appletouch is a full kernel driver, no userspace program is necessary
|
||||
* appletouch can be interfaced with the synaptics X11 driver, in order
|
||||
to have touchpad acceleration, scrolling, etc.
|
||||
|
@ -16,8 +21,8 @@ Frank Arnold for further improvements, and Alex Harper for some additional
|
|||
information about the inner workings of the touchpad sensors. Michael
|
||||
Hanselmann added support for the October 2005 models.
|
||||
|
||||
Usage:
|
||||
------
|
||||
Usage
|
||||
-----
|
||||
|
||||
In order to use the touchpad in the basic mode, compile the driver and load
|
||||
the module. A new input device will be detected and you will be able to read
|
||||
|
@ -27,13 +32,13 @@ In X11, you can configure the touchpad to use the synaptics X11 driver, which
|
|||
will give additional functionalities, like acceleration, scrolling, 2 finger
|
||||
tap for middle button mouse emulation, 3 finger tap for right button mouse
|
||||
emulation, etc. In order to do this, make sure you're using a recent version of
|
||||
the synaptics driver (tested with 0.14.2, available from [2]), and configure a
|
||||
new input device in your X11 configuration file (take a look below for an
|
||||
example). For additional configuration, see the synaptics driver documentation.
|
||||
the synaptics driver (tested with 0.14.2, available from [#f2]_), and configure
|
||||
a new input device in your X11 configuration file (take a look below for an
|
||||
example). For additional configuration, see the synaptics driver documentation::
|
||||
|
||||
Section "InputDevice"
|
||||
Identifier "Synaptics Touchpad"
|
||||
Driver "synaptics"
|
||||
Identifier "Synaptics Touchpad"
|
||||
Driver "synaptics"
|
||||
Option "SendCoreEvents" "true"
|
||||
Option "Device" "/dev/input/mice"
|
||||
Option "Protocol" "auto-dev"
|
||||
|
@ -60,8 +65,8 @@ example). For additional configuration, see the synaptics driver documentation.
|
|||
...
|
||||
EndSection
|
||||
|
||||
Fuzz problems:
|
||||
--------------
|
||||
Fuzz problems
|
||||
-------------
|
||||
|
||||
The touchpad sensors are very sensitive to heat, and will generate a lot of
|
||||
noise when the temperature changes. This is especially true when you power-on
|
||||
|
@ -73,13 +78,17 @@ the driver.
|
|||
|
||||
You can activate debugging using the 'debug' module parameter. A value of 0
|
||||
deactivates any debugging, 1 activates tracing of invalid samples, 2 activates
|
||||
full tracing (each sample is being traced):
|
||||
full tracing (each sample is being traced)::
|
||||
|
||||
modprobe appletouch debug=1
|
||||
or
|
||||
|
||||
or::
|
||||
|
||||
echo "1" > /sys/module/appletouch/parameters/debug
|
||||
|
||||
Links:
|
||||
------
|
||||
|
||||
[1]: http://johannes.sipsolutions.net/PowerBook/touchpad/
|
||||
[2]: http://web.archive.org/web/*/http://web.telia.com/~u89404340/touchpad/index.html
|
||||
.. Links:
|
||||
|
||||
.. [#f1] http://johannes.sipsolutions.net/PowerBook/touchpad/
|
||||
|
||||
.. [#f2] `<http://web.archive.org/web/*/http://web.telia.com/~u89404340/touchpad/index.html>`_
|
|
@ -1,7 +1,10 @@
|
|||
====================================
|
||||
Intelligent Keyboard (ikbd) Protocol
|
||||
====================================
|
||||
|
||||
|
||||
1. Introduction
|
||||
Introduction
|
||||
============
|
||||
|
||||
The Atari Corp. Intelligent Keyboard (ikbd) is a general purpose keyboard
|
||||
controller that is flexible enough that it can be used in a variety of
|
||||
|
@ -18,7 +21,8 @@ different applications of the keyboard, joysticks, or mouse. Limited use of
|
|||
the controller is possible in applications in which only a unidirectional
|
||||
communications medium is available by carefully designing the default modes.
|
||||
|
||||
3. Keyboard
|
||||
Keyboard
|
||||
========
|
||||
|
||||
The keyboard always returns key make/break scan codes. The ikbd generates
|
||||
keyboard scan codes for each key press and release. The key scan make (key
|
||||
|
@ -28,19 +32,25 @@ exists in that position on a particular keyboard. The break code for each key
|
|||
is obtained by ORing 0x80 with the make code.
|
||||
|
||||
The special codes 0xF6 through 0xFF are reserved for use as follows:
|
||||
|
||||
=================== ====================================================
|
||||
Code Command
|
||||
=================== ====================================================
|
||||
0xF6 status report
|
||||
0xF7 absolute mouse position record
|
||||
0xF8-0xFB relative mouse position records (lsbs determined by
|
||||
mouse button states)
|
||||
mouse button states)
|
||||
0xFC time-of-day
|
||||
0xFD joystick report (both sticks)
|
||||
0xFE joystick 0 event
|
||||
0xFF joystick 1 event
|
||||
=================== ====================================================
|
||||
|
||||
The two shift keys return different scan codes in this mode. The ENTER key
|
||||
and the RETurn key are also distinct.
|
||||
|
||||
4. Mouse
|
||||
Mouse
|
||||
=====
|
||||
|
||||
The mouse port should be capable of supporting a mouse with resolution of
|
||||
approximately 200 counts (phase changes or 'clicks') per inch of travel. The
|
||||
|
@ -53,7 +63,8 @@ key equivalents.
|
|||
The mouse buttons can be treated as part of the mouse or as additional
|
||||
keyboard keys.
|
||||
|
||||
4.1 Relative Position Reporting
|
||||
Relative Position Reporting
|
||||
---------------------------
|
||||
|
||||
In relative position mode, the ikbd will return relative mouse position
|
||||
records whenever a mouse event occurs. A mouse event consists of a mouse
|
||||
|
@ -67,7 +78,8 @@ been 'paused' ( the event will be stored until keyboard communications is
|
|||
resumed) (b) while any event is being transmitted.
|
||||
|
||||
The relative mouse position record is a three byte record of the form
|
||||
(regardless of keyboard mode):
|
||||
(regardless of keyboard mode)::
|
||||
|
||||
%111110xy ; mouse position record flag
|
||||
; where y is the right button state
|
||||
; and x is the left button state
|
||||
|
@ -81,13 +93,15 @@ If the accumulated motion before the report packet is generated exceeds the
|
|||
Note that the sign of the delta y reported is a function of the Y origin
|
||||
selected.
|
||||
|
||||
4.2 Absolute Position reporting
|
||||
Absolute Position reporting
|
||||
---------------------------
|
||||
|
||||
The ikbd can also maintain absolute mouse position. Commands exist for
|
||||
resetting the mouse position, setting X/Y scaling, and interrogating the
|
||||
current mouse position.
|
||||
|
||||
4.3 Mouse Cursor Key Mode
|
||||
Mouse Cursor Key Mode
|
||||
---------------------
|
||||
|
||||
The ikbd can translate mouse motion into the equivalent cursor keystrokes.
|
||||
The number of mouse clicks per keystroke is independently programmable in
|
||||
|
@ -99,32 +113,38 @@ break code for the appropriate cursor key. The mouse buttons produce scan
|
|||
codes above those normally assigned for the largest envisioned keyboard (i.e.
|
||||
LEFT=0x74 & RIGHT=0x75).
|
||||
|
||||
5. Joystick
|
||||
Joystick
|
||||
========
|
||||
|
||||
5.1 Joystick Event Reporting
|
||||
Joystick Event Reporting
|
||||
------------------------
|
||||
|
||||
In this mode, the ikbd generates a record whenever the joystick position is
|
||||
changed (i.e. for each opening or closing of a joystick switch or trigger).
|
||||
|
||||
The joystick event record is two bytes of the form:
|
||||
The joystick event record is two bytes of the form::
|
||||
|
||||
%1111111x ; Joystick event marker
|
||||
; where x is Joystick 0 or 1
|
||||
%x000yyyy ; where yyyy is the stick position
|
||||
; and x is the trigger
|
||||
|
||||
5.2 Joystick Interrogation
|
||||
Joystick Interrogation
|
||||
----------------------
|
||||
|
||||
The current state of the joystick ports may be interrogated at any time in
|
||||
this mode by sending an 'Interrogate Joystick' command to the ikbd.
|
||||
|
||||
The ikbd response to joystick interrogation is a three byte report of the form
|
||||
The ikbd response to joystick interrogation is a three byte report of the form::
|
||||
|
||||
0xFD ; joystick report header
|
||||
%x000yyyy ; Joystick 0
|
||||
%x000yyyy ; Joystick 1
|
||||
; where x is the trigger
|
||||
; and yyy is the stick position
|
||||
|
||||
5.3 Joystick Monitoring
|
||||
Joystick Monitoring
|
||||
-------------------
|
||||
|
||||
A mode is available that devotes nearly all of the keyboard communications
|
||||
time to reporting the state of the joystick ports at a user specifiable rate.
|
||||
|
@ -132,7 +152,8 @@ It remains in this mode until reset or commanded into another mode. The PAUSE
|
|||
command in this mode not only stop the output but also temporarily stops
|
||||
scanning the joysticks (samples are not queued).
|
||||
|
||||
5.4 Fire Button Monitoring
|
||||
Fire Button Monitoring
|
||||
----------------------
|
||||
|
||||
A mode is provided to permit monitoring a single input bit at a high rate. In
|
||||
this mode the ikbd monitors the state of the Joystick 1 fire button at the
|
||||
|
@ -142,7 +163,8 @@ until reset or commanded into another mode. The PAUSE command in this mode not
|
|||
only stops the output but also temporarily stops scanning the button (samples
|
||||
are not queued).
|
||||
|
||||
5.5 Joystick Key Code Mode
|
||||
Joystick Key Code Mode
|
||||
----------------------
|
||||
|
||||
The ikbd may be commanded to translate the use of either joystick into the
|
||||
equivalent cursor control keystroke(s). The ikbd provides a single breakpoint
|
||||
|
@ -152,18 +174,21 @@ for the appropriate cursor motion keys. The trigger or fire buttons of the
|
|||
joysticks produce pseudo key scan codes above those used by the largest key
|
||||
matrix envisioned (i.e. JOYSTICK0=0x74, JOYSTICK1=0x75).
|
||||
|
||||
6. Time-of-Day Clock
|
||||
Time-of-Day Clock
|
||||
=================
|
||||
|
||||
The ikbd also maintains a time-of-day clock for the system. Commands are
|
||||
available to set and interrogate the timer-of-day clock. Time-keeping is
|
||||
maintained down to a resolution of one second.
|
||||
|
||||
7. Status Inquiries
|
||||
Status Inquiries
|
||||
================
|
||||
|
||||
The current state of ikbd modes and parameters may be found by sending status
|
||||
inquiry commands that correspond to the ikbd set commands.
|
||||
|
||||
8. Power-Up Mode
|
||||
Power-Up Mode
|
||||
=============
|
||||
|
||||
The keyboard controller will perform a simple self-test on power-up to detect
|
||||
major controller faults (ROM checksum and RAM test) and such things as stuck
|
||||
|
@ -183,13 +208,17 @@ both buttons are logically connected to it. If a mouse disable command is
|
|||
received while port 0 is presumed to be a mouse, the button is logically
|
||||
assigned to Joystick1 (until the mouse is reenabled by another mouse command).
|
||||
|
||||
9. ikbd Command Set
|
||||
ikbd Command Set
|
||||
================
|
||||
|
||||
This section contains a list of commands that can be sent to the ikbd. Command
|
||||
codes (such as 0x00) which are not specified should perform no operation
|
||||
(NOPs).
|
||||
|
||||
9.1 RESET
|
||||
RESET
|
||||
-----
|
||||
|
||||
::
|
||||
|
||||
0x80
|
||||
0x01
|
||||
|
@ -208,7 +237,10 @@ ikbd will then scan the key matrix for any stuck (closed) keys. Any keys found
|
|||
closed will cause the break scan code to be generated (the break code arriving
|
||||
without being preceded by the make code is a flag for a key matrix error).
|
||||
|
||||
9.2. SET MOUSE BUTTON ACTION
|
||||
SET MOUSE BUTTON ACTION
|
||||
-----------------------
|
||||
|
||||
::
|
||||
|
||||
0x07
|
||||
%00000mss ; mouse button action
|
||||
|
@ -217,14 +249,17 @@ without being preceded by the make code is a flag for a key matrix error).
|
|||
; position report
|
||||
; where y=1, mouse key press causes absolute report
|
||||
; and x=1, mouse key release causes absolute report
|
||||
; mss=100, mouse buttons act like keys
|
||||
; mss=100, mouse buttons act like keys
|
||||
|
||||
This command sets how the ikbd should treat the buttons on the mouse. The
|
||||
default mouse button action mode is %00000000, the buttons are treated as part
|
||||
of the mouse logically.
|
||||
When buttons act like keys, LEFT=0x74 & RIGHT=0x75.
|
||||
|
||||
9.3 SET RELATIVE MOUSE POSITION REPORTING
|
||||
SET RELATIVE MOUSE POSITION REPORTING
|
||||
-------------------------------------
|
||||
|
||||
::
|
||||
|
||||
0x08
|
||||
|
||||
|
@ -235,14 +270,17 @@ key mode, mouse position reports may also be generated when either mouse
|
|||
button is pressed or released. Otherwise the mouse buttons behave as if they
|
||||
were keyboard keys.
|
||||
|
||||
9.4 SET ABSOLUTE MOUSE POSITIONING
|
||||
SET ABSOLUTE MOUSE POSITIONING
|
||||
------------------------------
|
||||
|
||||
::
|
||||
|
||||
0x09
|
||||
XMSB ; X maximum (in scaled mouse clicks)
|
||||
XLSB
|
||||
YMSB ; Y maximum (in scaled mouse clicks)
|
||||
YLSB
|
||||
|
||||
|
||||
Set absolute mouse position maintenance. Resets the ikbd maintained X and Y
|
||||
coordinates.
|
||||
In this mode, the value of the internally maintained coordinates does NOT wrap
|
||||
|
@ -250,7 +288,10 @@ between 0 and large positive numbers. Excess motion below 0 is ignored. The
|
|||
command sets the maximum positive value that can be attained in the scaled
|
||||
coordinate system. Motion beyond that value is also ignored.
|
||||
|
||||
9.5 SET MOUSE KEYCODE MOSE
|
||||
SET MOUSE KEYCODE MOSE
|
||||
----------------------
|
||||
|
||||
::
|
||||
|
||||
0x0A
|
||||
deltax ; distance in X clicks to return (LEFT) or (RIGHT)
|
||||
|
@ -263,7 +304,10 @@ either axis. When the keyboard is in key scan code mode, mouse motion will
|
|||
cause the make code immediately followed by the break code. Note that this
|
||||
command is not affected by the mouse motion origin.
|
||||
|
||||
9..6 SET MOUSE THRESHOLD
|
||||
SET MOUSE THRESHOLD
|
||||
-------------------
|
||||
|
||||
::
|
||||
|
||||
0x0B
|
||||
X ; x threshold in mouse ticks (positive integers)
|
||||
|
@ -274,7 +318,10 @@ it does NOT affect the resolution of the data returned to the host. This
|
|||
command is valid only in RELATIVE MOUSE POSITIONING mode. The thresholds
|
||||
default to 1 at RESET (or power-up).
|
||||
|
||||
9.7 SET MOUSE SCALE
|
||||
SET MOUSE SCALE
|
||||
---------------
|
||||
|
||||
::
|
||||
|
||||
0x0C
|
||||
X ; horizontal mouse ticks per internal X
|
||||
|
@ -288,7 +335,10 @@ information is available only by interrogating the ikbd in the ABSOLUTE MOUSE
|
|||
POSITIONING mode unless the ikbd has been commanded to report on button press
|
||||
or release (see SET MOSE BUTTON ACTION).
|
||||
|
||||
9.8 INTERROGATE MOUSE POSITION
|
||||
INTERROGATE MOUSE POSITION
|
||||
--------------------------
|
||||
|
||||
::
|
||||
|
||||
0x0D
|
||||
Returns:
|
||||
|
@ -306,7 +356,10 @@ or release (see SET MOSE BUTTON ACTION).
|
|||
The INTERROGATE MOUSE POSITION command is valid when in the ABSOLUTE MOUSE
|
||||
POSITIONING mode, regardless of the setting of the MOUSE BUTTON ACTION.
|
||||
|
||||
9.9 LOAD MOUSE POSITION
|
||||
LOAD MOUSE POSITION
|
||||
-------------------
|
||||
|
||||
::
|
||||
|
||||
0x0E
|
||||
0x00 ; filler
|
||||
|
@ -318,7 +371,10 @@ POSITIONING mode, regardless of the setting of the MOUSE BUTTON ACTION.
|
|||
This command allows the user to preset the internally maintained absolute
|
||||
mouse position.
|
||||
|
||||
9.10 SET Y=0 AT BOTTOM
|
||||
SET Y=0 AT BOTTOM
|
||||
-----------------
|
||||
|
||||
::
|
||||
|
||||
0x0F
|
||||
|
||||
|
@ -327,7 +383,10 @@ logical coordinate system internal to the ikbd for all relative or absolute
|
|||
mouse motion. This causes mouse motion toward the user to be negative in sign
|
||||
and away from the user to be positive.
|
||||
|
||||
9.11 SET Y=0 AT TOP
|
||||
SET Y=0 AT TOP
|
||||
--------------
|
||||
|
||||
::
|
||||
|
||||
0x10
|
||||
|
||||
|
@ -336,7 +395,10 @@ system within the ikbd for all relative or absolute mouse motion. (DEFAULT)
|
|||
This causes mouse motion toward the user to be positive in sign and away from
|
||||
the user to be negative.
|
||||
|
||||
9.12 RESUME
|
||||
RESUME
|
||||
------
|
||||
|
||||
::
|
||||
|
||||
0x11
|
||||
|
||||
|
@ -345,7 +407,10 @@ its output has been paused also causes an implicit RESUME this command can be
|
|||
thought of as a NO OPERATION command. If this command is received by the ikbd
|
||||
and it is not PAUSED, it is simply ignored.
|
||||
|
||||
9.13 DISABLE MOUSE
|
||||
DISABLE MOUSE
|
||||
-------------
|
||||
|
||||
::
|
||||
|
||||
0x12
|
||||
|
||||
|
@ -356,7 +421,10 @@ ABSOLUTE MOUSE POSITIONING, and SET MOUSE KEYCODE MODE. )
|
|||
N.B. If the mouse buttons have been commanded to act like keyboard keys, this
|
||||
command DOES affect their actions.
|
||||
|
||||
9.14 PAUSE OUTPUT
|
||||
PAUSE OUTPUT
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
0x13
|
||||
|
||||
|
@ -381,21 +449,30 @@ When the ikbd is in either the JOYSTICK MONITORING mode or the FIRE BUTTON
|
|||
MONITORING mode, the PAUSE OUTPUT command also temporarily stops the
|
||||
monitoring process (i.e. the samples are not enqueued for transmission).
|
||||
|
||||
0.15 SET JOYSTICK EVENT REPORTING
|
||||
SET JOYSTICK EVENT REPORTING
|
||||
----------------------------
|
||||
|
||||
::
|
||||
|
||||
0x14
|
||||
|
||||
Enter JOYSTICK EVENT REPORTING mode (DEFAULT). Each opening or closure of a
|
||||
joystick switch or trigger causes a joystick event record to be generated.
|
||||
|
||||
9.16 SET JOYSTICK INTERROGATION MODE
|
||||
SET JOYSTICK INTERROGATION MODE
|
||||
-------------------------------
|
||||
|
||||
::
|
||||
|
||||
0x15
|
||||
|
||||
Disables JOYSTICK EVENT REPORTING. Host must send individual JOYSTICK
|
||||
INTERROGATE commands to sense joystick state.
|
||||
|
||||
9.17 JOYSTICK INTERROGATE
|
||||
JOYSTICK INTERROGATE
|
||||
--------------------
|
||||
|
||||
::
|
||||
|
||||
0x16
|
||||
|
||||
|
@ -403,7 +480,10 @@ Return a record indicating the current state of the joysticks. This command
|
|||
is valid in either the JOYSTICK EVENT REPORTING mode or the JOYSTICK
|
||||
INTERROGATION MODE.
|
||||
|
||||
9.18 SET JOYSTICK MONITORING
|
||||
SET JOYSTICK MONITORING
|
||||
-----------------------
|
||||
|
||||
::
|
||||
|
||||
0x17
|
||||
rate ; time between samples in hundredths of a second
|
||||
|
@ -419,7 +499,10 @@ between joystick samples.
|
|||
N.B. The user should not set the rate higher than the serial communications
|
||||
channel will allow the 2 bytes packets to be transmitted.
|
||||
|
||||
9.19 SET FIRE BUTTON MONITORING
|
||||
SET FIRE BUTTON MONITORING
|
||||
--------------------------
|
||||
|
||||
::
|
||||
|
||||
0x18
|
||||
Returns: (as long as in mode)
|
||||
|
@ -432,7 +515,10 @@ is scanned at a rate that causes 8 samples to be made in the time it takes for
|
|||
the previous byte to be sent to the host (i.e. scan rate = 8/10 * baud rate).
|
||||
The sample interval should be as constant as possible.
|
||||
|
||||
9.20 SET JOYSTICK KEYCODE MODE
|
||||
SET JOYSTICK KEYCODE MODE
|
||||
-------------------------
|
||||
|
||||
::
|
||||
|
||||
0x19
|
||||
RX ; length of time (in tenths of seconds) until
|
||||
|
@ -462,7 +548,10 @@ Note that by setting RX and/or Ry to zero, the velocity feature can be
|
|||
disabled. The values of TX and TY then become meaningless, and the generation
|
||||
of cursor 'keystrokes' is set by VX and VY.
|
||||
|
||||
9.21 DISABLE JOYSTICKS
|
||||
DISABLE JOYSTICKS
|
||||
-----------------
|
||||
|
||||
::
|
||||
|
||||
0x1A
|
||||
|
||||
|
@ -472,7 +561,10 @@ joystick mode commands are SET JOYSTICK EVENT REPORTING, SET JOYSTICK
|
|||
INTERROGATION MODE, SET JOYSTICK MONITORING, SET FIRE BUTTON MONITORING, and
|
||||
SET JOYSTICK KEYCODE MODE.)
|
||||
|
||||
9.22 TIME-OF-DAY CLOCK SET
|
||||
TIME-OF-DAY CLOCK SET
|
||||
---------------------
|
||||
|
||||
::
|
||||
|
||||
0x1B
|
||||
YY ; year (2 least significant digits)
|
||||
|
@ -487,7 +579,10 @@ Any digit that is not a valid BCD digit should be treated as a 'don't care'
|
|||
and not alter that particular field of the date or time. This permits setting
|
||||
only some subfields of the time-of-day clock.
|
||||
|
||||
9.23 INTERROGATE TIME-OF-DAT CLOCK
|
||||
INTERROGATE TIME-OF-DAT CLOCK
|
||||
-----------------------------
|
||||
|
||||
::
|
||||
|
||||
0x1C
|
||||
Returns:
|
||||
|
@ -501,7 +596,10 @@ only some subfields of the time-of-day clock.
|
|||
|
||||
All time-of-day is sent in packed BCD format.
|
||||
|
||||
9.24 MEMORY LOAD
|
||||
MEMORY LOAD
|
||||
-----------
|
||||
|
||||
::
|
||||
|
||||
0x20
|
||||
ADRMSB ; address in controller
|
||||
|
@ -512,7 +610,10 @@ only some subfields of the time-of-day clock.
|
|||
This command permits the host to load arbitrary values into the ikbd
|
||||
controller memory. The time between data bytes must be less than 20ms.
|
||||
|
||||
9.25 MEMORY READ
|
||||
MEMORY READ
|
||||
-----------
|
||||
|
||||
::
|
||||
|
||||
0x21
|
||||
ADRMSB ; address in controller
|
||||
|
@ -524,7 +625,10 @@ controller memory. The time between data bytes must be less than 20ms.
|
|||
|
||||
This command permits the host to read from the ikbd controller memory.
|
||||
|
||||
9.26 CONTROLLER EXECUTE
|
||||
CONTROLLER EXECUTE
|
||||
------------------
|
||||
|
||||
::
|
||||
|
||||
0x22
|
||||
ADRMSB ; address of subroutine in
|
||||
|
@ -533,8 +637,11 @@ This command permits the host to read from the ikbd controller memory.
|
|||
This command allows the host to command the execution of a subroutine in the
|
||||
ikbd controller memory.
|
||||
|
||||
9.27 STATUS INQUIRIES
|
||||
|
||||
STATUS INQUIRIES
|
||||
----------------
|
||||
|
||||
::
|
||||
|
||||
Status commands are formed by inclusively ORing 0x80 with the
|
||||
relevant SET command.
|
||||
|
||||
|
@ -568,7 +675,7 @@ off the status report header byte) and later send them back as commands to
|
|||
ikbd to restore its state. The 0 pad bytes will be treated as NOPs by the
|
||||
ikbd.
|
||||
|
||||
Valid STATUS INQUIRY commands are:
|
||||
Valid STATUS INQUIRY commands are::
|
||||
|
||||
0x87 mouse button action
|
||||
0x88 mouse mode
|
||||
|
@ -595,14 +702,17 @@ STATUS INQUIRY commands are not valid if the ikbd is in JOYSTICK MONITORING
|
|||
mode or FIRE BUTTON MONITORING mode.
|
||||
|
||||
|
||||
10. SCAN CODES
|
||||
SCAN CODES
|
||||
==========
|
||||
|
||||
The key scan codes returned by the ikbd are chosen to simplify the
|
||||
implementation of GSX.
|
||||
|
||||
GSX Standard Keyboard Mapping.
|
||||
GSX Standard Keyboard Mapping
|
||||
|
||||
======= ============
|
||||
Hex Keytop
|
||||
======= ============
|
||||
01 Esc
|
||||
02 1
|
||||
03 2
|
||||
|
@ -614,8 +724,8 @@ Hex Keytop
|
|||
09 8
|
||||
0A 9
|
||||
0B 0
|
||||
0C -
|
||||
0D ==
|
||||
0C \-
|
||||
0D \=
|
||||
0E BS
|
||||
0F TAB
|
||||
10 Q
|
||||
|
@ -643,9 +753,9 @@ Hex Keytop
|
|||
26 L
|
||||
27 ;
|
||||
28 '
|
||||
29 `
|
||||
29 \`
|
||||
2A (LEFT) SHIFT
|
||||
2B \
|
||||
2B \\
|
||||
2C Z
|
||||
2D X
|
||||
2E C
|
||||
|
@ -707,3 +817,4 @@ Hex Keytop
|
|||
70 KEYPAD 0
|
||||
71 KEYPAD .
|
||||
72 KEYPAD ENTER
|
||||
======= ============
|
|
@ -1,19 +1,25 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
------------------------
|
||||
BCM5974 Driver (bcm5974)
|
||||
------------------------
|
||||
Copyright (C) 2008-2009 Henrik Rydberg <rydberg@euromail.se>
|
||||
|
||||
:Copyright: |copy| 2008-2009 Henrik Rydberg <rydberg@euromail.se>
|
||||
|
||||
The USB initialization and package decoding was made by Scott Shawcroft as
|
||||
part of the touchd user-space driver project:
|
||||
Copyright (C) 2008 Scott Shawcroft (scott.shawcroft@gmail.com)
|
||||
|
||||
:Copyright: |copy| 2008 Scott Shawcroft (scott.shawcroft@gmail.com)
|
||||
|
||||
The BCM5974 driver is based on the appletouch driver:
|
||||
Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
|
||||
Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
|
||||
Copyright (C) 2005 Stelian Pop (stelian@popies.net)
|
||||
Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
|
||||
Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
|
||||
Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
|
||||
Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch)
|
||||
|
||||
:Copyright: |copy| 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
|
||||
:Copyright: |copy| 2005 Johannes Berg (johannes@sipsolutions.net)
|
||||
:Copyright: |copy| 2005 Stelian Pop (stelian@popies.net)
|
||||
:Copyright: |copy| 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
|
||||
:Copyright: |copy| 2005 Peter Osterlund (petero2@telia.com)
|
||||
:Copyright: |copy| 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
|
||||
:Copyright: |copy| 2006 Nicolas Boichat (nicolas@boichat.ch)
|
||||
|
||||
This driver adds support for the multi-touch trackpad on the new Apple
|
||||
Macbook Air and Macbook Pro laptops. It replaces the appletouch driver on
|
||||
|
@ -44,22 +50,21 @@ Debug output
|
|||
|
||||
To ease the development for new hardware version, verbose packet output can
|
||||
be switched on with the debug kernel module parameter. The range [1-9]
|
||||
yields different levels of verbosity. Example (as root):
|
||||
yields different levels of verbosity. Example (as root)::
|
||||
|
||||
echo -n 9 > /sys/module/bcm5974/parameters/debug
|
||||
echo -n 9 > /sys/module/bcm5974/parameters/debug
|
||||
|
||||
tail -f /var/log/debug
|
||||
tail -f /var/log/debug
|
||||
|
||||
echo -n 0 > /sys/module/bcm5974/parameters/debug
|
||||
echo -n 0 > /sys/module/bcm5974/parameters/debug
|
||||
|
||||
Trivia
|
||||
------
|
||||
|
||||
The driver was developed at the ubuntu forums in June 2008 [1], and now has
|
||||
a more permanent home at bitmath.org [2].
|
||||
The driver was developed at the ubuntu forums in June 2008 [#f1]_, and now has
|
||||
a more permanent home at bitmath.org [#f2]_.
|
||||
|
||||
Links
|
||||
-----
|
||||
.. Links
|
||||
|
||||
[1] http://ubuntuforums.org/showthread.php?t=840040
|
||||
[2] http://bitmath.org/code/
|
||||
.. [#f1] http://ubuntuforums.org/showthread.php?t=840040
|
||||
.. [#f2] http://bitmath.org/code/
|
|
@ -1,30 +1,37 @@
|
|||
Kernel driver for CMA3000-D0x
|
||||
============================
|
||||
CMA3000-D0x Accelerometer
|
||||
=========================
|
||||
|
||||
Supported chips:
|
||||
* VTI CMA3000-D0x
|
||||
|
||||
Datasheet:
|
||||
CMA3000-D0X Product Family Specification 8281000A.02.pdf
|
||||
<http://www.vti.fi/en/>
|
||||
|
||||
Author: Hemanth V <hemanthv@ti.com>
|
||||
:Author: Hemanth V <hemanthv@ti.com>
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
CMA3000 Tri-axis accelerometer supports Motion detect, Measurement and
|
||||
Free fall modes.
|
||||
|
||||
Motion Detect Mode: Its the low power mode where interrupts are generated only
|
||||
when motion exceeds the defined thresholds.
|
||||
Motion Detect Mode:
|
||||
Its the low power mode where interrupts are generated only
|
||||
when motion exceeds the defined thresholds.
|
||||
|
||||
Measurement Mode: This mode is used to read the acceleration data on X,Y,Z
|
||||
axis and supports 400, 100, 40 Hz sample frequency.
|
||||
Measurement Mode:
|
||||
This mode is used to read the acceleration data on X,Y,Z
|
||||
axis and supports 400, 100, 40 Hz sample frequency.
|
||||
|
||||
Free fall Mode: This mode is intended to save system resources.
|
||||
Free fall Mode:
|
||||
This mode is intended to save system resources.
|
||||
|
||||
Threshold values: Chip supports defining threshold values for above modes
|
||||
which includes time and g value. Refer product specifications for more details.
|
||||
Threshold values:
|
||||
Chip supports defining threshold values for above modes
|
||||
which includes time and g value. Refer product specifications for
|
||||
more details.
|
||||
|
||||
CMA3000 chip supports mutually exclusive I2C and SPI interfaces for
|
||||
communication, currently the driver supports I2C based communication only.
|
||||
|
@ -38,28 +45,40 @@ Platform data need to be configured for initial default values.
|
|||
|
||||
Platform Data
|
||||
-------------
|
||||
fuzz_x: Noise on X Axis
|
||||
|
||||
fuzz_y: Noise on Y Axis
|
||||
fuzz_x:
|
||||
Noise on X Axis
|
||||
|
||||
fuzz_z: Noise on Z Axis
|
||||
fuzz_y:
|
||||
Noise on Y Axis
|
||||
|
||||
g_range: G range in milli g i.e 2000 or 8000
|
||||
fuzz_z:
|
||||
Noise on Z Axis
|
||||
|
||||
mode: Default Operating mode
|
||||
g_range:
|
||||
G range in milli g i.e 2000 or 8000
|
||||
|
||||
mdthr: Motion detect g range threshold value
|
||||
mode:
|
||||
Default Operating mode
|
||||
|
||||
mdfftmr: Motion detect and free fall time threshold value
|
||||
mdthr:
|
||||
Motion detect g range threshold value
|
||||
|
||||
ffthr: Free fall g range threshold value
|
||||
mdfftmr:
|
||||
Motion detect and free fall time threshold value
|
||||
|
||||
ffthr:
|
||||
Free fall g range threshold value
|
||||
|
||||
Input Interface
|
||||
--------------
|
||||
---------------
|
||||
|
||||
Input driver version is 1.0.0
|
||||
Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
|
||||
Input device name: "cma3000-accelerometer"
|
||||
Supported events:
|
||||
|
||||
Supported events::
|
||||
|
||||
Event type 0 (Sync)
|
||||
Event type 3 (Absolute)
|
||||
Event code 0 (X)
|
||||
|
@ -87,7 +106,8 @@ Supported events:
|
|||
Register/Platform parameters Description
|
||||
----------------------------------------
|
||||
|
||||
mode:
|
||||
mode::
|
||||
|
||||
0: power down mode
|
||||
1: 100 Hz Measurement mode
|
||||
2: 400 Hz Measurement mode
|
||||
|
@ -97,19 +117,23 @@ mode:
|
|||
6: 40 Hz Free fall mode
|
||||
7: Power off mode
|
||||
|
||||
grange:
|
||||
grange::
|
||||
|
||||
2000: 2000 mg or 2G Range
|
||||
8000: 8000 mg or 8G Range
|
||||
|
||||
mdthr:
|
||||
mdthr::
|
||||
|
||||
X: X * 71mg (8G Range)
|
||||
X: X * 18mg (2G Range)
|
||||
|
||||
mdfftmr:
|
||||
mdfftmr::
|
||||
|
||||
X: (X & 0x70) * 100 ms (MDTMR)
|
||||
(X & 0x0F) * 2.5 ms (FFTMR 400 Hz)
|
||||
(X & 0x0F) * 10 ms (FFTMR 100 Hz)
|
||||
|
||||
ffthr:
|
||||
ffthr::
|
||||
|
||||
X: (X >> 2) * 18mg (2G Range)
|
||||
X: (X & 0x0F) * 71 mg (8G Range)
|
|
@ -1,36 +1,34 @@
|
|||
Preface.
|
||||
Crystal SoundFusion CS4610/CS4612/CS461 joystick
|
||||
================================================
|
||||
|
||||
This is a new low-level driver to support analog joystick attached to
|
||||
Crystal SoundFusion CS4610/CS4612/CS4615. This code is based upon
|
||||
Crystal SoundFusion CS4610/CS4612/CS4615. This code is based upon
|
||||
Vortex/Solo drivers as an example of decoration style, and ALSA
|
||||
0.5.8a kernel drivers as an chipset documentation and samples.
|
||||
|
||||
This version does not have cooked mode support; the basic code
|
||||
is present here, but have not tested completely. The button analysis
|
||||
is completed in this mode, but the axis movement is not.
|
||||
This version does not have cooked mode support; the basic code
|
||||
is present here, but have not tested completely. The button analysis
|
||||
is completed in this mode, but the axis movement is not.
|
||||
|
||||
Raw mode works fine with analog joystick front-end driver and cs461x
|
||||
driver as a backend. I've tested this driver with CS4610, 4-axis and
|
||||
driver as a backend. I've tested this driver with CS4610, 4-axis and
|
||||
4-button joystick; I mean the jstest utility. Also I've tried to
|
||||
play in xracer game using joystick, and the result is better than
|
||||
keyboard only mode.
|
||||
|
||||
The sensitivity and calibrate quality have not been tested; the two
|
||||
reasons are performed: the same hardware cannot work under Win95 (blue
|
||||
screen in VJOYD); I have no documentation on my chip; and the existing
|
||||
behavior in my case was not raised the requirement of joystick calibration.
|
||||
reasons are performed: the same hardware cannot work under Win95 (blue
|
||||
screen in VJOYD); I have no documentation on my chip; and the existing
|
||||
behavior in my case was not raised the requirement of joystick calibration.
|
||||
So the driver have no code to perform hardware related calibration.
|
||||
|
||||
The patch contains minor changes of Config.in and Makefile files. All
|
||||
needed code have been moved to one separate file cs461x.c like ns558.c
|
||||
This driver have the basic support for PCI devices only; there is no
|
||||
ISA or PnP ISA cards supported. AFAIK the ns558 have support for Crystal
|
||||
ISA and PnP ISA series.
|
||||
ISA or PnP ISA cards supported.
|
||||
|
||||
The driver works with ALSA drivers simultaneously. For example, the xracer
|
||||
uses joystick as input device and PCM device as sound output in one time.
|
||||
There are no sound or input collisions detected. The source code have
|
||||
comments about them; but I've found the joystick can be initialized
|
||||
comments about them; but I've found the joystick can be initialized
|
||||
separately of ALSA modules. So, you can use only one joystick driver
|
||||
without ALSA drivers. The ALSA drivers are not needed to compile or
|
||||
run this driver.
|
||||
|
@ -38,7 +36,7 @@ run this driver.
|
|||
There are no debug information print have been placed in source, and no
|
||||
specific options required to work this driver. The found chipset parameters
|
||||
are printed via printk(KERN_INFO "..."), see the /var/log/messages to
|
||||
inspect cs461x: prefixed messages to determine possible card detection
|
||||
inspect cs461x: prefixed messages to determine possible card detection
|
||||
errors.
|
||||
|
||||
Regards,
|
|
@ -10,9 +10,7 @@ Elantech Touchpad Driver
|
|||
received from Woody at Xandros and forwarded to me
|
||||
by user StewieGriffin at the eeeuser.com forum
|
||||
|
||||
|
||||
Contents
|
||||
~~~~~~~~
|
||||
.. Contents
|
||||
|
||||
1. Introduction
|
||||
2. Extra knobs
|
||||
|
@ -45,8 +43,8 @@ Contents
|
|||
|
||||
|
||||
|
||||
1. Introduction
|
||||
~~~~~~~~~~~~
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Currently the Linux Elantech touchpad driver is aware of four different
|
||||
hardware versions unimaginatively called version 1,version 2, version 3
|
||||
|
@ -88,11 +86,8 @@ available Elantech documentation the information is provided here anyway for
|
|||
completeness sake.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
2. Extra knobs
|
||||
~~~~~~~~~~~
|
||||
Extra knobs
|
||||
~~~~~~~~~~~
|
||||
|
||||
Currently the Linux Elantech touchpad driver provides three extra knobs under
|
||||
/sys/bus/serio/drivers/psmouse/serio? for the user.
|
||||
|
@ -142,18 +137,17 @@ Currently the Linux Elantech touchpad driver provides three extra knobs under
|
|||
Reading the crc_enabled value will show the active value. Echoing
|
||||
"0" or "1" to this file will set the state to "0" or "1".
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Differentiating hardware versions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
3. Differentiating hardware versions
|
||||
=================================
|
||||
|
||||
To detect the hardware version, read the version number as param[0].param[1].param[2]
|
||||
To detect the hardware version, read the version number as param[0].param[1].param[2]::
|
||||
|
||||
4 bytes version: (after the arrow is the name given in the Dell-provided driver)
|
||||
02.00.22 => EF013
|
||||
02.06.00 => EF019
|
||||
|
||||
In the wild, there appear to be more versions, such as 00.01.64, 01.00.21,
|
||||
02.00.00, 02.00.04, 02.00.06.
|
||||
02.00.00, 02.00.04, 02.00.06::
|
||||
|
||||
6 bytes:
|
||||
02.00.30 => EF113
|
||||
|
@ -162,6 +156,7 @@ In the wild, there appear to be more versions, such as 00.01.64, 01.00.21,
|
|||
02.0B.00 => EF215
|
||||
04.01.XX => Scroll_EF051
|
||||
04.02.XX => EF051
|
||||
|
||||
In the wild, there appear to be more versions, such as 04.03.01, 04.04.11. There
|
||||
appears to be almost no difference, except for EF113, which does not report
|
||||
pressure/width and has different data consistency checks.
|
||||
|
@ -170,21 +165,20 @@ Probably all the versions with param[0] <= 01 can be considered as
|
|||
4 bytes/firmware 1. The versions < 02.08.00, with the exception of 02.00.30, as
|
||||
4 bytes/firmware 2. Everything >= 02.08.00 can be considered as 6 bytes.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
4. Hardware version 1
|
||||
==================
|
||||
Hardware version 1
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
4.1 Registers
|
||||
~~~~~~~~~
|
||||
Registers
|
||||
---------
|
||||
|
||||
By echoing a hexadecimal value to a register it contents can be altered.
|
||||
|
||||
For example:
|
||||
For example::
|
||||
|
||||
echo -n 0x16 > reg_10
|
||||
|
||||
* reg_10
|
||||
* reg_10::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
B C T D L A S E
|
||||
|
@ -198,7 +192,7 @@ For example:
|
|||
C: 1 = enable corner tap
|
||||
B: 1 = swap left and right button
|
||||
|
||||
* reg_11
|
||||
* reg_11::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
1 0 0 H V 1 F P
|
||||
|
@ -208,40 +202,41 @@ For example:
|
|||
V: 1 = enable vertical scroll area
|
||||
H: 1 = enable horizontal scroll area
|
||||
|
||||
* reg_20
|
||||
* reg_20::
|
||||
|
||||
single finger width?
|
||||
|
||||
* reg_21
|
||||
* reg_21::
|
||||
|
||||
scroll area width (small: 0x40 ... wide: 0xff)
|
||||
|
||||
* reg_22
|
||||
* reg_22::
|
||||
|
||||
drag lock time out (short: 0x14 ... long: 0xfe;
|
||||
0xff = tap again to release)
|
||||
|
||||
* reg_23
|
||||
* reg_23::
|
||||
|
||||
tap make timeout?
|
||||
|
||||
* reg_24
|
||||
* reg_24::
|
||||
|
||||
tap release timeout?
|
||||
|
||||
* reg_25
|
||||
* reg_25::
|
||||
|
||||
smart edge cursor speed (0x02 = slow, 0x03 = medium, 0x04 = fast)
|
||||
|
||||
* reg_26
|
||||
* reg_26::
|
||||
|
||||
smart edge activation area width?
|
||||
|
||||
|
||||
4.2 Native relative mode 4 byte packet format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Native relative mode 4 byte packet format
|
||||
-----------------------------------------
|
||||
|
||||
byte 0::
|
||||
|
||||
byte 0:
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
c c p2 p1 1 M R L
|
||||
|
||||
|
@ -251,20 +246,23 @@ byte 0:
|
|||
p1..p2 = byte 1 and 2 odd parity bit
|
||||
c = 1 when corner tap detected
|
||||
|
||||
byte 1:
|
||||
byte 1::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
dx7 dx6 dx5 dx4 dx3 dx2 dx1 dx0
|
||||
|
||||
dx7..dx0 = x movement; positive = right, negative = left
|
||||
byte 1 = 0xf0 when corner tap detected
|
||||
|
||||
byte 2:
|
||||
byte 2::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
dy7 dy6 dy5 dy4 dy3 dy2 dy1 dy0
|
||||
|
||||
dy7..dy0 = y movement; positive = up, negative = down
|
||||
|
||||
byte 3:
|
||||
byte 3::
|
||||
|
||||
parity checking enabled (reg_11, P = 1):
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
|
@ -296,14 +294,15 @@ byte 3:
|
|||
positive = down
|
||||
|
||||
|
||||
4.3 Native absolute mode 4 byte packet format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Native absolute mode 4 byte packet format
|
||||
-----------------------------------------
|
||||
|
||||
EF013 and EF019 have a special behaviour (due to a bug in the firmware?), and
|
||||
when 1 finger is touching, the first 2 position reports must be discarded.
|
||||
This counting is reset whenever a different number of fingers is reported.
|
||||
|
||||
byte 0:
|
||||
byte 0::
|
||||
|
||||
firmware version 1.x:
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
|
@ -322,7 +321,8 @@ byte 0:
|
|||
p1..p3 = byte 1..3 odd parity bit
|
||||
n1..n0 = number of fingers on touchpad
|
||||
|
||||
byte 1:
|
||||
byte 1::
|
||||
|
||||
firmware version 1.x:
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
|
@ -337,65 +337,68 @@ byte 1:
|
|||
bit 7 6 5 4 3 2 1 0
|
||||
. . . . x9 x8 y9 y8
|
||||
|
||||
byte 2:
|
||||
byte 2::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
x7 x6 x5 x4 x3 x2 x1 x0
|
||||
|
||||
x9..x0 = absolute x value (horizontal)
|
||||
|
||||
byte 3:
|
||||
byte 3::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
y7 y6 y5 y4 y3 y2 y1 y0
|
||||
|
||||
y9..y0 = absolute y value (vertical)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Hardware version 2
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
5. Hardware version 2
|
||||
==================
|
||||
|
||||
|
||||
5.1 Registers
|
||||
~~~~~~~~~
|
||||
Registers
|
||||
---------
|
||||
|
||||
By echoing a hexadecimal value to a register it contents can be altered.
|
||||
|
||||
For example:
|
||||
For example::
|
||||
|
||||
echo -n 0x56 > reg_10
|
||||
|
||||
* reg_10
|
||||
* reg_10::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
0 1 0 1 0 1 D 0
|
||||
|
||||
D: 1 = enable drag and drop
|
||||
|
||||
* reg_11
|
||||
* reg_11::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
1 0 0 0 S 0 1 0
|
||||
|
||||
S: 1 = enable vertical scroll
|
||||
|
||||
* reg_21
|
||||
* reg_21::
|
||||
|
||||
unknown (0x00)
|
||||
|
||||
* reg_22
|
||||
* reg_22::
|
||||
|
||||
drag and drop release time out (short: 0x70 ... long 0x7e;
|
||||
0x7f = never i.e. tap again to release)
|
||||
|
||||
|
||||
5.2 Native absolute mode 6 byte packet format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
5.2.1 Parity checking and packet re-synchronization
|
||||
Native absolute mode 6 byte packet format
|
||||
-----------------------------------------
|
||||
|
||||
Parity checking and packet re-synchronization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
There is no parity checking, however some consistency checks can be performed.
|
||||
|
||||
For instance for EF113:
|
||||
For instance for EF113::
|
||||
|
||||
SA1= packet[0];
|
||||
A1 = packet[1];
|
||||
B1 = packet[2];
|
||||
|
@ -410,7 +413,8 @@ For instance for EF113:
|
|||
(((SA1 & 0xC0) != 0x80) && (( C1 & 0xF0) != 0x00)) ) // check Byte 5
|
||||
// error detected
|
||||
|
||||
For all the other ones, there are just a few constant bits:
|
||||
For all the other ones, there are just a few constant bits::
|
||||
|
||||
if( ((packet[0] & 0x0C) != 0x04) ||
|
||||
((packet[3] & 0x0f) != 0x02) )
|
||||
// error detected
|
||||
|
@ -418,10 +422,10 @@ For all the other ones, there are just a few constant bits:
|
|||
|
||||
In case an error is detected, all the packets are shifted by one (and packet[0] is discarded).
|
||||
|
||||
5.2.2 One/Three finger touch
|
||||
~~~~~~~~~~~~~~~~
|
||||
One/Three finger touch
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
byte 0:
|
||||
byte 0::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
n1 n0 w3 w2 . . R L
|
||||
|
@ -429,19 +433,19 @@ byte 0:
|
|||
L, R = 1 when Left, Right mouse button pressed
|
||||
n1..n0 = number of fingers on touchpad
|
||||
|
||||
byte 1:
|
||||
byte 1::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
p7 p6 p5 p4 x11 x10 x9 x8
|
||||
|
||||
byte 2:
|
||||
byte 2::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
x7 x6 x5 x4 x3 x2 x1 x0
|
||||
|
||||
x11..x0 = absolute x value (horizontal)
|
||||
|
||||
byte 3:
|
||||
byte 3::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
n4 vf w1 w0 . . . b2
|
||||
|
@ -460,14 +464,14 @@ byte 3:
|
|||
6 = Another one
|
||||
7 = Another one
|
||||
|
||||
byte 4:
|
||||
byte 4::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
p3 p1 p2 p0 y11 y10 y9 y8
|
||||
|
||||
p7..p0 = pressure (not EF113)
|
||||
|
||||
byte 5:
|
||||
byte 5::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
y7 y6 y5 y4 y3 y2 y1 y0
|
||||
|
@ -475,15 +479,15 @@ byte 5:
|
|||
y11..y0 = absolute y value (vertical)
|
||||
|
||||
|
||||
5.2.3 Two finger touch
|
||||
~~~~~~~~~~~~~~~~
|
||||
Two finger touch
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Note that the two pairs of coordinates are not exactly the coordinates of the
|
||||
two fingers, but only the pair of the lower-left and upper-right coordinates.
|
||||
So the actual fingers might be situated on the other diagonal of the square
|
||||
defined by these two points.
|
||||
|
||||
byte 0:
|
||||
byte 0::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
n1 n0 ay8 ax8 . . R L
|
||||
|
@ -491,47 +495,46 @@ byte 0:
|
|||
L, R = 1 when Left, Right mouse button pressed
|
||||
n1..n0 = number of fingers on touchpad
|
||||
|
||||
byte 1:
|
||||
byte 1::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
|
||||
|
||||
ax8..ax0 = lower-left finger absolute x value
|
||||
|
||||
byte 2:
|
||||
byte 2::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0
|
||||
|
||||
ay8..ay0 = lower-left finger absolute y value
|
||||
|
||||
byte 3:
|
||||
byte 3::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
. . by8 bx8 . . . .
|
||||
|
||||
byte 4:
|
||||
byte 4::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
|
||||
|
||||
bx8..bx0 = upper-right finger absolute x value
|
||||
|
||||
byte 5:
|
||||
byte 5::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
by7 by8 by5 by4 by3 by2 by1 by0
|
||||
|
||||
by8..by0 = upper-right finger absolute y value
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Hardware version 3
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
6. Hardware version 3
|
||||
==================
|
||||
Registers
|
||||
---------
|
||||
|
||||
6.1 Registers
|
||||
~~~~~~~~~
|
||||
* reg_10
|
||||
* reg_10::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
0 0 0 0 R F T A
|
||||
|
@ -541,8 +544,9 @@ byte 5:
|
|||
F: 1 = disable ABS Position Filter
|
||||
R: 1 = enable real hardware resolution
|
||||
|
||||
6.2 Native absolute mode 6 byte packet format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Native absolute mode 6 byte packet format
|
||||
-----------------------------------------
|
||||
|
||||
1 and 3 finger touch shares the same 6-byte packet format, except that
|
||||
3 finger touch only reports the position of the center of all three fingers.
|
||||
|
||||
|
@ -552,19 +556,21 @@ Note on debounce:
|
|||
In case the box has unstable power supply or other electricity issues, or
|
||||
when number of finger changes, F/W would send "debounce packet" to inform
|
||||
driver that the hardware is in debounce status.
|
||||
The debouce packet has the following signature:
|
||||
The debouce packet has the following signature::
|
||||
|
||||
byte 0: 0xc4
|
||||
byte 1: 0xff
|
||||
byte 2: 0xff
|
||||
byte 3: 0x02
|
||||
byte 4: 0xff
|
||||
byte 5: 0xff
|
||||
|
||||
When we encounter this kind of packet, we just ignore it.
|
||||
|
||||
6.2.1 One/Three finger touch
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
One/Three finger touch
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
byte 0:
|
||||
byte 0::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
n1 n0 w3 w2 0 1 R L
|
||||
|
@ -572,63 +578,63 @@ byte 0:
|
|||
L, R = 1 when Left, Right mouse button pressed
|
||||
n1..n0 = number of fingers on touchpad
|
||||
|
||||
byte 1:
|
||||
byte 1::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
p7 p6 p5 p4 x11 x10 x9 x8
|
||||
|
||||
byte 2:
|
||||
byte 2::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
x7 x6 x5 x4 x3 x2 x1 x0
|
||||
|
||||
x11..x0 = absolute x value (horizontal)
|
||||
|
||||
byte 3:
|
||||
byte 3::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
0 0 w1 w0 0 0 1 0
|
||||
|
||||
w3..w0 = width of the finger touch
|
||||
|
||||
byte 4:
|
||||
byte 4::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
p3 p1 p2 p0 y11 y10 y9 y8
|
||||
|
||||
p7..p0 = pressure
|
||||
|
||||
byte 5:
|
||||
byte 5::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
y7 y6 y5 y4 y3 y2 y1 y0
|
||||
|
||||
y11..y0 = absolute y value (vertical)
|
||||
|
||||
6.2.2 Two finger touch
|
||||
~~~~~~~~~~~~~~~~
|
||||
Two finger touch
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The packet format is exactly the same for two finger touch, except the hardware
|
||||
sends two 6 byte packets. The first packet contains data for the first finger,
|
||||
the second packet has data for the second finger. So for two finger touch a
|
||||
total of 12 bytes are sent.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Hardware version 4
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
7. Hardware version 4
|
||||
==================
|
||||
Registers
|
||||
---------
|
||||
|
||||
7.1 Registers
|
||||
~~~~~~~~~
|
||||
* reg_07
|
||||
* reg_07::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
0 0 0 0 0 0 0 A
|
||||
|
||||
A: 1 = enable absolute tracking
|
||||
|
||||
7.2 Native absolute mode 6 byte packet format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Native absolute mode 6 byte packet format
|
||||
-----------------------------------------
|
||||
|
||||
v4 hardware is a true multitouch touchpad, capable of tracking up to 5 fingers.
|
||||
Unfortunately, due to PS/2's limited bandwidth, its packet format is rather
|
||||
complex.
|
||||
|
@ -647,45 +653,49 @@ position, until we receive a status packet.
|
|||
One exception is one finger touch. when a status packet tells us there is only
|
||||
one finger, the hardware would just send head packets afterwards.
|
||||
|
||||
7.2.1 Status packet
|
||||
~~~~~~~~~~~~~
|
||||
Status packet
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
byte 0:
|
||||
byte 0::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
. . . . 0 1 R L
|
||||
|
||||
L, R = 1 when Left, Right mouse button pressed
|
||||
|
||||
byte 1:
|
||||
byte 1::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
. . . ft4 ft3 ft2 ft1 ft0
|
||||
|
||||
ft4 ft3 ft2 ft1 ft0 ftn = 1 when finger n is on touchpad
|
||||
|
||||
byte 2: not used
|
||||
byte 2::
|
||||
|
||||
byte 3:
|
||||
not used
|
||||
|
||||
byte 3::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
. . . 1 0 0 0 0
|
||||
|
||||
constant bits
|
||||
|
||||
byte 4:
|
||||
byte 4::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
p . . . . . . .
|
||||
|
||||
p = 1 for palm
|
||||
|
||||
byte 5: not used
|
||||
byte 5::
|
||||
|
||||
7.2.2 Head packet
|
||||
~~~~~~~~~~~
|
||||
not used
|
||||
|
||||
byte 0:
|
||||
Head packet
|
||||
^^^^^^^^^^^
|
||||
|
||||
byte 0::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
w3 w2 w1 w0 0 1 R L
|
||||
|
@ -693,43 +703,43 @@ byte 0:
|
|||
L, R = 1 when Left, Right mouse button pressed
|
||||
w3..w0 = finger width (spans how many trace lines)
|
||||
|
||||
byte 1:
|
||||
byte 1::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
p7 p6 p5 p4 x11 x10 x9 x8
|
||||
|
||||
byte 2:
|
||||
byte 2::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
x7 x6 x5 x4 x3 x2 x1 x0
|
||||
|
||||
x11..x0 = absolute x value (horizontal)
|
||||
|
||||
byte 3:
|
||||
byte 3::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
id2 id1 id0 1 0 0 0 1
|
||||
|
||||
id2..id0 = finger id
|
||||
|
||||
byte 4:
|
||||
byte 4::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
p3 p1 p2 p0 y11 y10 y9 y8
|
||||
|
||||
p7..p0 = pressure
|
||||
|
||||
byte 5:
|
||||
byte 5::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
y7 y6 y5 y4 y3 y2 y1 y0
|
||||
|
||||
y11..y0 = absolute y value (vertical)
|
||||
|
||||
7.2.3 Motion packet
|
||||
~~~~~~~~~~~~~
|
||||
Motion packet
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
byte 0:
|
||||
byte 0::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
id2 id1 id0 w 0 1 R L
|
||||
|
@ -739,35 +749,35 @@ byte 0:
|
|||
w = 1 when delta overflows (> 127 or < -128), in this case
|
||||
firmware sends us (delta x / 5) and (delta y / 5)
|
||||
|
||||
byte 1:
|
||||
byte 1::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
x7 x6 x5 x4 x3 x2 x1 x0
|
||||
|
||||
x7..x0 = delta x (two's complement)
|
||||
|
||||
byte 2:
|
||||
byte 2::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
y7 y6 y5 y4 y3 y2 y1 y0
|
||||
|
||||
y7..y0 = delta y (two's complement)
|
||||
|
||||
byte 3:
|
||||
byte 3::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
id2 id1 id0 1 0 0 1 0
|
||||
|
||||
id2..id0 = finger id
|
||||
|
||||
byte 4:
|
||||
byte 4::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
x7 x6 x5 x4 x3 x2 x1 x0
|
||||
|
||||
x7..x0 = delta x (two's complement)
|
||||
|
||||
byte 5:
|
||||
byte 5::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
y7 y6 y5 y4 y3 y2 y1 y0
|
||||
|
@ -778,33 +788,47 @@ byte 5:
|
|||
byte 3 ~ 5 for another
|
||||
|
||||
|
||||
8. Trackpoint (for Hardware version 3 and 4)
|
||||
=========================================
|
||||
8.1 Registers
|
||||
~~~~~~~~~
|
||||
Trackpoint (for Hardware version 3 and 4)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Registers
|
||||
---------
|
||||
|
||||
No special registers have been identified.
|
||||
|
||||
8.2 Native relative mode 6 byte packet format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
8.2.1 Status Packet
|
||||
~~~~~~~~~~~~~
|
||||
Native relative mode 6 byte packet format
|
||||
-----------------------------------------
|
||||
|
||||
Status Packet
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
byte 0::
|
||||
|
||||
byte 0:
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
0 0 sx sy 0 M R L
|
||||
byte 1:
|
||||
|
||||
byte 1::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
~sx 0 0 0 0 0 0 0
|
||||
byte 2:
|
||||
|
||||
byte 2::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
~sy 0 0 0 0 0 0 0
|
||||
byte 3:
|
||||
|
||||
byte 3::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
0 0 ~sy ~sx 0 1 1 0
|
||||
byte 4:
|
||||
|
||||
byte 4::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
x7 x6 x5 x4 x3 x2 x1 x0
|
||||
byte 5:
|
||||
|
||||
byte 5::
|
||||
|
||||
bit 7 6 5 4 3 2 1 0
|
||||
y7 y6 y5 y4 y3 y2 y1 y0
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
Driver for tilt-switches connected via GPIOs
|
||||
============================================
|
||||
|
||||
Generic driver to read data from tilt switches connected via gpios.
|
||||
Orientation can be provided by one or more than one tilt switches,
|
||||
i.e. each tilt switch providing one axis, and the number of axes
|
||||
is also not limited.
|
||||
|
||||
|
||||
Data structures
|
||||
---------------
|
||||
|
||||
The array of struct gpio in the gpios field is used to list the gpios
|
||||
that represent the current tilt state.
|
||||
|
||||
The array of struct gpio_tilt_axis describes the axes that are reported
|
||||
to the input system. The values set therein are used for the
|
||||
input_set_abs_params calls needed to init the axes.
|
||||
|
||||
The array of struct gpio_tilt_state maps gpio states to the corresponding
|
||||
values to report. The gpio state is represented as a bitfield where the
|
||||
bit-index corresponds to the index of the gpio in the struct gpio array.
|
||||
In the same manner the values stored in the axes array correspond to
|
||||
the elements of the gpio_tilt_axis-array.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Example configuration for a single TS1003 tilt switch that rotates around
|
||||
one axis in 4 steps and emits the current tilt via two GPIOs::
|
||||
|
||||
static int sg060_tilt_enable(struct device *dev) {
|
||||
/* code to enable the sensors */
|
||||
};
|
||||
|
||||
static void sg060_tilt_disable(struct device *dev) {
|
||||
/* code to disable the sensors */
|
||||
};
|
||||
|
||||
static struct gpio sg060_tilt_gpios[] = {
|
||||
{ SG060_TILT_GPIO_SENSOR1, GPIOF_IN, "tilt_sensor1" },
|
||||
{ SG060_TILT_GPIO_SENSOR2, GPIOF_IN, "tilt_sensor2" },
|
||||
};
|
||||
|
||||
static struct gpio_tilt_state sg060_tilt_states[] = {
|
||||
{
|
||||
.gpios = (0 << 1) | (0 << 0),
|
||||
.axes = (int[]) {
|
||||
0,
|
||||
},
|
||||
}, {
|
||||
.gpios = (0 << 1) | (1 << 0),
|
||||
.axes = (int[]) {
|
||||
1, /* 90 degrees */
|
||||
},
|
||||
}, {
|
||||
.gpios = (1 << 1) | (1 << 0),
|
||||
.axes = (int[]) {
|
||||
2, /* 180 degrees */
|
||||
},
|
||||
}, {
|
||||
.gpios = (1 << 1) | (0 << 0),
|
||||
.axes = (int[]) {
|
||||
3, /* 270 degrees */
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_tilt_axis sg060_tilt_axes[] = {
|
||||
{
|
||||
.axis = ABS_RY,
|
||||
.min = 0,
|
||||
.max = 3,
|
||||
.fuzz = 0,
|
||||
.flat = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_tilt_platform_data sg060_tilt_pdata= {
|
||||
.gpios = sg060_tilt_gpios,
|
||||
.nr_gpios = ARRAY_SIZE(sg060_tilt_gpios),
|
||||
|
||||
.axes = sg060_tilt_axes,
|
||||
.nr_axes = ARRAY_SIZE(sg060_tilt_axes),
|
||||
|
||||
.states = sg060_tilt_states,
|
||||
.nr_states = ARRAY_SIZE(sg060_tilt_states),
|
||||
|
||||
.debounce_interval = 100,
|
||||
|
||||
.poll_interval = 1000,
|
||||
.enable = sg060_tilt_enable,
|
||||
.disable = sg060_tilt_disable,
|
||||
};
|
||||
|
||||
static struct platform_device sg060_device_tilt = {
|
||||
.name = "gpio-tilt-polled",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &sg060_tilt_pdata,
|
||||
},
|
||||
};
|
|
@ -0,0 +1,381 @@
|
|||
===============
|
||||
Iforce Protocol
|
||||
===============
|
||||
|
||||
:Author: Johann Deneux <johann.deneux@gmail.com>
|
||||
|
||||
Home page at `<http://web.archive.org/web/*/http://www.esil.univ-mrs.fr>`_
|
||||
|
||||
:Additions: by Vojtech Pavlik.
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This document describes what I managed to discover about the protocol used to
|
||||
specify force effects to I-Force 2.0 devices. None of this information comes
|
||||
from Immerse. That's why you should not trust what is written in this
|
||||
document. This document is intended to help understanding the protocol.
|
||||
This is not a reference. Comments and corrections are welcome. To contact me,
|
||||
send an email to: johann.deneux@gmail.com
|
||||
|
||||
.. warning::
|
||||
|
||||
I shall not be held responsible for any damage or harm caused if you try to
|
||||
send data to your I-Force device based on what you read in this document.
|
||||
|
||||
Preliminary Notes
|
||||
=================
|
||||
|
||||
All values are hexadecimal with big-endian encoding (msb on the left). Beware,
|
||||
values inside packets are encoded using little-endian. Bytes whose roles are
|
||||
unknown are marked ??? Information that needs deeper inspection is marked (?)
|
||||
|
||||
General form of a packet
|
||||
------------------------
|
||||
|
||||
This is how packets look when the device uses the rs232 to communicate.
|
||||
|
||||
== == === ==== ==
|
||||
2B OP LEN DATA CS
|
||||
== == === ==== ==
|
||||
|
||||
CS is the checksum. It is equal to the exclusive or of all bytes.
|
||||
|
||||
When using USB:
|
||||
|
||||
== ====
|
||||
OP DATA
|
||||
== ====
|
||||
|
||||
The 2B, LEN and CS fields have disappeared, probably because USB handles
|
||||
frames and data corruption is handled or unsignificant.
|
||||
|
||||
First, I describe effects that are sent by the device to the computer
|
||||
|
||||
Device input state
|
||||
==================
|
||||
|
||||
This packet is used to indicate the state of each button and the value of each
|
||||
axis::
|
||||
|
||||
OP= 01 for a joystick, 03 for a wheel
|
||||
LEN= Varies from device to device
|
||||
00 X-Axis lsb
|
||||
01 X-Axis msb
|
||||
02 Y-Axis lsb, or gas pedal for a wheel
|
||||
03 Y-Axis msb, or brake pedal for a wheel
|
||||
04 Throttle
|
||||
05 Buttons
|
||||
06 Lower 4 bits: Buttons
|
||||
Upper 4 bits: Hat
|
||||
07 Rudder
|
||||
|
||||
Device effects states
|
||||
=====================
|
||||
|
||||
::
|
||||
|
||||
OP= 02
|
||||
LEN= Varies
|
||||
00 ? Bit 1 (Value 2) is the value of the deadman switch
|
||||
01 Bit 8 is set if the effect is playing. Bits 0 to 7 are the effect id.
|
||||
02 ??
|
||||
03 Address of parameter block changed (lsb)
|
||||
04 Address of parameter block changed (msb)
|
||||
05 Address of second parameter block changed (lsb)
|
||||
... depending on the number of parameter blocks updated
|
||||
|
||||
Force effect
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
OP= 01
|
||||
LEN= 0e
|
||||
00 Channel (when playing several effects at the same time, each must
|
||||
be assigned a channel)
|
||||
01 Wave form
|
||||
Val 00 Constant
|
||||
Val 20 Square
|
||||
Val 21 Triangle
|
||||
Val 22 Sine
|
||||
Val 23 Sawtooth up
|
||||
Val 24 Sawtooth down
|
||||
Val 40 Spring (Force = f(pos))
|
||||
Val 41 Friction (Force = f(velocity)) and Inertia
|
||||
(Force = f(acceleration))
|
||||
|
||||
|
||||
02 Axes affected and trigger
|
||||
Bits 4-7: Val 2 = effect along one axis. Byte 05 indicates direction
|
||||
Val 4 = X axis only. Byte 05 must contain 5a
|
||||
Val 8 = Y axis only. Byte 05 must contain b4
|
||||
Val c = X and Y axes. Bytes 05 must contain 60
|
||||
Bits 0-3: Val 0 = No trigger
|
||||
Val x+1 = Button x triggers the effect
|
||||
When the whole byte is 0, cancel the previously set trigger
|
||||
|
||||
03-04 Duration of effect (little endian encoding, in ms)
|
||||
|
||||
05 Direction of effect, if applicable. Else, see 02 for value to assign.
|
||||
|
||||
06-07 Minimum time between triggering.
|
||||
|
||||
08-09 Address of periodicity or magnitude parameters
|
||||
0a-0b Address of attack and fade parameters, or ffff if none.
|
||||
*or*
|
||||
08-09 Address of interactive parameters for X-axis,
|
||||
or ffff if not applicable
|
||||
0a-0b Address of interactive parameters for Y-axis,
|
||||
or ffff if not applicable
|
||||
|
||||
0c-0d Delay before execution of effect (little endian encoding, in ms)
|
||||
|
||||
|
||||
Time based parameters
|
||||
---------------------
|
||||
|
||||
Attack and fade
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
::
|
||||
|
||||
OP= 02
|
||||
LEN= 08
|
||||
00-01 Address where to store the parameters
|
||||
02-03 Duration of attack (little endian encoding, in ms)
|
||||
04 Level at end of attack. Signed byte.
|
||||
05-06 Duration of fade.
|
||||
07 Level at end of fade.
|
||||
|
||||
Magnitude
|
||||
^^^^^^^^^
|
||||
|
||||
::
|
||||
|
||||
OP= 03
|
||||
LEN= 03
|
||||
00-01 Address
|
||||
02 Level. Signed byte.
|
||||
|
||||
Periodicity
|
||||
^^^^^^^^^^^
|
||||
|
||||
::
|
||||
|
||||
OP= 04
|
||||
LEN= 07
|
||||
00-01 Address
|
||||
02 Magnitude. Signed byte.
|
||||
03 Offset. Signed byte.
|
||||
04 Phase. Val 00 = 0 deg, Val 40 = 90 degs.
|
||||
05-06 Period (little endian encoding, in ms)
|
||||
|
||||
Interactive parameters
|
||||
----------------------
|
||||
|
||||
::
|
||||
|
||||
OP= 05
|
||||
LEN= 0a
|
||||
00-01 Address
|
||||
02 Positive Coeff
|
||||
03 Negative Coeff
|
||||
04+05 Offset (center)
|
||||
06+07 Dead band (Val 01F4 = 5000 (decimal))
|
||||
08 Positive saturation (Val 0a = 1000 (decimal) Val 64 = 10000 (decimal))
|
||||
09 Negative saturation
|
||||
|
||||
The encoding is a bit funny here: For coeffs, these are signed values. The
|
||||
maximum value is 64 (100 decimal), the min is 9c.
|
||||
For the offset, the minimum value is FE0C, the maximum value is 01F4.
|
||||
For the deadband, the minimum value is 0, the max is 03E8.
|
||||
|
||||
Controls
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
OP= 41
|
||||
LEN= 03
|
||||
00 Channel
|
||||
01 Start/Stop
|
||||
Val 00: Stop
|
||||
Val 01: Start and play once.
|
||||
Val 41: Start and play n times (See byte 02 below)
|
||||
02 Number of iterations n.
|
||||
|
||||
Init
|
||||
----
|
||||
|
||||
|
||||
Querying features
|
||||
^^^^^^^^^^^^^^^^^
|
||||
::
|
||||
|
||||
OP= ff
|
||||
Query command. Length varies according to the query type.
|
||||
The general format of this packet is:
|
||||
ff 01 QUERY [INDEX] CHECKSUM
|
||||
responses are of the same form:
|
||||
FF LEN QUERY VALUE_QUERIED CHECKSUM2
|
||||
where LEN = 1 + length(VALUE_QUERIED)
|
||||
|
||||
Query ram size
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
QUERY = 42 ('B'uffer size)
|
||||
|
||||
The device should reply with the same packet plus two additional bytes
|
||||
containing the size of the memory:
|
||||
ff 03 42 03 e8 CS would mean that the device has 1000 bytes of ram available.
|
||||
|
||||
Query number of effects
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
QUERY = 4e ('N'umber of effects)
|
||||
|
||||
The device should respond by sending the number of effects that can be played
|
||||
at the same time (one byte)
|
||||
ff 02 4e 14 CS would stand for 20 effects.
|
||||
|
||||
Vendor's id
|
||||
~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
QUERY = 4d ('M'anufacturer)
|
||||
|
||||
Query the vendors'id (2 bytes)
|
||||
|
||||
Product id
|
||||
~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
QUERY = 50 ('P'roduct)
|
||||
|
||||
Query the product id (2 bytes)
|
||||
|
||||
Open device
|
||||
~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
QUERY = 4f ('O'pen)
|
||||
|
||||
No data returned.
|
||||
|
||||
Close device
|
||||
~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
QUERY = 43 ('C')lose
|
||||
|
||||
No data returned.
|
||||
|
||||
Query effect
|
||||
~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
QUERY = 45 ('E')
|
||||
|
||||
Send effect type.
|
||||
Returns nonzero if supported (2 bytes)
|
||||
|
||||
Firmware Version
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
QUERY = 56 ('V'ersion)
|
||||
|
||||
Sends back 3 bytes - major, minor, subminor
|
||||
|
||||
Initialisation of the device
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Set Control
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. note::
|
||||
Device dependent, can be different on different models!
|
||||
|
||||
::
|
||||
|
||||
OP= 40 <idx> <val> [<val>]
|
||||
LEN= 2 or 3
|
||||
00 Idx
|
||||
Idx 00 Set dead zone (0..2048)
|
||||
Idx 01 Ignore Deadman sensor (0..1)
|
||||
Idx 02 Enable comm watchdog (0..1)
|
||||
Idx 03 Set the strength of the spring (0..100)
|
||||
Idx 04 Enable or disable the spring (0/1)
|
||||
Idx 05 Set axis saturation threshold (0..2048)
|
||||
|
||||
Set Effect State
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
OP= 42 <val>
|
||||
LEN= 1
|
||||
00 State
|
||||
Bit 3 Pause force feedback
|
||||
Bit 2 Enable force feedback
|
||||
Bit 0 Stop all effects
|
||||
|
||||
Set overall
|
||||
~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
OP= 43 <val>
|
||||
LEN= 1
|
||||
00 Gain
|
||||
Val 00 = 0%
|
||||
Val 40 = 50%
|
||||
Val 80 = 100%
|
||||
|
||||
Parameter memory
|
||||
----------------
|
||||
|
||||
Each device has a certain amount of memory to store parameters of effects.
|
||||
The amount of RAM may vary, I encountered values from 200 to 1000 bytes. Below
|
||||
is the amount of memory apparently needed for every set of parameters:
|
||||
|
||||
- period : 0c
|
||||
- magnitude : 02
|
||||
- attack and fade : 0e
|
||||
- interactive : 08
|
||||
|
||||
Appendix: How to study the protocol?
|
||||
====================================
|
||||
|
||||
1. Generate effects using the force editor provided with the DirectX SDK, or
|
||||
use Immersion Studio (freely available at their web site in the developer section:
|
||||
www.immersion.com)
|
||||
2. Start a soft spying RS232 or USB (depending on where you connected your
|
||||
joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
|
||||
3. Play the effect, and watch what happens on the spy screen.
|
||||
|
||||
A few words about ComPortSpy:
|
||||
At first glance, this software seems, hum, well... buggy. In fact, data appear with a
|
||||
few seconds latency. Personally, I restart it every time I play an effect.
|
||||
Remember it's free (as in free beer) and alpha!
|
||||
|
||||
URLS
|
||||
====
|
||||
|
||||
Check http://www.immerse.com for Immersion Studio,
|
||||
and http://www.fcoder.com for ComPortSpy.
|
||||
|
||||
|
||||
I-Force is trademark of Immersion Corp.
|
|
@ -0,0 +1,19 @@
|
|||
Driver-specific documentation
|
||||
=============================
|
||||
|
||||
This section provides information about various devices supported by the
|
||||
Linux kernel, their protocols, and driver details.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
:glob:
|
||||
|
||||
*
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
|
@ -0,0 +1,611 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
.. _joystick-parport:
|
||||
|
||||
==============================
|
||||
Parallel Port Joystick Drivers
|
||||
==============================
|
||||
|
||||
:Copyright: |copy| 1998-2000 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
:Copyright: |copy| 1998 Andree Borrmann <a.borrmann@tu-bs.de>
|
||||
|
||||
|
||||
Sponsored by SuSE
|
||||
|
||||
Disclaimer
|
||||
==========
|
||||
|
||||
Any information in this file is provided as-is, without any guarantee that
|
||||
it will be true. So, use it at your own risk. The possible damages that can
|
||||
happen include burning your parallel port, and/or the sticks and joystick
|
||||
and maybe even more. Like when a lightning kills you it is not our problem.
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The joystick parport drivers are used for joysticks and gamepads not
|
||||
originally designed for PCs and other computers Linux runs on. Because of
|
||||
that, PCs usually lack the right ports to connect these devices to. Parallel
|
||||
port, because of its ability to change single bits at will, and providing
|
||||
both output and input bits is the most suitable port on the PC for
|
||||
connecting such devices.
|
||||
|
||||
Devices supported
|
||||
=================
|
||||
|
||||
Many console and 8-bit computer gamepads and joysticks are supported. The
|
||||
following subsections discuss usage of each.
|
||||
|
||||
NES and SNES
|
||||
------------
|
||||
|
||||
The Nintendo Entertainment System and Super Nintendo Entertainment System
|
||||
gamepads are widely available, and easy to get. Also, they are quite easy to
|
||||
connect to a PC, and don't need much processing speed (108 us for NES and
|
||||
165 us for SNES, compared to about 1000 us for PC gamepads) to communicate
|
||||
with them.
|
||||
|
||||
All NES and SNES use the same synchronous serial protocol, clocked from
|
||||
the computer's side (and thus timing insensitive). To allow up to 5 NES
|
||||
and/or SNES gamepads and/or SNES mice connected to the parallel port at once,
|
||||
the output lines of the parallel port are shared, while one of 5 available
|
||||
input lines is assigned to each gamepad.
|
||||
|
||||
This protocol is handled by the gamecon.c driver, so that's the one
|
||||
you'll use for NES, SNES gamepads and SNES mice.
|
||||
|
||||
The main problem with PC parallel ports is that they don't have +5V power
|
||||
source on any of their pins. So, if you want a reliable source of power
|
||||
for your pads, use either keyboard or joystick port, and make a pass-through
|
||||
cable. You can also pull the power directly from the power supply (the red
|
||||
wire is +5V).
|
||||
|
||||
If you want to use the parallel port only, you can take the power is from
|
||||
some data pin. For most gamepad and parport implementations only one pin is
|
||||
needed, and I'd recommend pin 9 for that, the highest data bit. On the other
|
||||
hand, if you are not planning to use anything else than NES / SNES on the
|
||||
port, anything between and including pin 4 and pin 9 will work::
|
||||
|
||||
(pin 9) -----> Power
|
||||
|
||||
Unfortunately, there are pads that need a lot more of power, and parallel
|
||||
ports that can't give much current through the data pins. If this is your
|
||||
case, you'll need to use diodes (as a prevention of destroying your parallel
|
||||
port), and combine the currents of two or more data bits together::
|
||||
|
||||
Diodes
|
||||
(pin 9) ----|>|-------+------> Power
|
||||
|
|
||||
(pin 8) ----|>|-------+
|
||||
|
|
||||
(pin 7) ----|>|-------+
|
||||
|
|
||||
<and so on> :
|
||||
|
|
||||
(pin 4) ----|>|-------+
|
||||
|
||||
Ground is quite easy. On PC's parallel port the ground is on any of the
|
||||
pins from pin 18 to pin 25. So use any pin of these you like for the ground::
|
||||
|
||||
(pin 18) -----> Ground
|
||||
|
||||
NES and SNES pads have two input bits, Clock and Latch, which drive the
|
||||
serial transfer. These are connected to pins 2 and 3 of the parallel port,
|
||||
respectively::
|
||||
|
||||
(pin 2) -----> Clock
|
||||
(pin 3) -----> Latch
|
||||
|
||||
And the last thing is the NES / SNES data wire. Only that isn't shared and
|
||||
each pad needs its own data pin. The parallel port pins are::
|
||||
|
||||
(pin 10) -----> Pad 1 data
|
||||
(pin 11) -----> Pad 2 data
|
||||
(pin 12) -----> Pad 3 data
|
||||
(pin 13) -----> Pad 4 data
|
||||
(pin 15) -----> Pad 5 data
|
||||
|
||||
Note that pin 14 is not used, since it is not an input pin on the parallel
|
||||
port.
|
||||
|
||||
This is everything you need on the PC's side of the connection, now on to
|
||||
the gamepads side. The NES and SNES have different connectors. Also, there
|
||||
are quite a lot of NES clones, and because Nintendo used proprietary
|
||||
connectors for their machines, the cloners couldn't and used standard D-Cannon
|
||||
connectors. Anyway, if you've got a gamepad, and it has buttons A, B, Turbo
|
||||
A, Turbo B, Select and Start, and is connected through 5 wires, then it is
|
||||
either a NES or NES clone and will work with this connection. SNES gamepads
|
||||
also use 5 wires, but have more buttons. They will work as well, of course::
|
||||
|
||||
Pinout for NES gamepads Pinout for SNES gamepads and mice
|
||||
|
||||
+----> Power +-----------------------\
|
||||
| 7 | o o o o | x x o | 1
|
||||
5 +---------+ 7 +-----------------------/
|
||||
| x x o \ | | | | |
|
||||
| o o o o | | | | | +-> Ground
|
||||
4 +------------+ 1 | | | +------------> Data
|
||||
| | | | | | +---------------> Latch
|
||||
| | | +-> Ground | +------------------> Clock
|
||||
| | +----> Clock +---------------------> Power
|
||||
| +-------> Latch
|
||||
+----------> Data
|
||||
|
||||
Pinout for NES clone (db9) gamepads Pinout for NES clone (db15) gamepads
|
||||
|
||||
+---------> Clock +-----------------> Data
|
||||
| +-------> Latch | +---> Ground
|
||||
| | +-----> Data | |
|
||||
| | | ___________________
|
||||
_____________ 8 \ o x x x x x x o / 1
|
||||
5 \ x o o o x / 1 \ o x x o x x o /
|
||||
\ x o x o / 15 `~~~~~~~~~~~~~' 9
|
||||
9 `~~~~~~~' 6 | | |
|
||||
| | | | +----> Clock
|
||||
| +----> Power | +----------> Latch
|
||||
+--------> Ground +----------------> Power
|
||||
|
||||
Multisystem joysticks
|
||||
---------------------
|
||||
|
||||
In the era of 8-bit machines, there was something like de-facto standard
|
||||
for joystick ports. They were all digital, and all used D-Cannon 9 pin
|
||||
connectors (db9). Because of that, a single joystick could be used without
|
||||
hassle on Atari (130, 800XE, 800XL, 2600, 7200), Amiga, Commodore C64,
|
||||
Amstrad CPC, Sinclair ZX Spectrum and many other machines. That's why these
|
||||
joysticks are called "Multisystem".
|
||||
|
||||
Now their pinout::
|
||||
|
||||
+---------> Right
|
||||
| +-------> Left
|
||||
| | +-----> Down
|
||||
| | | +---> Up
|
||||
| | | |
|
||||
_____________
|
||||
5 \ x o o o o / 1
|
||||
\ x o x o /
|
||||
9 `~~~~~~~' 6
|
||||
| |
|
||||
| +----> Button
|
||||
+--------> Ground
|
||||
|
||||
However, as time passed, extensions to this standard developed, and these
|
||||
were not compatible with each other::
|
||||
|
||||
|
||||
Atari 130, 800/XL/XE MSX
|
||||
|
||||
+-----------> Power
|
||||
+---------> Right | +---------> Right
|
||||
| +-------> Left | | +-------> Left
|
||||
| | +-----> Down | | | +-----> Down
|
||||
| | | +---> Up | | | | +---> Up
|
||||
| | | | | | | | |
|
||||
_____________ _____________
|
||||
5 \ x o o o o / 1 5 \ o o o o o / 1
|
||||
\ x o o o / \ o o o o /
|
||||
9 `~~~~~~~' 6 9 `~~~~~~~' 6
|
||||
| | | | | | |
|
||||
| | +----> Button | | | +----> Button 1
|
||||
| +------> Power | | +------> Button 2
|
||||
+--------> Ground | +--------> Output 3
|
||||
+----------> Ground
|
||||
|
||||
Amstrad CPC Commodore C64
|
||||
|
||||
+-----------> Analog Y
|
||||
+---------> Right | +---------> Right
|
||||
| +-------> Left | | +-------> Left
|
||||
| | +-----> Down | | | +-----> Down
|
||||
| | | +---> Up | | | | +---> Up
|
||||
| | | | | | | | |
|
||||
_____________ _____________
|
||||
5 \ x o o o o / 1 5 \ o o o o o / 1
|
||||
\ x o o o / \ o o o o /
|
||||
9 `~~~~~~~' 6 9 `~~~~~~~' 6
|
||||
| | | | | | |
|
||||
| | +----> Button 1 | | | +----> Button
|
||||
| +------> Button 2 | | +------> Power
|
||||
+--------> Ground | +--------> Ground
|
||||
+----------> Analog X
|
||||
|
||||
Sinclair Spectrum +2A/+3 Amiga 1200
|
||||
|
||||
+-----------> Up +-----------> Button 3
|
||||
| +---------> Fire | +---------> Right
|
||||
| | | | +-------> Left
|
||||
| | +-----> Ground | | | +-----> Down
|
||||
| | | | | | | +---> Up
|
||||
| | | | | | | |
|
||||
_____________ _____________
|
||||
5 \ o o x o x / 1 5 \ o o o o o / 1
|
||||
\ o o o o / \ o o o o /
|
||||
9 `~~~~~~~' 6 9 `~~~~~~~' 6
|
||||
| | | | | | | |
|
||||
| | | +----> Right | | | +----> Button 1
|
||||
| | +------> Left | | +------> Power
|
||||
| +--------> Ground | +--------> Ground
|
||||
+----------> Down +----------> Button 2
|
||||
|
||||
And there were many others.
|
||||
|
||||
Multisystem joysticks using db9.c
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For the Multisystem joysticks, and their derivatives, the db9.c driver
|
||||
was written. It allows only one joystick / gamepad per parallel port, but
|
||||
the interface is easy to build and works with almost anything.
|
||||
|
||||
For the basic 1-button Multisystem joystick you connect its wires to the
|
||||
parallel port like this::
|
||||
|
||||
(pin 1) -----> Power
|
||||
(pin 18) -----> Ground
|
||||
|
||||
(pin 2) -----> Up
|
||||
(pin 3) -----> Down
|
||||
(pin 4) -----> Left
|
||||
(pin 5) -----> Right
|
||||
(pin 6) -----> Button 1
|
||||
|
||||
However, if the joystick is switch based (eg. clicks when you move it),
|
||||
you might or might not, depending on your parallel port, need 10 kOhm pullup
|
||||
resistors on each of the direction and button signals, like this::
|
||||
|
||||
(pin 2) ------------+------> Up
|
||||
Resistor |
|
||||
(pin 1) --[10kOhm]--+
|
||||
|
||||
Try without, and if it doesn't work, add them. For TTL based joysticks /
|
||||
gamepads the pullups are not needed.
|
||||
|
||||
For joysticks with two buttons you connect the second button to pin 7 on
|
||||
the parallel port::
|
||||
|
||||
(pin 7) -----> Button 2
|
||||
|
||||
And that's it.
|
||||
|
||||
On a side note, if you have already built a different adapter for use with
|
||||
the digital joystick driver 0.8.0.2, this is also supported by the db9.c
|
||||
driver, as device type 8. (See section 3.2)
|
||||
|
||||
Multisystem joysticks using gamecon.c
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For some people just one joystick per parallel port is not enough, and/or
|
||||
want to use them on one parallel port together with NES/SNES/PSX pads. This is
|
||||
possible using the gamecon.c. It supports up to 5 devices of the above types,
|
||||
including 1 and 2 buttons Multisystem joysticks.
|
||||
|
||||
However, there is nothing for free. To allow more sticks to be used at
|
||||
once, you need the sticks to be purely switch based (that is non-TTL), and
|
||||
not to need power. Just a plain simple six switches inside. If your
|
||||
joystick can do more (eg. turbofire) you'll need to disable it totally first
|
||||
if you want to use gamecon.c.
|
||||
|
||||
Also, the connection is a bit more complex. You'll need a bunch of diodes,
|
||||
and one pullup resistor. First, you connect the Directions and the button
|
||||
the same as for db9, however with the diodes between::
|
||||
|
||||
Diodes
|
||||
(pin 2) -----|<|----> Up
|
||||
(pin 3) -----|<|----> Down
|
||||
(pin 4) -----|<|----> Left
|
||||
(pin 5) -----|<|----> Right
|
||||
(pin 6) -----|<|----> Button 1
|
||||
|
||||
For two button sticks you also connect the other button::
|
||||
|
||||
(pin 7) -----|<|----> Button 2
|
||||
|
||||
And finally, you connect the Ground wire of the joystick, like done in
|
||||
this little schematic to Power and Data on the parallel port, as described
|
||||
for the NES / SNES pads in section 2.1 of this file - that is, one data pin
|
||||
for each joystick. The power source is shared::
|
||||
|
||||
Data ------------+-----> Ground
|
||||
Resistor |
|
||||
Power --[10kOhm]--+
|
||||
|
||||
And that's all, here we go!
|
||||
|
||||
Multisystem joysticks using turbografx.c
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The TurboGraFX interface, designed by
|
||||
|
||||
Steffen Schwenke <schwenke@burg-halle.de>
|
||||
|
||||
allows up to 7 Multisystem joysticks connected to the parallel port. In
|
||||
Steffen's version, there is support for up to 5 buttons per joystick. However,
|
||||
since this doesn't work reliably on all parallel ports, the turbografx.c driver
|
||||
supports only one button per joystick. For more information on how to build the
|
||||
interface, see:
|
||||
|
||||
http://www2.burg-halle.de/~schwenke/parport.html
|
||||
|
||||
Sony Playstation
|
||||
----------------
|
||||
|
||||
The PSX controller is supported by the gamecon.c. Pinout of the PSX
|
||||
controller (compatible with DirectPadPro)::
|
||||
|
||||
+---------+---------+---------+
|
||||
9 | o o o | o o o | o o o | 1 parallel
|
||||
\________|_________|________/ port pins
|
||||
| | | | | |
|
||||
| | | | | +--------> Clock --- (4)
|
||||
| | | | +------------> Select --- (3)
|
||||
| | | +---------------> Power --- (5-9)
|
||||
| | +------------------> Ground --- (18-25)
|
||||
| +-------------------------> Command --- (2)
|
||||
+----------------------------> Data --- (one of 10,11,12,13,15)
|
||||
|
||||
The driver supports these controllers:
|
||||
|
||||
* Standard PSX Pad
|
||||
* NegCon PSX Pad
|
||||
* Analog PSX Pad (red mode)
|
||||
* Analog PSX Pad (green mode)
|
||||
* PSX Rumble Pad
|
||||
* PSX DDR Pad
|
||||
|
||||
Sega
|
||||
----
|
||||
|
||||
All the Sega controllers are more or less based on the standard 2-button
|
||||
Multisystem joystick. However, since they don't use switches and use TTL
|
||||
logic, the only driver usable with them is the db9.c driver.
|
||||
|
||||
Sega Master System
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The SMS gamepads are almost exactly the same as normal 2-button
|
||||
Multisystem joysticks. Set the driver to Multi2 mode, use the corresponding
|
||||
parallel port pins, and the following schematic::
|
||||
|
||||
+-----------> Power
|
||||
| +---------> Right
|
||||
| | +-------> Left
|
||||
| | | +-----> Down
|
||||
| | | | +---> Up
|
||||
| | | | |
|
||||
_____________
|
||||
5 \ o o o o o / 1
|
||||
\ o o x o /
|
||||
9 `~~~~~~~' 6
|
||||
| | |
|
||||
| | +----> Button 1
|
||||
| +--------> Ground
|
||||
+----------> Button 2
|
||||
|
||||
Sega Genesis aka MegaDrive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Sega Genesis (in Europe sold as Sega MegaDrive) pads are an extension
|
||||
to the Sega Master System pads. They use more buttons (3+1, 5+1, 6+1). Use
|
||||
the following schematic::
|
||||
|
||||
+-----------> Power
|
||||
| +---------> Right
|
||||
| | +-------> Left
|
||||
| | | +-----> Down
|
||||
| | | | +---> Up
|
||||
| | | | |
|
||||
_____________
|
||||
5 \ o o o o o / 1
|
||||
\ o o o o /
|
||||
9 `~~~~~~~' 6
|
||||
| | | |
|
||||
| | | +----> Button 1
|
||||
| | +------> Select
|
||||
| +--------> Ground
|
||||
+----------> Button 2
|
||||
|
||||
The Select pin goes to pin 14 on the parallel port::
|
||||
|
||||
(pin 14) -----> Select
|
||||
|
||||
The rest is the same as for Multi2 joysticks using db9.c
|
||||
|
||||
Sega Saturn
|
||||
~~~~~~~~~~~
|
||||
|
||||
Sega Saturn has eight buttons, and to transfer that, without hacks like
|
||||
Genesis 6 pads use, it needs one more select pin. Anyway, it is still
|
||||
handled by the db9.c driver. Its pinout is very different from anything
|
||||
else. Use this schematic::
|
||||
|
||||
+-----------> Select 1
|
||||
| +---------> Power
|
||||
| | +-------> Up
|
||||
| | | +-----> Down
|
||||
| | | | +---> Ground
|
||||
| | | | |
|
||||
_____________
|
||||
5 \ o o o o o / 1
|
||||
\ o o o o /
|
||||
9 `~~~~~~~' 6
|
||||
| | | |
|
||||
| | | +----> Select 2
|
||||
| | +------> Right
|
||||
| +--------> Left
|
||||
+----------> Power
|
||||
|
||||
Select 1 is pin 14 on the parallel port, Select 2 is pin 16 on the
|
||||
parallel port::
|
||||
|
||||
(pin 14) -----> Select 1
|
||||
(pin 16) -----> Select 2
|
||||
|
||||
The other pins (Up, Down, Right, Left, Power, Ground) are the same as for
|
||||
Multi joysticks using db9.c
|
||||
|
||||
Amiga CD32
|
||||
----------
|
||||
|
||||
Amiga CD32 joypad uses the following pinout::
|
||||
|
||||
+-----------> Button 3
|
||||
| +---------> Right
|
||||
| | +-------> Left
|
||||
| | | +-----> Down
|
||||
| | | | +---> Up
|
||||
| | | | |
|
||||
_____________
|
||||
5 \ o o o o o / 1
|
||||
\ o o o o /
|
||||
9 `~~~~~~~' 6
|
||||
| | | |
|
||||
| | | +----> Button 1
|
||||
| | +------> Power
|
||||
| +--------> Ground
|
||||
+----------> Button 2
|
||||
|
||||
It can be connected to the parallel port and driven by db9.c driver. It needs the following wiring:
|
||||
|
||||
============ =============
|
||||
CD32 pad Parallel port
|
||||
============ =============
|
||||
1 (Up) 2 (D0)
|
||||
2 (Down) 3 (D1)
|
||||
3 (Left) 4 (D2)
|
||||
4 (Right) 5 (D3)
|
||||
5 (Button 3) 14 (AUTOFD)
|
||||
6 (Button 1) 17 (SELIN)
|
||||
7 (+5V) 1 (STROBE)
|
||||
8 (Gnd) 18 (Gnd)
|
||||
9 (Button 2) 7 (D5)
|
||||
============ =============
|
||||
|
||||
The drivers
|
||||
===========
|
||||
|
||||
There are three drivers for the parallel port interfaces. Each, as
|
||||
described above, allows to connect a different group of joysticks and pads.
|
||||
Here are described their command lines:
|
||||
|
||||
gamecon.c
|
||||
---------
|
||||
|
||||
Using gamecon.c you can connect up to five devices to one parallel port. It
|
||||
uses the following kernel/module command line::
|
||||
|
||||
gamecon.map=port,pad1,pad2,pad3,pad4,pad5
|
||||
|
||||
Where ``port`` the number of the parport interface (eg. 0 for parport0).
|
||||
|
||||
And ``pad1`` to ``pad5`` are pad types connected to different data input pins
|
||||
(10,11,12,13,15), as described in section 2.1 of this file.
|
||||
|
||||
The types are:
|
||||
|
||||
===== =============================
|
||||
Type Joystick/Pad
|
||||
===== =============================
|
||||
0 None
|
||||
1 SNES pad
|
||||
2 NES pad
|
||||
4 Multisystem 1-button joystick
|
||||
5 Multisystem 2-button joystick
|
||||
6 N64 pad
|
||||
7 Sony PSX controller
|
||||
8 Sony PSX DDR controller
|
||||
9 SNES mouse
|
||||
===== =============================
|
||||
|
||||
The exact type of the PSX controller type is autoprobed when used, so
|
||||
hot swapping should work (but is not recommended).
|
||||
|
||||
Should you want to use more than one of parallel ports at once, you can use
|
||||
gamecon.map2 and gamecon.map3 as additional command line parameters for two
|
||||
more parallel ports.
|
||||
|
||||
There are two options specific to PSX driver portion. gamecon.psx_delay sets
|
||||
the command delay when talking to the controllers. The default of 25 should
|
||||
work but you can try lowering it for better performance. If your pads don't
|
||||
respond try raising it until they work. Setting the type to 8 allows the
|
||||
driver to be used with Dance Dance Revolution or similar games. Arrow keys are
|
||||
registered as key presses instead of X and Y axes.
|
||||
|
||||
db9.c
|
||||
-----
|
||||
|
||||
Apart from making an interface, there is nothing difficult on using the
|
||||
db9.c driver. It uses the following kernel/module command line::
|
||||
|
||||
db9.dev=port,type
|
||||
|
||||
Where ``port`` is the number of the parport interface (eg. 0 for parport0).
|
||||
|
||||
Caveat here: This driver only works on bidirectional parallel ports. If
|
||||
your parallel port is recent enough, you should have no trouble with this.
|
||||
Old parallel ports may not have this feature.
|
||||
|
||||
``Type`` is the type of joystick or pad attached:
|
||||
|
||||
===== ======================================================
|
||||
Type Joystick/Pad
|
||||
===== ======================================================
|
||||
0 None
|
||||
1 Multisystem 1-button joystick
|
||||
2 Multisystem 2-button joystick
|
||||
3 Genesis pad (3+1 buttons)
|
||||
5 Genesis pad (5+1 buttons)
|
||||
6 Genesis pad (6+2 buttons)
|
||||
7 Saturn pad (8 buttons)
|
||||
8 Multisystem 1-button joystick (v0.8.0.2 pin-out)
|
||||
9 Two Multisystem 1-button joysticks (v0.8.0.2 pin-out)
|
||||
10 Amiga CD32 pad
|
||||
===== ======================================================
|
||||
|
||||
Should you want to use more than one of these joysticks/pads at once, you
|
||||
can use db9.dev2 and db9.dev3 as additional command line parameters for two
|
||||
more joysticks/pads.
|
||||
|
||||
turbografx.c
|
||||
------------
|
||||
|
||||
The turbografx.c driver uses a very simple kernel/module command line::
|
||||
|
||||
turbografx.map=port,js1,js2,js3,js4,js5,js6,js7
|
||||
|
||||
Where ``port`` is the number of the parport interface (eg. 0 for parport0).
|
||||
|
||||
``jsX`` is the number of buttons the Multisystem joysticks connected to the
|
||||
interface ports 1-7 have. For a standard multisystem joystick, this is 1.
|
||||
|
||||
Should you want to use more than one of these interfaces at once, you can
|
||||
use turbografx.map2 and turbografx.map3 as additional command line parameters
|
||||
for two more interfaces.
|
||||
|
||||
PC parallel port pinout
|
||||
=======================
|
||||
|
||||
::
|
||||
|
||||
.----------------------------------------.
|
||||
At the PC: \ 13 12 11 10 9 8 7 6 5 4 3 2 1 /
|
||||
\ 25 24 23 22 21 20 19 18 17 16 15 14 /
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
====== ======= =============
|
||||
Pin Name Description
|
||||
====== ======= =============
|
||||
1 /STROBE Strobe
|
||||
2-9 D0-D7 Data Bit 0-7
|
||||
10 /ACK Acknowledge
|
||||
11 BUSY Busy
|
||||
12 PE Paper End
|
||||
13 SELIN Select In
|
||||
14 /AUTOFD Autofeed
|
||||
15 /ERROR Error
|
||||
16 /INIT Initialize
|
||||
17 /SEL Select
|
||||
18-25 GND Signal Ground
|
||||
====== ======= =============
|
||||
|
||||
|
||||
That's all, folks! Have fun!
|
|
@ -1,7 +1,11 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
=========================
|
||||
N-Trig touchscreen Driver
|
||||
-------------------------
|
||||
Copyright (c) 2008-2010 Rafi Rubin <rafi@seas.upenn.edu>
|
||||
Copyright (c) 2009-2010 Stephane Chatty
|
||||
=========================
|
||||
|
||||
:Copyright: |copy| 2008-2010 Rafi Rubin <rafi@seas.upenn.edu>
|
||||
:Copyright: |copy| 2009-2010 Stephane Chatty
|
||||
|
||||
This driver provides support for N-Trig pen and multi-touch sensors. Single
|
||||
and multi-touch events are translated to the appropriate protocols for
|
||||
|
@ -22,16 +26,18 @@ but only for that one device.
|
|||
|
||||
The following parameters are used to configure filters to reduce noise:
|
||||
|
||||
activate_slack number of fingers to ignore before processing events
|
||||
|
||||
activation_height size threshold to activate immediately
|
||||
activation_width
|
||||
|
||||
min_height size threshold bellow which fingers are ignored
|
||||
min_width both to decide activation and during activity
|
||||
|
||||
deactivate_slack the number of "no contact" frames to ignore before
|
||||
propagating the end of activity events
|
||||
+-----------------------+-----------------------------------------------------+
|
||||
|activate_slack |number of fingers to ignore before processing events |
|
||||
+-----------------------+-----------------------------------------------------+
|
||||
|activation_height, |size threshold to activate immediately |
|
||||
|activation_width | |
|
||||
+-----------------------+-----------------------------------------------------+
|
||||
|min_height, |size threshold bellow which fingers are ignored |
|
||||
|min_width |both to decide activation and during activity |
|
||||
+-----------------------+-----------------------------------------------------+
|
||||
|deactivate_slack |the number of "no contact" frames to ignore before |
|
||||
| |propagating the end of activity events |
|
||||
+-----------------------+-----------------------------------------------------+
|
||||
|
||||
When the last finger is removed from the device, it sends a number of empty
|
||||
frames. By holding off on deactivation for a few frames we can tolerate false
|
||||
|
@ -44,15 +50,20 @@ Additional sysfs items
|
|||
----------------------
|
||||
|
||||
These nodes just provide easy access to the ranges reported by the device.
|
||||
sensor_logical_height the range for positions reported during activity
|
||||
sensor_logical_width
|
||||
|
||||
sensor_physical_height internal ranges not used for normal events but
|
||||
sensor_physical_width useful for tuning
|
||||
+-----------------------+-----------------------------------------------------+
|
||||
|sensor_logical_height, | the range for positions reported during activity |
|
||||
|sensor_logical_width | |
|
||||
+-----------------------+-----------------------------------------------------+
|
||||
|sensor_physical_height,| internal ranges not used for normal events but |
|
||||
|sensor_physical_width | useful for tuning |
|
||||
+-----------------------+-----------------------------------------------------+
|
||||
|
||||
All N-Trig devices with product id of 1 report events in the ranges of
|
||||
X: 0-9600
|
||||
Y: 0-7200
|
||||
|
||||
* X: 0-9600
|
||||
* Y: 0-7200
|
||||
|
||||
However not all of these devices have the same physical dimensions. Most
|
||||
seem to be 12" sensors (Dell Latitude XT and XT2 and the HP TX2), and
|
||||
at least one model (Dell Studio 17) has a 17" sensor. The ratio of physical
|
|
@ -1,8 +1,11 @@
|
|||
============================================================
|
||||
rotary-encoder - a generic driver for GPIO connected devices
|
||||
Daniel Mack <daniel@caiaq.de>, Feb 2009
|
||||
============================================================
|
||||
|
||||
0. Function
|
||||
-----------
|
||||
:Author: Daniel Mack <daniel@caiaq.de>, Feb 2009
|
||||
|
||||
Function
|
||||
--------
|
||||
|
||||
Rotary encoders are devices which are connected to the CPU or other
|
||||
peripherals with two wires. The outputs are phase-shifted by 90 degrees
|
||||
|
@ -13,7 +16,7 @@ Some encoders have both outputs low in stable states, others also have
|
|||
a stable state with both outputs high (half-period mode) and some have
|
||||
a stable state in all steps (quarter-period mode).
|
||||
|
||||
The phase diagram of these two outputs look like this:
|
||||
The phase diagram of these two outputs look like this::
|
||||
|
||||
_____ _____ _____
|
||||
| | | | | |
|
||||
|
@ -40,8 +43,8 @@ For more information, please see
|
|||
https://en.wikipedia.org/wiki/Rotary_encoder
|
||||
|
||||
|
||||
1. Events / state machine
|
||||
-------------------------
|
||||
Events / state machine
|
||||
----------------------
|
||||
|
||||
In half-period mode, state a) and c) above are used to determine the
|
||||
rotational direction based on the last stable state. Events are reported in
|
||||
|
@ -65,62 +68,64 @@ d) Falling edge on channel B, channel A in low state
|
|||
should have happened, unless it flipped back on half the way. The
|
||||
'armed' state tells us about that.
|
||||
|
||||
2. Platform requirements
|
||||
------------------------
|
||||
Platform requirements
|
||||
---------------------
|
||||
|
||||
As there is no hardware dependent call in this driver, the platform it is
|
||||
used with must support gpiolib. Another requirement is that IRQs must be
|
||||
able to fire on both edges.
|
||||
|
||||
|
||||
3. Board integration
|
||||
--------------------
|
||||
Board integration
|
||||
-----------------
|
||||
|
||||
To use this driver in your system, register a platform_device with the
|
||||
name 'rotary-encoder' and associate the IRQs and some specific platform
|
||||
data with it.
|
||||
data with it. Because the driver uses generic device properties, this can
|
||||
be done either via device tree, ACPI, or using static board files, like in
|
||||
example below:
|
||||
|
||||
struct rotary_encoder_platform_data is declared in
|
||||
include/linux/rotary-encoder.h and needs to be filled with the number of
|
||||
steps the encoder has and can carry information about externally inverted
|
||||
signals (because of an inverting buffer or other reasons). The encoder
|
||||
can be set up to deliver input information as either an absolute or relative
|
||||
axes. For relative axes the input event returns +/-1 for each step. For
|
||||
absolute axes the position of the encoder can either roll over between zero
|
||||
and the number of steps or will clamp at the maximum and zero depending on
|
||||
the configuration.
|
||||
::
|
||||
|
||||
Because GPIO to IRQ mapping is platform specific, this information must
|
||||
be given in separately to the driver. See the example below.
|
||||
/* board support file example */
|
||||
|
||||
---------<snip>---------
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
/* board support file example */
|
||||
#define GPIO_ROTARY_A 1
|
||||
#define GPIO_ROTARY_B 2
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/rotary_encoder.h>
|
||||
static struct gpiod_lookup_table rotary_encoder_gpios = {
|
||||
.dev_id = "rotary-encoder.0",
|
||||
.table = {
|
||||
GPIO_LOOKUP_IDX("gpio-0",
|
||||
GPIO_ROTARY_A, NULL, 0, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX("gpio-0",
|
||||
GPIO_ROTARY_B, NULL, 1, GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
#define GPIO_ROTARY_A 1
|
||||
#define GPIO_ROTARY_B 2
|
||||
static const struct property_entry rotary_encoder_properties[] __initconst = {
|
||||
PROPERTY_ENTRY_INTEGER("rotary-encoder,steps-per-period", u32, 24),
|
||||
PROPERTY_ENTRY_INTEGER("linux,axis", u32, ABS_X),
|
||||
PROPERTY_ENTRY_INTEGER("rotary-encoder,relative_axis", u32, 0),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct rotary_encoder_platform_data my_rotary_encoder_info = {
|
||||
.steps = 24,
|
||||
.axis = ABS_X,
|
||||
.relative_axis = false,
|
||||
.rollover = false,
|
||||
.gpio_a = GPIO_ROTARY_A,
|
||||
.gpio_b = GPIO_ROTARY_B,
|
||||
.inverted_a = 0,
|
||||
.inverted_b = 0,
|
||||
.half_period = false,
|
||||
.wakeup_source = false,
|
||||
};
|
||||
static struct platform_device rotary_encoder_device = {
|
||||
.name = "rotary-encoder",
|
||||
.id = 0,
|
||||
};
|
||||
|
||||
static struct platform_device rotary_encoder_device = {
|
||||
.name = "rotary-encoder",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &my_rotary_encoder_info,
|
||||
}
|
||||
};
|
||||
...
|
||||
|
||||
gpiod_add_lookup_table(&rotary_encoder_gpios);
|
||||
device_add_properties(&rotary_encoder_device, rotary_encoder_properties);
|
||||
platform_device_register(&rotary_encoder_device);
|
||||
|
||||
...
|
||||
|
||||
Please consult device tree binding documentation to see all properties
|
||||
supported by the driver.
|
|
@ -0,0 +1,901 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
=================
|
||||
Sentelic Touchpad
|
||||
=================
|
||||
|
||||
|
||||
:Copyright: |copy| 2002-2011 Sentelic Corporation.
|
||||
|
||||
:Last update: Dec-07-2011
|
||||
|
||||
Finger Sensing Pad Intellimouse Mode (scrolling wheel, 4th and 5th buttons)
|
||||
============================================================================
|
||||
|
||||
A) MSID 4: Scrolling wheel mode plus Forward page(4th button) and Backward
|
||||
page (5th button)
|
||||
|
||||
1. Set sample rate to 200;
|
||||
2. Set sample rate to 200;
|
||||
3. Set sample rate to 80;
|
||||
4. Issuing the "Get device ID" command (0xF2) and waits for the response;
|
||||
5. FSP will respond 0x04.
|
||||
|
||||
::
|
||||
|
||||
Packet 1
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |Y|X|y|x|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 | | |B|F|W|W|W|W|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7 => Y overflow
|
||||
Bit6 => X overflow
|
||||
Bit5 => Y sign bit
|
||||
Bit4 => X sign bit
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X Movement(9-bit 2's complement integers)
|
||||
Byte 3: Y Movement(9-bit 2's complement integers)
|
||||
Byte 4: Bit3~Bit0 => the scrolling wheel's movement since the last data report.
|
||||
valid values, -8 ~ +7
|
||||
Bit4 => 1 = 4th mouse button is pressed, Forward one page.
|
||||
0 = 4th mouse button is not pressed.
|
||||
Bit5 => 1 = 5th mouse button is pressed, Backward one page.
|
||||
0 = 5th mouse button is not pressed.
|
||||
|
||||
B) MSID 6: Horizontal and Vertical scrolling
|
||||
|
||||
- Set bit 1 in register 0x40 to 1
|
||||
|
||||
FSP replaces scrolling wheel's movement as 4 bits to show horizontal and
|
||||
vertical scrolling.
|
||||
|
||||
::
|
||||
|
||||
Packet 1
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |Y|X|y|x|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 | | |B|F|r|l|u|d|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7 => Y overflow
|
||||
Bit6 => X overflow
|
||||
Bit5 => Y sign bit
|
||||
Bit4 => X sign bit
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X Movement(9-bit 2's complement integers)
|
||||
Byte 3: Y Movement(9-bit 2's complement integers)
|
||||
Byte 4: Bit0 => the Vertical scrolling movement downward.
|
||||
Bit1 => the Vertical scrolling movement upward.
|
||||
Bit2 => the Horizontal scrolling movement leftward.
|
||||
Bit3 => the Horizontal scrolling movement rightward.
|
||||
Bit4 => 1 = 4th mouse button is pressed, Forward one page.
|
||||
0 = 4th mouse button is not pressed.
|
||||
Bit5 => 1 = 5th mouse button is pressed, Backward one page.
|
||||
0 = 5th mouse button is not pressed.
|
||||
|
||||
C) MSID 7
|
||||
|
||||
FSP uses 2 packets (8 Bytes) to represent Absolute Position.
|
||||
so we have PACKET NUMBER to identify packets.
|
||||
|
||||
If PACKET NUMBER is 0, the packet is Packet 1.
|
||||
If PACKET NUMBER is 1, the packet is Packet 2.
|
||||
Please count this number in program.
|
||||
|
||||
MSID6 special packet will be enable at the same time when enable MSID 7.
|
||||
|
||||
Absolute position for STL3886-G0
|
||||
================================
|
||||
|
||||
1. Set bit 2 or 3 in register 0x40 to 1
|
||||
2. Set bit 6 in register 0x40 to 1
|
||||
|
||||
::
|
||||
|
||||
Packet 1 (ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|1|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|d|u|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => valid bit
|
||||
Bit4 => 1
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => scroll up
|
||||
Bit5 => scroll down
|
||||
Bit6 => scroll left
|
||||
Bit7 => scroll right
|
||||
|
||||
Notify Packet for G0
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |1|0|0|1|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |M|M|M|M|M|M|M|M| 4 |0|0|0|0|0|0|0|0|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => 0
|
||||
Bit4 => 1
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: Message Type => 0x5A (Enable/Disable status packet)
|
||||
Mode Type => 0xA5 (Normal/Icon mode status)
|
||||
Byte 3: Message Type => 0x00 (Disabled)
|
||||
=> 0x01 (Enabled)
|
||||
Mode Type => 0x00 (Normal)
|
||||
=> 0x01 (Icon)
|
||||
Byte 4: Bit7~Bit0 => Don't Care
|
||||
|
||||
Absolute position for STL3888-Ax
|
||||
================================
|
||||
|
||||
::
|
||||
|
||||
Packet 1 (ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|A|1|L|0|1| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |x|x|y|y|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
|
||||
When both fingers are up, the last two reports have zero valid
|
||||
bit.
|
||||
Bit4 => arc
|
||||
Bit3 => 1
|
||||
Bit2 => Left Button, 1 is pressed, 0 is released.
|
||||
Bit1 => 0
|
||||
Bit0 => 1
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit5~Bit4 => y1_g
|
||||
Bit7~Bit6 => x1_g
|
||||
|
||||
Packet 2 (ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|A|1|R|1|0| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |x|x|y|y|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
|
||||
When both fingers are up, the last two reports have zero valid
|
||||
bit.
|
||||
Bit4 => arc
|
||||
Bit3 => 1
|
||||
Bit2 => Right Button, 1 is pressed, 0 is released.
|
||||
Bit1 => 1
|
||||
Bit0 => 0
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit5~Bit4 => y2_g
|
||||
Bit7~Bit6 => x2_g
|
||||
|
||||
Notify Packet for STL3888-Ax
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |1|0|1|P|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |0|0|F|F|0|0|0|i| 4 |r|l|d|u|0|0|0|0|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => 1
|
||||
Bit4 => when in absolute coordinates mode (valid when EN_PKT_GO is 1):
|
||||
0: left button is generated by the on-pad command
|
||||
1: left button is generated by the external button
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: Message Type => 0xB7 (Multi Finger, Multi Coordinate mode)
|
||||
Byte 3: Bit7~Bit6 => Don't care
|
||||
Bit5~Bit4 => Number of fingers
|
||||
Bit3~Bit1 => Reserved
|
||||
Bit0 => 1: enter gesture mode; 0: leaving gesture mode
|
||||
Byte 4: Bit7 => scroll right button
|
||||
Bit6 => scroll left button
|
||||
Bit5 => scroll down button
|
||||
Bit4 => scroll up button
|
||||
* Note that if gesture and additional button (Bit4~Bit7)
|
||||
happen at the same time, the button information will not
|
||||
be sent.
|
||||
Bit3~Bit0 => Reserved
|
||||
|
||||
Sample sequence of Multi-finger, Multi-coordinate mode:
|
||||
|
||||
notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1,
|
||||
abs pkt 2, ..., notify packet (valid bit == 0)
|
||||
|
||||
Absolute position for STL3888-B0
|
||||
================================
|
||||
|
||||
::
|
||||
|
||||
Packet 1(ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|F|1|0|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|u|d|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
|
||||
When both fingers are up, the last two reports have zero valid
|
||||
bit.
|
||||
Bit4 => finger up/down information. 1: finger down, 0: finger up.
|
||||
Bit3 => 1
|
||||
Bit2 => finger index, 0 is the first finger, 1 is the second finger.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => scroll down button
|
||||
Bit5 => scroll up button
|
||||
Bit6 => scroll left button
|
||||
Bit7 => scroll right button
|
||||
|
||||
Packet 2 (ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|F|1|1|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|u|d|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
|
||||
When both fingers are up, the last two reports have zero valid
|
||||
bit.
|
||||
Bit4 => finger up/down information. 1: finger down, 0: finger up.
|
||||
Bit3 => 1
|
||||
Bit2 => finger index, 0 is the first finger, 1 is the second finger.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => scroll down button
|
||||
Bit5 => scroll up button
|
||||
Bit6 => scroll left button
|
||||
Bit7 => scroll right button
|
||||
|
||||
Notify Packet for STL3888-B0::
|
||||
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |1|0|1|P|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |0|0|F|F|0|0|0|i| 4 |r|l|u|d|0|0|0|0|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => 1
|
||||
Bit4 => when in absolute coordinates mode (valid when EN_PKT_GO is 1):
|
||||
0: left button is generated by the on-pad command
|
||||
1: left button is generated by the external button
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: Message Type => 0xB7 (Multi Finger, Multi Coordinate mode)
|
||||
Byte 3: Bit7~Bit6 => Don't care
|
||||
Bit5~Bit4 => Number of fingers
|
||||
Bit3~Bit1 => Reserved
|
||||
Bit0 => 1: enter gesture mode; 0: leaving gesture mode
|
||||
Byte 4: Bit7 => scroll right button
|
||||
Bit6 => scroll left button
|
||||
Bit5 => scroll up button
|
||||
Bit4 => scroll down button
|
||||
* Note that if gesture and additional button(Bit4~Bit7)
|
||||
happen at the same time, the button information will not
|
||||
be sent.
|
||||
Bit3~Bit0 => Reserved
|
||||
|
||||
Sample sequence of Multi-finger, Multi-coordinate mode:
|
||||
|
||||
notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1,
|
||||
abs pkt 2, ..., notify packet (valid bit == 0)
|
||||
|
||||
Absolute position for STL3888-Cx and STL3888-Dx
|
||||
===============================================
|
||||
|
||||
::
|
||||
|
||||
Single Finger, Absolute Coordinate Mode (SFAC)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|0|P|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|B|F|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => Coordinate mode(always 0 in SFAC mode):
|
||||
0: single-finger absolute coordinates (SFAC) mode
|
||||
1: multi-finger, multiple coordinates (MFMC) mode
|
||||
Bit4 => 0: The LEFT button is generated by on-pad command (OPC)
|
||||
1: The LEFT button is generated by external button
|
||||
Default is 1 even if the LEFT button is not pressed.
|
||||
Bit3 => Always 1, as specified by PS/2 protocol.
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => 4th mouse button(forward one page)
|
||||
Bit5 => 5th mouse button(backward one page)
|
||||
Bit6 => scroll left button
|
||||
Bit7 => scroll right button
|
||||
|
||||
Multi Finger, Multiple Coordinates Mode (MFMC):
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|1|P|1|F|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|B|F|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => Coordinate mode (always 1 in MFMC mode):
|
||||
0: single-finger absolute coordinates (SFAC) mode
|
||||
1: multi-finger, multiple coordinates (MFMC) mode
|
||||
Bit4 => 0: The LEFT button is generated by on-pad command (OPC)
|
||||
1: The LEFT button is generated by external button
|
||||
Default is 1 even if the LEFT button is not pressed.
|
||||
Bit3 => Always 1, as specified by PS/2 protocol.
|
||||
Bit2 => Finger index, 0 is the first finger, 1 is the second finger.
|
||||
If bit 1 and 0 are all 1 and bit 4 is 0, the middle external
|
||||
button is pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => 4th mouse button(forward one page)
|
||||
Bit5 => 5th mouse button(backward one page)
|
||||
Bit6 => scroll left button
|
||||
Bit7 => scroll right button
|
||||
|
||||
When one of the two fingers is up, the device will output four consecutive
|
||||
MFMC#0 report packets with zero X and Y to represent 1st finger is up or
|
||||
four consecutive MFMC#1 report packets with zero X and Y to represent that
|
||||
the 2nd finger is up. On the other hand, if both fingers are up, the device
|
||||
will output four consecutive single-finger, absolute coordinate(SFAC) packets
|
||||
with zero X and Y.
|
||||
|
||||
Notify Packet for STL3888-Cx/Dx::
|
||||
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |1|0|0|P|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |0|0|F|F|0|0|0|i| 4 |r|l|u|d|0|0|0|0|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => Always 0
|
||||
Bit4 => 0: The LEFT button is generated by on-pad command(OPC)
|
||||
1: The LEFT button is generated by external button
|
||||
Default is 1 even if the LEFT button is not pressed.
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: Message type:
|
||||
0xba => gesture information
|
||||
0xc0 => one finger hold-rotating gesture
|
||||
Byte 3: The first parameter for the received message:
|
||||
0xba => gesture ID (refer to the 'Gesture ID' section)
|
||||
0xc0 => region ID
|
||||
Byte 4: The second parameter for the received message:
|
||||
0xba => N/A
|
||||
0xc0 => finger up/down information
|
||||
|
||||
Sample sequence of Multi-finger, Multi-coordinates mode:
|
||||
|
||||
notify packet (valid bit == 1), MFMC packet 1 (byte 1, bit 2 == 0),
|
||||
MFMC packet 2 (byte 1, bit 2 == 1), MFMC packet 1, MFMC packet 2,
|
||||
..., notify packet (valid bit == 0)
|
||||
|
||||
That is, when the device is in MFMC mode, the host will receive
|
||||
interleaved absolute coordinate packets for each finger.
|
||||
|
||||
FSP Enable/Disable packet
|
||||
=========================
|
||||
|
||||
::
|
||||
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |Y|X|0|0|1|M|R|L| 2 |0|1|0|1|1|0|1|E| 3 | | | | | | | | | 4 | | | | | | | | |
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
FSP will send out enable/disable packet when FSP receive PS/2 enable/disable
|
||||
command. Host will receive the packet which Middle, Right, Left button will
|
||||
be set. The packet only use byte 0 and byte 1 as a pattern of original packet.
|
||||
Ignore the other bytes of the packet.
|
||||
|
||||
Byte 1: Bit7 => 0, Y overflow
|
||||
Bit6 => 0, X overflow
|
||||
Bit5 => 0, Y sign bit
|
||||
Bit4 => 0, X sign bit
|
||||
Bit3 => 1
|
||||
Bit2 => 1, Middle Button
|
||||
Bit1 => 1, Right Button
|
||||
Bit0 => 1, Left Button
|
||||
Byte 2: Bit7~1 => (0101101b)
|
||||
Bit0 => 1 = Enable
|
||||
0 = Disable
|
||||
Byte 3: Don't care
|
||||
Byte 4: Don't care (MOUSE ID 3, 4)
|
||||
Byte 5~8: Don't care (Absolute packet)
|
||||
|
||||
PS/2 Command Set
|
||||
================
|
||||
|
||||
FSP supports basic PS/2 commanding set and modes, refer to following URL for
|
||||
details about PS/2 commands:
|
||||
|
||||
http://www.computer-engineering.org/ps2mouse/
|
||||
|
||||
Programming Sequence for Determining Packet Parsing Flow
|
||||
========================================================
|
||||
|
||||
1. Identify FSP by reading device ID(0x00) and version(0x01) register
|
||||
|
||||
2. For FSP version < STL3888 Cx, determine number of buttons by reading
|
||||
the 'test mode status' (0x20) register::
|
||||
|
||||
buttons = reg[0x20] & 0x30
|
||||
|
||||
if buttons == 0x30 or buttons == 0x20:
|
||||
# two/four buttons
|
||||
Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
|
||||
section A for packet parsing detail(ignore byte 4, bit ~ 7)
|
||||
elif buttons == 0x10:
|
||||
# 6 buttons
|
||||
Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
|
||||
section B for packet parsing detail
|
||||
elif buttons == 0x00:
|
||||
# 6 buttons
|
||||
Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
|
||||
section A for packet parsing detail
|
||||
|
||||
3. For FSP version >= STL3888 Cx:
|
||||
Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
|
||||
section A for packet parsing detail (ignore byte 4, bit ~ 7)
|
||||
|
||||
Programming Sequence for Register Reading/Writing
|
||||
=================================================
|
||||
|
||||
Register inversion requirement:
|
||||
|
||||
Following values needed to be inverted(the '~' operator in C) before being
|
||||
sent to FSP::
|
||||
|
||||
0xe8, 0xe9, 0xee, 0xf2, 0xf3 and 0xff.
|
||||
|
||||
Register swapping requirement:
|
||||
|
||||
Following values needed to have their higher 4 bits and lower 4 bits being
|
||||
swapped before being sent to FSP::
|
||||
|
||||
10, 20, 40, 60, 80, 100 and 200.
|
||||
|
||||
Register reading sequence:
|
||||
|
||||
1. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
2. send 0x66 PS/2 command to FSP;
|
||||
|
||||
3. send 0x88 PS/2 command to FSP;
|
||||
|
||||
4. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
5. if the register address being to read is not required to be
|
||||
inverted(refer to the 'Register inversion requirement' section),
|
||||
goto step 6
|
||||
|
||||
a. send 0x68 PS/2 command to FSP;
|
||||
|
||||
b. send the inverted register address to FSP and goto step 8;
|
||||
|
||||
6. if the register address being to read is not required to be
|
||||
swapped(refer to the 'Register swapping requirement' section),
|
||||
goto step 7
|
||||
|
||||
a. send 0xcc PS/2 command to FSP;
|
||||
|
||||
b. send the swapped register address to FSP and goto step 8;
|
||||
|
||||
7. send 0x66 PS/2 command to FSP;
|
||||
|
||||
a. send the original register address to FSP and goto step 8;
|
||||
|
||||
8. send 0xe9(status request) PS/2 command to FSP;
|
||||
|
||||
9. the 4th byte of the response read from FSP should be the
|
||||
requested register value(?? indicates don't care byte)::
|
||||
|
||||
host: 0xe9
|
||||
3888: 0xfa (??) (??) (val)
|
||||
|
||||
* Note that since the Cx release, the hardware will return 1's
|
||||
complement of the register value at the 3rd byte of status request
|
||||
result::
|
||||
|
||||
host: 0xe9
|
||||
3888: 0xfa (??) (~val) (val)
|
||||
|
||||
Register writing sequence:
|
||||
|
||||
1. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
2. if the register address being to write is not required to be
|
||||
inverted(refer to the 'Register inversion requirement' section),
|
||||
goto step 3
|
||||
|
||||
a. send 0x74 PS/2 command to FSP;
|
||||
|
||||
b. send the inverted register address to FSP and goto step 5;
|
||||
|
||||
3. if the register address being to write is not required to be
|
||||
swapped(refer to the 'Register swapping requirement' section),
|
||||
goto step 4
|
||||
|
||||
a. send 0x77 PS/2 command to FSP;
|
||||
|
||||
b. send the swapped register address to FSP and goto step 5;
|
||||
|
||||
4. send 0x55 PS/2 command to FSP;
|
||||
|
||||
a. send the register address to FSP and goto step 5;
|
||||
|
||||
5. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
6. if the register value being to write is not required to be
|
||||
inverted(refer to the 'Register inversion requirement' section),
|
||||
goto step 7
|
||||
|
||||
a. send 0x47 PS/2 command to FSP;
|
||||
|
||||
b. send the inverted register value to FSP and goto step 9;
|
||||
|
||||
7. if the register value being to write is not required to be
|
||||
swapped(refer to the 'Register swapping requirement' section),
|
||||
goto step 8
|
||||
|
||||
a. send 0x44 PS/2 command to FSP;
|
||||
|
||||
b. send the swapped register value to FSP and goto step 9;
|
||||
|
||||
8. send 0x33 PS/2 command to FSP;
|
||||
|
||||
a. send the register value to FSP;
|
||||
|
||||
9. the register writing sequence is completed.
|
||||
|
||||
* Since the Cx release, the hardware will return 1's
|
||||
complement of the register value at the 3rd byte of status request
|
||||
result. Host can optionally send another 0xe9 (status request) PS/2
|
||||
command to FSP at the end of register writing to verify that the
|
||||
register writing operation is successful (?? indicates don't care
|
||||
byte)::
|
||||
|
||||
host: 0xe9
|
||||
3888: 0xfa (??) (~val) (val)
|
||||
|
||||
Programming Sequence for Page Register Reading/Writing
|
||||
======================================================
|
||||
|
||||
In order to overcome the limitation of maximum number of registers
|
||||
supported, the hardware separates register into different groups called
|
||||
'pages.' Each page is able to include up to 255 registers.
|
||||
|
||||
The default page after power up is 0x82; therefore, if one has to get
|
||||
access to register 0x8301, one has to use following sequence to switch
|
||||
to page 0x83, then start reading/writing from/to offset 0x01 by using
|
||||
the register read/write sequence described in previous section.
|
||||
|
||||
Page register reading sequence:
|
||||
|
||||
1. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
2. send 0x66 PS/2 command to FSP;
|
||||
|
||||
3. send 0x88 PS/2 command to FSP;
|
||||
|
||||
4. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
5. send 0x83 PS/2 command to FSP;
|
||||
|
||||
6. send 0x88 PS/2 command to FSP;
|
||||
|
||||
7. send 0xe9(status request) PS/2 command to FSP;
|
||||
|
||||
8. the response read from FSP should be the requested page value.
|
||||
|
||||
|
||||
Page register writing sequence:
|
||||
|
||||
1. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
2. send 0x38 PS/2 command to FSP;
|
||||
|
||||
3. send 0x88 PS/2 command to FSP;
|
||||
|
||||
4. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
5. if the page address being written is not required to be
|
||||
inverted(refer to the 'Register inversion requirement' section),
|
||||
goto step 6
|
||||
|
||||
a. send 0x47 PS/2 command to FSP;
|
||||
|
||||
b. send the inverted page address to FSP and goto step 9;
|
||||
|
||||
6. if the page address being written is not required to be
|
||||
swapped(refer to the 'Register swapping requirement' section),
|
||||
goto step 7
|
||||
|
||||
a. send 0x44 PS/2 command to FSP;
|
||||
|
||||
b. send the swapped page address to FSP and goto step 9;
|
||||
|
||||
7. send 0x33 PS/2 command to FSP;
|
||||
|
||||
8. send the page address to FSP;
|
||||
|
||||
9. the page register writing sequence is completed.
|
||||
|
||||
Gesture ID
|
||||
==========
|
||||
|
||||
Unlike other devices which sends multiple fingers' coordinates to host,
|
||||
FSP processes multiple fingers' coordinates internally and convert them
|
||||
into a 8 bits integer, namely 'Gesture ID.' Following is a list of
|
||||
supported gesture IDs:
|
||||
|
||||
======= ==================================
|
||||
ID Description
|
||||
======= ==================================
|
||||
0x86 2 finger straight up
|
||||
0x82 2 finger straight down
|
||||
0x80 2 finger straight right
|
||||
0x84 2 finger straight left
|
||||
0x8f 2 finger zoom in
|
||||
0x8b 2 finger zoom out
|
||||
0xc0 2 finger curve, counter clockwise
|
||||
0xc4 2 finger curve, clockwise
|
||||
0x2e 3 finger straight up
|
||||
0x2a 3 finger straight down
|
||||
0x28 3 finger straight right
|
||||
0x2c 3 finger straight left
|
||||
0x38 palm
|
||||
======= ==================================
|
||||
|
||||
Register Listing
|
||||
================
|
||||
|
||||
Registers are represented in 16 bits values. The higher 8 bits represent
|
||||
the page address and the lower 8 bits represent the relative offset within
|
||||
that particular page. Refer to the 'Programming Sequence for Page Register
|
||||
Reading/Writing' section for instructions on how to change current page
|
||||
address::
|
||||
|
||||
offset width default r/w name
|
||||
0x8200 bit7~bit0 0x01 RO device ID
|
||||
|
||||
0x8201 bit7~bit0 RW version ID
|
||||
0xc1: STL3888 Ax
|
||||
0xd0 ~ 0xd2: STL3888 Bx
|
||||
0xe0 ~ 0xe1: STL3888 Cx
|
||||
0xe2 ~ 0xe3: STL3888 Dx
|
||||
|
||||
0x8202 bit7~bit0 0x01 RO vendor ID
|
||||
|
||||
0x8203 bit7~bit0 0x01 RO product ID
|
||||
|
||||
0x8204 bit3~bit0 0x01 RW revision ID
|
||||
|
||||
0x820b test mode status 1
|
||||
bit3 1 RO 0: rotate 180 degree
|
||||
1: no rotation
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x820f register file page control
|
||||
bit2 0 RW 1: rotate 180 degree
|
||||
0: no rotation
|
||||
*supported since Cx
|
||||
|
||||
bit0 0 RW 1 to enable page 1 register files
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8210 RW system control 1
|
||||
bit0 1 RW Reserved, must be 1
|
||||
bit1 0 RW Reserved, must be 0
|
||||
bit4 0 RW Reserved, must be 0
|
||||
bit5 1 RW register clock gating enable
|
||||
0: read only, 1: read/write enable
|
||||
(Note that following registers does not require clock gating being
|
||||
enabled prior to write: 05 06 07 08 09 0c 0f 10 11 12 16 17 18 23 2e
|
||||
40 41 42 43. In addition to that, this bit must be 1 when gesture
|
||||
mode is enabled)
|
||||
|
||||
0x8220 test mode status
|
||||
bit5~bit4 RO number of buttons
|
||||
11 => 2, lbtn/rbtn
|
||||
10 => 4, lbtn/rbtn/scru/scrd
|
||||
01 => 6, lbtn/rbtn/scru/scrd/scrl/scrr
|
||||
00 => 6, lbtn/rbtn/scru/scrd/fbtn/bbtn
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8231 RW on-pad command detection
|
||||
bit7 0 RW on-pad command left button down tag
|
||||
enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8234 RW on-pad command control 5
|
||||
bit4~bit0 0x05 RW XLO in 0s/4/1, so 03h = 0010.1b = 2.5
|
||||
(Note that position unit is in 0.5 scanline)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit7 0 RW on-pad tap zone enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8235 RW on-pad command control 6
|
||||
bit4~bit0 0x1d RW XHI in 0s/4/1, so 19h = 1100.1b = 12.5
|
||||
(Note that position unit is in 0.5 scanline)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8236 RW on-pad command control 7
|
||||
bit4~bit0 0x04 RW YLO in 0s/4/1, so 03h = 0010.1b = 2.5
|
||||
(Note that position unit is in 0.5 scanline)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8237 RW on-pad command control 8
|
||||
bit4~bit0 0x13 RW YHI in 0s/4/1, so 11h = 1000.1b = 8.5
|
||||
(Note that position unit is in 0.5 scanline)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8240 RW system control 5
|
||||
bit1 0 RW FSP Intellimouse mode enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit2 0 RW movement + abs. coordinate mode enable
|
||||
0: disable, 1: enable
|
||||
(Note that this function has the functionality of bit 1 even when
|
||||
bit 1 is not set. However, the format is different from that of bit 1.
|
||||
In addition, when bit 1 and bit 2 are set at the same time, bit 2 will
|
||||
override bit 1.)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit3 0 RW abs. coordinate only mode enable
|
||||
0: disable, 1: enable
|
||||
(Note that this function has the functionality of bit 1 even when
|
||||
bit 1 is not set. However, the format is different from that of bit 1.
|
||||
In addition, when bit 1, bit 2 and bit 3 are set at the same time,
|
||||
bit 3 will override bit 1 and 2.)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit5 0 RW auto switch enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit6 0 RW G0 abs. + notify packet format enable
|
||||
0: disable, 1: enable
|
||||
(Note that the absolute/relative coordinate output still depends on
|
||||
bit 2 and 3. That is, if any of those bit is 1, host will receive
|
||||
absolute coordinates; otherwise, host only receives packets with
|
||||
relative coordinate.)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit7 0 RW EN_PS2_F2: PS/2 gesture mode 2nd
|
||||
finger packet enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8243 RW on-pad control
|
||||
bit0 0 RW on-pad control enable
|
||||
0: disable, 1: enable
|
||||
(Note that if this bit is cleared, bit 3/5 will be ineffective)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit3 0 RW on-pad fix vertical scrolling enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit5 0 RW on-pad fix horizontal scrolling enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8290 RW software control register 1
|
||||
bit0 0 RW absolute coordination mode
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit1 0 RW gesture ID output
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit2 0 RW two fingers' coordinates output
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit3 0 RW finger up one packet output
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit4 0 RW absolute coordination continuous mode
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit6~bit5 00 RW gesture group selection
|
||||
00: basic
|
||||
01: suite
|
||||
10: suite pro
|
||||
11: advanced
|
||||
*supported since Cx
|
||||
|
||||
bit7 0 RW Bx packet output compatible mode
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
*supported since Cx
|
||||
|
||||
|
||||
0x833d RW on-pad command control 1
|
||||
bit7 1 RW on-pad command detection enable
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
0x833e RW on-pad command detection
|
||||
bit7 0 RW on-pad command left button down tag
|
||||
enable. Works only in H/W based PS/2
|
||||
data packet mode.
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
|
@ -1,3 +1,6 @@
|
|||
===========================
|
||||
Walkera WK-0701 transmitter
|
||||
===========================
|
||||
|
||||
Walkera WK-0701 transmitter is supplied with a ready to fly Walkera
|
||||
helicopters such as HM36, HM37, HM60. The walkera0701 module enables to use
|
||||
|
@ -10,7 +13,8 @@ or use cogito:
|
|||
cg-clone http://zub.fei.tuke.sk/GIT/walkera0701-joystick
|
||||
|
||||
|
||||
Connecting to PC:
|
||||
Connecting to PC
|
||||
================
|
||||
|
||||
At back side of transmitter S-video connector can be found. Modulation
|
||||
pulses from processor to HF part can be found at pin 2 of this connector,
|
||||
|
@ -19,7 +23,8 @@ modulation pulses to PC, signal pulses must be amplified.
|
|||
|
||||
Cable: (walkera TX to parport)
|
||||
|
||||
Walkera WK-0701 TX S-VIDEO connector:
|
||||
Walkera WK-0701 TX S-VIDEO connector::
|
||||
|
||||
(back side of TX)
|
||||
__ __ S-video: canon25
|
||||
/ |_| \ pin 2 (signal) NPN parport
|
||||
|
@ -30,10 +35,10 @@ Walkera WK-0701 TX S-VIDEO connector:
|
|||
------- 3 __________________________________|________________ 25 GND
|
||||
E
|
||||
|
||||
|
||||
I use green LED and BC109 NPN transistor.
|
||||
|
||||
Software:
|
||||
Software
|
||||
========
|
||||
|
||||
Build kernel with walkera0701 module. Module walkera0701 need exclusive
|
||||
access to parport, modules like lp must be unloaded before loading
|
||||
|
@ -44,7 +49,8 @@ be changed by TX "joystick", check output from /proc/interrupts. Value for
|
|||
|
||||
|
||||
|
||||
Technical details:
|
||||
Technical details
|
||||
=================
|
||||
|
||||
Driver use interrupt from parport ACK input bit to measure pulse length
|
||||
using hrtimers.
|
||||
|
@ -53,17 +59,29 @@ Frame format:
|
|||
Based on walkera WK-0701 PCM Format description by Shaul Eizikovich.
|
||||
(downloaded from http://www.smartpropoplus.com/Docs/Walkera_Wk-0701_PCM.pdf)
|
||||
|
||||
Signal pulses:
|
||||
(ANALOG)
|
||||
SYNC BIN OCT
|
||||
+---------+ +------+
|
||||
| | | |
|
||||
--+ +------+ +---
|
||||
Signal pulses
|
||||
-------------
|
||||
|
||||
::
|
||||
|
||||
(ANALOG)
|
||||
SYNC BIN OCT
|
||||
+---------+ +------+
|
||||
| | | |
|
||||
--+ +------+ +---
|
||||
|
||||
Frame
|
||||
-----
|
||||
|
||||
::
|
||||
|
||||
Frame:
|
||||
SYNC , BIN1, OCT1, BIN2, OCT2 ... BIN24, OCT24, BIN25, next frame SYNC ..
|
||||
|
||||
pulse length:
|
||||
pulse length
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
Binary values: Analog octal values:
|
||||
|
||||
288 uS Binary 0 318 uS 000
|
||||
|
@ -80,7 +98,8 @@ pulse length:
|
|||
(Warning, pulses on ACK are inverted by transistor, irq is raised up on sync
|
||||
to bin change or octal value to bin change).
|
||||
|
||||
Binary data representations:
|
||||
Binary data representations
|
||||
---------------------------
|
||||
|
||||
One binary and octal value can be grouped to nibble. 24 nibbles + one binary
|
||||
values can be sampled between sync pulses.
|
||||
|
@ -100,10 +119,10 @@ binary value can be sampled. This bit and magic number is not used in
|
|||
software driver. Some details about this magic numbers can be found in
|
||||
Walkera_Wk-0701_PCM.pdf.
|
||||
|
||||
Checksum calculation:
|
||||
Checksum calculation
|
||||
--------------------
|
||||
|
||||
Summary of octal values in nibbles must be same as octal value in checksum
|
||||
nibble (only first 3 bits are used). Binary value for checksum nibble is
|
||||
calculated by sum of binary values in checked nibbles + sum of octal values
|
||||
in checked nibbles divided by 8. Only bit 0 of this sum is used.
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
=======================================================
|
||||
xpad - Linux USB driver for Xbox compatible controllers
|
||||
=======================================================
|
||||
|
||||
This driver exposes all first-party and third-party Xbox compatible
|
||||
controllers. It has a long history and has enjoyed considerable usage
|
||||
|
@ -15,9 +17,11 @@ the Xbox One's rumble protocol has not been reverse engineered but in
|
|||
the future could be supported.
|
||||
|
||||
|
||||
0. Notes
|
||||
--------
|
||||
Notes
|
||||
=====
|
||||
|
||||
The number of buttons/axes reported varies based on 3 things:
|
||||
|
||||
- if you are using a known controller
|
||||
- if you are using a known dance pad
|
||||
- if using an unknown device (one not listed below), what you set in the
|
||||
|
@ -35,8 +39,9 @@ This is not true. Both dpad_to_buttons and triggers_to_buttons only affect
|
|||
unknown controllers.
|
||||
|
||||
|
||||
0.1 Normal Controllers
|
||||
----------------------
|
||||
Normal Controllers
|
||||
------------------
|
||||
|
||||
With a normal controller, the directional pad is mapped to its own X/Y axes.
|
||||
The jstest-program from joystick-1.2.15 (jstest-version 2.1.0) will report 8
|
||||
axes and 10 buttons.
|
||||
|
@ -55,8 +60,9 @@ in game functionality were OK. However, I find it rather difficult to
|
|||
play first person shooters with a pad. Your mileage may vary.
|
||||
|
||||
|
||||
0.2 Xbox Dance Pads
|
||||
-------------------
|
||||
Xbox Dance Pads
|
||||
---------------
|
||||
|
||||
When using a known dance pad, jstest will report 6 axes and 14 buttons.
|
||||
|
||||
For dance style pads (like the redoctane pad) several changes
|
||||
|
@ -73,24 +79,21 @@ of buttons, see section 0.3 - Unknown Controllers
|
|||
I've tested this with Stepmania, and it works quite well.
|
||||
|
||||
|
||||
0.3 Unknown Controllers
|
||||
----------------------
|
||||
Unknown Controllers
|
||||
-------------------
|
||||
|
||||
If you have an unknown xbox controller, it should work just fine with
|
||||
the default settings.
|
||||
|
||||
HOWEVER if you have an unknown dance pad not listed below, it will not
|
||||
work UNLESS you set "dpad_to_buttons" to 1 in the module configuration.
|
||||
|
||||
PLEASE, if you have an unknown controller, email Dom <binary1230@yahoo.com> with
|
||||
a dump from /proc/bus/usb and a description of the pad (manufacturer, country,
|
||||
whether it is a dance pad or normal controller) so that we can add your pad
|
||||
to the list of supported devices, ensuring that it will work out of the
|
||||
box in the future.
|
||||
|
||||
USB adapters
|
||||
============
|
||||
|
||||
1. USB adapters
|
||||
--------------
|
||||
All generations of Xbox controllers speak USB over the wire.
|
||||
|
||||
- Original Xbox controllers use a proprietary connector and require adapters.
|
||||
- Wireless Xbox 360 controllers require a 'Xbox 360 Wireless Gaming Receiver
|
||||
for Windows'
|
||||
|
@ -101,8 +104,9 @@ All generations of Xbox controllers speak USB over the wire.
|
|||
|
||||
|
||||
|
||||
1.1 Original Xbox USB adapters
|
||||
--------------
|
||||
Original Xbox USB adapters
|
||||
--------------------------
|
||||
|
||||
Using this driver with an Original Xbox controller requires an
|
||||
adapter cable to break out the proprietary connector's pins to USB.
|
||||
You can buy these online fairly cheap, or build your own.
|
||||
|
@ -115,7 +119,7 @@ the controller device) with the only difference in a nonstandard connector
|
|||
You just need to solder a USB connector onto the cable and keep the
|
||||
yellow wire unconnected. The other pins have the same order on both
|
||||
connectors so there is no magic to it. Detailed info on these matters
|
||||
can be found on the net ([1], [2], [3]).
|
||||
can be found on the net ([1]_, [2]_, [3]_).
|
||||
|
||||
Thanks to the trip splitter found on the cable you don't even need to cut the
|
||||
original one. You can buy an extension cable and cut that instead. That way,
|
||||
|
@ -123,22 +127,46 @@ you can still use the controller with your X-Box, if you have one ;)
|
|||
|
||||
|
||||
|
||||
2. Driver Installation
|
||||
----------------------
|
||||
Driver Installation
|
||||
===================
|
||||
|
||||
Once you have the adapter cable, if needed, and the controller connected
|
||||
the xpad module should be auto loaded. To confirm you can cat
|
||||
/proc/bus/usb/devices. There should be an entry like the one at the end [4].
|
||||
/sys/kernel/debug/usb/devices. There should be an entry like those:
|
||||
|
||||
.. code-block:: none
|
||||
:caption: dump from InterAct PowerPad Pro (Germany)
|
||||
|
||||
T: Bus=01 Lev=03 Prnt=04 Port=00 Cnt=01 Dev#= 5 Spd=12 MxCh= 0
|
||||
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=32 #Cfgs= 1
|
||||
P: Vendor=05fd ProdID=107a Rev= 1.00
|
||||
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
|
||||
I: If#= 0 Alt= 0 #EPs= 2 Cls=58(unk. ) Sub=42 Prot=00 Driver=(none)
|
||||
E: Ad=81(I) Atr=03(Int.) MxPS= 32 Ivl= 10ms
|
||||
E: Ad=02(O) Atr=03(Int.) MxPS= 32 Ivl= 10ms
|
||||
|
||||
.. code-block:: none
|
||||
:caption: dump from Redoctane Xbox Dance Pad (US)
|
||||
|
||||
T: Bus=01 Lev=02 Prnt=09 Port=00 Cnt=01 Dev#= 10 Spd=12 MxCh= 0
|
||||
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
|
||||
P: Vendor=0c12 ProdID=8809 Rev= 0.01
|
||||
S: Product=XBOX DDR
|
||||
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
|
||||
I: If#= 0 Alt= 0 #EPs= 2 Cls=58(unk. ) Sub=42 Prot=00 Driver=xpad
|
||||
E: Ad=82(I) Atr=03(Int.) MxPS= 32 Ivl=4ms
|
||||
E: Ad=02(O) Atr=03(Int.) MxPS= 32 Ivl=4ms
|
||||
|
||||
|
||||
Supported Controllers
|
||||
=====================
|
||||
|
||||
3. Supported Controllers
|
||||
------------------------
|
||||
For a full list of supported controllers and associated vendor and product
|
||||
IDs see the xpad_device[] array[6].
|
||||
IDs see the xpad_device[] array\ [4]_.
|
||||
|
||||
As of the historic version 0.0.6 (2006-10-10) the following devices
|
||||
were supported:
|
||||
were supported::
|
||||
|
||||
original Microsoft XBOX controller (US), vendor=0x045e, product=0x0202
|
||||
smaller Microsoft XBOX controller (US), vendor=0x045e, product=0x0289
|
||||
original Microsoft XBOX controller (Japan), vendor=0x045e, product=0x0285
|
||||
|
@ -152,14 +180,16 @@ the module option 'dpad_to_buttons'.
|
|||
If you have an unrecognized controller please see 0.3 - Unknown Controllers
|
||||
|
||||
|
||||
4. Manual Testing
|
||||
-----------------
|
||||
Manual Testing
|
||||
==============
|
||||
|
||||
To test this driver's functionality you may use 'jstest'.
|
||||
|
||||
For example:
|
||||
> modprobe xpad
|
||||
> modprobe joydev
|
||||
> jstest /dev/js0
|
||||
For example::
|
||||
|
||||
> modprobe xpad
|
||||
> modprobe joydev
|
||||
> jstest /dev/js0
|
||||
|
||||
If you're using a normal controller, there should be a single line showing
|
||||
18 inputs (8 axes, 10 buttons), and its values should change if you move
|
||||
|
@ -170,57 +200,34 @@ It works? Voila, you're done ;)
|
|||
|
||||
|
||||
|
||||
5. Thanks
|
||||
---------
|
||||
Thanks
|
||||
======
|
||||
|
||||
I have to thank ITO Takayuki for the detailed info on his site
|
||||
http://euc.jp/periphs/xbox-controller.ja.html.
|
||||
|
||||
http://euc.jp/periphs/xbox-controller.ja.html.
|
||||
|
||||
His useful info and both the usb-skeleton as well as the iforce input driver
|
||||
(Greg Kroah-Hartmann; Vojtech Pavlik) helped a lot in rapid prototyping
|
||||
the basic functionality.
|
||||
|
||||
|
||||
|
||||
6. References
|
||||
-------------
|
||||
References
|
||||
==========
|
||||
|
||||
[1]: http://euc.jp/periphs/xbox-controller.ja.html (ITO Takayuki)
|
||||
[2]: http://xpad.xbox-scene.com/
|
||||
[3]: http://www.markosweb.com/www/xboxhackz.com/
|
||||
[4]: /proc/bus/usb/devices - dump from InterAct PowerPad Pro (Germany):
|
||||
|
||||
T: Bus=01 Lev=03 Prnt=04 Port=00 Cnt=01 Dev#= 5 Spd=12 MxCh= 0
|
||||
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=32 #Cfgs= 1
|
||||
P: Vendor=05fd ProdID=107a Rev= 1.00
|
||||
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
|
||||
I: If#= 0 Alt= 0 #EPs= 2 Cls=58(unk. ) Sub=42 Prot=00 Driver=(none)
|
||||
E: Ad=81(I) Atr=03(Int.) MxPS= 32 Ivl= 10ms
|
||||
E: Ad=02(O) Atr=03(Int.) MxPS= 32 Ivl= 10ms
|
||||
|
||||
[5]: /proc/bus/usb/devices - dump from Redoctane Xbox Dance Pad (US):
|
||||
|
||||
T: Bus=01 Lev=02 Prnt=09 Port=00 Cnt=01 Dev#= 10 Spd=12 MxCh= 0
|
||||
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
|
||||
P: Vendor=0c12 ProdID=8809 Rev= 0.01
|
||||
S: Product=XBOX DDR
|
||||
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
|
||||
I: If#= 0 Alt= 0 #EPs= 2 Cls=58(unk. ) Sub=42 Prot=00 Driver=xpad
|
||||
E: Ad=82(I) Atr=03(Int.) MxPS= 32 Ivl=4ms
|
||||
E: Ad=02(O) Atr=03(Int.) MxPS= 32 Ivl=4ms
|
||||
|
||||
[6]: http://lxr.free-electrons.com/ident?i=xpad_device
|
||||
.. [1] http://euc.jp/periphs/xbox-controller.ja.html (ITO Takayuki)
|
||||
.. [2] http://xpad.xbox-scene.com/
|
||||
.. [3] http://www.markosweb.com/www/xboxhackz.com/
|
||||
.. [4] http://lxr.free-electrons.com/ident?i=xpad_device
|
||||
|
||||
|
||||
Historic Edits
|
||||
==============
|
||||
|
||||
7. Historic Edits
|
||||
-----------------
|
||||
Marko Friedemann <mfr@bmx-chemnitz.de>
|
||||
2002-07-16
|
||||
2002-07-16 - Marko Friedemann <mfr@bmx-chemnitz.de>
|
||||
- original doc
|
||||
|
||||
Dominic Cerquetti <binary1230@yahoo.com>
|
||||
2005-03-19
|
||||
2005-03-19 - Dominic Cerquetti <binary1230@yahoo.com>
|
||||
- added stuff for dance pads, new d-pad->axes mappings
|
||||
|
||||
Later changes may be viewed with 'git log Documentation/input/xpad.txt'
|
|
@ -1,8 +1,12 @@
|
|||
===============================================
|
||||
Driver documentation for yealink usb-p1k phones
|
||||
===============================================
|
||||
|
||||
Status
|
||||
======
|
||||
|
||||
0. Status
|
||||
~~~~~~~~~
|
||||
The p1k is a relatively cheap usb 1.1 phone with:
|
||||
|
||||
- keyboard full support, yealink.ko / input event API
|
||||
- LCD full support, yealink.ko / sysfs API
|
||||
- LED full support, yealink.ko / sysfs API
|
||||
|
@ -14,38 +18,11 @@ The p1k is a relatively cheap usb 1.1 phone with:
|
|||
For vendor documentation see http://www.yealink.com
|
||||
|
||||
|
||||
1. Compilation (stand alone version)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Currently only kernel 2.6.x.y versions are supported.
|
||||
In order to build the yealink.ko module do
|
||||
keyboard features
|
||||
=================
|
||||
|
||||
make
|
||||
|
||||
If you encounter problems please check if in the MAKE_OPTS variable in
|
||||
the Makefile is pointing to the location where your kernel sources
|
||||
are located, default /usr/src/linux.
|
||||
|
||||
|
||||
1.1 Troubleshooting
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Q: Module yealink compiled and installed without any problem but phone
|
||||
is not initialized and does not react to any actions.
|
||||
A: If you see something like:
|
||||
hiddev0: USB HID v1.00 Device [Yealink Network Technology Ltd. VOIP USB Phone
|
||||
in dmesg, it means that the hid driver has grabbed the device first. Try to
|
||||
load module yealink before any other usb hid driver. Please see the
|
||||
instructions provided by your distribution on module configuration.
|
||||
|
||||
Q: Phone is working now (displays version and accepts keypad input) but I can't
|
||||
find the sysfs files.
|
||||
A: The sysfs files are located on the particular usb endpoint. On most
|
||||
distributions you can do: "find /sys/ -name get_icons" for a hint.
|
||||
|
||||
|
||||
2. keyboard features
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
The current mapping in the kernel is provided by the map_p1k_to_key
|
||||
function:
|
||||
function::
|
||||
|
||||
Physical USB-P1K button layout input events
|
||||
|
||||
|
@ -60,14 +37,15 @@ function:
|
|||
7 8 9 7, 8, 9,
|
||||
* 0 # *, 0, #,
|
||||
|
||||
The "up" and "down" keys, are symbolised by arrows on the button.
|
||||
The "pickup" and "hangup" keys are symbolised by a green and red phone
|
||||
on the button.
|
||||
The "up" and "down" keys, are symbolised by arrows on the button.
|
||||
The "pickup" and "hangup" keys are symbolised by a green and red phone
|
||||
on the button.
|
||||
|
||||
|
||||
3. LCD features
|
||||
~~~~~~~~~~~~~~~
|
||||
The LCD is divided and organised as a 3 line display:
|
||||
LCD features
|
||||
============
|
||||
|
||||
The LCD is divided and organised as a 3 line display::
|
||||
|
||||
|[] [][] [][] [][] in |[][]
|
||||
|[] M [][] D [][] : [][] out |[][]
|
||||
|
@ -79,18 +57,19 @@ The LCD is divided and organised as a 3 line display:
|
|||
[] [] [] [] [] [] [] [] [] [] [] []
|
||||
|
||||
|
||||
Line 1 Format (see below) : 18.e8.M8.88...188
|
||||
Icon names : M D : IN OUT STORE
|
||||
Line 2 Format : .........
|
||||
Icon name : NEW REP SU MO TU WE TH FR SA
|
||||
Line 3 Format : 888888888888
|
||||
Line 1 Format (see below) : 18.e8.M8.88...188
|
||||
Icon names : M D : IN OUT STORE
|
||||
Line 2 Format : .........
|
||||
Icon name : NEW REP SU MO TU WE TH FR SA
|
||||
Line 3 Format : 888888888888
|
||||
|
||||
|
||||
Format description:
|
||||
From a userspace perspective the world is separated into "digits" and "icons".
|
||||
A digit can have a character set, an icon can only be ON or OFF.
|
||||
|
||||
Format specifier
|
||||
Format specifier::
|
||||
|
||||
'8' : Generic 7 segment digit with individual addressable segments
|
||||
|
||||
Reduced capability 7 segment digit, when segments are hard wired together.
|
||||
|
@ -105,9 +84,11 @@ Format description:
|
|||
elements.
|
||||
|
||||
|
||||
4. Driver usage
|
||||
~~~~~~~~~~~~~~~
|
||||
For userland the following interfaces are available using the sysfs interface:
|
||||
Driver usage
|
||||
============
|
||||
|
||||
For userland the following interfaces are available using the sysfs interface::
|
||||
|
||||
/sys/.../
|
||||
line1 Read/Write, lcd line1
|
||||
line2 Read/Write, lcd line2
|
||||
|
@ -118,38 +99,43 @@ For userland the following interfaces are available using the sysfs interface:
|
|||
show_icon Write, display the element by writing the icon name.
|
||||
|
||||
map_seg7 Read/Write, the 7 segments char set, common for all
|
||||
yealink phones. (see map_to_7segment.h)
|
||||
yealink phones. (see map_to_7segment.h)
|
||||
|
||||
ringtone Write, upload binary representation of a ringtone,
|
||||
see yealink.c. status EXPERIMENTAL due to potential
|
||||
see yealink.c. status EXPERIMENTAL due to potential
|
||||
races between async. and sync usb calls.
|
||||
|
||||
|
||||
4.1 lineX
|
||||
~~~~~~~~~
|
||||
Reading /sys/../lineX will return the format string with its current value:
|
||||
lineX
|
||||
~~~~~
|
||||
|
||||
Example:
|
||||
cat ./line3
|
||||
888888888888
|
||||
Linux Rocks!
|
||||
Reading /sys/../lineX will return the format string with its current value.
|
||||
|
||||
Example::
|
||||
|
||||
cat ./line3
|
||||
888888888888
|
||||
Linux Rocks!
|
||||
|
||||
Writing to /sys/../lineX will set the corresponding LCD line.
|
||||
|
||||
- Excess characters are ignored.
|
||||
- If less characters are written than allowed, the remaining digits are
|
||||
unchanged.
|
||||
- The tab '\t'and '\n' char does not overwrite the original content.
|
||||
- Writing a space to an icon will always hide its content.
|
||||
|
||||
Example:
|
||||
date +"%m.%e.%k:%M" | sed 's/^0/ /' > ./line1
|
||||
Example::
|
||||
|
||||
date +"%m.%e.%k:%M" | sed 's/^0/ /' > ./line1
|
||||
|
||||
Will update the LCD with the current date & time.
|
||||
|
||||
|
||||
4.2 get_icons
|
||||
~~~~~~~~~~~~~
|
||||
Reading will return all available icon names and its current settings:
|
||||
get_icons
|
||||
~~~~~~~~~
|
||||
|
||||
Reading will return all available icon names and its current settings::
|
||||
|
||||
cat ./get_icons
|
||||
on M
|
||||
|
@ -172,45 +158,68 @@ Reading will return all available icon names and its current settings:
|
|||
RINGTONE
|
||||
|
||||
|
||||
4.3 show/hide icons
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
show/hide icons
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Writing to these files will update the state of the icon.
|
||||
Only one icon at a time can be updated.
|
||||
|
||||
If an icon is also on a ./lineX the corresponding value is
|
||||
updated with the first letter of the icon.
|
||||
|
||||
Example - light up the store icon:
|
||||
echo -n "STORE" > ./show_icon
|
||||
Example - light up the store icon::
|
||||
|
||||
cat ./line1
|
||||
18.e8.M8.88...188
|
||||
S
|
||||
echo -n "STORE" > ./show_icon
|
||||
|
||||
Example - sound the ringtone for 10 seconds:
|
||||
echo -n RINGTONE > /sys/..../show_icon
|
||||
sleep 10
|
||||
echo -n RINGTONE > /sys/..../hide_icon
|
||||
cat ./line1
|
||||
18.e8.M8.88...188
|
||||
S
|
||||
|
||||
Example - sound the ringtone for 10 seconds::
|
||||
|
||||
echo -n RINGTONE > /sys/..../show_icon
|
||||
sleep 10
|
||||
echo -n RINGTONE > /sys/..../hide_icon
|
||||
|
||||
|
||||
5. Sound features
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Sound features
|
||||
==============
|
||||
|
||||
Sound is supported by the ALSA driver: snd_usb_audio
|
||||
|
||||
One 16-bit channel with sample and playback rates of 8000 Hz is the practical
|
||||
limit of the device.
|
||||
|
||||
Example - recording test:
|
||||
arecord -v -d 10 -r 8000 -f S16_LE -t wav foobar.wav
|
||||
Example - recording test::
|
||||
|
||||
Example - playback test:
|
||||
aplay foobar.wav
|
||||
arecord -v -d 10 -r 8000 -f S16_LE -t wav foobar.wav
|
||||
|
||||
Example - playback test::
|
||||
|
||||
aplay foobar.wav
|
||||
|
||||
|
||||
6. Credits & Acknowledgments
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Troubleshooting
|
||||
===============
|
||||
|
||||
:Q: Module yealink compiled and installed without any problem but phone
|
||||
is not initialized and does not react to any actions.
|
||||
:A: If you see something like:
|
||||
hiddev0: USB HID v1.00 Device [Yealink Network Technology Ltd. VOIP USB Phone
|
||||
in dmesg, it means that the hid driver has grabbed the device first. Try to
|
||||
load module yealink before any other usb hid driver. Please see the
|
||||
instructions provided by your distribution on module configuration.
|
||||
|
||||
:Q: Phone is working now (displays version and accepts keypad input) but I can't
|
||||
find the sysfs files.
|
||||
:A: The sysfs files are located on the particular usb endpoint. On most
|
||||
distributions you can do: "find /sys/ -name get_icons" for a hint.
|
||||
|
||||
|
||||
Credits & Acknowledgments
|
||||
=========================
|
||||
|
||||
- Olivier Vandorpe, for starting the usbb2k-api project doing much of
|
||||
the reverse engineering.
|
||||
the reverse engineering.
|
||||
- Martin Diehl, for pointing out how to handle USB memory allocation.
|
||||
- Dmitry Torokhov, for the numerous code reviews and suggestions.
|
||||
|
|
@ -1,3 +1,10 @@
|
|||
.. _input-event-codes:
|
||||
|
||||
=================
|
||||
Input event codes
|
||||
=================
|
||||
|
||||
|
||||
The input protocol uses a map of types and codes to express input device values
|
||||
to userspace. This document describes the types and codes and how and when they
|
||||
may be used.
|
||||
|
@ -17,82 +24,102 @@ reports supported by a device are also provided by sysfs in
|
|||
class/input/event*/device/capabilities/, and the properties of a device are
|
||||
provided in class/input/event*/device/properties.
|
||||
|
||||
Event types:
|
||||
Event types
|
||||
===========
|
||||
|
||||
Event types are groupings of codes under a logical input construct. Each
|
||||
type has a set of applicable codes to be used in generating events. See the
|
||||
Codes section for details on valid codes for each type.
|
||||
|
||||
* EV_SYN:
|
||||
|
||||
- Used as markers to separate events. Events may be separated in time or in
|
||||
space, such as with the multitouch protocol.
|
||||
|
||||
* EV_KEY:
|
||||
|
||||
- Used to describe state changes of keyboards, buttons, or other key-like
|
||||
devices.
|
||||
|
||||
* EV_REL:
|
||||
|
||||
- Used to describe relative axis value changes, e.g. moving the mouse 5 units
|
||||
to the left.
|
||||
|
||||
* EV_ABS:
|
||||
|
||||
- Used to describe absolute axis value changes, e.g. describing the
|
||||
coordinates of a touch on a touchscreen.
|
||||
|
||||
* EV_MSC:
|
||||
|
||||
- Used to describe miscellaneous input data that do not fit into other types.
|
||||
|
||||
* EV_SW:
|
||||
|
||||
- Used to describe binary state input switches.
|
||||
|
||||
* EV_LED:
|
||||
|
||||
- Used to turn LEDs on devices on and off.
|
||||
|
||||
* EV_SND:
|
||||
|
||||
- Used to output sound to devices.
|
||||
|
||||
* EV_REP:
|
||||
|
||||
- Used for autorepeating devices.
|
||||
|
||||
* EV_FF:
|
||||
|
||||
- Used to send force feedback commands to an input device.
|
||||
|
||||
* EV_PWR:
|
||||
|
||||
- A special type for power button and switch input.
|
||||
|
||||
* EV_FF_STATUS:
|
||||
|
||||
- Used to receive force feedback device status.
|
||||
|
||||
Event codes:
|
||||
Event codes
|
||||
===========
|
||||
|
||||
Event codes define the precise type of event.
|
||||
|
||||
EV_SYN:
|
||||
----------
|
||||
EV_SYN
|
||||
------
|
||||
|
||||
EV_SYN event values are undefined. Their usage is defined only by when they are
|
||||
sent in the evdev event stream.
|
||||
|
||||
* SYN_REPORT:
|
||||
|
||||
- Used to synchronize and separate events into packets of input data changes
|
||||
occurring at the same moment in time. For example, motion of a mouse may set
|
||||
the REL_X and REL_Y values for one motion, then emit a SYN_REPORT. The next
|
||||
motion will emit more REL_X and REL_Y values and send another SYN_REPORT.
|
||||
|
||||
* SYN_CONFIG:
|
||||
|
||||
- TBD
|
||||
|
||||
* SYN_MT_REPORT:
|
||||
|
||||
- Used to synchronize and separate touch events. See the
|
||||
multi-touch-protocol.txt document for more information.
|
||||
|
||||
* SYN_DROPPED:
|
||||
|
||||
- Used to indicate buffer overrun in the evdev client's event queue.
|
||||
Client should ignore all events up to and including next SYN_REPORT
|
||||
event and query the device (using EVIOCG* ioctls) to obtain its
|
||||
current state.
|
||||
|
||||
EV_KEY:
|
||||
----------
|
||||
EV_KEY
|
||||
------
|
||||
|
||||
EV_KEY events take the form KEY_<name> or BTN_<name>. For example, KEY_A is used
|
||||
to represent the 'A' key on a keyboard. When a key is depressed, an event with
|
||||
the key's code is emitted with value 1. When the key is released, an event is
|
||||
|
@ -103,6 +130,7 @@ BTN_<name> is used for other types of momentary switch events.
|
|||
A few EV_KEY codes have special meanings:
|
||||
|
||||
* BTN_TOOL_<name>:
|
||||
|
||||
- These codes are used in conjunction with input trackpads, tablets, and
|
||||
touchscreens. These devices may be used with fingers, pens, or other tools.
|
||||
When an event occurs and a tool is used, the corresponding BTN_TOOL_<name>
|
||||
|
@ -112,6 +140,7 @@ A few EV_KEY codes have special meanings:
|
|||
code when events are generated.
|
||||
|
||||
* BTN_TOUCH:
|
||||
|
||||
BTN_TOUCH is used for touch contact. While an input tool is determined to be
|
||||
within meaningful physical contact, the value of this property must be set
|
||||
to 1. Meaningful physical contact may mean any contact, or it may mean
|
||||
|
@ -132,6 +161,7 @@ future, this distinction will be deprecated and the device properties ioctl
|
|||
EVIOCGPROP, defined in linux/input.h, will be used to convey the device type.
|
||||
|
||||
* BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP:
|
||||
|
||||
- These codes denote one, two, three, and four finger interaction on a
|
||||
trackpad or touchscreen. For example, if the user uses two fingers and moves
|
||||
them on the touchpad in an effort to scroll content on screen,
|
||||
|
@ -147,8 +177,9 @@ a value of 1 in the same synchronization frame. This usage is deprecated.
|
|||
Note: In multitouch drivers, the input_mt_report_finger_count() function should
|
||||
be used to emit these codes. Please see multi-touch-protocol.txt for details.
|
||||
|
||||
EV_REL:
|
||||
----------
|
||||
EV_REL
|
||||
------
|
||||
|
||||
EV_REL events describe relative changes in a property. For example, a mouse may
|
||||
move to the left by a certain number of units, but its absolute position in
|
||||
space is unknown. If the absolute position is known, EV_ABS codes should be used
|
||||
|
@ -157,17 +188,20 @@ instead of EV_REL codes.
|
|||
A few EV_REL codes have special meanings:
|
||||
|
||||
* REL_WHEEL, REL_HWHEEL:
|
||||
|
||||
- These codes are used for vertical and horizontal scroll wheels,
|
||||
respectively.
|
||||
|
||||
EV_ABS:
|
||||
----------
|
||||
EV_ABS
|
||||
------
|
||||
|
||||
EV_ABS events describe absolute changes in a property. For example, a touchpad
|
||||
may emit coordinates for a touch location.
|
||||
|
||||
A few EV_ABS codes have special meanings:
|
||||
|
||||
* ABS_DISTANCE:
|
||||
|
||||
- Used to describe the distance of a tool from an interaction surface. This
|
||||
event should only be emitted while the tool is hovering, meaning in close
|
||||
proximity of the device and while the value of the BTN_TOUCH code is 0. If
|
||||
|
@ -179,11 +213,13 @@ A few EV_ABS codes have special meanings:
|
|||
hardware and is otherwise independent of ABS_DISTANCE and/or BTN_TOUCH.
|
||||
|
||||
* ABS_MT_<name>:
|
||||
|
||||
- Used to describe multitouch input events. Please see
|
||||
multi-touch-protocol.txt for details.
|
||||
|
||||
EV_SW:
|
||||
----------
|
||||
EV_SW
|
||||
-----
|
||||
|
||||
EV_SW events describe stateful binary switches. For example, the SW_LID code is
|
||||
used to denote when a laptop lid is closed.
|
||||
|
||||
|
@ -195,14 +231,16 @@ Upon resume, if the switch state is the same as before suspend, then the input
|
|||
subsystem will filter out the duplicate switch state reports. The driver does
|
||||
not need to keep the state of the switch at any time.
|
||||
|
||||
EV_MSC:
|
||||
----------
|
||||
EV_MSC
|
||||
------
|
||||
|
||||
EV_MSC events are used for input and output events that do not fall under other
|
||||
categories.
|
||||
|
||||
A few EV_MSC codes have special meaning:
|
||||
|
||||
* MSC_TIMESTAMP:
|
||||
|
||||
- Used to report the number of microseconds since the last reset. This event
|
||||
should be coded as an uint32 value, which is allowed to wrap around with
|
||||
no special consequence. It is assumed that the time difference between two
|
||||
|
@ -211,39 +249,46 @@ A few EV_MSC codes have special meaning:
|
|||
unknown. If the device does not provide this information, the driver must
|
||||
not provide it to user space.
|
||||
|
||||
EV_LED:
|
||||
----------
|
||||
EV_LED
|
||||
------
|
||||
|
||||
EV_LED events are used for input and output to set and query the state of
|
||||
various LEDs on devices.
|
||||
|
||||
EV_REP:
|
||||
----------
|
||||
EV_REP
|
||||
------
|
||||
|
||||
EV_REP events are used for specifying autorepeating events.
|
||||
|
||||
EV_SND:
|
||||
----------
|
||||
EV_SND
|
||||
------
|
||||
|
||||
EV_SND events are used for sending sound commands to simple sound output
|
||||
devices.
|
||||
|
||||
EV_FF:
|
||||
----------
|
||||
EV_FF
|
||||
-----
|
||||
|
||||
EV_FF events are used to initialize a force feedback capable device and to cause
|
||||
such device to feedback.
|
||||
|
||||
EV_PWR:
|
||||
----------
|
||||
EV_PWR
|
||||
------
|
||||
|
||||
EV_PWR events are a special type of event used specifically for power
|
||||
management. Its usage is not well defined. To be addressed later.
|
||||
|
||||
Device properties:
|
||||
Device properties
|
||||
=================
|
||||
|
||||
Normally, userspace sets up an input device based on the data it emits,
|
||||
i.e., the event types. In the case of two devices emitting the same event
|
||||
types, additional information can be provided in the form of device
|
||||
properties.
|
||||
|
||||
INPUT_PROP_DIRECT + INPUT_PROP_POINTER:
|
||||
INPUT_PROP_DIRECT + INPUT_PROP_POINTER
|
||||
--------------------------------------
|
||||
|
||||
The INPUT_PROP_DIRECT property indicates that device coordinates should be
|
||||
directly mapped to screen coordinates (not taking into account trivial
|
||||
transformations, such as scaling, flipping and rotating). Non-direct input
|
||||
|
@ -260,8 +305,9 @@ If neither INPUT_PROP_DIRECT or INPUT_PROP_POINTER are set, the property is
|
|||
considered undefined and the device type should be deduced in the
|
||||
traditional way, using emitted event types.
|
||||
|
||||
INPUT_PROP_BUTTONPAD:
|
||||
INPUT_PROP_BUTTONPAD
|
||||
--------------------
|
||||
|
||||
For touchpads where the button is placed beneath the surface, such that
|
||||
pressing down on the pad causes a button click, this property should be
|
||||
set. Common in clickpad notebooks and macbooks from 2009 and onwards.
|
||||
|
@ -270,8 +316,9 @@ Originally, the buttonpad property was coded into the bcm5974 driver
|
|||
version field under the name integrated button. For backwards
|
||||
compatibility, both methods need to be checked in userspace.
|
||||
|
||||
INPUT_PROP_SEMI_MT:
|
||||
INPUT_PROP_SEMI_MT
|
||||
------------------
|
||||
|
||||
Some touchpads, most common between 2008 and 2011, can detect the presence
|
||||
of multiple contacts without resolving the individual positions; only the
|
||||
number of contacts and a rectangular shape is known. For such
|
||||
|
@ -285,9 +332,10 @@ gestures can normally be extracted from it.
|
|||
If INPUT_PROP_SEMI_MT is not set, the device is assumed to be a true MT
|
||||
device.
|
||||
|
||||
INPUT_PROP_TOPBUTTONPAD:
|
||||
INPUT_PROP_TOPBUTTONPAD
|
||||
-----------------------
|
||||
Some laptops, most notably the Lenovo *40 series provide a trackstick
|
||||
|
||||
Some laptops, most notably the Lenovo 40 series provide a trackstick
|
||||
device but do not have physical buttons associated with the trackstick
|
||||
device. Instead, the top area of the touchpad is marked to show
|
||||
visual/haptic areas for left, middle, right buttons intended to be used
|
||||
|
@ -299,7 +347,8 @@ The kernel does not provide button emulation for such devices but treats
|
|||
them as any other INPUT_PROP_BUTTONPAD device.
|
||||
|
||||
INPUT_PROP_ACCELEROMETER
|
||||
-------------------------
|
||||
------------------------
|
||||
|
||||
Directional axes on this device (absolute and/or relative x, y, z) represent
|
||||
accelerometer data. Some devices also report gyroscope data, which devices
|
||||
can report through the rotational axes (absolute and/or relative rx, ry, rz).
|
||||
|
@ -307,21 +356,24 @@ can report through the rotational axes (absolute and/or relative rx, ry, rz).
|
|||
All other axes retain their meaning. A device must not mix
|
||||
regular directional axes and accelerometer axes on the same event node.
|
||||
|
||||
Guidelines:
|
||||
Guidelines
|
||||
==========
|
||||
|
||||
The guidelines below ensure proper single-touch and multi-finger functionality.
|
||||
For multi-touch functionality, see the multi-touch-protocol.txt document for
|
||||
more information.
|
||||
|
||||
Mice:
|
||||
----------
|
||||
Mice
|
||||
----
|
||||
|
||||
REL_{X,Y} must be reported when the mouse moves. BTN_LEFT must be used to report
|
||||
the primary button press. BTN_{MIDDLE,RIGHT,4,5,etc.} should be used to report
|
||||
further buttons of the device. REL_WHEEL and REL_HWHEEL should be used to report
|
||||
scroll wheel events where available.
|
||||
|
||||
Touchscreens:
|
||||
----------
|
||||
Touchscreens
|
||||
------------
|
||||
|
||||
ABS_{X,Y} must be reported with the location of the touch. BTN_TOUCH must be
|
||||
used to report when a touch is active on the screen.
|
||||
BTN_{MOUSE,LEFT,MIDDLE,RIGHT} must not be reported as the result of touch
|
||||
|
@ -329,8 +381,9 @@ contact. BTN_TOOL_<name> events should be reported where possible.
|
|||
|
||||
For new hardware, INPUT_PROP_DIRECT should be set.
|
||||
|
||||
Trackpads:
|
||||
----------
|
||||
Trackpads
|
||||
---------
|
||||
|
||||
Legacy trackpads that only provide relative position information must report
|
||||
events like mice described above.
|
||||
|
||||
|
@ -341,8 +394,9 @@ be used to report the number of touches active on the trackpad.
|
|||
|
||||
For new hardware, INPUT_PROP_POINTER should be set.
|
||||
|
||||
Tablets:
|
||||
----------
|
||||
Tablets
|
||||
-------
|
||||
|
||||
BTN_TOOL_<name> events must be reported when a stylus or other tool is active on
|
||||
the tablet. ABS_{X,Y} must be reported with the location of the tool. BTN_TOUCH
|
||||
should be used to report when the tool is in contact with the tablet.
|
|
@ -1,12 +1,16 @@
|
|||
Force feedback for Linux.
|
||||
By Johann Deneux <johann.deneux@gmail.com> on 2001/04/22.
|
||||
Updated by Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
|
||||
You may redistribute this file. Please remember to include shape.fig and
|
||||
interactive.fig as well.
|
||||
----------------------------------------------------------------------------
|
||||
========================
|
||||
Force feedback for Linux
|
||||
========================
|
||||
|
||||
:Author: Johann Deneux <johann.deneux@gmail.com> on 2001/04/22.
|
||||
:Updated: Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
|
||||
|
||||
You may redistribute this file. Please remember to include shape.svg and
|
||||
interactive.svg as well.
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
|
||||
1. Introduction
|
||||
~~~~~~~~~~~~~~~
|
||||
This document describes how to use force feedback devices under Linux. The
|
||||
goal is not to support these devices as if they were simple input-only devices
|
||||
(as it is already the case), but to really enable the rendering of force
|
||||
|
@ -15,8 +19,9 @@ This document only describes the force feedback part of the Linux input
|
|||
interface. Please read joystick.txt and input.txt before reading further this
|
||||
document.
|
||||
|
||||
2. Instructions to the user
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Instructions to the user
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To enable force feedback, you have to:
|
||||
|
||||
1. have your kernel configured with evdev and a driver that supports your
|
||||
|
@ -33,39 +38,48 @@ something goes wrong.
|
|||
If you have a serial iforce device, you need to start inputattach. See
|
||||
joystick.txt for details.
|
||||
|
||||
2.1 Does it work ?
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
There is an utility called fftest that will allow you to test the driver.
|
||||
% fftest /dev/input/eventXX
|
||||
Does it work ?
|
||||
--------------
|
||||
|
||||
There is an utility called fftest that will allow you to test the driver::
|
||||
|
||||
% fftest /dev/input/eventXX
|
||||
|
||||
Instructions to the developer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
3. Instructions to the developer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
All interactions are done using the event API. That is, you can use ioctl()
|
||||
and write() on /dev/input/eventXX.
|
||||
This information is subject to change.
|
||||
|
||||
3.1 Querying device capabilities
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#include <linux/input.h>
|
||||
#include <sys/ioctl.h>
|
||||
Querying device capabilities
|
||||
----------------------------
|
||||
|
||||
#define BITS_TO_LONGS(x) \
|
||||
(((x) + 8 * sizeof (unsigned long) - 1) / (8 * sizeof (unsigned long)))
|
||||
unsigned long features[BITS_TO_LONGS(FF_CNT)];
|
||||
int ioctl(int file_descriptor, int request, unsigned long *features);
|
||||
::
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#define BITS_TO_LONGS(x) \
|
||||
(((x) + 8 * sizeof (unsigned long) - 1) / (8 * sizeof (unsigned long)))
|
||||
unsigned long features[BITS_TO_LONGS(FF_CNT)];
|
||||
int ioctl(int file_descriptor, int request, unsigned long *features);
|
||||
|
||||
"request" must be EVIOCGBIT(EV_FF, size of features array in bytes )
|
||||
|
||||
Returns the features supported by the device. features is a bitfield with the
|
||||
following bits:
|
||||
|
||||
- FF_CONSTANT can render constant force effects
|
||||
- FF_PERIODIC can render periodic effects with the following waveforms:
|
||||
|
||||
- FF_SQUARE square waveform
|
||||
- FF_TRIANGLE triangle waveform
|
||||
- FF_SINE sine waveform
|
||||
- FF_SAW_UP sawtooth up waveform
|
||||
- FF_SAW_DOWN sawtooth down waveform
|
||||
- FF_CUSTOM custom waveform
|
||||
|
||||
- FF_RAMP can render ramp effects
|
||||
- FF_SPRING can simulate the presence of a spring
|
||||
- FF_FRICTION can simulate friction
|
||||
|
@ -75,24 +89,30 @@ following bits:
|
|||
- FF_GAIN gain is adjustable
|
||||
- FF_AUTOCENTER autocenter is adjustable
|
||||
|
||||
Note: In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All
|
||||
.. note::
|
||||
|
||||
- In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All
|
||||
devices that support FF_RUMBLE support FF_PERIODIC (square, triangle,
|
||||
sine) and the other way around.
|
||||
|
||||
Note: The exact syntax FF_CUSTOM is undefined for the time being as no driver
|
||||
- The exact syntax FF_CUSTOM is undefined for the time being as no driver
|
||||
supports it yet.
|
||||
|
||||
::
|
||||
|
||||
int ioctl(int fd, EVIOCGEFFECTS, int *n);
|
||||
int ioctl(int fd, EVIOCGEFFECTS, int *n);
|
||||
|
||||
Returns the number of effects the device can keep in its memory.
|
||||
|
||||
3.2 Uploading effects to the device
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#include <linux/input.h>
|
||||
#include <sys/ioctl.h>
|
||||
Uploading effects to the device
|
||||
-------------------------------
|
||||
|
||||
int ioctl(int file_descriptor, int request, struct ff_effect *effect);
|
||||
::
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
int ioctl(int file_descriptor, int request, struct ff_effect *effect);
|
||||
|
||||
"request" must be EVIOCSFF.
|
||||
|
||||
|
@ -106,38 +126,53 @@ allocate a new effect.
|
|||
|
||||
Effects are file descriptor specific.
|
||||
|
||||
See <uapi/linux/input.h> for a description of the ff_effect struct. You should
|
||||
also find help in a few sketches, contained in files shape.fig and
|
||||
interactive.fig. You need xfig to visualize these files.
|
||||
See <uapi/linux/input.h> for a description of the ff_effect struct. You
|
||||
should also find help in a few sketches, contained in files shape.svg
|
||||
and interactive.svg:
|
||||
|
||||
3.3 Removing an effect from the device
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
int ioctl(int fd, EVIOCRMFF, effect.id);
|
||||
.. figure:: shape.svg
|
||||
|
||||
Shape
|
||||
|
||||
.. figure:: interactive.svg
|
||||
|
||||
Interactive
|
||||
|
||||
|
||||
Removing an effect from the device
|
||||
----------------------------------
|
||||
|
||||
::
|
||||
|
||||
int ioctl(int fd, EVIOCRMFF, effect.id);
|
||||
|
||||
This makes room for new effects in the device's memory. Note that this also
|
||||
stops the effect if it was playing.
|
||||
|
||||
3.4 Controlling the playback of effects
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Controlling the playback of effects
|
||||
-----------------------------------
|
||||
|
||||
Control of playing is done with write(). Below is an example:
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <unistd.h>
|
||||
::
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct input_event play;
|
||||
struct input_event stop;
|
||||
struct ff_effect effect;
|
||||
int fd;
|
||||
...
|
||||
...
|
||||
fd = open("/dev/input/eventXX", O_RDWR);
|
||||
...
|
||||
...
|
||||
/* Play three times */
|
||||
play.type = EV_FF;
|
||||
play.code = effect.id;
|
||||
play.value = 3;
|
||||
|
||||
write(fd, (const void*) &play, sizeof(play));
|
||||
...
|
||||
...
|
||||
/* Stop an effect */
|
||||
stop.type = EV_FF;
|
||||
stop.code = effect.id;
|
||||
|
@ -145,43 +180,50 @@ Control of playing is done with write(). Below is an example:
|
|||
|
||||
write(fd, (const void*) &play, sizeof(stop));
|
||||
|
||||
3.5 Setting the gain
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
Setting the gain
|
||||
----------------
|
||||
|
||||
Not all devices have the same strength. Therefore, users should set a gain
|
||||
factor depending on how strong they want effects to be. This setting is
|
||||
persistent across access to the driver.
|
||||
|
||||
/* Set the gain of the device
|
||||
int gain; /* between 0 and 100 */
|
||||
struct input_event ie; /* structure used to communicate with the driver */
|
||||
::
|
||||
|
||||
ie.type = EV_FF;
|
||||
ie.code = FF_GAIN;
|
||||
ie.value = 0xFFFFUL * gain / 100;
|
||||
/* Set the gain of the device
|
||||
int gain; /* between 0 and 100 */
|
||||
struct input_event ie; /* structure used to communicate with the driver */
|
||||
|
||||
if (write(fd, &ie, sizeof(ie)) == -1)
|
||||
ie.type = EV_FF;
|
||||
ie.code = FF_GAIN;
|
||||
ie.value = 0xFFFFUL * gain / 100;
|
||||
|
||||
if (write(fd, &ie, sizeof(ie)) == -1)
|
||||
perror("set gain");
|
||||
|
||||
3.6 Enabling/Disabling autocenter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Enabling/Disabling autocenter
|
||||
-----------------------------
|
||||
|
||||
The autocenter feature quite disturbs the rendering of effects in my opinion,
|
||||
and I think it should be an effect, which computation depends on the game
|
||||
type. But you can enable it if you want.
|
||||
|
||||
int autocenter; /* between 0 and 100 */
|
||||
struct input_event ie;
|
||||
::
|
||||
|
||||
ie.type = EV_FF;
|
||||
ie.code = FF_AUTOCENTER;
|
||||
ie.value = 0xFFFFUL * autocenter / 100;
|
||||
int autocenter; /* between 0 and 100 */
|
||||
struct input_event ie;
|
||||
|
||||
if (write(fd, &ie, sizeof(ie)) == -1)
|
||||
ie.type = EV_FF;
|
||||
ie.code = FF_AUTOCENTER;
|
||||
ie.value = 0xFFFFUL * autocenter / 100;
|
||||
|
||||
if (write(fd, &ie, sizeof(ie)) == -1)
|
||||
perror("set auto-center");
|
||||
|
||||
A value of 0 means "no auto-center".
|
||||
|
||||
3.7 Dynamic update of an effect
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Dynamic update of an effect
|
||||
---------------------------
|
||||
|
||||
Proceed as if you wanted to upload a new effect, except that instead of
|
||||
setting the id field to -1, you set it to the wanted effect id.
|
||||
Normally, the effect is not stopped and restarted. However, depending on the
|
||||
|
@ -192,30 +234,32 @@ case, the driver stops the effect, up-load it, and restart it.
|
|||
Therefore it is recommended to dynamically change direction while the effect
|
||||
is playing only when it is ok to restart the effect with a replay count of 1.
|
||||
|
||||
3.8 Information about the status of effects
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Information about the status of effects
|
||||
---------------------------------------
|
||||
|
||||
Every time the status of an effect is changed, an event is sent. The values
|
||||
and meanings of the fields of the event are as follows:
|
||||
and meanings of the fields of the event are as follows::
|
||||
|
||||
struct input_event {
|
||||
/* When the status of the effect changed */
|
||||
struct timeval time;
|
||||
struct input_event {
|
||||
/* When the status of the effect changed */
|
||||
struct timeval time;
|
||||
|
||||
/* Set to EV_FF_STATUS */
|
||||
unsigned short type;
|
||||
/* Set to EV_FF_STATUS */
|
||||
unsigned short type;
|
||||
|
||||
/* Contains the id of the effect */
|
||||
unsigned short code;
|
||||
/* Contains the id of the effect */
|
||||
unsigned short code;
|
||||
|
||||
/* Indicates the status */
|
||||
unsigned int value;
|
||||
};
|
||||
/* Indicates the status */
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
FF_STATUS_STOPPED The effect stopped playing
|
||||
FF_STATUS_PLAYING The effect started to play
|
||||
FF_STATUS_STOPPED The effect stopped playing
|
||||
FF_STATUS_PLAYING The effect started to play
|
||||
|
||||
NOTE: Status feedback is only supported by iforce driver. If you have
|
||||
.. note::
|
||||
|
||||
- Status feedback is only supported by iforce driver. If you have
|
||||
a really good reason to use this, please contact
|
||||
linux-joystick@atrey.karlin.mff.cuni.cz or anssi.hannula@gmail.com
|
||||
so that support for it can be added to the rest of the drivers.
|
||||
|
|
@ -1,15 +1,19 @@
|
|||
Linux Gamepad API
|
||||
----------------------------------------------------------------------------
|
||||
---------------------------
|
||||
Linux Gamepad Specification
|
||||
---------------------------
|
||||
|
||||
1. Intro
|
||||
~~~~~~~~
|
||||
:Author: 2013 by David Herrmann <dh.herrmann@gmail.com>
|
||||
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
Linux provides many different input drivers for gamepad hardware. To avoid
|
||||
having user-space deal with different button-mappings for each gamepad, this
|
||||
document defines how gamepads are supposed to report their data.
|
||||
|
||||
2. Geometry
|
||||
~~~~~~~~~~~
|
||||
As "gamepad" we define devices which roughly look like this:
|
||||
Geometry
|
||||
~~~~~~~~
|
||||
As "gamepad" we define devices which roughly look like this::
|
||||
|
||||
____________________________ __
|
||||
/ [__ZL__] [__ZR__] \ |
|
||||
|
@ -35,6 +39,7 @@ As "gamepad" we define devices which roughly look like this:
|
|||
Menu Pad
|
||||
|
||||
Most gamepads have the following features:
|
||||
|
||||
- Action-Pad
|
||||
4 buttons in diamonds-shape (on the right side). The buttons are
|
||||
differently labeled on most devices so we define them as NORTH,
|
||||
|
@ -58,8 +63,9 @@ Most gamepads have the following features:
|
|||
Many devices provide force-feedback features. But are mostly just
|
||||
simple rumble motors.
|
||||
|
||||
3. Detection
|
||||
~~~~~~~~~~~~
|
||||
Detection
|
||||
~~~~~~~~~
|
||||
|
||||
All gamepads that follow the protocol described here map BTN_GAMEPAD. This is
|
||||
an alias for BTN_SOUTH/BTN_A. It can be used to identify a gamepad as such.
|
||||
However, not all gamepads provide all features, so you need to test for all
|
||||
|
@ -85,75 +91,101 @@ devices that report a small subset of the events.
|
|||
No other devices, that do not look/feel like a gamepad, shall report these
|
||||
events.
|
||||
|
||||
4. Events
|
||||
~~~~~~~~~
|
||||
Events
|
||||
~~~~~~
|
||||
|
||||
Gamepads report the following events:
|
||||
|
||||
Action-Pad:
|
||||
- Action-Pad:
|
||||
|
||||
Every gamepad device has at least 2 action buttons. This means, that every
|
||||
device reports BTN_SOUTH (which BTN_GAMEPAD is an alias for). Regardless
|
||||
of the labels on the buttons, the codes are sent according to the
|
||||
physical position of the buttons.
|
||||
|
||||
Please note that 2- and 3-button pads are fairly rare and old. You might
|
||||
want to filter gamepads that do not report all four.
|
||||
2-Button Pad:
|
||||
|
||||
- 2-Button Pad:
|
||||
|
||||
If only 2 action-buttons are present, they are reported as BTN_SOUTH and
|
||||
BTN_EAST. For vertical layouts, the upper button is BTN_EAST. For
|
||||
horizontal layouts, the button more on the right is BTN_EAST.
|
||||
3-Button Pad:
|
||||
|
||||
- 3-Button Pad:
|
||||
|
||||
If only 3 action-buttons are present, they are reported as (from left
|
||||
to right): BTN_WEST, BTN_SOUTH, BTN_EAST
|
||||
If the buttons are aligned perfectly vertically, they are reported as
|
||||
(from top down): BTN_WEST, BTN_SOUTH, BTN_EAST
|
||||
4-Button Pad:
|
||||
|
||||
- 4-Button Pad:
|
||||
|
||||
If all 4 action-buttons are present, they can be aligned in two
|
||||
different formations. If diamond-shaped, they are reported as BTN_NORTH,
|
||||
BTN_WEST, BTN_SOUTH, BTN_EAST according to their physical location.
|
||||
If rectangular-shaped, the upper-left button is BTN_NORTH, lower-left
|
||||
is BTN_WEST, lower-right is BTN_SOUTH and upper-right is BTN_EAST.
|
||||
|
||||
D-Pad:
|
||||
- D-Pad:
|
||||
|
||||
Every gamepad provides a D-Pad with four directions: Up, Down, Left, Right
|
||||
Some of these are available as digital buttons, some as analog buttons. Some
|
||||
may even report both. The kernel does not convert between these so
|
||||
applications should support both and choose what is more appropriate if
|
||||
both are reported.
|
||||
Digital buttons are reported as:
|
||||
BTN_DPAD_*
|
||||
Analog buttons are reported as:
|
||||
ABS_HAT0X and ABS_HAT0Y
|
||||
(for ABS values negative is left/up, positive is right/down)
|
||||
|
||||
Analog-Sticks:
|
||||
- Digital buttons are reported as:
|
||||
|
||||
BTN_DPAD_*
|
||||
|
||||
- Analog buttons are reported as:
|
||||
|
||||
ABS_HAT0X and ABS_HAT0Y
|
||||
|
||||
(for ABS values negative is left/up, positive is right/down)
|
||||
|
||||
- Analog-Sticks:
|
||||
|
||||
The left analog-stick is reported as ABS_X, ABS_Y. The right analog stick is
|
||||
reported as ABS_RX, ABS_RY. Zero, one or two sticks may be present.
|
||||
If analog-sticks provide digital buttons, they are mapped accordingly as
|
||||
BTN_THUMBL (first/left) and BTN_THUMBR (second/right).
|
||||
(for ABS values negative is left/up, positive is right/down)
|
||||
|
||||
Triggers:
|
||||
(for ABS values negative is left/up, positive is right/down)
|
||||
|
||||
- Triggers:
|
||||
|
||||
Trigger buttons can be available as digital or analog buttons or both. User-
|
||||
space must correctly deal with any situation and choose the most appropriate
|
||||
mode.
|
||||
|
||||
Upper trigger buttons are reported as BTN_TR or ABS_HAT1X (right) and BTN_TL
|
||||
or ABS_HAT1Y (left). Lower trigger buttons are reported as BTN_TR2 or
|
||||
ABS_HAT2X (right/ZR) and BTN_TL2 or ABS_HAT2Y (left/ZL).
|
||||
|
||||
If only one trigger-button combination is present (upper+lower), they are
|
||||
reported as "right" triggers (BTN_TR/ABS_HAT1X).
|
||||
(ABS trigger values start at 0, pressure is reported as positive values)
|
||||
|
||||
Menu-Pad:
|
||||
(ABS trigger values start at 0, pressure is reported as positive values)
|
||||
|
||||
- Menu-Pad:
|
||||
|
||||
Menu buttons are always digital and are mapped according to their location
|
||||
instead of their labels. That is:
|
||||
1-button Pad: Mapped as BTN_START
|
||||
2-button Pad: Left button mapped as BTN_SELECT, right button mapped as
|
||||
BTN_START
|
||||
|
||||
- 1-button Pad:
|
||||
|
||||
Mapped as BTN_START
|
||||
|
||||
- 2-button Pad:
|
||||
|
||||
Left button mapped as BTN_SELECT, right button mapped as BTN_START
|
||||
|
||||
Many pads also have a third button which is branded or has a special symbol
|
||||
and meaning. Such buttons are mapped as BTN_MODE. Examples are the Nintendo
|
||||
"HOME" button, the XBox "X"-button or Sony "PS" button.
|
||||
|
||||
Rumble:
|
||||
Rumble is advertised as FF_RUMBLE.
|
||||
- Rumble:
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Written 2013 by David Herrmann <dh.herrmann@gmail.com>
|
||||
Rumble is advertised as FF_RUMBLE.
|
|
@ -1,11 +1,12 @@
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Programming gameport drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. A basic classic gameport
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
A basic classic gameport
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If the gameport doesn't provide more than the inb()/outb() functionality,
|
||||
the code needed to register it with the joystick drivers is simple:
|
||||
the code needed to register it with the joystick drivers is simple::
|
||||
|
||||
struct gameport gameport;
|
||||
|
||||
|
@ -37,12 +38,12 @@ space only when something really is using it. Disable it again in the
|
|||
callback, so that it doesn't fail if some of the possible addresses are
|
||||
already occupied by other gameports.
|
||||
|
||||
2. Memory mapped gameport
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Memory mapped gameport
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When a gameport can be accessed through MMIO, this way is preferred, because
|
||||
it is faster, allowing more reads per second. Registering such a gameport
|
||||
isn't as easy as a basic IO one, but not so much complex:
|
||||
isn't as easy as a basic IO one, but not so much complex::
|
||||
|
||||
struct gameport gameport;
|
||||
|
||||
|
@ -53,19 +54,21 @@ isn't as easy as a basic IO one, but not so much complex:
|
|||
|
||||
unsigned char my_read(struct gameport *gameport)
|
||||
{
|
||||
return my_mmio;
|
||||
return my_mmio;
|
||||
}
|
||||
|
||||
gameport.read = my_read;
|
||||
gameport.trigger = my_trigger;
|
||||
gameport_register_port(&gameport);
|
||||
|
||||
3. Cooked mode gameport
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
.. _gameport_pgm_cooked_mode:
|
||||
|
||||
Cooked mode gameport
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are gameports that can report the axis values as numbers, that means
|
||||
the driver doesn't have to measure them the old way - an ADC is built into
|
||||
the gameport. To register a cooked gameport:
|
||||
the gameport. To register a cooked gameport::
|
||||
|
||||
struct gameport gameport;
|
||||
|
||||
|
@ -95,8 +98,8 @@ See analog.c and input.c for handling of fuzz - the fuzz value determines
|
|||
the size of a gaussian filter window that is used to eliminate the noise
|
||||
in the data.
|
||||
|
||||
4. More complex gameports
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
More complex gameports
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gameports can support both raw and cooked modes. In that case combine either
|
||||
examples 1+2 or 1+3. Gameports can support internal calibration - see below,
|
||||
|
@ -104,65 +107,91 @@ and also lightning.c and analog.c on how that works. If your driver supports
|
|||
more than one gameport instance simultaneously, use the ->private member of
|
||||
the gameport struct to point to your data.
|
||||
|
||||
5. Unregistering a gameport
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Unregistering a gameport
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Simple:
|
||||
Simple::
|
||||
|
||||
gameport_unregister_port(&gameport);
|
||||
gameport_unregister_port(&gameport);
|
||||
|
||||
6. The gameport structure
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The gameport structure
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
struct gameport {
|
||||
.. note::
|
||||
|
||||
This section is outdated. There are several fields here that don't
|
||||
match what's there at include/linux/gameport.h.
|
||||
|
||||
::
|
||||
|
||||
struct gameport {
|
||||
|
||||
void *private;
|
||||
|
||||
A private pointer for free use in the gameport driver. (Not the joystick
|
||||
driver!)
|
||||
|
||||
::
|
||||
|
||||
int number;
|
||||
|
||||
Number assigned to the gameport when registered. Informational purpose only.
|
||||
|
||||
::
|
||||
|
||||
int io;
|
||||
|
||||
I/O address for use with raw mode. You have to either set this, or ->read()
|
||||
to some value if your gameport supports raw mode.
|
||||
|
||||
::
|
||||
|
||||
int speed;
|
||||
|
||||
Raw mode speed of the gameport reads in thousands of reads per second.
|
||||
|
||||
::
|
||||
|
||||
int fuzz;
|
||||
|
||||
If the gameport supports cooked mode, this should be set to a value that
|
||||
represents the amount of noise in the data. See section 3.
|
||||
represents the amount of noise in the data. See
|
||||
:ref:`gameport_pgm_cooked_mode`.
|
||||
|
||||
::
|
||||
|
||||
void (*trigger)(struct gameport *);
|
||||
|
||||
Trigger. This function should trigger the ns558 oneshots. If set to NULL,
|
||||
outb(0xff, io) will be used.
|
||||
|
||||
::
|
||||
|
||||
unsigned char (*read)(struct gameport *);
|
||||
|
||||
Read the buttons and ns558 oneshot bits. If set to NULL, inb(io) will be
|
||||
used instead.
|
||||
|
||||
int (*cooked_read)(struct gameport *, int *axes, int *buttons);
|
||||
::
|
||||
|
||||
int (*cooked_read)(struct gameport *, int *axes, int *buttons);
|
||||
|
||||
If the gameport supports cooked mode, it should point this to its cooked
|
||||
read function. It should fill axes[0..3] with four values of the joystick axes
|
||||
and buttons[0] with four bits representing the buttons.
|
||||
|
||||
int (*calibrate)(struct gameport *, int *axes, int *max);
|
||||
::
|
||||
|
||||
int (*calibrate)(struct gameport *, int *axes, int *max);
|
||||
|
||||
Function for calibrating the ADC hardware. When called, axes[0..3] should be
|
||||
pre-filled by cooked data by the caller, max[0..3] should be pre-filled with
|
||||
expected maximums for each axis. The calibrate() function should set the
|
||||
sensitivity of the ADC hardware so that the maximums fit in its range and
|
||||
recompute the axes[] values to match the new sensitivity or re-read them from
|
||||
the hardware so that they give valid values.
|
||||
the hardware so that they give valid values.
|
||||
|
||||
::
|
||||
|
||||
int (*open)(struct gameport *, int mode);
|
||||
|
||||
|
@ -172,16 +201,22 @@ Second, resource allocation can happen here. The port can also be enabled
|
|||
here. Prior to this call, other fields of the gameport struct (namely the io
|
||||
member) need not to be valid.
|
||||
|
||||
::
|
||||
|
||||
void (*close)(struct gameport *);
|
||||
|
||||
Close() should free the resources allocated by open, possibly disabling the
|
||||
gameport.
|
||||
|
||||
::
|
||||
|
||||
struct gameport_dev *dev;
|
||||
struct gameport *next;
|
||||
|
||||
For internal use by the gameport layer.
|
||||
|
||||
};
|
||||
::
|
||||
|
||||
};
|
||||
|
||||
Enjoy!
|
|
@ -1,103 +0,0 @@
|
|||
Driver for tilt-switches connected via GPIOs
|
||||
============================================
|
||||
|
||||
Generic driver to read data from tilt switches connected via gpios.
|
||||
Orientation can be provided by one or more than one tilt switches,
|
||||
i.e. each tilt switch providing one axis, and the number of axes
|
||||
is also not limited.
|
||||
|
||||
|
||||
Data structures:
|
||||
----------------
|
||||
|
||||
The array of struct gpio in the gpios field is used to list the gpios
|
||||
that represent the current tilt state.
|
||||
|
||||
The array of struct gpio_tilt_axis describes the axes that are reported
|
||||
to the input system. The values set therein are used for the
|
||||
input_set_abs_params calls needed to init the axes.
|
||||
|
||||
The array of struct gpio_tilt_state maps gpio states to the corresponding
|
||||
values to report. The gpio state is represented as a bitfield where the
|
||||
bit-index corresponds to the index of the gpio in the struct gpio array.
|
||||
In the same manner the values stored in the axes array correspond to
|
||||
the elements of the gpio_tilt_axis-array.
|
||||
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
Example configuration for a single TS1003 tilt switch that rotates around
|
||||
one axis in 4 steps and emits the current tilt via two GPIOs.
|
||||
|
||||
static int sg060_tilt_enable(struct device *dev) {
|
||||
/* code to enable the sensors */
|
||||
};
|
||||
|
||||
static void sg060_tilt_disable(struct device *dev) {
|
||||
/* code to disable the sensors */
|
||||
};
|
||||
|
||||
static struct gpio sg060_tilt_gpios[] = {
|
||||
{ SG060_TILT_GPIO_SENSOR1, GPIOF_IN, "tilt_sensor1" },
|
||||
{ SG060_TILT_GPIO_SENSOR2, GPIOF_IN, "tilt_sensor2" },
|
||||
};
|
||||
|
||||
static struct gpio_tilt_state sg060_tilt_states[] = {
|
||||
{
|
||||
.gpios = (0 << 1) | (0 << 0),
|
||||
.axes = (int[]) {
|
||||
0,
|
||||
},
|
||||
}, {
|
||||
.gpios = (0 << 1) | (1 << 0),
|
||||
.axes = (int[]) {
|
||||
1, /* 90 degrees */
|
||||
},
|
||||
}, {
|
||||
.gpios = (1 << 1) | (1 << 0),
|
||||
.axes = (int[]) {
|
||||
2, /* 180 degrees */
|
||||
},
|
||||
}, {
|
||||
.gpios = (1 << 1) | (0 << 0),
|
||||
.axes = (int[]) {
|
||||
3, /* 270 degrees */
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_tilt_axis sg060_tilt_axes[] = {
|
||||
{
|
||||
.axis = ABS_RY,
|
||||
.min = 0,
|
||||
.max = 3,
|
||||
.fuzz = 0,
|
||||
.flat = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_tilt_platform_data sg060_tilt_pdata= {
|
||||
.gpios = sg060_tilt_gpios,
|
||||
.nr_gpios = ARRAY_SIZE(sg060_tilt_gpios),
|
||||
|
||||
.axes = sg060_tilt_axes,
|
||||
.nr_axes = ARRAY_SIZE(sg060_tilt_axes),
|
||||
|
||||
.states = sg060_tilt_states,
|
||||
.nr_states = ARRAY_SIZE(sg060_tilt_states),
|
||||
|
||||
.debounce_interval = 100,
|
||||
|
||||
.poll_interval = 1000,
|
||||
.enable = sg060_tilt_enable,
|
||||
.disable = sg060_tilt_disable,
|
||||
};
|
||||
|
||||
static struct platform_device sg060_device_tilt = {
|
||||
.name = "gpio-tilt-polled",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &sg060_tilt_pdata,
|
||||
},
|
||||
};
|
|
@ -1,258 +0,0 @@
|
|||
** Introduction
|
||||
This document describes what I managed to discover about the protocol used to
|
||||
specify force effects to I-Force 2.0 devices. None of this information comes
|
||||
from Immerse. That's why you should not trust what is written in this
|
||||
document. This document is intended to help understanding the protocol.
|
||||
This is not a reference. Comments and corrections are welcome. To contact me,
|
||||
send an email to: johann.deneux@gmail.com
|
||||
|
||||
** WARNING **
|
||||
I shall not be held responsible for any damage or harm caused if you try to
|
||||
send data to your I-Force device based on what you read in this document.
|
||||
|
||||
** Preliminary Notes:
|
||||
All values are hexadecimal with big-endian encoding (msb on the left). Beware,
|
||||
values inside packets are encoded using little-endian. Bytes whose roles are
|
||||
unknown are marked ??? Information that needs deeper inspection is marked (?)
|
||||
|
||||
** General form of a packet **
|
||||
This is how packets look when the device uses the rs232 to communicate.
|
||||
2B OP LEN DATA CS
|
||||
CS is the checksum. It is equal to the exclusive or of all bytes.
|
||||
|
||||
When using USB:
|
||||
OP DATA
|
||||
The 2B, LEN and CS fields have disappeared, probably because USB handles frames and
|
||||
data corruption is handled or unsignificant.
|
||||
|
||||
First, I describe effects that are sent by the device to the computer
|
||||
|
||||
** Device input state
|
||||
This packet is used to indicate the state of each button and the value of each
|
||||
axis
|
||||
OP= 01 for a joystick, 03 for a wheel
|
||||
LEN= Varies from device to device
|
||||
00 X-Axis lsb
|
||||
01 X-Axis msb
|
||||
02 Y-Axis lsb, or gas pedal for a wheel
|
||||
03 Y-Axis msb, or brake pedal for a wheel
|
||||
04 Throttle
|
||||
05 Buttons
|
||||
06 Lower 4 bits: Buttons
|
||||
Upper 4 bits: Hat
|
||||
07 Rudder
|
||||
|
||||
** Device effects states
|
||||
OP= 02
|
||||
LEN= Varies
|
||||
00 ? Bit 1 (Value 2) is the value of the deadman switch
|
||||
01 Bit 8 is set if the effect is playing. Bits 0 to 7 are the effect id.
|
||||
02 ??
|
||||
03 Address of parameter block changed (lsb)
|
||||
04 Address of parameter block changed (msb)
|
||||
05 Address of second parameter block changed (lsb)
|
||||
... depending on the number of parameter blocks updated
|
||||
|
||||
** Force effect **
|
||||
OP= 01
|
||||
LEN= 0e
|
||||
00 Channel (when playing several effects at the same time, each must be assigned a channel)
|
||||
01 Wave form
|
||||
Val 00 Constant
|
||||
Val 20 Square
|
||||
Val 21 Triangle
|
||||
Val 22 Sine
|
||||
Val 23 Sawtooth up
|
||||
Val 24 Sawtooth down
|
||||
Val 40 Spring (Force = f(pos))
|
||||
Val 41 Friction (Force = f(velocity)) and Inertia (Force = f(acceleration))
|
||||
|
||||
|
||||
02 Axes affected and trigger
|
||||
Bits 4-7: Val 2 = effect along one axis. Byte 05 indicates direction
|
||||
Val 4 = X axis only. Byte 05 must contain 5a
|
||||
Val 8 = Y axis only. Byte 05 must contain b4
|
||||
Val c = X and Y axes. Bytes 05 must contain 60
|
||||
Bits 0-3: Val 0 = No trigger
|
||||
Val x+1 = Button x triggers the effect
|
||||
When the whole byte is 0, cancel the previously set trigger
|
||||
|
||||
03-04 Duration of effect (little endian encoding, in ms)
|
||||
|
||||
05 Direction of effect, if applicable. Else, see 02 for value to assign.
|
||||
|
||||
06-07 Minimum time between triggering.
|
||||
|
||||
08-09 Address of periodicity or magnitude parameters
|
||||
0a-0b Address of attack and fade parameters, or ffff if none.
|
||||
*or*
|
||||
08-09 Address of interactive parameters for X-axis, or ffff if not applicable
|
||||
0a-0b Address of interactive parameters for Y-axis, or ffff if not applicable
|
||||
|
||||
0c-0d Delay before execution of effect (little endian encoding, in ms)
|
||||
|
||||
|
||||
** Time based parameters **
|
||||
|
||||
*** Attack and fade ***
|
||||
OP= 02
|
||||
LEN= 08
|
||||
00-01 Address where to store the parameters
|
||||
02-03 Duration of attack (little endian encoding, in ms)
|
||||
04 Level at end of attack. Signed byte.
|
||||
05-06 Duration of fade.
|
||||
07 Level at end of fade.
|
||||
|
||||
*** Magnitude ***
|
||||
OP= 03
|
||||
LEN= 03
|
||||
00-01 Address
|
||||
02 Level. Signed byte.
|
||||
|
||||
*** Periodicity ***
|
||||
OP= 04
|
||||
LEN= 07
|
||||
00-01 Address
|
||||
02 Magnitude. Signed byte.
|
||||
03 Offset. Signed byte.
|
||||
04 Phase. Val 00 = 0 deg, Val 40 = 90 degs.
|
||||
05-06 Period (little endian encoding, in ms)
|
||||
|
||||
** Interactive parameters **
|
||||
OP= 05
|
||||
LEN= 0a
|
||||
00-01 Address
|
||||
02 Positive Coeff
|
||||
03 Negative Coeff
|
||||
04+05 Offset (center)
|
||||
06+07 Dead band (Val 01F4 = 5000 (decimal))
|
||||
08 Positive saturation (Val 0a = 1000 (decimal) Val 64 = 10000 (decimal))
|
||||
09 Negative saturation
|
||||
|
||||
The encoding is a bit funny here: For coeffs, these are signed values. The
|
||||
maximum value is 64 (100 decimal), the min is 9c.
|
||||
For the offset, the minimum value is FE0C, the maximum value is 01F4.
|
||||
For the deadband, the minimum value is 0, the max is 03E8.
|
||||
|
||||
** Controls **
|
||||
OP= 41
|
||||
LEN= 03
|
||||
00 Channel
|
||||
01 Start/Stop
|
||||
Val 00: Stop
|
||||
Val 01: Start and play once.
|
||||
Val 41: Start and play n times (See byte 02 below)
|
||||
02 Number of iterations n.
|
||||
|
||||
** Init **
|
||||
|
||||
*** Querying features ***
|
||||
OP= ff
|
||||
Query command. Length varies according to the query type.
|
||||
The general format of this packet is:
|
||||
ff 01 QUERY [INDEX] CHECKSUM
|
||||
responses are of the same form:
|
||||
FF LEN QUERY VALUE_QUERIED CHECKSUM2
|
||||
where LEN = 1 + length(VALUE_QUERIED)
|
||||
|
||||
**** Query ram size ****
|
||||
QUERY = 42 ('B'uffer size)
|
||||
The device should reply with the same packet plus two additional bytes
|
||||
containing the size of the memory:
|
||||
ff 03 42 03 e8 CS would mean that the device has 1000 bytes of ram available.
|
||||
|
||||
**** Query number of effects ****
|
||||
QUERY = 4e ('N'umber of effects)
|
||||
The device should respond by sending the number of effects that can be played
|
||||
at the same time (one byte)
|
||||
ff 02 4e 14 CS would stand for 20 effects.
|
||||
|
||||
**** Vendor's id ****
|
||||
QUERY = 4d ('M'anufacturer)
|
||||
Query the vendors'id (2 bytes)
|
||||
|
||||
**** Product id *****
|
||||
QUERY = 50 ('P'roduct)
|
||||
Query the product id (2 bytes)
|
||||
|
||||
**** Open device ****
|
||||
QUERY = 4f ('O'pen)
|
||||
No data returned.
|
||||
|
||||
**** Close device *****
|
||||
QUERY = 43 ('C')lose
|
||||
No data returned.
|
||||
|
||||
**** Query effect ****
|
||||
QUERY = 45 ('E')
|
||||
Send effect type.
|
||||
Returns nonzero if supported (2 bytes)
|
||||
|
||||
**** Firmware Version ****
|
||||
QUERY = 56 ('V'ersion)
|
||||
Sends back 3 bytes - major, minor, subminor
|
||||
|
||||
*** Initialisation of the device ***
|
||||
|
||||
**** Set Control ****
|
||||
!!! Device dependent, can be different on different models !!!
|
||||
OP= 40 <idx> <val> [<val>]
|
||||
LEN= 2 or 3
|
||||
00 Idx
|
||||
Idx 00 Set dead zone (0..2048)
|
||||
Idx 01 Ignore Deadman sensor (0..1)
|
||||
Idx 02 Enable comm watchdog (0..1)
|
||||
Idx 03 Set the strength of the spring (0..100)
|
||||
Idx 04 Enable or disable the spring (0/1)
|
||||
Idx 05 Set axis saturation threshold (0..2048)
|
||||
|
||||
**** Set Effect State ****
|
||||
OP= 42 <val>
|
||||
LEN= 1
|
||||
00 State
|
||||
Bit 3 Pause force feedback
|
||||
Bit 2 Enable force feedback
|
||||
Bit 0 Stop all effects
|
||||
|
||||
**** Set overall gain ****
|
||||
OP= 43 <val>
|
||||
LEN= 1
|
||||
00 Gain
|
||||
Val 00 = 0%
|
||||
Val 40 = 50%
|
||||
Val 80 = 100%
|
||||
|
||||
** Parameter memory **
|
||||
|
||||
Each device has a certain amount of memory to store parameters of effects.
|
||||
The amount of RAM may vary, I encountered values from 200 to 1000 bytes. Below
|
||||
is the amount of memory apparently needed for every set of parameters:
|
||||
- period : 0c
|
||||
- magnitude : 02
|
||||
- attack and fade : 0e
|
||||
- interactive : 08
|
||||
|
||||
** Appendix: How to study the protocol ? **
|
||||
|
||||
1. Generate effects using the force editor provided with the DirectX SDK, or
|
||||
use Immersion Studio (freely available at their web site in the developer section:
|
||||
www.immersion.com)
|
||||
2. Start a soft spying RS232 or USB (depending on where you connected your
|
||||
joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
|
||||
3. Play the effect, and watch what happens on the spy screen.
|
||||
|
||||
A few words about ComPortSpy:
|
||||
At first glance, this software seems, hum, well... buggy. In fact, data appear with a
|
||||
few seconds latency. Personally, I restart it every time I play an effect.
|
||||
Remember it's free (as in free beer) and alpha!
|
||||
|
||||
** URLS **
|
||||
Check www.immerse.com for Immersion Studio, and www.fcoder.com for ComPortSpy.
|
||||
|
||||
** Author of this document **
|
||||
Johann Deneux <johann.deneux@gmail.com>
|
||||
Home page at http://web.archive.org/web/*/http://www.esil.univ-mrs.fr
|
||||
|
||||
Additions by Vojtech Pavlik.
|
||||
|
||||
I-Force is trademark of Immersion Corp.
|
|
@ -0,0 +1,20 @@
|
|||
=============================
|
||||
The Linux Input Documentation
|
||||
=============================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
|
||||
input_uapi
|
||||
input_kapi
|
||||
devices/index
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
|
@ -1,77 +1,75 @@
|
|||
Programming input drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
===============================
|
||||
Creating an input device driver
|
||||
===============================
|
||||
|
||||
1. Creating an input device driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1.0 The simplest example
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The simplest example
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Here comes a very simple example of an input device driver. The device has
|
||||
just one button and the button is accessible at i/o port BUTTON_PORT. When
|
||||
pressed or released a BUTTON_IRQ happens. The driver could look like:
|
||||
pressed or released a BUTTON_IRQ happens. The driver could look like::
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
static struct input_dev *button_dev;
|
||||
static struct input_dev *button_dev;
|
||||
|
||||
static irqreturn_t button_interrupt(int irq, void *dummy)
|
||||
{
|
||||
input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1);
|
||||
input_sync(button_dev);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
static irqreturn_t button_interrupt(int irq, void *dummy)
|
||||
{
|
||||
input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1);
|
||||
input_sync(button_dev);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __init button_init(void)
|
||||
{
|
||||
int error;
|
||||
static int __init button_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
|
||||
printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
|
||||
printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
button_dev = input_allocate_device();
|
||||
if (!button_dev) {
|
||||
printk(KERN_ERR "button.c: Not enough memory\n");
|
||||
error = -ENOMEM;
|
||||
goto err_free_irq;
|
||||
}
|
||||
button_dev = input_allocate_device();
|
||||
if (!button_dev) {
|
||||
printk(KERN_ERR "button.c: Not enough memory\n");
|
||||
error = -ENOMEM;
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
button_dev->evbit[0] = BIT_MASK(EV_KEY);
|
||||
button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
|
||||
button_dev->evbit[0] = BIT_MASK(EV_KEY);
|
||||
button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
|
||||
|
||||
error = input_register_device(button_dev);
|
||||
if (error) {
|
||||
printk(KERN_ERR "button.c: Failed to register device\n");
|
||||
goto err_free_dev;
|
||||
}
|
||||
error = input_register_device(button_dev);
|
||||
if (error) {
|
||||
printk(KERN_ERR "button.c: Failed to register device\n");
|
||||
goto err_free_dev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
err_free_dev:
|
||||
input_free_device(button_dev);
|
||||
err_free_irq:
|
||||
free_irq(BUTTON_IRQ, button_interrupt);
|
||||
return error;
|
||||
}
|
||||
err_free_dev:
|
||||
input_free_device(button_dev);
|
||||
err_free_irq:
|
||||
free_irq(BUTTON_IRQ, button_interrupt);
|
||||
return error;
|
||||
}
|
||||
|
||||
static void __exit button_exit(void)
|
||||
{
|
||||
input_unregister_device(button_dev);
|
||||
free_irq(BUTTON_IRQ, button_interrupt);
|
||||
}
|
||||
static void __exit button_exit(void)
|
||||
{
|
||||
input_unregister_device(button_dev);
|
||||
free_irq(BUTTON_IRQ, button_interrupt);
|
||||
}
|
||||
|
||||
module_init(button_init);
|
||||
module_exit(button_exit);
|
||||
module_init(button_init);
|
||||
module_exit(button_exit);
|
||||
|
||||
1.1 What the example does
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
What the example does
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First it has to include the <linux/input.h> file, which interfaces to the
|
||||
input subsystem. This provides all the definitions needed.
|
||||
|
@ -85,7 +83,7 @@ and sets up input bitfields. This way the device driver tells the other
|
|||
parts of the input systems what it is - what events can be generated or
|
||||
accepted by this input device. Our example device can only generate EV_KEY
|
||||
type events, and from those only BTN_0 event code. Thus we only set these
|
||||
two bits. We could have used
|
||||
two bits. We could have used::
|
||||
|
||||
set_bit(EV_KEY, button_dev.evbit);
|
||||
set_bit(BTN_0, button_dev.keybit);
|
||||
|
@ -93,7 +91,7 @@ two bits. We could have used
|
|||
as well, but with more than single bits the first approach tends to be
|
||||
shorter.
|
||||
|
||||
Then the example driver registers the input device structure by calling
|
||||
Then the example driver registers the input device structure by calling::
|
||||
|
||||
input_register_device(&button_dev);
|
||||
|
||||
|
@ -102,12 +100,12 @@ calls device handler modules _connect functions to tell them a new input
|
|||
device has appeared. input_register_device() may sleep and therefore must
|
||||
not be called from an interrupt or with a spinlock held.
|
||||
|
||||
While in use, the only used function of the driver is
|
||||
While in use, the only used function of the driver is::
|
||||
|
||||
button_interrupt()
|
||||
|
||||
which upon every interrupt from the button checks its state and reports it
|
||||
via the
|
||||
via the::
|
||||
|
||||
input_report_key()
|
||||
|
||||
|
@ -116,7 +114,7 @@ routine isn't reporting two same value events (press, press for example) to
|
|||
the input system, because the input_report_* functions check that
|
||||
themselves.
|
||||
|
||||
Then there is the
|
||||
Then there is the::
|
||||
|
||||
input_sync()
|
||||
|
||||
|
@ -125,38 +123,38 @@ This doesn't seem important in the one button case, but is quite important
|
|||
for for example mouse movement, where you don't want the X and Y values
|
||||
to be interpreted separately, because that'd result in a different movement.
|
||||
|
||||
1.2 dev->open() and dev->close()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
dev->open() and dev->close()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In case the driver has to repeatedly poll the device, because it doesn't
|
||||
have an interrupt coming from it and the polling is too expensive to be done
|
||||
all the time, or if the device uses a valuable resource (eg. interrupt), it
|
||||
can use the open and close callback to know when it can stop polling or
|
||||
release the interrupt and when it must resume polling or grab the interrupt
|
||||
again. To do that, we would add this to our example driver:
|
||||
again. To do that, we would add this to our example driver::
|
||||
|
||||
static int button_open(struct input_dev *dev)
|
||||
{
|
||||
if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
|
||||
printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
static int button_open(struct input_dev *dev)
|
||||
{
|
||||
if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
|
||||
printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void button_close(struct input_dev *dev)
|
||||
{
|
||||
free_irq(IRQ_AMIGA_VERTB, button_interrupt);
|
||||
}
|
||||
static void button_close(struct input_dev *dev)
|
||||
{
|
||||
free_irq(IRQ_AMIGA_VERTB, button_interrupt);
|
||||
}
|
||||
|
||||
static int __init button_init(void)
|
||||
{
|
||||
...
|
||||
button_dev->open = button_open;
|
||||
button_dev->close = button_close;
|
||||
...
|
||||
}
|
||||
static int __init button_init(void)
|
||||
{
|
||||
...
|
||||
button_dev->open = button_open;
|
||||
button_dev->close = button_close;
|
||||
...
|
||||
}
|
||||
|
||||
Note that input core keeps track of number of users for the device and
|
||||
makes sure that dev->open() is called only when the first user connects
|
||||
|
@ -166,11 +164,11 @@ disconnects. Calls to both callbacks are serialized.
|
|||
The open() callback should return a 0 in case of success or any nonzero value
|
||||
in case of failure. The close() callback (which is void) must always succeed.
|
||||
|
||||
1.3 Basic event types
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
Basic event types
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The most simple event type is EV_KEY, which is used for keys and buttons.
|
||||
It's reported to the input system via:
|
||||
It's reported to the input system via::
|
||||
|
||||
input_report_key(struct input_dev *dev, int code, int value)
|
||||
|
||||
|
@ -188,7 +186,7 @@ events are namely for joysticks and digitizers - devices that do work in an
|
|||
absolute coordinate systems.
|
||||
|
||||
Having the device report EV_REL buttons is as simple as with EV_KEY, simply
|
||||
set the corresponding bits and call the
|
||||
set the corresponding bits and call the::
|
||||
|
||||
input_report_rel(struct input_dev *dev, int code, int value)
|
||||
|
||||
|
@ -197,14 +195,14 @@ function. Events are generated only for nonzero value.
|
|||
However EV_ABS requires a little special care. Before calling
|
||||
input_register_device, you have to fill additional fields in the input_dev
|
||||
struct for each absolute axis your device has. If our button device had also
|
||||
the ABS_X axis:
|
||||
the ABS_X axis::
|
||||
|
||||
button_dev.absmin[ABS_X] = 0;
|
||||
button_dev.absmax[ABS_X] = 255;
|
||||
button_dev.absfuzz[ABS_X] = 4;
|
||||
button_dev.absflat[ABS_X] = 8;
|
||||
|
||||
Or, you can just say:
|
||||
Or, you can just say::
|
||||
|
||||
input_set_abs_params(button_dev, ABS_X, 0, 255, 4, 8);
|
||||
|
||||
|
@ -218,18 +216,18 @@ If you don't need absfuzz and absflat, you can set them to zero, which mean
|
|||
that the thing is precise and always returns to exactly the center position
|
||||
(if it has any).
|
||||
|
||||
1.4 BITS_TO_LONGS(), BIT_WORD(), BIT_MASK()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
BITS_TO_LONGS(), BIT_WORD(), BIT_MASK()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
These three macros from bitops.h help some bitfield computations:
|
||||
These three macros from bitops.h help some bitfield computations::
|
||||
|
||||
BITS_TO_LONGS(x) - returns the length of a bitfield array in longs for
|
||||
x bits
|
||||
BIT_WORD(x) - returns the index in the array in longs for bit x
|
||||
BIT_MASK(x) - returns the index in a long for bit x
|
||||
|
||||
1.5 The id* and name fields
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The id* and name fields
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The dev->name should be set before registering the input device by the input
|
||||
device driver. It's a string like 'Generic button device' containing a
|
||||
|
@ -245,8 +243,8 @@ driver.
|
|||
|
||||
The id and name fields can be passed to userland via the evdev interface.
|
||||
|
||||
1.6 The keycode, keycodemax, keycodesize fields
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The keycode, keycodemax, keycodesize fields
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
These three fields should be used by input devices that have dense keymaps.
|
||||
The keycode is an array used to map from scancodes to input system keycodes.
|
||||
|
@ -259,14 +257,15 @@ When a device has all 3 aforementioned fields filled in, the driver may
|
|||
rely on kernel's default implementation of setting and querying keycode
|
||||
mappings.
|
||||
|
||||
1.7 dev->getkeycode() and dev->setkeycode()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
dev->getkeycode() and dev->setkeycode()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
getkeycode() and setkeycode() callbacks allow drivers to override default
|
||||
keycode/keycodesize/keycodemax mapping mechanism provided by input core
|
||||
and implement sparse keycode maps.
|
||||
|
||||
1.8 Key autorepeat
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Key autorepeat
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
... is simple. It is handled by the input.c module. Hardware autorepeat is
|
||||
not used, because it's not present in many devices and even where it is
|
||||
|
@ -274,29 +273,30 @@ present, it is broken sometimes (at keyboards: Toshiba notebooks). To enable
|
|||
autorepeat for your device, just set EV_REP in dev->evbit. All will be
|
||||
handled by the input system.
|
||||
|
||||
1.9 Other event types, handling output events
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Other event types, handling output events
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The other event types up to now are:
|
||||
|
||||
EV_LED - used for the keyboard LEDs.
|
||||
EV_SND - used for keyboard beeps.
|
||||
- EV_LED - used for the keyboard LEDs.
|
||||
- EV_SND - used for keyboard beeps.
|
||||
|
||||
They are very similar to for example key events, but they go in the other
|
||||
direction - from the system to the input device driver. If your input device
|
||||
driver can handle these events, it has to set the respective bits in evbit,
|
||||
*and* also the callback routine:
|
||||
*and* also the callback routine::
|
||||
|
||||
button_dev->event = button_event;
|
||||
button_dev->event = button_event;
|
||||
|
||||
int button_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
|
||||
{
|
||||
if (type == EV_SND && code == SND_BELL) {
|
||||
outb(value, BUTTON_BELL);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int button_event(struct input_dev *dev, unsigned int type,
|
||||
unsigned int code, int value)
|
||||
{
|
||||
if (type == EV_SND && code == SND_BELL) {
|
||||
outb(value, BUTTON_BELL);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
This callback routine can be called from an interrupt or a BH (although that
|
||||
isn't a rule), and thus must not sleep, and must not take too long to finish.
|
|
@ -0,0 +1,281 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
============
|
||||
Introduction
|
||||
============
|
||||
|
||||
:Copyright: |copy| 1999-2001 Vojtech Pavlik <vojtech@ucw.cz> - Sponsored by SuSE
|
||||
|
||||
Architecture
|
||||
============
|
||||
|
||||
Input subsystem a collection of drivers that is designed to support
|
||||
all input devices under Linux. Most of the drivers reside in
|
||||
drivers/input, although quite a few live in drivers/hid and
|
||||
drivers/platform.
|
||||
|
||||
The core of the input subsystem is the input module, which must be
|
||||
loaded before any other of the input modules - it serves as a way of
|
||||
communication between two groups of modules:
|
||||
|
||||
Device drivers
|
||||
--------------
|
||||
|
||||
These modules talk to the hardware (for example via USB), and provide
|
||||
events (keystrokes, mouse movements) to the input module.
|
||||
|
||||
Event handlers
|
||||
--------------
|
||||
|
||||
These modules get events from input core and pass them where needed
|
||||
via various interfaces - keystrokes to the kernel, mouse movements via
|
||||
a simulated PS/2 interface to GPM and X, and so on.
|
||||
|
||||
Simple Usage
|
||||
============
|
||||
|
||||
For the most usual configuration, with one USB mouse and one USB keyboard,
|
||||
you'll have to load the following modules (or have them built in to the
|
||||
kernel)::
|
||||
|
||||
input
|
||||
mousedev
|
||||
usbcore
|
||||
uhci_hcd or ohci_hcd or ehci_hcd
|
||||
usbhid
|
||||
hid_generic
|
||||
|
||||
After this, the USB keyboard will work straight away, and the USB mouse
|
||||
will be available as a character device on major 13, minor 63::
|
||||
|
||||
crw-r--r-- 1 root root 13, 63 Mar 28 22:45 mice
|
||||
|
||||
This device usually created automatically by the system. The commands
|
||||
to create it by hand are::
|
||||
|
||||
cd /dev
|
||||
mkdir input
|
||||
mknod input/mice c 13 63
|
||||
|
||||
After that you have to point GPM (the textmode mouse cut&paste tool) and
|
||||
XFree to this device to use it - GPM should be called like::
|
||||
|
||||
gpm -t ps2 -m /dev/input/mice
|
||||
|
||||
And in X::
|
||||
|
||||
Section "Pointer"
|
||||
Protocol "ImPS/2"
|
||||
Device "/dev/input/mice"
|
||||
ZAxisMapping 4 5
|
||||
EndSection
|
||||
|
||||
When you do all of the above, you can use your USB mouse and keyboard.
|
||||
|
||||
Detailed Description
|
||||
====================
|
||||
|
||||
Event handlers
|
||||
--------------
|
||||
|
||||
Event handlers distribute the events from the devices to userspace and
|
||||
in-kernel consumers, as needed.
|
||||
|
||||
evdev
|
||||
~~~~~
|
||||
|
||||
``evdev`` is the generic input event interface. It passes the events
|
||||
generated in the kernel straight to the program, with timestamps. The
|
||||
event codes are the same on all architectures and are hardware
|
||||
independent.
|
||||
|
||||
This is the preferred interface for userspace to consume user
|
||||
input, and all clients are encouraged to use it.
|
||||
|
||||
See :ref:`event-interface` for notes on API.
|
||||
|
||||
The devices are in /dev/input::
|
||||
|
||||
crw-r--r-- 1 root root 13, 64 Apr 1 10:49 event0
|
||||
crw-r--r-- 1 root root 13, 65 Apr 1 10:50 event1
|
||||
crw-r--r-- 1 root root 13, 66 Apr 1 10:50 event2
|
||||
crw-r--r-- 1 root root 13, 67 Apr 1 10:50 event3
|
||||
...
|
||||
|
||||
There are two ranges of minors: 64 through 95 is the static legacy
|
||||
range. If there are more than 32 input devices in a system, additional
|
||||
evdev nodes are created with minors starting with 256.
|
||||
|
||||
keyboard
|
||||
~~~~~~~~
|
||||
|
||||
``keyboard`` is in-kernel input handler ad is a part of VT code. It
|
||||
consumes keyboard keystrokes and handles user input for VT consoles.
|
||||
|
||||
mousedev
|
||||
~~~~~~~~
|
||||
|
||||
``mousedev`` is a hack to make legacy programs that use mouse input
|
||||
work. It takes events from either mice or digitizers/tablets and makes
|
||||
a PS/2-style (a la /dev/psaux) mouse device available to the
|
||||
userland.
|
||||
|
||||
Mousedev devices in /dev/input (as shown above) are::
|
||||
|
||||
crw-r--r-- 1 root root 13, 32 Mar 28 22:45 mouse0
|
||||
crw-r--r-- 1 root root 13, 33 Mar 29 00:41 mouse1
|
||||
crw-r--r-- 1 root root 13, 34 Mar 29 00:41 mouse2
|
||||
crw-r--r-- 1 root root 13, 35 Apr 1 10:50 mouse3
|
||||
...
|
||||
...
|
||||
crw-r--r-- 1 root root 13, 62 Apr 1 10:50 mouse30
|
||||
crw-r--r-- 1 root root 13, 63 Apr 1 10:50 mice
|
||||
|
||||
Each ``mouse`` device is assigned to a single mouse or digitizer, except
|
||||
the last one - ``mice``. This single character device is shared by all
|
||||
mice and digitizers, and even if none are connected, the device is
|
||||
present. This is useful for hotplugging USB mice, so that older programs
|
||||
that do not handle hotplug can open the device even when no mice are
|
||||
present.
|
||||
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_[XY] in the kernel configuration are
|
||||
the size of your screen (in pixels) in XFree86. This is needed if you
|
||||
want to use your digitizer in X, because its movement is sent to X
|
||||
via a virtual PS/2 mouse and thus needs to be scaled
|
||||
accordingly. These values won't be used if you use a mouse only.
|
||||
|
||||
Mousedev will generate either PS/2, ImPS/2 (Microsoft IntelliMouse) or
|
||||
ExplorerPS/2 (IntelliMouse Explorer) protocols, depending on what the
|
||||
program reading the data wishes. You can set GPM and X to any of
|
||||
these. You'll need ImPS/2 if you want to make use of a wheel on a USB
|
||||
mouse and ExplorerPS/2 if you want to use extra (up to 5) buttons.
|
||||
|
||||
joydev
|
||||
~~~~~~
|
||||
|
||||
``joydev`` implements v0.x and v1.x Linux joystick API. See
|
||||
:ref:`joystick-api` for details.
|
||||
|
||||
As soon as any joystick is connected, it can be accessed in /dev/input on::
|
||||
|
||||
crw-r--r-- 1 root root 13, 0 Apr 1 10:50 js0
|
||||
crw-r--r-- 1 root root 13, 1 Apr 1 10:50 js1
|
||||
crw-r--r-- 1 root root 13, 2 Apr 1 10:50 js2
|
||||
crw-r--r-- 1 root root 13, 3 Apr 1 10:50 js3
|
||||
...
|
||||
|
||||
And so on up to js31 in legacy range, and additional nodes with minors
|
||||
above 256 if there are more joystick devices.
|
||||
|
||||
Device drivers
|
||||
--------------
|
||||
|
||||
Device drivers are the modules that generate events.
|
||||
|
||||
hid-generic
|
||||
~~~~~~~~~~~
|
||||
|
||||
``hid-generic`` is one of the largest and most complex driver of the
|
||||
whole suite. It handles all HID devices, and because there is a very
|
||||
wide variety of them, and because the USB HID specification isn't
|
||||
simple, it needs to be this big.
|
||||
|
||||
Currently, it handles USB mice, joysticks, gamepads, steering wheels
|
||||
keyboards, trackballs and digitizers.
|
||||
|
||||
However, USB uses HID also for monitor controls, speaker controls, UPSs,
|
||||
LCDs and many other purposes.
|
||||
|
||||
The monitor and speaker controls should be easy to add to the hid/input
|
||||
interface, but for the UPSs and LCDs it doesn't make much sense. For this,
|
||||
the hiddev interface was designed. See Documentation/hid/hiddev.txt
|
||||
for more information about it.
|
||||
|
||||
The usage of the usbhid module is very simple, it takes no parameters,
|
||||
detects everything automatically and when a HID device is inserted, it
|
||||
detects it appropriately.
|
||||
|
||||
However, because the devices vary wildly, you might happen to have a
|
||||
device that doesn't work well. In that case #define DEBUG at the beginning
|
||||
of hid-core.c and send me the syslog traces.
|
||||
|
||||
usbmouse
|
||||
~~~~~~~~
|
||||
|
||||
For embedded systems, for mice with broken HID descriptors and just any
|
||||
other use when the big usbhid wouldn't be a good choice, there is the
|
||||
usbmouse driver. It handles USB mice only. It uses a simpler HIDBP
|
||||
protocol. This also means the mice must support this simpler protocol. Not
|
||||
all do. If you don't have any strong reason to use this module, use usbhid
|
||||
instead.
|
||||
|
||||
usbkbd
|
||||
~~~~~~
|
||||
|
||||
Much like usbmouse, this module talks to keyboards with a simplified
|
||||
HIDBP protocol. It's smaller, but doesn't support any extra special keys.
|
||||
Use usbhid instead if there isn't any special reason to use this.
|
||||
|
||||
psmouse
|
||||
~~~~~~~
|
||||
|
||||
This is driver for all flavors of pointing devices using PS/2
|
||||
protocol, including Synaptics and ALPS touchpads, Intellimouse
|
||||
Explorer devices, Logitech PS/2 mice and so on.
|
||||
|
||||
atkbd
|
||||
~~~~~
|
||||
|
||||
This is driver for PS/2 (AT) keyboards.
|
||||
|
||||
iforce
|
||||
~~~~~~
|
||||
|
||||
A driver for I-Force joysticks and wheels, both over USB and RS232.
|
||||
It includes Force Feedback support now, even though Immersion
|
||||
Corp. considers the protocol a trade secret and won't disclose a word
|
||||
about it.
|
||||
|
||||
Verifying if it works
|
||||
=====================
|
||||
|
||||
Typing a couple keys on the keyboard should be enough to check that
|
||||
a keyboard works and is correctly connected to the kernel keyboard
|
||||
driver.
|
||||
|
||||
Doing a ``cat /dev/input/mouse0`` (c, 13, 32) will verify that a mouse
|
||||
is also emulated; characters should appear if you move it.
|
||||
|
||||
You can test the joystick emulation with the ``jstest`` utility,
|
||||
available in the joystick package (see :ref:`joystick-doc`).
|
||||
|
||||
You can test the event devices with the ``evtest`` utility.
|
||||
|
||||
.. _event-interface:
|
||||
|
||||
Event interface
|
||||
===============
|
||||
|
||||
You can use blocking and nonblocking reads, and also select() on the
|
||||
/dev/input/eventX devices, and you'll always get a whole number of input
|
||||
events on a read. Their layout is::
|
||||
|
||||
struct input_event {
|
||||
struct timeval time;
|
||||
unsigned short type;
|
||||
unsigned short code;
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
``time`` is the timestamp, it returns the time at which the event happened.
|
||||
Type is for example EV_REL for relative moment, EV_KEY for a keypress or
|
||||
release. More types are defined in include/uapi/linux/input-event-codes.h.
|
||||
|
||||
``code`` is event code, for example REL_X or KEY_BACKSPACE, again a complete
|
||||
list is in include/uapi/linux/input-event-codes.h.
|
||||
|
||||
``value`` is the value the event carries. Either a relative change for
|
||||
EV_REL, absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for
|
||||
release, 1 for keypress and 2 for autorepeat.
|
||||
|
||||
See :ref:`input-event-codes` for more information about various even codes.
|
|
@ -1,290 +0,0 @@
|
|||
Linux Input drivers v1.0
|
||||
(c) 1999-2001 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
Sponsored by SuSE
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
0. Disclaimer
|
||||
~~~~~~~~~~~~~
|
||||
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 the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Should you need to contact me, the author, you can do so either by e-mail
|
||||
- mail your message to <vojtech@ucw.cz>, or by paper mail: Vojtech Pavlik,
|
||||
Simunkova 1594, Prague 8, 182 00 Czech Republic
|
||||
|
||||
For your convenience, the GNU General Public License version 2 is included
|
||||
in the package: See the file COPYING.
|
||||
|
||||
1. Introduction
|
||||
~~~~~~~~~~~~~~~
|
||||
This is a collection of drivers that is designed to support all input
|
||||
devices under Linux. While it is currently used only on for USB input
|
||||
devices, future use (say 2.5/2.6) is expected to expand to replace
|
||||
most of the existing input system, which is why it lives in
|
||||
drivers/input/ instead of drivers/usb/.
|
||||
|
||||
The centre of the input drivers is the input module, which must be
|
||||
loaded before any other of the input modules - it serves as a way of
|
||||
communication between two groups of modules:
|
||||
|
||||
1.1 Device drivers
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
These modules talk to the hardware (for example via USB), and provide
|
||||
events (keystrokes, mouse movements) to the input module.
|
||||
|
||||
1.2 Event handlers
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
These modules get events from input and pass them where needed via
|
||||
various interfaces - keystrokes to the kernel, mouse movements via a
|
||||
simulated PS/2 interface to GPM and X and so on.
|
||||
|
||||
2. Simple Usage
|
||||
~~~~~~~~~~~~~~~
|
||||
For the most usual configuration, with one USB mouse and one USB keyboard,
|
||||
you'll have to load the following modules (or have them built in to the
|
||||
kernel):
|
||||
|
||||
input
|
||||
mousedev
|
||||
keybdev
|
||||
usbcore
|
||||
uhci_hcd or ohci_hcd or ehci_hcd
|
||||
usbhid
|
||||
|
||||
After this, the USB keyboard will work straight away, and the USB mouse
|
||||
will be available as a character device on major 13, minor 63:
|
||||
|
||||
crw-r--r-- 1 root root 13, 63 Mar 28 22:45 mice
|
||||
|
||||
This device has to be created.
|
||||
The commands to create it by hand are:
|
||||
|
||||
cd /dev
|
||||
mkdir input
|
||||
mknod input/mice c 13 63
|
||||
|
||||
After that you have to point GPM (the textmode mouse cut&paste tool) and
|
||||
XFree to this device to use it - GPM should be called like:
|
||||
|
||||
gpm -t ps2 -m /dev/input/mice
|
||||
|
||||
And in X:
|
||||
|
||||
Section "Pointer"
|
||||
Protocol "ImPS/2"
|
||||
Device "/dev/input/mice"
|
||||
ZAxisMapping 4 5
|
||||
EndSection
|
||||
|
||||
When you do all of the above, you can use your USB mouse and keyboard.
|
||||
|
||||
3. Detailed Description
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
3.1 Device drivers
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Device drivers are the modules that generate events. The events are
|
||||
however not useful without being handled, so you also will need to use some
|
||||
of the modules from section 3.2.
|
||||
|
||||
3.1.1 usbhid
|
||||
~~~~~~~~~~~~
|
||||
usbhid is the largest and most complex driver of the whole suite. It
|
||||
handles all HID devices, and because there is a very wide variety of them,
|
||||
and because the USB HID specification isn't simple, it needs to be this big.
|
||||
|
||||
Currently, it handles USB mice, joysticks, gamepads, steering wheels
|
||||
keyboards, trackballs and digitizers.
|
||||
|
||||
However, USB uses HID also for monitor controls, speaker controls, UPSs,
|
||||
LCDs and many other purposes.
|
||||
|
||||
The monitor and speaker controls should be easy to add to the hid/input
|
||||
interface, but for the UPSs and LCDs it doesn't make much sense. For this,
|
||||
the hiddev interface was designed. See Documentation/hid/hiddev.txt
|
||||
for more information about it.
|
||||
|
||||
The usage of the usbhid module is very simple, it takes no parameters,
|
||||
detects everything automatically and when a HID device is inserted, it
|
||||
detects it appropriately.
|
||||
|
||||
However, because the devices vary wildly, you might happen to have a
|
||||
device that doesn't work well. In that case #define DEBUG at the beginning
|
||||
of hid-core.c and send me the syslog traces.
|
||||
|
||||
3.1.2 usbmouse
|
||||
~~~~~~~~~~~~~~
|
||||
For embedded systems, for mice with broken HID descriptors and just any
|
||||
other use when the big usbhid wouldn't be a good choice, there is the
|
||||
usbmouse driver. It handles USB mice only. It uses a simpler HIDBP
|
||||
protocol. This also means the mice must support this simpler protocol. Not
|
||||
all do. If you don't have any strong reason to use this module, use usbhid
|
||||
instead.
|
||||
|
||||
3.1.3 usbkbd
|
||||
~~~~~~~~~~~~
|
||||
Much like usbmouse, this module talks to keyboards with a simplified
|
||||
HIDBP protocol. It's smaller, but doesn't support any extra special keys.
|
||||
Use usbhid instead if there isn't any special reason to use this.
|
||||
|
||||
3.1.4 wacom
|
||||
~~~~~~~~~~~
|
||||
This is a driver for Wacom Graphire and Intuos tablets. Not for Wacom
|
||||
PenPartner, that one is handled by the HID driver. Although the Intuos and
|
||||
Graphire tablets claim that they are HID tablets as well, they are not and
|
||||
thus need this specific driver.
|
||||
|
||||
3.1.5 iforce
|
||||
~~~~~~~~~~~~
|
||||
A driver for I-Force joysticks and wheels, both over USB and RS232.
|
||||
It includes ForceFeedback support now, even though Immersion
|
||||
Corp. considers the protocol a trade secret and won't disclose a word
|
||||
about it.
|
||||
|
||||
3.2 Event handlers
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Event handlers distribute the events from the devices to userland and
|
||||
kernel, as needed.
|
||||
|
||||
3.2.1 keybdev
|
||||
~~~~~~~~~~~~~
|
||||
keybdev is currently a rather ugly hack that translates the input
|
||||
events into architecture-specific keyboard raw mode (Xlated AT Set2 on
|
||||
x86), and passes them into the handle_scancode function of the
|
||||
keyboard.c module. This works well enough on all architectures that
|
||||
keybdev can generate rawmode on, other architectures can be added to
|
||||
it.
|
||||
|
||||
The right way would be to pass the events to keyboard.c directly,
|
||||
best if keyboard.c would itself be an event handler. This is done in
|
||||
the input patch, available on the webpage mentioned below.
|
||||
|
||||
3.2.2 mousedev
|
||||
~~~~~~~~~~~~~~
|
||||
mousedev is also a hack to make programs that use mouse input
|
||||
work. It takes events from either mice or digitizers/tablets and makes
|
||||
a PS/2-style (a la /dev/psaux) mouse device available to the
|
||||
userland. Ideally, the programs could use a more reasonable interface,
|
||||
for example evdev
|
||||
|
||||
Mousedev devices in /dev/input (as shown above) are:
|
||||
|
||||
crw-r--r-- 1 root root 13, 32 Mar 28 22:45 mouse0
|
||||
crw-r--r-- 1 root root 13, 33 Mar 29 00:41 mouse1
|
||||
crw-r--r-- 1 root root 13, 34 Mar 29 00:41 mouse2
|
||||
crw-r--r-- 1 root root 13, 35 Apr 1 10:50 mouse3
|
||||
...
|
||||
...
|
||||
crw-r--r-- 1 root root 13, 62 Apr 1 10:50 mouse30
|
||||
crw-r--r-- 1 root root 13, 63 Apr 1 10:50 mice
|
||||
|
||||
Each 'mouse' device is assigned to a single mouse or digitizer, except
|
||||
the last one - 'mice'. This single character device is shared by all
|
||||
mice and digitizers, and even if none are connected, the device is
|
||||
present. This is useful for hotplugging USB mice, so that programs
|
||||
can open the device even when no mice are present.
|
||||
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_[XY] in the kernel configuration are
|
||||
the size of your screen (in pixels) in XFree86. This is needed if you
|
||||
want to use your digitizer in X, because its movement is sent to X
|
||||
via a virtual PS/2 mouse and thus needs to be scaled
|
||||
accordingly. These values won't be used if you use a mouse only.
|
||||
|
||||
Mousedev will generate either PS/2, ImPS/2 (Microsoft IntelliMouse) or
|
||||
ExplorerPS/2 (IntelliMouse Explorer) protocols, depending on what the
|
||||
program reading the data wishes. You can set GPM and X to any of
|
||||
these. You'll need ImPS/2 if you want to make use of a wheel on a USB
|
||||
mouse and ExplorerPS/2 if you want to use extra (up to 5) buttons.
|
||||
|
||||
3.2.3 joydev
|
||||
~~~~~~~~~~~~
|
||||
Joydev implements v0.x and v1.x Linux joystick api, much like
|
||||
drivers/char/joystick/joystick.c used to in earlier versions. See
|
||||
joystick-api.txt in the Documentation subdirectory for details. As
|
||||
soon as any joystick is connected, it can be accessed in /dev/input
|
||||
on:
|
||||
|
||||
crw-r--r-- 1 root root 13, 0 Apr 1 10:50 js0
|
||||
crw-r--r-- 1 root root 13, 1 Apr 1 10:50 js1
|
||||
crw-r--r-- 1 root root 13, 2 Apr 1 10:50 js2
|
||||
crw-r--r-- 1 root root 13, 3 Apr 1 10:50 js3
|
||||
...
|
||||
|
||||
And so on up to js31.
|
||||
|
||||
3.2.4 evdev
|
||||
~~~~~~~~~~~
|
||||
evdev is the generic input event interface. It passes the events
|
||||
generated in the kernel straight to the program, with timestamps. The
|
||||
API is still evolving, but should be usable now. It's described in
|
||||
section 5.
|
||||
|
||||
This should be the way for GPM and X to get keyboard and mouse
|
||||
events. It allows for multihead in X without any specific multihead
|
||||
kernel support. The event codes are the same on all architectures and
|
||||
are hardware independent.
|
||||
|
||||
The devices are in /dev/input:
|
||||
|
||||
crw-r--r-- 1 root root 13, 64 Apr 1 10:49 event0
|
||||
crw-r--r-- 1 root root 13, 65 Apr 1 10:50 event1
|
||||
crw-r--r-- 1 root root 13, 66 Apr 1 10:50 event2
|
||||
crw-r--r-- 1 root root 13, 67 Apr 1 10:50 event3
|
||||
...
|
||||
|
||||
And so on up to event31.
|
||||
|
||||
4. Verifying if it works
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Typing a couple keys on the keyboard should be enough to check that
|
||||
a USB keyboard works and is correctly connected to the kernel keyboard
|
||||
driver.
|
||||
|
||||
Doing a "cat /dev/input/mouse0" (c, 13, 32) will verify that a mouse
|
||||
is also emulated; characters should appear if you move it.
|
||||
|
||||
You can test the joystick emulation with the 'jstest' utility,
|
||||
available in the joystick package (see Documentation/input/joystick.txt).
|
||||
|
||||
You can test the event devices with the 'evtest' utility available
|
||||
in the LinuxConsole project CVS archive (see the URL below).
|
||||
|
||||
5. Event interface
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
Should you want to add event device support into any application (X, gpm,
|
||||
svgalib ...) I <vojtech@ucw.cz> will be happy to provide you any help I
|
||||
can. Here goes a description of the current state of things, which is going
|
||||
to be extended, but not changed incompatibly as time goes:
|
||||
|
||||
You can use blocking and nonblocking reads, also select() on the
|
||||
/dev/input/eventX devices, and you'll always get a whole number of input
|
||||
events on a read. Their layout is:
|
||||
|
||||
struct input_event {
|
||||
struct timeval time;
|
||||
unsigned short type;
|
||||
unsigned short code;
|
||||
unsigned int value;
|
||||
};
|
||||
|
||||
'time' is the timestamp, it returns the time at which the event happened.
|
||||
Type is for example EV_REL for relative moment, EV_KEY for a keypress or
|
||||
release. More types are defined in include/uapi/linux/input-event-codes.h.
|
||||
|
||||
'code' is event code, for example REL_X or KEY_BACKSPACE, again a complete
|
||||
list is in include/uapi/linux/input-event-codes.h.
|
||||
|
||||
'value' is the value the event carries. Either a relative change for
|
||||
EV_REL, absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for
|
||||
release, 1 for keypress and 2 for autorepeat.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
################################
|
||||
Linux Input Subsystem kernel API
|
||||
################################
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
|
||||
input-programming
|
||||
gameport-programming
|
||||
notifier
|
|
@ -0,0 +1,22 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
###################################
|
||||
Linux Input Subsystem userspace API
|
||||
###################################
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
|
||||
input
|
||||
event-codes
|
||||
multi-touch-protocol
|
||||
gamepad
|
||||
ff
|
||||
joydev/index
|
||||
uinput
|
||||
userio
|
|
@ -1,42 +0,0 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 6
|
||||
1200 3600 1800 3600 2400 4800 3000 4800 4200 5700 4800 5700
|
||||
2 2 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5
|
||||
1200 3150 4800 3150 4800 6300 1200 6300 1200 3150
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
1200 4800 4800 4800
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 4
|
||||
2400 4800 2400 6525 1950 7125 1950 7800
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 4
|
||||
3000 4800 3000 6525 3600 7125 3600 7800
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 1 3
|
||||
0 0 1.00 60.00 120.00
|
||||
3825 5400 4125 5100 5400 5100
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 1 3
|
||||
0 0 1.00 60.00 120.00
|
||||
2100 4200 2400 3900 5400 3900
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
4800 5700 5400 5700
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
1800 3600 5400 3600
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 1 3
|
||||
0 0 1.00 60.00 120.00
|
||||
2700 4800 2700 4425 5400 4425
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
0 0 1.00 60.00 120.00
|
||||
1950 7800 3600 7800
|
||||
4 1 0 50 0 0 12 0.0000 4 135 810 2775 7725 Dead band\001
|
||||
4 0 0 50 0 0 12 0.0000 4 180 1155 5400 5700 right saturation\001
|
||||
4 0 0 50 0 0 12 0.0000 4 135 1065 5400 3600 left saturation\001
|
||||
4 0 0 50 0 0 12 0.0000 4 180 2505 5400 3900 left coeff ( positive in that case )\001
|
||||
4 0 0 50 0 0 12 0.0000 4 180 2640 5475 5100 right coeff ( negative in that case )\001
|
||||
4 0 0 50 0 0 12 0.0000 4 105 480 5400 4425 center\001
|
|
@ -0,0 +1,24 @@
|
|||
<svg width="5.75in" height="3.90in" version="1.1" viewBox="1178 3138 6779.9424 4671.3427" xmlns="http://www.w3.org/2000/svg">
|
||||
<polyline transform="translate(-18.5,-16.294)" points="1200 3600 1800 3600 2400 4800 3e3 4800 4200 5700 4800 5700" fill="none" stroke="#000" stroke-width="15"/>
|
||||
<rect x="1181.5" y="3133.7" width="3600" height="3150" rx="0" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="1200 4800 4800 4800" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="2400 4800 2400 6525 1950 7125 1950 7800" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="3e3 4800 3e3 6525 3600 7125 3600 7800" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="3837 5389 4125 5100 5400 5100" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="3889 5292 3826 5398 3932 5334" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="2112 4189 2400 3900 5400 3900" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="2164 4092 2101 4198 2207 4134" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="4800 5700 5400 5700" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="1800 3600 5400 3600" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="2700 4784 2700 4425 5400 4425" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="2670 4678 2700 4798 2730 4678" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="1967 7800 3583 7800" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="3478 7830 3598 7800 3478 7770" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-18.5,-16.294)" points="2072 7770 1952 7800 2072 7830" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<text x="2775" y="7725" font-family="sans-serif" font-size="144px" stroke="#000000" stroke-width=".025in" text-anchor="middle" xml:space="preserve">Dead band</text>
|
||||
<text x="5400" y="5700" font-family="sans-serif" font-size="144px" stroke="#000000" stroke-width=".025in" xml:space="preserve">right saturation</text>
|
||||
<text x="5400" y="3600" font-family="sans-serif" font-size="144px" stroke="#000000" stroke-width=".025in" xml:space="preserve">left saturation</text>
|
||||
<text x="5400" y="3900" font-family="sans-serif" font-size="144px" stroke="#000000" stroke-width=".025in" xml:space="preserve">left coeff ( positive in that case )</text>
|
||||
<text x="5475" y="5100" font-family="sans-serif" font-size="144px" stroke="#000000" stroke-width=".025in" xml:space="preserve">right coeff ( negative in that case )</text>
|
||||
<text x="5400" y="4425" font-family="sans-serif" font-size="144px" stroke="#000000" stroke-width=".025in" xml:space="preserve">center</text>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 3.3 KiB |
|
@ -0,0 +1,18 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
======================
|
||||
Linux Joystick support
|
||||
======================
|
||||
|
||||
:Copyright: |copy| 1996-2000 Vojtech Pavlik <vojtech@ucw.cz> - Sponsored by SuSE
|
||||
|
||||
.. class:: toc-title
|
||||
|
||||
Table of Contents
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:numbered:
|
||||
|
||||
joystick
|
||||
joystick-api
|
|
@ -1,31 +1,54 @@
|
|||
Joystick API Documentation -*-Text-*-
|
||||
.. _joystick-api:
|
||||
|
||||
Ragnar Hojland Espinosa
|
||||
<ragnar@macula.net>
|
||||
=====================
|
||||
Programming Interface
|
||||
=====================
|
||||
|
||||
7 Aug 1998
|
||||
:Author: Ragnar Hojland Espinosa <ragnar@macula.net> - 7 Aug 1998
|
||||
|
||||
1. Initialization
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Introduction
|
||||
============
|
||||
|
||||
.. important::
|
||||
This document describes legacy ``js`` interface. Newer clients are
|
||||
encouraged to switch to the generic event (``evdev``) interface.
|
||||
|
||||
The 1.0 driver uses a new, event based approach to the joystick driver.
|
||||
Instead of the user program polling for the joystick values, the joystick
|
||||
driver now reports only any changes of its state. See joystick-api.txt,
|
||||
joystick.h and jstest.c included in the joystick package for more
|
||||
information. The joystick device can be used in either blocking or
|
||||
nonblocking mode, and supports select() calls.
|
||||
|
||||
For backward compatibility the old (v0.x) interface is still included.
|
||||
Any call to the joystick driver using the old interface will return values
|
||||
that are compatible to the old interface. This interface is still limited
|
||||
to 2 axes, and applications using it usually decode only 2 buttons, although
|
||||
the driver provides up to 32.
|
||||
|
||||
Initialization
|
||||
==============
|
||||
|
||||
Open the joystick device following the usual semantics (that is, with open).
|
||||
Since the driver now reports events instead of polling for changes,
|
||||
immediately after the open it will issue a series of synthetic events
|
||||
(JS_EVENT_INIT) that you can read to check the initial state of the
|
||||
(JS_EVENT_INIT) that you can read to obtain the initial state of the
|
||||
joystick.
|
||||
|
||||
By default, the device is opened in blocking mode.
|
||||
By default, the device is opened in blocking mode::
|
||||
|
||||
int fd = open ("/dev/input/js0", O_RDONLY);
|
||||
|
||||
|
||||
2. Event Reading
|
||||
~~~~~~~~~~~~~~~~
|
||||
Event Reading
|
||||
=============
|
||||
|
||||
::
|
||||
|
||||
struct js_event e;
|
||||
read (fd, &e, sizeof(e));
|
||||
|
||||
where js_event is defined as
|
||||
where js_event is defined as::
|
||||
|
||||
struct js_event {
|
||||
__u32 time; /* event timestamp in milliseconds */
|
||||
|
@ -38,10 +61,10 @@ If the read is successful, it will return sizeof(e), unless you wanted to read
|
|||
more than one event per read as described in section 3.1.
|
||||
|
||||
|
||||
2.1 js_event.type
|
||||
~~~~~~~~~~~~~~~~~
|
||||
js_event.type
|
||||
-------------
|
||||
|
||||
The possible values of ``type'' are
|
||||
The possible values of ``type`` are::
|
||||
|
||||
#define JS_EVENT_BUTTON 0x01 /* button pressed/released */
|
||||
#define JS_EVENT_AXIS 0x02 /* joystick moved */
|
||||
|
@ -49,47 +72,50 @@ The possible values of ``type'' are
|
|||
|
||||
As mentioned above, the driver will issue synthetic JS_EVENT_INIT ORed
|
||||
events on open. That is, if it's issuing a INIT BUTTON event, the
|
||||
current type value will be
|
||||
current type value will be::
|
||||
|
||||
int type = JS_EVENT_BUTTON | JS_EVENT_INIT; /* 0x81 */
|
||||
|
||||
If you choose not to differentiate between synthetic or real events
|
||||
you can turn off the JS_EVENT_INIT bits
|
||||
you can turn off the JS_EVENT_INIT bits::
|
||||
|
||||
type &= ~JS_EVENT_INIT; /* 0x01 */
|
||||
|
||||
|
||||
2.2 js_event.number
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
js_event.number
|
||||
---------------
|
||||
|
||||
The values of ``number'' correspond to the axis or button that
|
||||
The values of ``number`` correspond to the axis or button that
|
||||
generated the event. Note that they carry separate numeration (that
|
||||
is, you have both an axis 0 and a button 0). Generally,
|
||||
|
||||
number
|
||||
=============== =======
|
||||
Axis number
|
||||
=============== =======
|
||||
1st Axis X 0
|
||||
1st Axis Y 1
|
||||
2nd Axis X 2
|
||||
2nd Axis Y 3
|
||||
...and so on
|
||||
=============== =======
|
||||
|
||||
Hats vary from one joystick type to another. Some can be moved in 8
|
||||
directions, some only in 4, The driver, however, always reports a hat as two
|
||||
independent axis, even if the hardware doesn't allow independent movement.
|
||||
|
||||
|
||||
2.3 js_event.value
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
js_event.value
|
||||
--------------
|
||||
|
||||
For an axis, ``value'' is a signed integer between -32767 and +32767
|
||||
For an axis, ``value`` is a signed integer between -32767 and +32767
|
||||
representing the position of the joystick along that axis. If you
|
||||
don't read a 0 when the joystick is `dead', or if it doesn't span the
|
||||
don't read a 0 when the joystick is ``dead``, or if it doesn't span the
|
||||
full range, you should recalibrate it (with, for example, jscal).
|
||||
|
||||
For a button, ``value'' for a press button event is 1 and for a release
|
||||
For a button, ``value`` for a press button event is 1 and for a release
|
||||
button event is 0.
|
||||
|
||||
Though this
|
||||
Though this::
|
||||
|
||||
if (js_event.type == JS_EVENT_BUTTON) {
|
||||
buttons_state ^= (1 << js_event.number);
|
||||
|
@ -97,6 +123,8 @@ Though this
|
|||
|
||||
may work well if you handle JS_EVENT_INIT events separately,
|
||||
|
||||
::
|
||||
|
||||
if ((js_event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) {
|
||||
if (js_event.value)
|
||||
buttons_state |= (1 << js_event.number);
|
||||
|
@ -109,17 +137,17 @@ have to write a separate handler for JS_EVENT_INIT events in the first
|
|||
snippet, this ends up being shorter.
|
||||
|
||||
|
||||
2.4 js_event.time
|
||||
~~~~~~~~~~~~~~~~~
|
||||
js_event.time
|
||||
-------------
|
||||
|
||||
The time an event was generated is stored in ``js_event.time''. It's a time
|
||||
The time an event was generated is stored in ``js_event.time``. It's a time
|
||||
in milliseconds since ... well, since sometime in the past. This eases the
|
||||
task of detecting double clicks, figuring out if movement of axis and button
|
||||
presses happened at the same time, and similar.
|
||||
|
||||
|
||||
3. Reading
|
||||
~~~~~~~~~~
|
||||
Reading
|
||||
=======
|
||||
|
||||
If you open the device in blocking mode, a read will block (that is,
|
||||
wait) forever until an event is generated and effectively read. There
|
||||
|
@ -133,8 +161,8 @@ admittedly, a long time;)
|
|||
b) open the device in non-blocking mode (O_NONBLOCK)
|
||||
|
||||
|
||||
3.1 O_NONBLOCK
|
||||
~~~~~~~~~~~~~~
|
||||
O_NONBLOCK
|
||||
----------
|
||||
|
||||
If read returns -1 when reading in O_NONBLOCK mode, this isn't
|
||||
necessarily a "real" error (check errno(3)); it can just mean there
|
||||
|
@ -143,6 +171,8 @@ all events on the queue (that is, until you get a -1).
|
|||
|
||||
For example,
|
||||
|
||||
::
|
||||
|
||||
while (1) {
|
||||
while (read (fd, &e, sizeof(e)) > 0) {
|
||||
process_event (e);
|
||||
|
@ -171,14 +201,17 @@ the driver will switch to startup mode and next time you read it,
|
|||
synthetic events (JS_EVENT_INIT) will be generated to inform you of
|
||||
the actual state of the joystick.
|
||||
|
||||
[As for version 1.2.8, the queue is circular and able to hold 64
|
||||
|
||||
.. note::
|
||||
|
||||
As of version 1.2.8, the queue is circular and able to hold 64
|
||||
events. You can increment this size bumping up JS_BUFF_SIZE in
|
||||
joystick.h and recompiling the driver.]
|
||||
joystick.h and recompiling the driver.
|
||||
|
||||
|
||||
In the above code, you might as well want to read more than one event
|
||||
at a time using the typical read(2) functionality. For that, you would
|
||||
replace the read above with something like
|
||||
replace the read above with something like::
|
||||
|
||||
struct js_event mybuffer[0xff];
|
||||
int i = read (fd, mybuffer, sizeof(mybuffer));
|
||||
|
@ -189,10 +222,10 @@ sizeof(js_event) Again, if the buffer was full, it's a good idea to
|
|||
process the events and keep reading it until you empty the driver queue.
|
||||
|
||||
|
||||
4. IOCTLs
|
||||
~~~~~~~~~
|
||||
IOCTLs
|
||||
======
|
||||
|
||||
The joystick driver defines the following ioctl(2) operations.
|
||||
The joystick driver defines the following ioctl(2) operations::
|
||||
|
||||
/* function 3rd arg */
|
||||
#define JSIOCGAXES /* get number of axes char */
|
||||
|
@ -202,31 +235,31 @@ The joystick driver defines the following ioctl(2) operations.
|
|||
#define JSIOCSCORR /* set correction values &js_corr */
|
||||
#define JSIOCGCORR /* get correction values &js_corr */
|
||||
|
||||
For example, to read the number of axes
|
||||
For example, to read the number of axes::
|
||||
|
||||
char number_of_axes;
|
||||
ioctl (fd, JSIOCGAXES, &number_of_axes);
|
||||
|
||||
|
||||
4.1 JSIOGCVERSION
|
||||
~~~~~~~~~~~~~~~~~
|
||||
JSIOGCVERSION
|
||||
-------------
|
||||
|
||||
JSIOGCVERSION is a good way to check in run-time whether the running
|
||||
driver is 1.0+ and supports the event interface. If it is not, the
|
||||
IOCTL will fail. For a compile-time decision, you can test the
|
||||
JS_VERSION symbol
|
||||
JS_VERSION symbol::
|
||||
|
||||
#ifdef JS_VERSION
|
||||
#if JS_VERSION > 0xsomething
|
||||
|
||||
|
||||
4.2 JSIOCGNAME
|
||||
~~~~~~~~~~~~~~
|
||||
JSIOCGNAME
|
||||
----------
|
||||
|
||||
JSIOCGNAME(len) allows you to get the name string of the joystick - the same
|
||||
as is being printed at boot time. The 'len' argument is the length of the
|
||||
buffer provided by the application asking for the name. It is used to avoid
|
||||
possible overrun should the name be too long.
|
||||
possible overrun should the name be too long::
|
||||
|
||||
char name[128];
|
||||
if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0)
|
||||
|
@ -234,8 +267,8 @@ possible overrun should the name be too long.
|
|||
printf("Name: %s\n", name);
|
||||
|
||||
|
||||
4.3 JSIOC[SG]CORR
|
||||
~~~~~~~~~~~~~~~~~
|
||||
JSIOC[SG]CORR
|
||||
-------------
|
||||
|
||||
For usage on JSIOC[SG]CORR I suggest you to look into jscal.c They are
|
||||
not needed in a normal program, only in joystick calibration software
|
||||
|
@ -246,7 +279,7 @@ warning in following releases of the driver.
|
|||
Both JSIOCSCORR and JSIOCGCORR expect &js_corr to be able to hold
|
||||
information for all axis. That is, struct js_corr corr[MAX_AXIS];
|
||||
|
||||
struct js_corr is defined as
|
||||
struct js_corr is defined as::
|
||||
|
||||
struct js_corr {
|
||||
__s32 coef[8];
|
||||
|
@ -254,17 +287,17 @@ struct js_corr is defined as
|
|||
__u16 type;
|
||||
};
|
||||
|
||||
and ``type''
|
||||
and ``type``::
|
||||
|
||||
#define JS_CORR_NONE 0x00 /* returns raw values */
|
||||
#define JS_CORR_BROKEN 0x01 /* broken line */
|
||||
|
||||
|
||||
5. Backward compatibility
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Backward compatibility
|
||||
======================
|
||||
|
||||
The 0.x joystick driver API is quite limited and its usage is deprecated.
|
||||
The driver offers backward compatibility, though. Here's a quick summary:
|
||||
The driver offers backward compatibility, though. Here's a quick summary::
|
||||
|
||||
struct JS_DATA_TYPE js;
|
||||
while (1) {
|
||||
|
@ -275,7 +308,7 @@ The driver offers backward compatibility, though. Here's a quick summary:
|
|||
}
|
||||
|
||||
As you can figure out from the example, the read returns immediately,
|
||||
with the actual state of the joystick.
|
||||
with the actual state of the joystick::
|
||||
|
||||
struct JS_DATA_TYPE {
|
||||
int buttons; /* immediate button state */
|
||||
|
@ -283,12 +316,14 @@ with the actual state of the joystick.
|
|||
int y; /* immediate y axis value */
|
||||
};
|
||||
|
||||
and JS_RETURN is defined as
|
||||
and JS_RETURN is defined as::
|
||||
|
||||
#define JS_RETURN sizeof(struct JS_DATA_TYPE)
|
||||
|
||||
To test the state of the buttons,
|
||||
|
||||
::
|
||||
|
||||
first_button_state = js.buttons & 1;
|
||||
second_button_state = js.buttons & 2;
|
||||
|
||||
|
@ -302,13 +337,12 @@ called Multisystem joysticks in this driver), under /dev/djsX. This driver
|
|||
doesn't try to be compatible with that interface.
|
||||
|
||||
|
||||
6. Final Notes
|
||||
~~~~~~~~~~~~~~
|
||||
Final Notes
|
||||
===========
|
||||
|
||||
____/| Comments, additions, and specially corrections are welcome.
|
||||
\ o.O| Documentation valid for at least version 1.2.8 of the joystick
|
||||
=(_)= driver and as usual, the ultimate source for documentation is
|
||||
U to "Use The Source Luke" or, at your convenience, Vojtech ;)
|
||||
::
|
||||
|
||||
- Ragnar
|
||||
EOF
|
||||
____/| Comments, additions, and specially corrections are welcome.
|
||||
\ o.O| Documentation valid for at least version 1.2.8 of the joystick
|
||||
=(_)= driver and as usual, the ultimate source for documentation is
|
||||
U to "Use The Source Luke" or, at your convenience, Vojtech ;)
|
|
@ -0,0 +1,585 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
.. _joystick-doc:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The joystick driver for Linux provides support for a variety of joysticks
|
||||
and similar devices. It is based on a larger project aiming to support all
|
||||
input devices in Linux.
|
||||
|
||||
The mailing list for the project is:
|
||||
|
||||
linux-input@vger.kernel.org
|
||||
|
||||
send "subscribe linux-input" to majordomo@vger.kernel.org to subscribe to it.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
For basic usage you just choose the right options in kernel config and
|
||||
you should be set.
|
||||
|
||||
Utilities
|
||||
---------
|
||||
|
||||
For testing and other purposes (for example serial devices), there is a set
|
||||
of utilities, such as ``jstest``, ``jscal``, and ``evtest``,
|
||||
usually packaged as ``joystick``, ``input-utils``, ``evtest``, and so on.
|
||||
|
||||
``inputattach`` utility is required if your joystick is connected to a
|
||||
serial port.
|
||||
|
||||
Device nodes
|
||||
------------
|
||||
|
||||
For applications to be able to use the joysticks, device nodes should be
|
||||
created in /dev. Normally it is done automatically by the system, but
|
||||
it can also be done by hand::
|
||||
|
||||
cd /dev
|
||||
rm js*
|
||||
mkdir input
|
||||
mknod input/js0 c 13 0
|
||||
mknod input/js1 c 13 1
|
||||
mknod input/js2 c 13 2
|
||||
mknod input/js3 c 13 3
|
||||
ln -s input/js0 js0
|
||||
ln -s input/js1 js1
|
||||
ln -s input/js2 js2
|
||||
ln -s input/js3 js3
|
||||
|
||||
For testing with inpututils it's also convenient to create these::
|
||||
|
||||
mknod input/event0 c 13 64
|
||||
mknod input/event1 c 13 65
|
||||
mknod input/event2 c 13 66
|
||||
mknod input/event3 c 13 67
|
||||
|
||||
Modules needed
|
||||
--------------
|
||||
|
||||
For all joystick drivers to function, you'll need the userland interface
|
||||
module in kernel, either loaded or compiled in::
|
||||
|
||||
modprobe joydev
|
||||
|
||||
For gameport joysticks, you'll have to load the gameport driver as well::
|
||||
|
||||
modprobe ns558
|
||||
|
||||
And for serial port joysticks, you'll need the serial input line
|
||||
discipline module loaded and the inputattach utility started::
|
||||
|
||||
modprobe serport
|
||||
inputattach -xxx /dev/tts/X &
|
||||
|
||||
In addition to that, you'll need the joystick driver module itself, most
|
||||
usually you'll have an analog joystick::
|
||||
|
||||
modprobe analog
|
||||
|
||||
For automatic module loading, something like this might work - tailor to
|
||||
your needs::
|
||||
|
||||
alias tty-ldisc-2 serport
|
||||
alias char-major-13 input
|
||||
above input joydev ns558 analog
|
||||
options analog map=gamepad,none,2btn
|
||||
|
||||
Verifying that it works
|
||||
-----------------------
|
||||
|
||||
For testing the joystick driver functionality, there is the jstest
|
||||
program in the utilities package. You run it by typing::
|
||||
|
||||
jstest /dev/input/js0
|
||||
|
||||
And it should show a line with the joystick values, which update as you
|
||||
move the stick, and press its buttons. The axes should all be zero when the
|
||||
joystick is in the center position. They should not jitter by themselves to
|
||||
other close values, and they also should be steady in any other position of
|
||||
the stick. They should have the full range from -32767 to 32767. If all this
|
||||
is met, then it's all fine, and you can play the games. :)
|
||||
|
||||
If it's not, then there might be a problem. Try to calibrate the joystick,
|
||||
and if it still doesn't work, read the drivers section of this file, the
|
||||
troubleshooting section, and the FAQ.
|
||||
|
||||
Calibration
|
||||
-----------
|
||||
|
||||
For most joysticks you won't need any manual calibration, since the
|
||||
joystick should be autocalibrated by the driver automagically. However, with
|
||||
some analog joysticks, that either do not use linear resistors, or if you
|
||||
want better precision, you can use the jscal program::
|
||||
|
||||
jscal -c /dev/input/js0
|
||||
|
||||
included in the joystick package to set better correction coefficients than
|
||||
what the driver would choose itself.
|
||||
|
||||
After calibrating the joystick you can verify if you like the new
|
||||
calibration using the jstest command, and if you do, you then can save the
|
||||
correction coefficients into a file::
|
||||
|
||||
jscal -p /dev/input/js0 > /etc/joystick.cal
|
||||
|
||||
And add a line to your rc script executing that file::
|
||||
|
||||
source /etc/joystick.cal
|
||||
|
||||
This way, after the next reboot your joystick will remain calibrated. You
|
||||
can also add the ``jscal -p`` line to your shutdown script.
|
||||
|
||||
HW specific driver information
|
||||
==============================
|
||||
|
||||
In this section each of the separate hardware specific drivers is described.
|
||||
|
||||
Analog joysticks
|
||||
----------------
|
||||
|
||||
The analog.c uses the standard analog inputs of the gameport, and thus
|
||||
supports all standard joysticks and gamepads. It uses a very advanced
|
||||
routine for this, allowing for data precision that can't be found on any
|
||||
other system.
|
||||
|
||||
It also supports extensions like additional hats and buttons compatible
|
||||
with CH Flightstick Pro, ThrustMaster FCS or 6 and 8 button gamepads. Saitek
|
||||
Cyborg 'digital' joysticks are also supported by this driver, because
|
||||
they're basically souped up CHF sticks.
|
||||
|
||||
However the only types that can be autodetected are:
|
||||
|
||||
* 2-axis, 4-button joystick
|
||||
* 3-axis, 4-button joystick
|
||||
* 4-axis, 4-button joystick
|
||||
* Saitek Cyborg 'digital' joysticks
|
||||
|
||||
For other joystick types (more/less axes, hats, and buttons) support
|
||||
you'll need to specify the types either on the kernel command line or on the
|
||||
module command line, when inserting analog into the kernel. The
|
||||
parameters are::
|
||||
|
||||
analog.map=<type1>,<type2>,<type3>,....
|
||||
|
||||
'type' is type of the joystick from the table below, defining joysticks
|
||||
present on gameports in the system, starting with gameport0, second 'type'
|
||||
entry defining joystick on gameport1 and so on.
|
||||
|
||||
========= =====================================================
|
||||
Type Meaning
|
||||
========= =====================================================
|
||||
none No analog joystick on that port
|
||||
auto Autodetect joystick
|
||||
2btn 2-button n-axis joystick
|
||||
y-joy Two 2-button 2-axis joysticks on an Y-cable
|
||||
y-pad Two 2-button 2-axis gamepads on an Y-cable
|
||||
fcs Thrustmaster FCS compatible joystick
|
||||
chf Joystick with a CH Flightstick compatible hat
|
||||
fullchf CH Flightstick compatible with two hats and 6 buttons
|
||||
gamepad 4/6-button n-axis gamepad
|
||||
gamepad8 8-button 2-axis gamepad
|
||||
========= =====================================================
|
||||
|
||||
In case your joystick doesn't fit in any of the above categories, you can
|
||||
specify the type as a number by combining the bits in the table below. This
|
||||
is not recommended unless you really know what are you doing. It's not
|
||||
dangerous, but not simple either.
|
||||
|
||||
==== =========================
|
||||
Bit Meaning
|
||||
==== =========================
|
||||
0 Axis X1
|
||||
1 Axis Y1
|
||||
2 Axis X2
|
||||
3 Axis Y2
|
||||
4 Button A
|
||||
5 Button B
|
||||
6 Button C
|
||||
7 Button D
|
||||
8 CHF Buttons X and Y
|
||||
9 CHF Hat 1
|
||||
10 CHF Hat 2
|
||||
11 FCS Hat
|
||||
12 Pad Button X
|
||||
13 Pad Button Y
|
||||
14 Pad Button U
|
||||
15 Pad Button V
|
||||
16 Saitek F1-F4 Buttons
|
||||
17 Saitek Digital Mode
|
||||
19 GamePad
|
||||
20 Joy2 Axis X1
|
||||
21 Joy2 Axis Y1
|
||||
22 Joy2 Axis X2
|
||||
23 Joy2 Axis Y2
|
||||
24 Joy2 Button A
|
||||
25 Joy2 Button B
|
||||
26 Joy2 Button C
|
||||
27 Joy2 Button D
|
||||
31 Joy2 GamePad
|
||||
==== =========================
|
||||
|
||||
Microsoft SideWinder joysticks
|
||||
------------------------------
|
||||
|
||||
Microsoft 'Digital Overdrive' protocol is supported by the sidewinder.c
|
||||
module. All currently supported joysticks:
|
||||
|
||||
* Microsoft SideWinder 3D Pro
|
||||
* Microsoft SideWinder Force Feedback Pro
|
||||
* Microsoft SideWinder Force Feedback Wheel
|
||||
* Microsoft SideWinder FreeStyle Pro
|
||||
* Microsoft SideWinder GamePad (up to four, chained)
|
||||
* Microsoft SideWinder Precision Pro
|
||||
* Microsoft SideWinder Precision Pro USB
|
||||
|
||||
are autodetected, and thus no module parameters are needed.
|
||||
|
||||
There is one caveat with the 3D Pro. There are 9 buttons reported,
|
||||
although the joystick has only 8. The 9th button is the mode switch on the
|
||||
rear side of the joystick. However, moving it, you'll reset the joystick,
|
||||
and make it unresponsive for about a one third of a second. Furthermore, the
|
||||
joystick will also re-center itself, taking the position it was in during
|
||||
this time as a new center position. Use it if you want, but think first.
|
||||
|
||||
The SideWinder Standard is not a digital joystick, and thus is supported
|
||||
by the analog driver described above.
|
||||
|
||||
Logitech ADI devices
|
||||
--------------------
|
||||
|
||||
Logitech ADI protocol is supported by the adi.c module. It should support
|
||||
any Logitech device using this protocol. This includes, but is not limited
|
||||
to:
|
||||
|
||||
* Logitech CyberMan 2
|
||||
* Logitech ThunderPad Digital
|
||||
* Logitech WingMan Extreme Digital
|
||||
* Logitech WingMan Formula
|
||||
* Logitech WingMan Interceptor
|
||||
* Logitech WingMan GamePad
|
||||
* Logitech WingMan GamePad USB
|
||||
* Logitech WingMan GamePad Extreme
|
||||
* Logitech WingMan Extreme Digital 3D
|
||||
|
||||
ADI devices are autodetected, and the driver supports up to two (any
|
||||
combination of) devices on a single gameport, using an Y-cable or chained
|
||||
together.
|
||||
|
||||
Logitech WingMan Joystick, Logitech WingMan Attack, Logitech WingMan
|
||||
Extreme and Logitech WingMan ThunderPad are not digital joysticks and are
|
||||
handled by the analog driver described above. Logitech WingMan Warrior and
|
||||
Logitech Magellan are supported by serial drivers described below. Logitech
|
||||
WingMan Force and Logitech WingMan Formula Force are supported by the
|
||||
I-Force driver described below. Logitech CyberMan is not supported yet.
|
||||
|
||||
Gravis GrIP
|
||||
-----------
|
||||
|
||||
Gravis GrIP protocol is supported by the grip.c module. It currently
|
||||
supports:
|
||||
|
||||
* Gravis GamePad Pro
|
||||
* Gravis BlackHawk Digital
|
||||
* Gravis Xterminator
|
||||
* Gravis Xterminator DualControl
|
||||
|
||||
All these devices are autodetected, and you can even use any combination
|
||||
of up to two of these pads either chained together or using an Y-cable on a
|
||||
single gameport.
|
||||
|
||||
GrIP MultiPort isn't supported yet. Gravis Stinger is a serial device and is
|
||||
supported by the stinger driver. Other Gravis joysticks are supported by the
|
||||
analog driver.
|
||||
|
||||
FPGaming A3D and MadCatz A3D
|
||||
----------------------------
|
||||
|
||||
The Assassin 3D protocol created by FPGaming, is used both by FPGaming
|
||||
themselves and is licensed to MadCatz. A3D devices are supported by the
|
||||
a3d.c module. It currently supports:
|
||||
|
||||
* FPGaming Assassin 3D
|
||||
* MadCatz Panther
|
||||
* MadCatz Panther XL
|
||||
|
||||
All these devices are autodetected. Because the Assassin 3D and the Panther
|
||||
allow connecting analog joysticks to them, you'll need to load the analog
|
||||
driver as well to handle the attached joysticks.
|
||||
|
||||
The trackball should work with USB mousedev module as a normal mouse. See
|
||||
the USB documentation for how to setup an USB mouse.
|
||||
|
||||
ThrustMaster DirectConnect (BSP)
|
||||
--------------------------------
|
||||
|
||||
The TM DirectConnect (BSP) protocol is supported by the tmdc.c
|
||||
module. This includes, but is not limited to:
|
||||
|
||||
* ThrustMaster Millennium 3D Interceptor
|
||||
* ThrustMaster 3D Rage Pad
|
||||
* ThrustMaster Fusion Digital Game Pad
|
||||
|
||||
Devices not directly supported, but hopefully working are:
|
||||
|
||||
* ThrustMaster FragMaster
|
||||
* ThrustMaster Attack Throttle
|
||||
|
||||
If you have one of these, contact me.
|
||||
|
||||
TMDC devices are autodetected, and thus no parameters to the module
|
||||
are needed. Up to two TMDC devices can be connected to one gameport, using
|
||||
an Y-cable.
|
||||
|
||||
Creative Labs Blaster
|
||||
---------------------
|
||||
|
||||
The Blaster protocol is supported by the cobra.c module. It supports only
|
||||
the:
|
||||
|
||||
* Creative Blaster GamePad Cobra
|
||||
|
||||
Up to two of these can be used on a single gameport, using an Y-cable.
|
||||
|
||||
Genius Digital joysticks
|
||||
------------------------
|
||||
|
||||
The Genius digitally communicating joysticks are supported by the gf2k.c
|
||||
module. This includes:
|
||||
|
||||
* Genius Flight2000 F-23 joystick
|
||||
* Genius Flight2000 F-31 joystick
|
||||
* Genius G-09D gamepad
|
||||
|
||||
Other Genius digital joysticks are not supported yet, but support can be
|
||||
added fairly easily.
|
||||
|
||||
InterAct Digital joysticks
|
||||
--------------------------
|
||||
|
||||
The InterAct digitally communicating joysticks are supported by the
|
||||
interact.c module. This includes:
|
||||
|
||||
* InterAct HammerHead/FX gamepad
|
||||
* InterAct ProPad8 gamepad
|
||||
|
||||
Other InterAct digital joysticks are not supported yet, but support can be
|
||||
added fairly easily.
|
||||
|
||||
PDPI Lightning 4 gamecards
|
||||
--------------------------
|
||||
|
||||
PDPI Lightning 4 gamecards are supported by the lightning.c module.
|
||||
Once the module is loaded, the analog driver can be used to handle the
|
||||
joysticks. Digitally communicating joystick will work only on port 0, while
|
||||
using Y-cables, you can connect up to 8 analog joysticks to a single L4
|
||||
card, 16 in case you have two in your system.
|
||||
|
||||
Trident 4DWave / Aureal Vortex
|
||||
------------------------------
|
||||
|
||||
Soundcards with a Trident 4DWave DX/NX or Aureal Vortex/Vortex2 chipsets
|
||||
provide an "Enhanced Game Port" mode where the soundcard handles polling the
|
||||
joystick. This mode is supported by the pcigame.c module. Once loaded the
|
||||
analog driver can use the enhanced features of these gameports..
|
||||
|
||||
Crystal SoundFusion
|
||||
-------------------
|
||||
|
||||
Soundcards with Crystal SoundFusion chipsets provide an "Enhanced Game
|
||||
Port", much like the 4DWave or Vortex above. This, and also the normal mode
|
||||
for the port of the SoundFusion is supported by the cs461x.c module.
|
||||
|
||||
SoundBlaster Live!
|
||||
------------------
|
||||
|
||||
The Live! has a special PCI gameport, which, although it doesn't provide
|
||||
any "Enhanced" stuff like 4DWave and friends, is quite a bit faster than
|
||||
its ISA counterparts. It also requires special support, hence the
|
||||
emu10k1-gp.c module for it instead of the normal ns558.c one.
|
||||
|
||||
SoundBlaster 64 and 128 - ES1370 and ES1371, ESS Solo1 and S3 SonicVibes
|
||||
------------------------------------------------------------------------
|
||||
|
||||
These PCI soundcards have specific gameports. They are handled by the
|
||||
sound drivers themselves. Make sure you select gameport support in the
|
||||
joystick menu and sound card support in the sound menu for your appropriate
|
||||
card.
|
||||
|
||||
Amiga
|
||||
-----
|
||||
|
||||
Amiga joysticks, connected to an Amiga, are supported by the amijoy.c
|
||||
driver. Since they can't be autodetected, the driver has a command line:
|
||||
|
||||
amijoy.map=<a>,<b>
|
||||
|
||||
a and b define the joysticks connected to the JOY0DAT and JOY1DAT ports of
|
||||
the Amiga.
|
||||
|
||||
====== ===========================
|
||||
Value Joystick type
|
||||
====== ===========================
|
||||
0 None
|
||||
1 1-button digital joystick
|
||||
====== ===========================
|
||||
|
||||
No more joystick types are supported now, but that should change in the
|
||||
future if I get an Amiga in the reach of my fingers.
|
||||
|
||||
Game console and 8-bit pads and joysticks
|
||||
-----------------------------------------
|
||||
|
||||
These pads and joysticks are not designed for PCs and other computers
|
||||
Linux runs on, and usually require a special connector for attaching
|
||||
them through a parallel port.
|
||||
|
||||
See :ref:`joystick-parport` for more info.
|
||||
|
||||
SpaceTec/LabTec devices
|
||||
-----------------------
|
||||
|
||||
SpaceTec serial devices communicate using the SpaceWare protocol. It is
|
||||
supported by the spaceorb.c and spaceball.c drivers. The devices currently
|
||||
supported by spaceorb.c are:
|
||||
|
||||
* SpaceTec SpaceBall Avenger
|
||||
* SpaceTec SpaceOrb 360
|
||||
|
||||
Devices currently supported by spaceball.c are:
|
||||
|
||||
* SpaceTec SpaceBall 4000 FLX
|
||||
|
||||
In addition to having the spaceorb/spaceball and serport modules in the
|
||||
kernel, you also need to attach a serial port to it. to do that, run the
|
||||
inputattach program::
|
||||
|
||||
inputattach --spaceorb /dev/tts/x &
|
||||
|
||||
or::
|
||||
|
||||
inputattach --spaceball /dev/tts/x &
|
||||
|
||||
where /dev/tts/x is the serial port which the device is connected to. After
|
||||
doing this, the device will be reported and will start working.
|
||||
|
||||
There is one caveat with the SpaceOrb. The button #6, the on the bottom
|
||||
side of the orb, although reported as an ordinary button, causes internal
|
||||
recentering of the spaceorb, moving the zero point to the position in which
|
||||
the ball is at the moment of pressing the button. So, think first before
|
||||
you bind it to some other function.
|
||||
|
||||
SpaceTec SpaceBall 2003 FLX and 3003 FLX are not supported yet.
|
||||
|
||||
Logitech SWIFT devices
|
||||
----------------------
|
||||
|
||||
The SWIFT serial protocol is supported by the warrior.c module. It
|
||||
currently supports only the:
|
||||
|
||||
* Logitech WingMan Warrior
|
||||
|
||||
but in the future, Logitech CyberMan (the original one, not CM2) could be
|
||||
supported as well. To use the module, you need to run inputattach after you
|
||||
insert/compile the module into your kernel::
|
||||
|
||||
inputattach --warrior /dev/tts/x &
|
||||
|
||||
/dev/tts/x is the serial port your Warrior is attached to.
|
||||
|
||||
Magellan / Space Mouse
|
||||
----------------------
|
||||
|
||||
The Magellan (or Space Mouse), manufactured by LogiCad3d (formerly Space
|
||||
Systems), for many other companies (Logitech, HP, ...) is supported by the
|
||||
joy-magellan module. It currently supports only the:
|
||||
|
||||
* Magellan 3D
|
||||
* Space Mouse
|
||||
|
||||
models, the additional buttons on the 'Plus' versions are not supported yet.
|
||||
|
||||
To use it, you need to attach the serial port to the driver using the::
|
||||
|
||||
inputattach --magellan /dev/tts/x &
|
||||
|
||||
command. After that the Magellan will be detected, initialized, will beep,
|
||||
and the /dev/input/jsX device should become usable.
|
||||
|
||||
I-Force devices
|
||||
---------------
|
||||
|
||||
All I-Force devices are supported by the iforce module. This includes:
|
||||
|
||||
* AVB Mag Turbo Force
|
||||
* AVB Top Shot Pegasus
|
||||
* AVB Top Shot Force Feedback Racing Wheel
|
||||
* Logitech WingMan Force
|
||||
* Logitech WingMan Force Wheel
|
||||
* Guillemot Race Leader Force Feedback
|
||||
* Guillemot Force Feedback Racing Wheel
|
||||
* Thrustmaster Motor Sport GT
|
||||
|
||||
To use it, you need to attach the serial port to the driver using the::
|
||||
|
||||
inputattach --iforce /dev/tts/x &
|
||||
|
||||
command. After that the I-Force device will be detected, and the
|
||||
/dev/input/jsX device should become usable.
|
||||
|
||||
In case you're using the device via the USB port, the inputattach command
|
||||
isn't needed.
|
||||
|
||||
The I-Force driver now supports force feedback via the event interface.
|
||||
|
||||
Please note that Logitech WingMan 3D devices are _not_ supported by this
|
||||
module, rather by hid. Force feedback is not supported for those devices.
|
||||
Logitech gamepads are also hid devices.
|
||||
|
||||
Gravis Stinger gamepad
|
||||
----------------------
|
||||
|
||||
The Gravis Stinger serial port gamepad, designed for use with laptop
|
||||
computers, is supported by the stinger.c module. To use it, attach the
|
||||
serial port to the driver using::
|
||||
|
||||
inputattach --stinger /dev/tty/x &
|
||||
|
||||
where x is the number of the serial port.
|
||||
|
||||
Troubleshooting
|
||||
===============
|
||||
|
||||
There is quite a high probability that you run into some problems. For
|
||||
testing whether the driver works, if in doubt, use the jstest utility in
|
||||
some of its modes. The most useful modes are "normal" - for the 1.x
|
||||
interface, and "old" for the "0.x" interface. You run it by typing::
|
||||
|
||||
jstest --normal /dev/input/js0
|
||||
jstest --old /dev/input/js0
|
||||
|
||||
Additionally you can do a test with the evtest utility::
|
||||
|
||||
evtest /dev/input/event0
|
||||
|
||||
Oh, and read the FAQ! :)
|
||||
|
||||
FAQ
|
||||
===
|
||||
|
||||
:Q: Running 'jstest /dev/input/js0' results in "File not found" error. What's the
|
||||
cause?
|
||||
:A: The device files don't exist. Create them (see section 2.2).
|
||||
|
||||
:Q: Is it possible to connect my old Atari/Commodore/Amiga/console joystick
|
||||
or pad that uses a 9-pin D-type cannon connector to the serial port of my
|
||||
PC?
|
||||
:A: Yes, it is possible, but it'll burn your serial port or the pad. It
|
||||
won't work, of course.
|
||||
|
||||
:Q: My joystick doesn't work with Quake / Quake 2. What's the cause?
|
||||
:A: Quake / Quake 2 don't support joystick. Use joy2key to simulate keypresses
|
||||
for them.
|
|
@ -1,542 +0,0 @@
|
|||
Linux Joystick parport drivers v2.0
|
||||
(c) 1998-2000 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
(c) 1998 Andree Borrmann <a.borrmann@tu-bs.de>
|
||||
Sponsored by SuSE
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
0. Disclaimer
|
||||
~~~~~~~~~~~~~
|
||||
Any information in this file is provided as-is, without any guarantee that
|
||||
it will be true. So, use it at your own risk. The possible damages that can
|
||||
happen include burning your parallel port, and/or the sticks and joystick
|
||||
and maybe even more. Like when a lightning kills you it is not our problem.
|
||||
|
||||
1. Intro
|
||||
~~~~~~~~
|
||||
The joystick parport drivers are used for joysticks and gamepads not
|
||||
originally designed for PCs and other computers Linux runs on. Because of
|
||||
that, PCs usually lack the right ports to connect these devices to. Parallel
|
||||
port, because of its ability to change single bits at will, and providing
|
||||
both output and input bits is the most suitable port on the PC for
|
||||
connecting such devices.
|
||||
|
||||
2. Devices supported
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
Many console and 8-bit computer gamepads and joysticks are supported. The
|
||||
following subsections discuss usage of each.
|
||||
|
||||
2.1 NES and SNES
|
||||
~~~~~~~~~~~~~~~~
|
||||
The Nintendo Entertainment System and Super Nintendo Entertainment System
|
||||
gamepads are widely available, and easy to get. Also, they are quite easy to
|
||||
connect to a PC, and don't need much processing speed (108 us for NES and
|
||||
165 us for SNES, compared to about 1000 us for PC gamepads) to communicate
|
||||
with them.
|
||||
|
||||
All NES and SNES use the same synchronous serial protocol, clocked from
|
||||
the computer's side (and thus timing insensitive). To allow up to 5 NES
|
||||
and/or SNES gamepads and/or SNES mice connected to the parallel port at once,
|
||||
the output lines of the parallel port are shared, while one of 5 available
|
||||
input lines is assigned to each gamepad.
|
||||
|
||||
This protocol is handled by the gamecon.c driver, so that's the one
|
||||
you'll use for NES, SNES gamepads and SNES mice.
|
||||
|
||||
The main problem with PC parallel ports is that they don't have +5V power
|
||||
source on any of their pins. So, if you want a reliable source of power
|
||||
for your pads, use either keyboard or joystick port, and make a pass-through
|
||||
cable. You can also pull the power directly from the power supply (the red
|
||||
wire is +5V).
|
||||
|
||||
If you want to use the parallel port only, you can take the power is from
|
||||
some data pin. For most gamepad and parport implementations only one pin is
|
||||
needed, and I'd recommend pin 9 for that, the highest data bit. On the other
|
||||
hand, if you are not planning to use anything else than NES / SNES on the
|
||||
port, anything between and including pin 4 and pin 9 will work.
|
||||
|
||||
(pin 9) -----> Power
|
||||
|
||||
Unfortunately, there are pads that need a lot more of power, and parallel
|
||||
ports that can't give much current through the data pins. If this is your
|
||||
case, you'll need to use diodes (as a prevention of destroying your parallel
|
||||
port), and combine the currents of two or more data bits together.
|
||||
|
||||
Diodes
|
||||
(pin 9) ----|>|-------+------> Power
|
||||
|
|
||||
(pin 8) ----|>|-------+
|
||||
|
|
||||
(pin 7) ----|>|-------+
|
||||
|
|
||||
<and so on> :
|
||||
|
|
||||
(pin 4) ----|>|-------+
|
||||
|
||||
Ground is quite easy. On PC's parallel port the ground is on any of the
|
||||
pins from pin 18 to pin 25. So use any pin of these you like for the ground.
|
||||
|
||||
(pin 18) -----> Ground
|
||||
|
||||
NES and SNES pads have two input bits, Clock and Latch, which drive the
|
||||
serial transfer. These are connected to pins 2 and 3 of the parallel port,
|
||||
respectively.
|
||||
|
||||
(pin 2) -----> Clock
|
||||
(pin 3) -----> Latch
|
||||
|
||||
And the last thing is the NES / SNES data wire. Only that isn't shared and
|
||||
each pad needs its own data pin. The parallel port pins are:
|
||||
|
||||
(pin 10) -----> Pad 1 data
|
||||
(pin 11) -----> Pad 2 data
|
||||
(pin 12) -----> Pad 3 data
|
||||
(pin 13) -----> Pad 4 data
|
||||
(pin 15) -----> Pad 5 data
|
||||
|
||||
Note that pin 14 is not used, since it is not an input pin on the parallel
|
||||
port.
|
||||
|
||||
This is everything you need on the PC's side of the connection, now on to
|
||||
the gamepads side. The NES and SNES have different connectors. Also, there
|
||||
are quite a lot of NES clones, and because Nintendo used proprietary
|
||||
connectors for their machines, the cloners couldn't and used standard D-Cannon
|
||||
connectors. Anyway, if you've got a gamepad, and it has buttons A, B, Turbo
|
||||
A, Turbo B, Select and Start, and is connected through 5 wires, then it is
|
||||
either a NES or NES clone and will work with this connection. SNES gamepads
|
||||
also use 5 wires, but have more buttons. They will work as well, of course.
|
||||
|
||||
Pinout for NES gamepads Pinout for SNES gamepads and mice
|
||||
|
||||
+----> Power +-----------------------\
|
||||
| 7 | o o o o | x x o | 1
|
||||
5 +---------+ 7 +-----------------------/
|
||||
| x x o \ | | | | |
|
||||
| o o o o | | | | | +-> Ground
|
||||
4 +------------+ 1 | | | +------------> Data
|
||||
| | | | | | +---------------> Latch
|
||||
| | | +-> Ground | +------------------> Clock
|
||||
| | +----> Clock +---------------------> Power
|
||||
| +-------> Latch
|
||||
+----------> Data
|
||||
|
||||
Pinout for NES clone (db9) gamepads Pinout for NES clone (db15) gamepads
|
||||
|
||||
+---------> Clock +-----------------> Data
|
||||
| +-------> Latch | +---> Ground
|
||||
| | +-----> Data | |
|
||||
| | | ___________________
|
||||
_____________ 8 \ o x x x x x x o / 1
|
||||
5 \ x o o o x / 1 \ o x x o x x o /
|
||||
\ x o x o / 15 `~~~~~~~~~~~~~' 9
|
||||
9 `~~~~~~~' 6 | | |
|
||||
| | | | +----> Clock
|
||||
| +----> Power | +----------> Latch
|
||||
+--------> Ground +----------------> Power
|
||||
|
||||
2.2 Multisystem joysticks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
In the era of 8-bit machines, there was something like de-facto standard
|
||||
for joystick ports. They were all digital, and all used D-Cannon 9 pin
|
||||
connectors (db9). Because of that, a single joystick could be used without
|
||||
hassle on Atari (130, 800XE, 800XL, 2600, 7200), Amiga, Commodore C64,
|
||||
Amstrad CPC, Sinclair ZX Spectrum and many other machines. That's why these
|
||||
joysticks are called "Multisystem".
|
||||
|
||||
Now their pinout:
|
||||
|
||||
+---------> Right
|
||||
| +-------> Left
|
||||
| | +-----> Down
|
||||
| | | +---> Up
|
||||
| | | |
|
||||
_____________
|
||||
5 \ x o o o o / 1
|
||||
\ x o x o /
|
||||
9 `~~~~~~~' 6
|
||||
| |
|
||||
| +----> Button
|
||||
+--------> Ground
|
||||
|
||||
However, as time passed, extensions to this standard developed, and these
|
||||
were not compatible with each other:
|
||||
|
||||
|
||||
Atari 130, 800/XL/XE MSX
|
||||
|
||||
+-----------> Power
|
||||
+---------> Right | +---------> Right
|
||||
| +-------> Left | | +-------> Left
|
||||
| | +-----> Down | | | +-----> Down
|
||||
| | | +---> Up | | | | +---> Up
|
||||
| | | | | | | | |
|
||||
_____________ _____________
|
||||
5 \ x o o o o / 1 5 \ o o o o o / 1
|
||||
\ x o o o / \ o o o o /
|
||||
9 `~~~~~~~' 6 9 `~~~~~~~' 6
|
||||
| | | | | | |
|
||||
| | +----> Button | | | +----> Button 1
|
||||
| +------> Power | | +------> Button 2
|
||||
+--------> Ground | +--------> Output 3
|
||||
+----------> Ground
|
||||
|
||||
Amstrad CPC Commodore C64
|
||||
|
||||
+-----------> Analog Y
|
||||
+---------> Right | +---------> Right
|
||||
| +-------> Left | | +-------> Left
|
||||
| | +-----> Down | | | +-----> Down
|
||||
| | | +---> Up | | | | +---> Up
|
||||
| | | | | | | | |
|
||||
_____________ _____________
|
||||
5 \ x o o o o / 1 5 \ o o o o o / 1
|
||||
\ x o o o / \ o o o o /
|
||||
9 `~~~~~~~' 6 9 `~~~~~~~' 6
|
||||
| | | | | | |
|
||||
| | +----> Button 1 | | | +----> Button
|
||||
| +------> Button 2 | | +------> Power
|
||||
+--------> Ground | +--------> Ground
|
||||
+----------> Analog X
|
||||
|
||||
Sinclair Spectrum +2A/+3 Amiga 1200
|
||||
|
||||
+-----------> Up +-----------> Button 3
|
||||
| +---------> Fire | +---------> Right
|
||||
| | | | +-------> Left
|
||||
| | +-----> Ground | | | +-----> Down
|
||||
| | | | | | | +---> Up
|
||||
| | | | | | | |
|
||||
_____________ _____________
|
||||
5 \ o o x o x / 1 5 \ o o o o o / 1
|
||||
\ o o o o / \ o o o o /
|
||||
9 `~~~~~~~' 6 9 `~~~~~~~' 6
|
||||
| | | | | | | |
|
||||
| | | +----> Right | | | +----> Button 1
|
||||
| | +------> Left | | +------> Power
|
||||
| +--------> Ground | +--------> Ground
|
||||
+----------> Down +----------> Button 2
|
||||
|
||||
And there were many others.
|
||||
|
||||
2.2.1 Multisystem joysticks using db9.c
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
For the Multisystem joysticks, and their derivatives, the db9.c driver
|
||||
was written. It allows only one joystick / gamepad per parallel port, but
|
||||
the interface is easy to build and works with almost anything.
|
||||
|
||||
For the basic 1-button Multisystem joystick you connect its wires to the
|
||||
parallel port like this:
|
||||
|
||||
(pin 1) -----> Power
|
||||
(pin 18) -----> Ground
|
||||
|
||||
(pin 2) -----> Up
|
||||
(pin 3) -----> Down
|
||||
(pin 4) -----> Left
|
||||
(pin 5) -----> Right
|
||||
(pin 6) -----> Button 1
|
||||
|
||||
However, if the joystick is switch based (eg. clicks when you move it),
|
||||
you might or might not, depending on your parallel port, need 10 kOhm pullup
|
||||
resistors on each of the direction and button signals, like this:
|
||||
|
||||
(pin 2) ------------+------> Up
|
||||
Resistor |
|
||||
(pin 1) --[10kOhm]--+
|
||||
|
||||
Try without, and if it doesn't work, add them. For TTL based joysticks /
|
||||
gamepads the pullups are not needed.
|
||||
|
||||
For joysticks with two buttons you connect the second button to pin 7 on
|
||||
the parallel port.
|
||||
|
||||
(pin 7) -----> Button 2
|
||||
|
||||
And that's it.
|
||||
|
||||
On a side note, if you have already built a different adapter for use with
|
||||
the digital joystick driver 0.8.0.2, this is also supported by the db9.c
|
||||
driver, as device type 8. (See section 3.2)
|
||||
|
||||
2.2.2 Multisystem joysticks using gamecon.c
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
For some people just one joystick per parallel port is not enough, and/or
|
||||
want to use them on one parallel port together with NES/SNES/PSX pads. This is
|
||||
possible using the gamecon.c. It supports up to 5 devices of the above types,
|
||||
including 1 and 2 buttons Multisystem joysticks.
|
||||
|
||||
However, there is nothing for free. To allow more sticks to be used at
|
||||
once, you need the sticks to be purely switch based (that is non-TTL), and
|
||||
not to need power. Just a plain simple six switches inside. If your
|
||||
joystick can do more (eg. turbofire) you'll need to disable it totally first
|
||||
if you want to use gamecon.c.
|
||||
|
||||
Also, the connection is a bit more complex. You'll need a bunch of diodes,
|
||||
and one pullup resistor. First, you connect the Directions and the button
|
||||
the same as for db9, however with the diodes between.
|
||||
|
||||
Diodes
|
||||
(pin 2) -----|<|----> Up
|
||||
(pin 3) -----|<|----> Down
|
||||
(pin 4) -----|<|----> Left
|
||||
(pin 5) -----|<|----> Right
|
||||
(pin 6) -----|<|----> Button 1
|
||||
|
||||
For two button sticks you also connect the other button.
|
||||
|
||||
(pin 7) -----|<|----> Button 2
|
||||
|
||||
And finally, you connect the Ground wire of the joystick, like done in
|
||||
this little schematic to Power and Data on the parallel port, as described
|
||||
for the NES / SNES pads in section 2.1 of this file - that is, one data pin
|
||||
for each joystick. The power source is shared.
|
||||
|
||||
Data ------------+-----> Ground
|
||||
Resistor |
|
||||
Power --[10kOhm]--+
|
||||
|
||||
And that's all, here we go!
|
||||
|
||||
2.2.3 Multisystem joysticks using turbografx.c
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The TurboGraFX interface, designed by
|
||||
|
||||
Steffen Schwenke <schwenke@burg-halle.de>
|
||||
|
||||
allows up to 7 Multisystem joysticks connected to the parallel port. In
|
||||
Steffen's version, there is support for up to 5 buttons per joystick. However,
|
||||
since this doesn't work reliably on all parallel ports, the turbografx.c driver
|
||||
supports only one button per joystick. For more information on how to build the
|
||||
interface, see
|
||||
|
||||
http://www2.burg-halle.de/~schwenke/parport.html
|
||||
|
||||
2.3 Sony Playstation
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The PSX controller is supported by the gamecon.c. Pinout of the PSX
|
||||
controller (compatible with DirectPadPro):
|
||||
|
||||
+---------+---------+---------+
|
||||
9 | o o o | o o o | o o o | 1 parallel
|
||||
\________|_________|________/ port pins
|
||||
| | | | | |
|
||||
| | | | | +--------> Clock --- (4)
|
||||
| | | | +------------> Select --- (3)
|
||||
| | | +---------------> Power --- (5-9)
|
||||
| | +------------------> Ground --- (18-25)
|
||||
| +-------------------------> Command --- (2)
|
||||
+----------------------------> Data --- (one of 10,11,12,13,15)
|
||||
|
||||
The driver supports these controllers:
|
||||
|
||||
* Standard PSX Pad
|
||||
* NegCon PSX Pad
|
||||
* Analog PSX Pad (red mode)
|
||||
* Analog PSX Pad (green mode)
|
||||
* PSX Rumble Pad
|
||||
* PSX DDR Pad
|
||||
|
||||
2.4 Sega
|
||||
~~~~~~~~
|
||||
All the Sega controllers are more or less based on the standard 2-button
|
||||
Multisystem joystick. However, since they don't use switches and use TTL
|
||||
logic, the only driver usable with them is the db9.c driver.
|
||||
|
||||
2.4.1 Sega Master System
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The SMS gamepads are almost exactly the same as normal 2-button
|
||||
Multisystem joysticks. Set the driver to Multi2 mode, use the corresponding
|
||||
parallel port pins, and the following schematic:
|
||||
|
||||
+-----------> Power
|
||||
| +---------> Right
|
||||
| | +-------> Left
|
||||
| | | +-----> Down
|
||||
| | | | +---> Up
|
||||
| | | | |
|
||||
_____________
|
||||
5 \ o o o o o / 1
|
||||
\ o o x o /
|
||||
9 `~~~~~~~' 6
|
||||
| | |
|
||||
| | +----> Button 1
|
||||
| +--------> Ground
|
||||
+----------> Button 2
|
||||
|
||||
2.4.2 Sega Genesis aka MegaDrive
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The Sega Genesis (in Europe sold as Sega MegaDrive) pads are an extension
|
||||
to the Sega Master System pads. They use more buttons (3+1, 5+1, 6+1). Use
|
||||
the following schematic:
|
||||
|
||||
+-----------> Power
|
||||
| +---------> Right
|
||||
| | +-------> Left
|
||||
| | | +-----> Down
|
||||
| | | | +---> Up
|
||||
| | | | |
|
||||
_____________
|
||||
5 \ o o o o o / 1
|
||||
\ o o o o /
|
||||
9 `~~~~~~~' 6
|
||||
| | | |
|
||||
| | | +----> Button 1
|
||||
| | +------> Select
|
||||
| +--------> Ground
|
||||
+----------> Button 2
|
||||
|
||||
The Select pin goes to pin 14 on the parallel port.
|
||||
|
||||
(pin 14) -----> Select
|
||||
|
||||
The rest is the same as for Multi2 joysticks using db9.c
|
||||
|
||||
2.4.3 Sega Saturn
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Sega Saturn has eight buttons, and to transfer that, without hacks like
|
||||
Genesis 6 pads use, it needs one more select pin. Anyway, it is still
|
||||
handled by the db9.c driver. Its pinout is very different from anything
|
||||
else. Use this schematic:
|
||||
|
||||
+-----------> Select 1
|
||||
| +---------> Power
|
||||
| | +-------> Up
|
||||
| | | +-----> Down
|
||||
| | | | +---> Ground
|
||||
| | | | |
|
||||
_____________
|
||||
5 \ o o o o o / 1
|
||||
\ o o o o /
|
||||
9 `~~~~~~~' 6
|
||||
| | | |
|
||||
| | | +----> Select 2
|
||||
| | +------> Right
|
||||
| +--------> Left
|
||||
+----------> Power
|
||||
|
||||
Select 1 is pin 14 on the parallel port, Select 2 is pin 16 on the
|
||||
parallel port.
|
||||
|
||||
(pin 14) -----> Select 1
|
||||
(pin 16) -----> Select 2
|
||||
|
||||
The other pins (Up, Down, Right, Left, Power, Ground) are the same as for
|
||||
Multi joysticks using db9.c
|
||||
|
||||
3. The drivers
|
||||
~~~~~~~~~~~~~~
|
||||
There are three drivers for the parallel port interfaces. Each, as
|
||||
described above, allows to connect a different group of joysticks and pads.
|
||||
Here are described their command lines:
|
||||
|
||||
3.1 gamecon.c
|
||||
~~~~~~~~~~~~~
|
||||
Using gamecon.c you can connect up to five devices to one parallel port. It
|
||||
uses the following kernel/module command line:
|
||||
|
||||
gamecon.map=port,pad1,pad2,pad3,pad4,pad5
|
||||
|
||||
Where 'port' the number of the parport interface (eg. 0 for parport0).
|
||||
|
||||
And 'pad1' to 'pad5' are pad types connected to different data input pins
|
||||
(10,11,12,13,15), as described in section 2.1 of this file.
|
||||
|
||||
The types are:
|
||||
|
||||
Type | Joystick/Pad
|
||||
--------------------
|
||||
0 | None
|
||||
1 | SNES pad
|
||||
2 | NES pad
|
||||
4 | Multisystem 1-button joystick
|
||||
5 | Multisystem 2-button joystick
|
||||
6 | N64 pad
|
||||
7 | Sony PSX controller
|
||||
8 | Sony PSX DDR controller
|
||||
9 | SNES mouse
|
||||
|
||||
The exact type of the PSX controller type is autoprobed when used, so
|
||||
hot swapping should work (but is not recommended).
|
||||
|
||||
Should you want to use more than one of parallel ports at once, you can use
|
||||
gamecon.map2 and gamecon.map3 as additional command line parameters for two
|
||||
more parallel ports.
|
||||
|
||||
There are two options specific to PSX driver portion. gamecon.psx_delay sets
|
||||
the command delay when talking to the controllers. The default of 25 should
|
||||
work but you can try lowering it for better performance. If your pads don't
|
||||
respond try raising it until they work. Setting the type to 8 allows the
|
||||
driver to be used with Dance Dance Revolution or similar games. Arrow keys are
|
||||
registered as key presses instead of X and Y axes.
|
||||
|
||||
3.2 db9.c
|
||||
~~~~~~~~~
|
||||
Apart from making an interface, there is nothing difficult on using the
|
||||
db9.c driver. It uses the following kernel/module command line:
|
||||
|
||||
db9.dev=port,type
|
||||
|
||||
Where 'port' is the number of the parport interface (eg. 0 for parport0).
|
||||
|
||||
Caveat here: This driver only works on bidirectional parallel ports. If
|
||||
your parallel port is recent enough, you should have no trouble with this.
|
||||
Old parallel ports may not have this feature.
|
||||
|
||||
'Type' is the type of joystick or pad attached:
|
||||
|
||||
Type | Joystick/Pad
|
||||
--------------------
|
||||
0 | None
|
||||
1 | Multisystem 1-button joystick
|
||||
2 | Multisystem 2-button joystick
|
||||
3 | Genesis pad (3+1 buttons)
|
||||
5 | Genesis pad (5+1 buttons)
|
||||
6 | Genesis pad (6+2 buttons)
|
||||
7 | Saturn pad (8 buttons)
|
||||
8 | Multisystem 1-button joystick (v0.8.0.2 pin-out)
|
||||
9 | Two Multisystem 1-button joysticks (v0.8.0.2 pin-out)
|
||||
10 | Amiga CD32 pad
|
||||
|
||||
Should you want to use more than one of these joysticks/pads at once, you
|
||||
can use db9.dev2 and db9.dev3 as additional command line parameters for two
|
||||
more joysticks/pads.
|
||||
|
||||
3.3 turbografx.c
|
||||
~~~~~~~~~~~~~~~~
|
||||
The turbografx.c driver uses a very simple kernel/module command line:
|
||||
|
||||
turbografx.map=port,js1,js2,js3,js4,js5,js6,js7
|
||||
|
||||
Where 'port' is the number of the parport interface (eg. 0 for parport0).
|
||||
|
||||
'jsX' is the number of buttons the Multisystem joysticks connected to the
|
||||
interface ports 1-7 have. For a standard multisystem joystick, this is 1.
|
||||
|
||||
Should you want to use more than one of these interfaces at once, you can
|
||||
use turbografx.map2 and turbografx.map3 as additional command line parameters
|
||||
for two more interfaces.
|
||||
|
||||
3.4 PC parallel port pinout
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
.----------------------------------------.
|
||||
At the PC: \ 13 12 11 10 9 8 7 6 5 4 3 2 1 /
|
||||
\ 25 24 23 22 21 20 19 18 17 16 15 14 /
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Pin | Name | Description
|
||||
~~~~~~|~~~~~~~~~|~~~~~~~~~~
|
||||
1 | /STROBE | Strobe
|
||||
2-9 | D0-D7 | Data Bit 0-7
|
||||
10 | /ACK | Acknowledge
|
||||
11 | BUSY | Busy
|
||||
12 | PE | Paper End
|
||||
13 | SELIN | Select In
|
||||
14 | /AUTOFD | Autofeed
|
||||
15 | /ERROR | Error
|
||||
16 | /INIT | Initialize
|
||||
17 | /SEL | Select
|
||||
18-25 | GND | Signal Ground
|
||||
|
||||
3.5 End
|
||||
~~~~~~~
|
||||
That's all, folks! Have fun!
|
|
@ -1,586 +0,0 @@
|
|||
Linux Joystick driver v2.0.0
|
||||
(c) 1996-2000 Vojtech Pavlik <vojtech@ucw.cz>
|
||||
Sponsored by SuSE
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
0. Disclaimer
|
||||
~~~~~~~~~~~~~
|
||||
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 the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Should you need to contact me, the author, you can do so either by e-mail
|
||||
- mail your message to <vojtech@ucw.cz>, or by paper mail: Vojtech Pavlik,
|
||||
Simunkova 1594, Prague 8, 182 00 Czech Republic
|
||||
|
||||
For your convenience, the GNU General Public License version 2 is included
|
||||
in the package: See the file COPYING.
|
||||
|
||||
1. Intro
|
||||
~~~~~~~~
|
||||
The joystick driver for Linux provides support for a variety of joysticks
|
||||
and similar devices. It is based on a larger project aiming to support all
|
||||
input devices in Linux.
|
||||
|
||||
Should you encounter any problems while using the driver, or joysticks
|
||||
this driver can't make complete use of, I'm very interested in hearing about
|
||||
them. Bug reports and success stories are also welcome.
|
||||
|
||||
The input project website is at:
|
||||
|
||||
http://atrey.karlin.mff.cuni.cz/~vojtech/input/
|
||||
|
||||
There is also a mailing list for the driver at:
|
||||
|
||||
listproc@atrey.karlin.mff.cuni.cz
|
||||
|
||||
send "subscribe linux-joystick Your Name" to subscribe to it.
|
||||
|
||||
2. Usage
|
||||
~~~~~~~~
|
||||
For basic usage you just choose the right options in kernel config and
|
||||
you should be set.
|
||||
|
||||
2.1 inpututils
|
||||
~~~~~~~~~~~~~~
|
||||
For testing and other purposes (for example serial devices), a set of
|
||||
utilities is available at the abovementioned website. I suggest you download
|
||||
and install it before going on.
|
||||
|
||||
2.2 Device nodes
|
||||
~~~~~~~~~~~~~~~~
|
||||
For applications to be able to use the joysticks,
|
||||
you'll have to manually create these nodes in /dev:
|
||||
|
||||
cd /dev
|
||||
rm js*
|
||||
mkdir input
|
||||
mknod input/js0 c 13 0
|
||||
mknod input/js1 c 13 1
|
||||
mknod input/js2 c 13 2
|
||||
mknod input/js3 c 13 3
|
||||
ln -s input/js0 js0
|
||||
ln -s input/js1 js1
|
||||
ln -s input/js2 js2
|
||||
ln -s input/js3 js3
|
||||
|
||||
For testing with inpututils it's also convenient to create these:
|
||||
|
||||
mknod input/event0 c 13 64
|
||||
mknod input/event1 c 13 65
|
||||
mknod input/event2 c 13 66
|
||||
mknod input/event3 c 13 67
|
||||
|
||||
2.4 Modules needed
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
For all joystick drivers to function, you'll need the userland interface
|
||||
module in kernel, either loaded or compiled in:
|
||||
|
||||
modprobe joydev
|
||||
|
||||
For gameport joysticks, you'll have to load the gameport driver as well;
|
||||
|
||||
modprobe ns558
|
||||
|
||||
And for serial port joysticks, you'll need the serial input line
|
||||
discipline module loaded and the inputattach utility started:
|
||||
|
||||
modprobe serport
|
||||
inputattach -xxx /dev/tts/X &
|
||||
|
||||
In addition to that, you'll need the joystick driver module itself, most
|
||||
usually you'll have an analog joystick:
|
||||
|
||||
modprobe analog
|
||||
|
||||
For automatic module loading, something like this might work - tailor to
|
||||
your needs:
|
||||
|
||||
alias tty-ldisc-2 serport
|
||||
alias char-major-13 input
|
||||
above input joydev ns558 analog
|
||||
options analog map=gamepad,none,2btn
|
||||
|
||||
2.5 Verifying that it works
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
For testing the joystick driver functionality, there is the jstest
|
||||
program in the utilities package. You run it by typing:
|
||||
|
||||
jstest /dev/input/js0
|
||||
|
||||
And it should show a line with the joystick values, which update as you
|
||||
move the stick, and press its buttons. The axes should all be zero when the
|
||||
joystick is in the center position. They should not jitter by themselves to
|
||||
other close values, and they also should be steady in any other position of
|
||||
the stick. They should have the full range from -32767 to 32767. If all this
|
||||
is met, then it's all fine, and you can play the games. :)
|
||||
|
||||
If it's not, then there might be a problem. Try to calibrate the joystick,
|
||||
and if it still doesn't work, read the drivers section of this file, the
|
||||
troubleshooting section, and the FAQ.
|
||||
|
||||
2.6. Calibration
|
||||
~~~~~~~~~~~~~~~~
|
||||
For most joysticks you won't need any manual calibration, since the
|
||||
joystick should be autocalibrated by the driver automagically. However, with
|
||||
some analog joysticks, that either do not use linear resistors, or if you
|
||||
want better precision, you can use the jscal program
|
||||
|
||||
jscal -c /dev/input/js0
|
||||
|
||||
included in the joystick package to set better correction coefficients than
|
||||
what the driver would choose itself.
|
||||
|
||||
After calibrating the joystick you can verify if you like the new
|
||||
calibration using the jstest command, and if you do, you then can save the
|
||||
correction coefficients into a file
|
||||
|
||||
jscal -p /dev/input/js0 > /etc/joystick.cal
|
||||
|
||||
And add a line to your rc script executing that file
|
||||
|
||||
source /etc/joystick.cal
|
||||
|
||||
This way, after the next reboot your joystick will remain calibrated. You
|
||||
can also add the jscal -p line to your shutdown script.
|
||||
|
||||
|
||||
3. HW specific driver information
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
In this section each of the separate hardware specific drivers is described.
|
||||
|
||||
3.1 Analog joysticks
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
The analog.c uses the standard analog inputs of the gameport, and thus
|
||||
supports all standard joysticks and gamepads. It uses a very advanced
|
||||
routine for this, allowing for data precision that can't be found on any
|
||||
other system.
|
||||
|
||||
It also supports extensions like additional hats and buttons compatible
|
||||
with CH Flightstick Pro, ThrustMaster FCS or 6 and 8 button gamepads. Saitek
|
||||
Cyborg 'digital' joysticks are also supported by this driver, because
|
||||
they're basically souped up CHF sticks.
|
||||
|
||||
However the only types that can be autodetected are:
|
||||
|
||||
* 2-axis, 4-button joystick
|
||||
* 3-axis, 4-button joystick
|
||||
* 4-axis, 4-button joystick
|
||||
* Saitek Cyborg 'digital' joysticks
|
||||
|
||||
For other joystick types (more/less axes, hats, and buttons) support
|
||||
you'll need to specify the types either on the kernel command line or on the
|
||||
module command line, when inserting analog into the kernel. The
|
||||
parameters are:
|
||||
|
||||
analog.map=<type1>,<type2>,<type3>,....
|
||||
|
||||
'type' is type of the joystick from the table below, defining joysticks
|
||||
present on gameports in the system, starting with gameport0, second 'type'
|
||||
entry defining joystick on gameport1 and so on.
|
||||
|
||||
Type | Meaning
|
||||
-----------------------------------
|
||||
none | No analog joystick on that port
|
||||
auto | Autodetect joystick
|
||||
2btn | 2-button n-axis joystick
|
||||
y-joy | Two 2-button 2-axis joysticks on an Y-cable
|
||||
y-pad | Two 2-button 2-axis gamepads on an Y-cable
|
||||
fcs | Thrustmaster FCS compatible joystick
|
||||
chf | Joystick with a CH Flightstick compatible hat
|
||||
fullchf | CH Flightstick compatible with two hats and 6 buttons
|
||||
gamepad | 4/6-button n-axis gamepad
|
||||
gamepad8 | 8-button 2-axis gamepad
|
||||
|
||||
In case your joystick doesn't fit in any of the above categories, you can
|
||||
specify the type as a number by combining the bits in the table below. This
|
||||
is not recommended unless you really know what are you doing. It's not
|
||||
dangerous, but not simple either.
|
||||
|
||||
Bit | Meaning
|
||||
--------------------------
|
||||
0 | Axis X1
|
||||
1 | Axis Y1
|
||||
2 | Axis X2
|
||||
3 | Axis Y2
|
||||
4 | Button A
|
||||
5 | Button B
|
||||
6 | Button C
|
||||
7 | Button D
|
||||
8 | CHF Buttons X and Y
|
||||
9 | CHF Hat 1
|
||||
10 | CHF Hat 2
|
||||
11 | FCS Hat
|
||||
12 | Pad Button X
|
||||
13 | Pad Button Y
|
||||
14 | Pad Button U
|
||||
15 | Pad Button V
|
||||
16 | Saitek F1-F4 Buttons
|
||||
17 | Saitek Digital Mode
|
||||
19 | GamePad
|
||||
20 | Joy2 Axis X1
|
||||
21 | Joy2 Axis Y1
|
||||
22 | Joy2 Axis X2
|
||||
23 | Joy2 Axis Y2
|
||||
24 | Joy2 Button A
|
||||
25 | Joy2 Button B
|
||||
26 | Joy2 Button C
|
||||
27 | Joy2 Button D
|
||||
31 | Joy2 GamePad
|
||||
|
||||
3.2 Microsoft SideWinder joysticks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Microsoft 'Digital Overdrive' protocol is supported by the sidewinder.c
|
||||
module. All currently supported joysticks:
|
||||
|
||||
* Microsoft SideWinder 3D Pro
|
||||
* Microsoft SideWinder Force Feedback Pro
|
||||
* Microsoft SideWinder Force Feedback Wheel
|
||||
* Microsoft SideWinder FreeStyle Pro
|
||||
* Microsoft SideWinder GamePad (up to four, chained)
|
||||
* Microsoft SideWinder Precision Pro
|
||||
* Microsoft SideWinder Precision Pro USB
|
||||
|
||||
are autodetected, and thus no module parameters are needed.
|
||||
|
||||
There is one caveat with the 3D Pro. There are 9 buttons reported,
|
||||
although the joystick has only 8. The 9th button is the mode switch on the
|
||||
rear side of the joystick. However, moving it, you'll reset the joystick,
|
||||
and make it unresponsive for about a one third of a second. Furthermore, the
|
||||
joystick will also re-center itself, taking the position it was in during
|
||||
this time as a new center position. Use it if you want, but think first.
|
||||
|
||||
The SideWinder Standard is not a digital joystick, and thus is supported
|
||||
by the analog driver described above.
|
||||
|
||||
3.3 Logitech ADI devices
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Logitech ADI protocol is supported by the adi.c module. It should support
|
||||
any Logitech device using this protocol. This includes, but is not limited
|
||||
to:
|
||||
|
||||
* Logitech CyberMan 2
|
||||
* Logitech ThunderPad Digital
|
||||
* Logitech WingMan Extreme Digital
|
||||
* Logitech WingMan Formula
|
||||
* Logitech WingMan Interceptor
|
||||
* Logitech WingMan GamePad
|
||||
* Logitech WingMan GamePad USB
|
||||
* Logitech WingMan GamePad Extreme
|
||||
* Logitech WingMan Extreme Digital 3D
|
||||
|
||||
ADI devices are autodetected, and the driver supports up to two (any
|
||||
combination of) devices on a single gameport, using an Y-cable or chained
|
||||
together.
|
||||
|
||||
Logitech WingMan Joystick, Logitech WingMan Attack, Logitech WingMan
|
||||
Extreme and Logitech WingMan ThunderPad are not digital joysticks and are
|
||||
handled by the analog driver described above. Logitech WingMan Warrior and
|
||||
Logitech Magellan are supported by serial drivers described below. Logitech
|
||||
WingMan Force and Logitech WingMan Formula Force are supported by the
|
||||
I-Force driver described below. Logitech CyberMan is not supported yet.
|
||||
|
||||
3.4 Gravis GrIP
|
||||
~~~~~~~~~~~~~~~
|
||||
Gravis GrIP protocol is supported by the grip.c module. It currently
|
||||
supports:
|
||||
|
||||
* Gravis GamePad Pro
|
||||
* Gravis BlackHawk Digital
|
||||
* Gravis Xterminator
|
||||
* Gravis Xterminator DualControl
|
||||
|
||||
All these devices are autodetected, and you can even use any combination
|
||||
of up to two of these pads either chained together or using an Y-cable on a
|
||||
single gameport.
|
||||
|
||||
GrIP MultiPort isn't supported yet. Gravis Stinger is a serial device and is
|
||||
supported by the stinger driver. Other Gravis joysticks are supported by the
|
||||
analog driver.
|
||||
|
||||
3.5 FPGaming A3D and MadCatz A3D
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The Assassin 3D protocol created by FPGaming, is used both by FPGaming
|
||||
themselves and is licensed to MadCatz. A3D devices are supported by the
|
||||
a3d.c module. It currently supports:
|
||||
|
||||
* FPGaming Assassin 3D
|
||||
* MadCatz Panther
|
||||
* MadCatz Panther XL
|
||||
|
||||
All these devices are autodetected. Because the Assassin 3D and the Panther
|
||||
allow connecting analog joysticks to them, you'll need to load the analog
|
||||
driver as well to handle the attached joysticks.
|
||||
|
||||
The trackball should work with USB mousedev module as a normal mouse. See
|
||||
the USB documentation for how to setup an USB mouse.
|
||||
|
||||
3.6 ThrustMaster DirectConnect (BSP)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The TM DirectConnect (BSP) protocol is supported by the tmdc.c
|
||||
module. This includes, but is not limited to:
|
||||
|
||||
* ThrustMaster Millennium 3D Interceptor
|
||||
* ThrustMaster 3D Rage Pad
|
||||
* ThrustMaster Fusion Digital Game Pad
|
||||
|
||||
Devices not directly supported, but hopefully working are:
|
||||
|
||||
* ThrustMaster FragMaster
|
||||
* ThrustMaster Attack Throttle
|
||||
|
||||
If you have one of these, contact me.
|
||||
|
||||
TMDC devices are autodetected, and thus no parameters to the module
|
||||
are needed. Up to two TMDC devices can be connected to one gameport, using
|
||||
an Y-cable.
|
||||
|
||||
3.7 Creative Labs Blaster
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The Blaster protocol is supported by the cobra.c module. It supports only
|
||||
the:
|
||||
|
||||
* Creative Blaster GamePad Cobra
|
||||
|
||||
Up to two of these can be used on a single gameport, using an Y-cable.
|
||||
|
||||
3.8 Genius Digital joysticks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The Genius digitally communicating joysticks are supported by the gf2k.c
|
||||
module. This includes:
|
||||
|
||||
* Genius Flight2000 F-23 joystick
|
||||
* Genius Flight2000 F-31 joystick
|
||||
* Genius G-09D gamepad
|
||||
|
||||
Other Genius digital joysticks are not supported yet, but support can be
|
||||
added fairly easily.
|
||||
|
||||
3.9 InterAct Digital joysticks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The InterAct digitally communicating joysticks are supported by the
|
||||
interact.c module. This includes:
|
||||
|
||||
* InterAct HammerHead/FX gamepad
|
||||
* InterAct ProPad8 gamepad
|
||||
|
||||
Other InterAct digital joysticks are not supported yet, but support can be
|
||||
added fairly easily.
|
||||
|
||||
3.10 PDPI Lightning 4 gamecards
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
PDPI Lightning 4 gamecards are supported by the lightning.c module.
|
||||
Once the module is loaded, the analog driver can be used to handle the
|
||||
joysticks. Digitally communicating joystick will work only on port 0, while
|
||||
using Y-cables, you can connect up to 8 analog joysticks to a single L4
|
||||
card, 16 in case you have two in your system.
|
||||
|
||||
3.11 Trident 4DWave / Aureal Vortex
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Soundcards with a Trident 4DWave DX/NX or Aureal Vortex/Vortex2 chipsets
|
||||
provide an "Enhanced Game Port" mode where the soundcard handles polling the
|
||||
joystick. This mode is supported by the pcigame.c module. Once loaded the
|
||||
analog driver can use the enhanced features of these gameports..
|
||||
|
||||
3.13 Crystal SoundFusion
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Soundcards with Crystal SoundFusion chipsets provide an "Enhanced Game
|
||||
Port", much like the 4DWave or Vortex above. This, and also the normal mode
|
||||
for the port of the SoundFusion is supported by the cs461x.c module.
|
||||
|
||||
3.14 SoundBlaster Live!
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The Live! has a special PCI gameport, which, although it doesn't provide
|
||||
any "Enhanced" stuff like 4DWave and friends, is quite a bit faster than
|
||||
its ISA counterparts. It also requires special support, hence the
|
||||
emu10k1-gp.c module for it instead of the normal ns558.c one.
|
||||
|
||||
3.15 SoundBlaster 64 and 128 - ES1370 and ES1371, ESS Solo1 and S3 SonicVibes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
These PCI soundcards have specific gameports. They are handled by the
|
||||
sound drivers themselves. Make sure you select gameport support in the
|
||||
joystick menu and sound card support in the sound menu for your appropriate
|
||||
card.
|
||||
|
||||
3.16 Amiga
|
||||
~~~~~~~~~~
|
||||
Amiga joysticks, connected to an Amiga, are supported by the amijoy.c
|
||||
driver. Since they can't be autodetected, the driver has a command line.
|
||||
|
||||
amijoy.map=<a>,<b>
|
||||
|
||||
a and b define the joysticks connected to the JOY0DAT and JOY1DAT ports of
|
||||
the Amiga.
|
||||
|
||||
Value | Joystick type
|
||||
---------------------
|
||||
0 | None
|
||||
1 | 1-button digital joystick
|
||||
|
||||
No more joystick types are supported now, but that should change in the
|
||||
future if I get an Amiga in the reach of my fingers.
|
||||
|
||||
3.17 Game console and 8-bit pads and joysticks
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
See joystick-parport.txt for more info.
|
||||
|
||||
3.18 SpaceTec/LabTec devices
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
SpaceTec serial devices communicate using the SpaceWare protocol. It is
|
||||
supported by the spaceorb.c and spaceball.c drivers. The devices currently
|
||||
supported by spaceorb.c are:
|
||||
|
||||
* SpaceTec SpaceBall Avenger
|
||||
* SpaceTec SpaceOrb 360
|
||||
|
||||
Devices currently supported by spaceball.c are:
|
||||
|
||||
* SpaceTec SpaceBall 4000 FLX
|
||||
|
||||
In addition to having the spaceorb/spaceball and serport modules in the
|
||||
kernel, you also need to attach a serial port to it. to do that, run the
|
||||
inputattach program:
|
||||
|
||||
inputattach --spaceorb /dev/tts/x &
|
||||
or
|
||||
inputattach --spaceball /dev/tts/x &
|
||||
|
||||
where /dev/tts/x is the serial port which the device is connected to. After
|
||||
doing this, the device will be reported and will start working.
|
||||
|
||||
There is one caveat with the SpaceOrb. The button #6, the on the bottom
|
||||
side of the orb, although reported as an ordinary button, causes internal
|
||||
recentering of the spaceorb, moving the zero point to the position in which
|
||||
the ball is at the moment of pressing the button. So, think first before
|
||||
you bind it to some other function.
|
||||
|
||||
SpaceTec SpaceBall 2003 FLX and 3003 FLX are not supported yet.
|
||||
|
||||
3.19 Logitech SWIFT devices
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The SWIFT serial protocol is supported by the warrior.c module. It
|
||||
currently supports only the:
|
||||
|
||||
* Logitech WingMan Warrior
|
||||
|
||||
but in the future, Logitech CyberMan (the original one, not CM2) could be
|
||||
supported as well. To use the module, you need to run inputattach after you
|
||||
insert/compile the module into your kernel:
|
||||
|
||||
inputattach --warrior /dev/tts/x &
|
||||
|
||||
/dev/tts/x is the serial port your Warrior is attached to.
|
||||
|
||||
3.20 Magellan / Space Mouse
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The Magellan (or Space Mouse), manufactured by LogiCad3d (formerly Space
|
||||
Systems), for many other companies (Logitech, HP, ...) is supported by the
|
||||
joy-magellan module. It currently supports only the:
|
||||
|
||||
* Magellan 3D
|
||||
* Space Mouse
|
||||
|
||||
models, the additional buttons on the 'Plus' versions are not supported yet.
|
||||
|
||||
To use it, you need to attach the serial port to the driver using the
|
||||
|
||||
inputattach --magellan /dev/tts/x &
|
||||
|
||||
command. After that the Magellan will be detected, initialized, will beep,
|
||||
and the /dev/input/jsX device should become usable.
|
||||
|
||||
3.21 I-Force devices
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
All I-Force devices are supported by the iforce module. This includes:
|
||||
|
||||
* AVB Mag Turbo Force
|
||||
* AVB Top Shot Pegasus
|
||||
* AVB Top Shot Force Feedback Racing Wheel
|
||||
* Logitech WingMan Force
|
||||
* Logitech WingMan Force Wheel
|
||||
* Guillemot Race Leader Force Feedback
|
||||
* Guillemot Force Feedback Racing Wheel
|
||||
* Thrustmaster Motor Sport GT
|
||||
|
||||
To use it, you need to attach the serial port to the driver using the
|
||||
|
||||
inputattach --iforce /dev/tts/x &
|
||||
|
||||
command. After that the I-Force device will be detected, and the
|
||||
/dev/input/jsX device should become usable.
|
||||
|
||||
In case you're using the device via the USB port, the inputattach command
|
||||
isn't needed.
|
||||
|
||||
The I-Force driver now supports force feedback via the event interface.
|
||||
|
||||
Please note that Logitech WingMan *3D devices are _not_ supported by this
|
||||
module, rather by hid. Force feedback is not supported for those devices.
|
||||
Logitech gamepads are also hid devices.
|
||||
|
||||
3.22 Gravis Stinger gamepad
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The Gravis Stinger serial port gamepad, designed for use with laptop
|
||||
computers, is supported by the stinger.c module. To use it, attach the
|
||||
serial port to the driver using:
|
||||
|
||||
inputattach --stinger /dev/tty/x &
|
||||
|
||||
where x is the number of the serial port.
|
||||
|
||||
4. Troubleshooting
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
There is quite a high probability that you run into some problems. For
|
||||
testing whether the driver works, if in doubt, use the jstest utility in
|
||||
some of its modes. The most useful modes are "normal" - for the 1.x
|
||||
interface, and "old" for the "0.x" interface. You run it by typing:
|
||||
|
||||
jstest --normal /dev/input/js0
|
||||
jstest --old /dev/input/js0
|
||||
|
||||
Additionally you can do a test with the evtest utility:
|
||||
|
||||
evtest /dev/input/event0
|
||||
|
||||
Oh, and read the FAQ! :)
|
||||
|
||||
5. FAQ
|
||||
~~~~~~
|
||||
Q: Running 'jstest /dev/input/js0' results in "File not found" error. What's the
|
||||
cause?
|
||||
A: The device files don't exist. Create them (see section 2.2).
|
||||
|
||||
Q: Is it possible to connect my old Atari/Commodore/Amiga/console joystick
|
||||
or pad that uses a 9-pin D-type cannon connector to the serial port of my
|
||||
PC?
|
||||
A: Yes, it is possible, but it'll burn your serial port or the pad. It
|
||||
won't work, of course.
|
||||
|
||||
Q: My joystick doesn't work with Quake / Quake 2. What's the cause?
|
||||
A: Quake / Quake 2 don't support joystick. Use joy2key to simulate keypresses
|
||||
for them.
|
||||
|
||||
6. Programming Interface
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The 1.0 driver uses a new, event based approach to the joystick driver.
|
||||
Instead of the user program polling for the joystick values, the joystick
|
||||
driver now reports only any changes of its state. See joystick-api.txt,
|
||||
joystick.h and jstest.c included in the joystick package for more
|
||||
information. The joystick device can be used in either blocking or
|
||||
nonblocking mode and supports select() calls.
|
||||
|
||||
For backward compatibility the old (v0.x) interface is still included.
|
||||
Any call to the joystick driver using the old interface will return values
|
||||
that are compatible to the old interface. This interface is still limited
|
||||
to 2 axes, and applications using it usually decode only 2 buttons, although
|
||||
the driver provides up to 32.
|
|
@ -1,6 +1,10 @@
|
|||
.. include:: <isonum.txt>
|
||||
|
||||
=========================
|
||||
Multi-touch (MT) Protocol
|
||||
-------------------------
|
||||
Copyright (C) 2009-2010 Henrik Rydberg <rydberg@euromail.se>
|
||||
=========================
|
||||
|
||||
:Copyright: |copy| 2009-2010 Henrik Rydberg <rydberg@euromail.se>
|
||||
|
||||
|
||||
Introduction
|
||||
|
@ -18,6 +22,9 @@ describes how to send the raw data for all contacts to the receiver. For
|
|||
devices capable of tracking identifiable contacts (type B), the protocol
|
||||
describes how to send updates for individual contacts via event slots.
|
||||
|
||||
.. note::
|
||||
MT potocol type A is obsolete, all kernel drivers have been
|
||||
converted to use type B.
|
||||
|
||||
Protocol Usage
|
||||
--------------
|
||||
|
@ -47,12 +54,12 @@ The main difference between the stateless type A protocol and the stateful
|
|||
type B slot protocol lies in the usage of identifiable contacts to reduce
|
||||
the amount of data sent to userspace. The slot protocol requires the use of
|
||||
the ABS_MT_TRACKING_ID, either provided by the hardware or computed from
|
||||
the raw data [5].
|
||||
the raw data [#f5]_.
|
||||
|
||||
For type A devices, the kernel driver should generate an arbitrary
|
||||
enumeration of the full set of anonymous contacts currently on the
|
||||
surface. The order in which the packets appear in the event stream is not
|
||||
important. Event filtering and finger tracking is left to user space [3].
|
||||
important. Event filtering and finger tracking is left to user space [#f3]_.
|
||||
|
||||
For type B devices, the kernel driver should associate a slot with each
|
||||
identified contact, and use that slot to propagate changes for the contact.
|
||||
|
@ -86,7 +93,7 @@ Protocol Example A
|
|||
------------------
|
||||
|
||||
Here is what a minimal event sequence for a two-contact touch would look
|
||||
like for a type A device:
|
||||
like for a type A device::
|
||||
|
||||
ABS_MT_POSITION_X x[0]
|
||||
ABS_MT_POSITION_Y y[0]
|
||||
|
@ -100,14 +107,14 @@ The sequence after moving one of the contacts looks exactly the same; the
|
|||
raw data for all present contacts are sent between every synchronization
|
||||
with SYN_REPORT.
|
||||
|
||||
Here is the sequence after lifting the first contact:
|
||||
Here is the sequence after lifting the first contact::
|
||||
|
||||
ABS_MT_POSITION_X x[1]
|
||||
ABS_MT_POSITION_Y y[1]
|
||||
SYN_MT_REPORT
|
||||
SYN_REPORT
|
||||
|
||||
And here is the sequence after lifting the second contact:
|
||||
And here is the sequence after lifting the second contact::
|
||||
|
||||
SYN_MT_REPORT
|
||||
SYN_REPORT
|
||||
|
@ -122,7 +129,7 @@ Protocol Example B
|
|||
------------------
|
||||
|
||||
Here is what a minimal event sequence for a two-contact touch would look
|
||||
like for a type B device:
|
||||
like for a type B device::
|
||||
|
||||
ABS_MT_SLOT 0
|
||||
ABS_MT_TRACKING_ID 45
|
||||
|
@ -134,13 +141,13 @@ like for a type B device:
|
|||
ABS_MT_POSITION_Y y[1]
|
||||
SYN_REPORT
|
||||
|
||||
Here is the sequence after moving contact 45 in the x direction:
|
||||
Here is the sequence after moving contact 45 in the x direction::
|
||||
|
||||
ABS_MT_SLOT 0
|
||||
ABS_MT_POSITION_X x[0]
|
||||
SYN_REPORT
|
||||
|
||||
Here is the sequence after lifting the contact in slot 0:
|
||||
Here is the sequence after lifting the contact in slot 0::
|
||||
|
||||
ABS_MT_TRACKING_ID -1
|
||||
SYN_REPORT
|
||||
|
@ -149,7 +156,7 @@ The slot being modified is already 0, so the ABS_MT_SLOT is omitted. The
|
|||
message removes the association of slot 0 with contact 45, thereby
|
||||
destroying contact 45 and freeing slot 0 to be reused for another contact.
|
||||
|
||||
Finally, here is the sequence after lifting the second contact:
|
||||
Finally, here is the sequence after lifting the second contact::
|
||||
|
||||
ABS_MT_SLOT 1
|
||||
ABS_MT_TRACKING_ID -1
|
||||
|
@ -181,6 +188,8 @@ ABS_MT_PRESSURE may be used to provide the pressure on the contact area
|
|||
instead. Devices capable of contact hovering can use ABS_MT_DISTANCE to
|
||||
indicate the distance between the contact and the surface.
|
||||
|
||||
::
|
||||
|
||||
|
||||
Linux MT Win8
|
||||
__________ _______________________
|
||||
|
@ -212,7 +221,7 @@ via ABS_MT_BLOB_ID.
|
|||
|
||||
The ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a
|
||||
finger or a pen or something else. Finally, the ABS_MT_TRACKING_ID event
|
||||
may be used to track identified contacts over time [5].
|
||||
may be used to track identified contacts over time [#f5]_.
|
||||
|
||||
In the type B protocol, ABS_MT_TOOL_TYPE and ABS_MT_TRACKING_ID are
|
||||
implicitly handled by input core; drivers should instead call
|
||||
|
@ -223,117 +232,103 @@ Event Semantics
|
|||
---------------
|
||||
|
||||
ABS_MT_TOUCH_MAJOR
|
||||
|
||||
The length of the major axis of the contact. The length should be given in
|
||||
surface units. If the surface has an X times Y resolution, the largest
|
||||
possible value of ABS_MT_TOUCH_MAJOR is sqrt(X^2 + Y^2), the diagonal [4].
|
||||
The length of the major axis of the contact. The length should be given in
|
||||
surface units. If the surface has an X times Y resolution, the largest
|
||||
possible value of ABS_MT_TOUCH_MAJOR is sqrt(X^2 + Y^2), the diagonal [#f4]_.
|
||||
|
||||
ABS_MT_TOUCH_MINOR
|
||||
|
||||
The length, in surface units, of the minor axis of the contact. If the
|
||||
contact is circular, this event can be omitted [4].
|
||||
The length, in surface units, of the minor axis of the contact. If the
|
||||
contact is circular, this event can be omitted [#f4]_.
|
||||
|
||||
ABS_MT_WIDTH_MAJOR
|
||||
|
||||
The length, in surface units, of the major axis of the approaching
|
||||
tool. This should be understood as the size of the tool itself. The
|
||||
orientation of the contact and the approaching tool are assumed to be the
|
||||
same [4].
|
||||
The length, in surface units, of the major axis of the approaching
|
||||
tool. This should be understood as the size of the tool itself. The
|
||||
orientation of the contact and the approaching tool are assumed to be the
|
||||
same [#f4]_.
|
||||
|
||||
ABS_MT_WIDTH_MINOR
|
||||
The length, in surface units, of the minor axis of the approaching
|
||||
tool. Omit if circular [#f4]_.
|
||||
|
||||
The length, in surface units, of the minor axis of the approaching
|
||||
tool. Omit if circular [4].
|
||||
|
||||
The above four values can be used to derive additional information about
|
||||
the contact. The ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR approximates
|
||||
the notion of pressure. The fingers of the hand and the palm all have
|
||||
different characteristic widths.
|
||||
The above four values can be used to derive additional information about
|
||||
the contact. The ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR approximates
|
||||
the notion of pressure. The fingers of the hand and the palm all have
|
||||
different characteristic widths.
|
||||
|
||||
ABS_MT_PRESSURE
|
||||
|
||||
The pressure, in arbitrary units, on the contact area. May be used instead
|
||||
of TOUCH and WIDTH for pressure-based devices or any device with a spatial
|
||||
signal intensity distribution.
|
||||
The pressure, in arbitrary units, on the contact area. May be used instead
|
||||
of TOUCH and WIDTH for pressure-based devices or any device with a spatial
|
||||
signal intensity distribution.
|
||||
|
||||
ABS_MT_DISTANCE
|
||||
|
||||
The distance, in surface units, between the contact and the surface. Zero
|
||||
distance means the contact is touching the surface. A positive number means
|
||||
the contact is hovering above the surface.
|
||||
The distance, in surface units, between the contact and the surface. Zero
|
||||
distance means the contact is touching the surface. A positive number means
|
||||
the contact is hovering above the surface.
|
||||
|
||||
ABS_MT_ORIENTATION
|
||||
The orientation of the touching ellipse. The value should describe a signed
|
||||
quarter of a revolution clockwise around the touch center. The signed value
|
||||
range is arbitrary, but zero should be returned for an ellipse aligned with
|
||||
the Y axis of the surface, a negative value when the ellipse is turned to
|
||||
the left, and a positive value when the ellipse is turned to the
|
||||
right. When completely aligned with the X axis, the range max should be
|
||||
returned.
|
||||
|
||||
The orientation of the touching ellipse. The value should describe a signed
|
||||
quarter of a revolution clockwise around the touch center. The signed value
|
||||
range is arbitrary, but zero should be returned for an ellipse aligned with
|
||||
the Y axis of the surface, a negative value when the ellipse is turned to
|
||||
the left, and a positive value when the ellipse is turned to the
|
||||
right. When completely aligned with the X axis, the range max should be
|
||||
returned.
|
||||
Touch ellipsis are symmetrical by default. For devices capable of true 360
|
||||
degree orientation, the reported orientation must exceed the range max to
|
||||
indicate more than a quarter of a revolution. For an upside-down finger,
|
||||
range max * 2 should be returned.
|
||||
|
||||
Touch ellipsis are symmetrical by default. For devices capable of true 360
|
||||
degree orientation, the reported orientation must exceed the range max to
|
||||
indicate more than a quarter of a revolution. For an upside-down finger,
|
||||
range max * 2 should be returned.
|
||||
|
||||
Orientation can be omitted if the touch area is circular, or if the
|
||||
information is not available in the kernel driver. Partial orientation
|
||||
support is possible if the device can distinguish between the two axis, but
|
||||
not (uniquely) any values in between. In such cases, the range of
|
||||
ABS_MT_ORIENTATION should be [0, 1] [4].
|
||||
Orientation can be omitted if the touch area is circular, or if the
|
||||
information is not available in the kernel driver. Partial orientation
|
||||
support is possible if the device can distinguish between the two axis, but
|
||||
not (uniquely) any values in between. In such cases, the range of
|
||||
ABS_MT_ORIENTATION should be [0, 1] [#f4]_.
|
||||
|
||||
ABS_MT_POSITION_X
|
||||
|
||||
The surface X coordinate of the center of the touching ellipse.
|
||||
The surface X coordinate of the center of the touching ellipse.
|
||||
|
||||
ABS_MT_POSITION_Y
|
||||
|
||||
The surface Y coordinate of the center of the touching ellipse.
|
||||
The surface Y coordinate of the center of the touching ellipse.
|
||||
|
||||
ABS_MT_TOOL_X
|
||||
|
||||
The surface X coordinate of the center of the approaching tool. Omit if
|
||||
the device cannot distinguish between the intended touch point and the
|
||||
tool itself.
|
||||
The surface X coordinate of the center of the approaching tool. Omit if
|
||||
the device cannot distinguish between the intended touch point and the
|
||||
tool itself.
|
||||
|
||||
ABS_MT_TOOL_Y
|
||||
The surface Y coordinate of the center of the approaching tool. Omit if the
|
||||
device cannot distinguish between the intended touch point and the tool
|
||||
itself.
|
||||
|
||||
The surface Y coordinate of the center of the approaching tool. Omit if the
|
||||
device cannot distinguish between the intended touch point and the tool
|
||||
itself.
|
||||
|
||||
The four position values can be used to separate the position of the touch
|
||||
from the position of the tool. If both positions are present, the major
|
||||
tool axis points towards the touch point [1]. Otherwise, the tool axes are
|
||||
aligned with the touch axes.
|
||||
The four position values can be used to separate the position of the touch
|
||||
from the position of the tool. If both positions are present, the major
|
||||
tool axis points towards the touch point [#f1]_. Otherwise, the tool axes are
|
||||
aligned with the touch axes.
|
||||
|
||||
ABS_MT_TOOL_TYPE
|
||||
|
||||
The type of approaching tool. A lot of kernel drivers cannot distinguish
|
||||
between different tool types, such as a finger or a pen. In such cases, the
|
||||
event should be omitted. The protocol currently supports MT_TOOL_FINGER,
|
||||
MT_TOOL_PEN, and MT_TOOL_PALM [2]. For type B devices, this event is handled
|
||||
by input core; drivers should instead use input_mt_report_slot_state().
|
||||
A contact's ABS_MT_TOOL_TYPE may change over time while still touching the
|
||||
device, because the firmware may not be able to determine which tool is being
|
||||
used when it first appears.
|
||||
The type of approaching tool. A lot of kernel drivers cannot distinguish
|
||||
between different tool types, such as a finger or a pen. In such cases, the
|
||||
event should be omitted. The protocol currently supports MT_TOOL_FINGER,
|
||||
MT_TOOL_PEN, and MT_TOOL_PALM [#f2]_. For type B devices, this event is
|
||||
handled by input core; drivers should instead use
|
||||
input_mt_report_slot_state(). A contact's ABS_MT_TOOL_TYPE may change over
|
||||
time while still touching the device, because the firmware may not be able
|
||||
to determine which tool is being used when it first appears.
|
||||
|
||||
ABS_MT_BLOB_ID
|
||||
|
||||
The BLOB_ID groups several packets together into one arbitrarily shaped
|
||||
contact. The sequence of points forms a polygon which defines the shape of
|
||||
the contact. This is a low-level anonymous grouping for type A devices, and
|
||||
should not be confused with the high-level trackingID [5]. Most type A
|
||||
devices do not have blob capability, so drivers can safely omit this event.
|
||||
The BLOB_ID groups several packets together into one arbitrarily shaped
|
||||
contact. The sequence of points forms a polygon which defines the shape of
|
||||
the contact. This is a low-level anonymous grouping for type A devices, and
|
||||
should not be confused with the high-level trackingID [#f5]_. Most type A
|
||||
devices do not have blob capability, so drivers can safely omit this event.
|
||||
|
||||
ABS_MT_TRACKING_ID
|
||||
|
||||
The TRACKING_ID identifies an initiated contact throughout its life cycle
|
||||
[5]. The value range of the TRACKING_ID should be large enough to ensure
|
||||
unique identification of a contact maintained over an extended period of
|
||||
time. For type B devices, this event is handled by input core; drivers
|
||||
should instead use input_mt_report_slot_state().
|
||||
The TRACKING_ID identifies an initiated contact throughout its life cycle
|
||||
[#f5]_. The value range of the TRACKING_ID should be large enough to ensure
|
||||
unique identification of a contact maintained over an extended period of
|
||||
time. For type B devices, this event is handled by input core; drivers
|
||||
should instead use input_mt_report_slot_state().
|
||||
|
||||
|
||||
Event Computation
|
||||
|
@ -346,7 +341,7 @@ this section gives recipes for how to compute certain events.
|
|||
For devices reporting contacts as rectangular shapes, signed orientation
|
||||
cannot be obtained. Assuming X and Y are the lengths of the sides of the
|
||||
touching rectangle, here is a simple formula that retains the most
|
||||
information possible:
|
||||
information possible::
|
||||
|
||||
ABS_MT_TOUCH_MAJOR := max(X, Y)
|
||||
ABS_MT_TOUCH_MINOR := min(X, Y)
|
||||
|
@ -356,7 +351,7 @@ The range of ABS_MT_ORIENTATION should be set to [0, 1], to indicate that
|
|||
the device can distinguish between a finger along the Y axis (0) and a
|
||||
finger along the X axis (1).
|
||||
|
||||
For win8 devices with both T and C coordinates, the position mapping is
|
||||
For win8 devices with both T and C coordinates, the position mapping is::
|
||||
|
||||
ABS_MT_POSITION_X := T_X
|
||||
ABS_MT_POSITION_Y := T_Y
|
||||
|
@ -365,7 +360,7 @@ For win8 devices with both T and C coordinates, the position mapping is
|
|||
|
||||
Unfortunately, there is not enough information to specify both the touching
|
||||
ellipse and the tool ellipse, so one has to resort to approximations. One
|
||||
simple scheme, which is compatible with earlier usage, is:
|
||||
simple scheme, which is compatible with earlier usage, is::
|
||||
|
||||
ABS_MT_TOUCH_MAJOR := min(X, Y)
|
||||
ABS_MT_TOUCH_MINOR := <not used>
|
||||
|
@ -386,7 +381,7 @@ The process of finger tracking, i.e., to assign a unique trackingID to each
|
|||
initiated contact on the surface, is a Euclidian Bipartite Matching
|
||||
problem. At each event synchronization, the set of actual contacts is
|
||||
matched to the set of contacts from the previous synchronization. A full
|
||||
implementation can be found in [3].
|
||||
implementation can be found in [#f3]_.
|
||||
|
||||
|
||||
Gestures
|
||||
|
@ -408,11 +403,8 @@ in a finger packet must not be recognized as single-touch events.
|
|||
For type A devices, all finger data bypasses input filtering, since
|
||||
subsequent events of the same type refer to different fingers.
|
||||
|
||||
For example usage of the type A protocol, see the bcm5974 driver. For
|
||||
example usage of the type B protocol, see the hid-egalax driver.
|
||||
|
||||
[1] Also, the difference (TOOL_X - POSITION_X) can be used to model tilt.
|
||||
[2] The list can of course be extended.
|
||||
[3] The mtdev project: http://bitmath.org/code/mtdev/.
|
||||
[4] See the section on event computation.
|
||||
[5] See the section on finger tracking.
|
||||
.. [#f1] Also, the difference (TOOL_X - POSITION_X) can be used to model tilt.
|
||||
.. [#f2] The list can of course be extended.
|
||||
.. [#f3] The mtdev project: http://bitmath.org/code/mtdev/.
|
||||
.. [#f4] See the section on event computation.
|
||||
.. [#f5] See the section on finger tracking.
|
|
@ -1,4 +1,6 @@
|
|||
=================
|
||||
Keyboard notifier
|
||||
=================
|
||||
|
||||
One can use register_keyboard_notifier to get called back on keyboard
|
||||
events (see kbd_keycode() function for details). The passed structure is
|
||||
|
@ -23,9 +25,9 @@ For each kind of event but the last, the callback may return NOTIFY_STOP in
|
|||
order to "eat" the event: the notify loop is stopped and the keyboard event is
|
||||
dropped.
|
||||
|
||||
In a rough C snippet, we have:
|
||||
In a rough C snippet, we have::
|
||||
|
||||
kbd_keycode(keycode) {
|
||||
kbd_keycode(keycode) {
|
||||
...
|
||||
params.value = keycode;
|
||||
if (notifier_call_chain(KBD_KEYCODE,¶ms) == NOTIFY_STOP)
|
||||
|
@ -47,6 +49,6 @@ kbd_keycode(keycode) {
|
|||
return;
|
||||
apply keysym;
|
||||
notifier_call_chain(KBD_POST_KEYSYM,¶ms);
|
||||
}
|
||||
}
|
||||
|
||||
NOTE: This notifier is usually called from interrupt context.
|
||||
.. note:: This notifier is usually called from interrupt context.
|
|
@ -1,873 +0,0 @@
|
|||
Copyright (C) 2002-2011 Sentelic Corporation.
|
||||
Last update: Dec-07-2011
|
||||
|
||||
==============================================================================
|
||||
* Finger Sensing Pad Intellimouse Mode(scrolling wheel, 4th and 5th buttons)
|
||||
==============================================================================
|
||||
A) MSID 4: Scrolling wheel mode plus Forward page(4th button) and Backward
|
||||
page (5th button)
|
||||
@1. Set sample rate to 200;
|
||||
@2. Set sample rate to 200;
|
||||
@3. Set sample rate to 80;
|
||||
@4. Issuing the "Get device ID" command (0xF2) and waits for the response;
|
||||
@5. FSP will respond 0x04.
|
||||
|
||||
Packet 1
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |Y|X|y|x|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 | | |B|F|W|W|W|W|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7 => Y overflow
|
||||
Bit6 => X overflow
|
||||
Bit5 => Y sign bit
|
||||
Bit4 => X sign bit
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X Movement(9-bit 2's complement integers)
|
||||
Byte 3: Y Movement(9-bit 2's complement integers)
|
||||
Byte 4: Bit3~Bit0 => the scrolling wheel's movement since the last data report.
|
||||
valid values, -8 ~ +7
|
||||
Bit4 => 1 = 4th mouse button is pressed, Forward one page.
|
||||
0 = 4th mouse button is not pressed.
|
||||
Bit5 => 1 = 5th mouse button is pressed, Backward one page.
|
||||
0 = 5th mouse button is not pressed.
|
||||
|
||||
B) MSID 6: Horizontal and Vertical scrolling.
|
||||
@ Set bit 1 in register 0x40 to 1
|
||||
|
||||
# FSP replaces scrolling wheel's movement as 4 bits to show horizontal and
|
||||
vertical scrolling.
|
||||
|
||||
Packet 1
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |Y|X|y|x|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 | | |B|F|r|l|u|d|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7 => Y overflow
|
||||
Bit6 => X overflow
|
||||
Bit5 => Y sign bit
|
||||
Bit4 => X sign bit
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X Movement(9-bit 2's complement integers)
|
||||
Byte 3: Y Movement(9-bit 2's complement integers)
|
||||
Byte 4: Bit0 => the Vertical scrolling movement downward.
|
||||
Bit1 => the Vertical scrolling movement upward.
|
||||
Bit2 => the Horizontal scrolling movement leftward.
|
||||
Bit3 => the Horizontal scrolling movement rightward.
|
||||
Bit4 => 1 = 4th mouse button is pressed, Forward one page.
|
||||
0 = 4th mouse button is not pressed.
|
||||
Bit5 => 1 = 5th mouse button is pressed, Backward one page.
|
||||
0 = 5th mouse button is not pressed.
|
||||
|
||||
C) MSID 7:
|
||||
# FSP uses 2 packets (8 Bytes) to represent Absolute Position.
|
||||
so we have PACKET NUMBER to identify packets.
|
||||
If PACKET NUMBER is 0, the packet is Packet 1.
|
||||
If PACKET NUMBER is 1, the packet is Packet 2.
|
||||
Please count this number in program.
|
||||
|
||||
# MSID6 special packet will be enable at the same time when enable MSID 7.
|
||||
|
||||
==============================================================================
|
||||
* Absolute position for STL3886-G0.
|
||||
==============================================================================
|
||||
@ Set bit 2 or 3 in register 0x40 to 1
|
||||
@ Set bit 6 in register 0x40 to 1
|
||||
|
||||
Packet 1 (ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|1|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|d|u|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => valid bit
|
||||
Bit4 => 1
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => scroll up
|
||||
Bit5 => scroll down
|
||||
Bit6 => scroll left
|
||||
Bit7 => scroll right
|
||||
|
||||
Notify Packet for G0
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |1|0|0|1|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |M|M|M|M|M|M|M|M| 4 |0|0|0|0|0|0|0|0|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => 0
|
||||
Bit4 => 1
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: Message Type => 0x5A (Enable/Disable status packet)
|
||||
Mode Type => 0xA5 (Normal/Icon mode status)
|
||||
Byte 3: Message Type => 0x00 (Disabled)
|
||||
=> 0x01 (Enabled)
|
||||
Mode Type => 0x00 (Normal)
|
||||
=> 0x01 (Icon)
|
||||
Byte 4: Bit7~Bit0 => Don't Care
|
||||
|
||||
==============================================================================
|
||||
* Absolute position for STL3888-Ax.
|
||||
==============================================================================
|
||||
Packet 1 (ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|A|1|L|0|1| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |x|x|y|y|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
|
||||
When both fingers are up, the last two reports have zero valid
|
||||
bit.
|
||||
Bit4 => arc
|
||||
Bit3 => 1
|
||||
Bit2 => Left Button, 1 is pressed, 0 is released.
|
||||
Bit1 => 0
|
||||
Bit0 => 1
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit5~Bit4 => y1_g
|
||||
Bit7~Bit6 => x1_g
|
||||
|
||||
Packet 2 (ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|A|1|R|1|0| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |x|x|y|y|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
|
||||
When both fingers are up, the last two reports have zero valid
|
||||
bit.
|
||||
Bit4 => arc
|
||||
Bit3 => 1
|
||||
Bit2 => Right Button, 1 is pressed, 0 is released.
|
||||
Bit1 => 1
|
||||
Bit0 => 0
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit5~Bit4 => y2_g
|
||||
Bit7~Bit6 => x2_g
|
||||
|
||||
Notify Packet for STL3888-Ax
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |1|0|1|P|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |0|0|F|F|0|0|0|i| 4 |r|l|d|u|0|0|0|0|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => 1
|
||||
Bit4 => when in absolute coordinates mode (valid when EN_PKT_GO is 1):
|
||||
0: left button is generated by the on-pad command
|
||||
1: left button is generated by the external button
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: Message Type => 0xB7 (Multi Finger, Multi Coordinate mode)
|
||||
Byte 3: Bit7~Bit6 => Don't care
|
||||
Bit5~Bit4 => Number of fingers
|
||||
Bit3~Bit1 => Reserved
|
||||
Bit0 => 1: enter gesture mode; 0: leaving gesture mode
|
||||
Byte 4: Bit7 => scroll right button
|
||||
Bit6 => scroll left button
|
||||
Bit5 => scroll down button
|
||||
Bit4 => scroll up button
|
||||
* Note that if gesture and additional button (Bit4~Bit7)
|
||||
happen at the same time, the button information will not
|
||||
be sent.
|
||||
Bit3~Bit0 => Reserved
|
||||
|
||||
Sample sequence of Multi-finger, Multi-coordinate mode:
|
||||
|
||||
notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1,
|
||||
abs pkt 2, ..., notify packet (valid bit == 0)
|
||||
|
||||
==============================================================================
|
||||
* Absolute position for STL3888-B0.
|
||||
==============================================================================
|
||||
Packet 1(ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|F|1|0|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|u|d|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
|
||||
When both fingers are up, the last two reports have zero valid
|
||||
bit.
|
||||
Bit4 => finger up/down information. 1: finger down, 0: finger up.
|
||||
Bit3 => 1
|
||||
Bit2 => finger index, 0 is the first finger, 1 is the second finger.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => scroll down button
|
||||
Bit5 => scroll up button
|
||||
Bit6 => scroll left button
|
||||
Bit7 => scroll right button
|
||||
|
||||
Packet 2 (ABSOLUTE POSITION)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|V|F|1|1|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|u|d|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
|
||||
When both fingers are up, the last two reports have zero valid
|
||||
bit.
|
||||
Bit4 => finger up/down information. 1: finger down, 0: finger up.
|
||||
Bit3 => 1
|
||||
Bit2 => finger index, 0 is the first finger, 1 is the second finger.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => scroll down button
|
||||
Bit5 => scroll up button
|
||||
Bit6 => scroll left button
|
||||
Bit7 => scroll right button
|
||||
|
||||
Notify Packet for STL3888-B0
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |1|0|1|P|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |0|0|F|F|0|0|0|i| 4 |r|l|u|d|0|0|0|0|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
=> 11, Normal data packet with on-pad click
|
||||
Bit5 => 1
|
||||
Bit4 => when in absolute coordinates mode (valid when EN_PKT_GO is 1):
|
||||
0: left button is generated by the on-pad command
|
||||
1: left button is generated by the external button
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: Message Type => 0xB7 (Multi Finger, Multi Coordinate mode)
|
||||
Byte 3: Bit7~Bit6 => Don't care
|
||||
Bit5~Bit4 => Number of fingers
|
||||
Bit3~Bit1 => Reserved
|
||||
Bit0 => 1: enter gesture mode; 0: leaving gesture mode
|
||||
Byte 4: Bit7 => scroll right button
|
||||
Bit6 => scroll left button
|
||||
Bit5 => scroll up button
|
||||
Bit4 => scroll down button
|
||||
* Note that if gesture and additional button(Bit4~Bit7)
|
||||
happen at the same time, the button information will not
|
||||
be sent.
|
||||
Bit3~Bit0 => Reserved
|
||||
|
||||
Sample sequence of Multi-finger, Multi-coordinate mode:
|
||||
|
||||
notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1,
|
||||
abs pkt 2, ..., notify packet (valid bit == 0)
|
||||
|
||||
==============================================================================
|
||||
* Absolute position for STL3888-Cx and STL3888-Dx.
|
||||
==============================================================================
|
||||
Single Finger, Absolute Coordinate Mode (SFAC)
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|0|P|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|B|F|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => Coordinate mode(always 0 in SFAC mode):
|
||||
0: single-finger absolute coordinates (SFAC) mode
|
||||
1: multi-finger, multiple coordinates (MFMC) mode
|
||||
Bit4 => 0: The LEFT button is generated by on-pad command (OPC)
|
||||
1: The LEFT button is generated by external button
|
||||
Default is 1 even if the LEFT button is not pressed.
|
||||
Bit3 => Always 1, as specified by PS/2 protocol.
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => 4th mouse button(forward one page)
|
||||
Bit5 => 5th mouse button(backward one page)
|
||||
Bit6 => scroll left button
|
||||
Bit7 => scroll right button
|
||||
|
||||
Multi Finger, Multiple Coordinates Mode (MFMC):
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |0|1|1|P|1|F|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|B|F|X|X|Y|Y|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordination packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => Coordinate mode (always 1 in MFMC mode):
|
||||
0: single-finger absolute coordinates (SFAC) mode
|
||||
1: multi-finger, multiple coordinates (MFMC) mode
|
||||
Bit4 => 0: The LEFT button is generated by on-pad command (OPC)
|
||||
1: The LEFT button is generated by external button
|
||||
Default is 1 even if the LEFT button is not pressed.
|
||||
Bit3 => Always 1, as specified by PS/2 protocol.
|
||||
Bit2 => Finger index, 0 is the first finger, 1 is the second finger.
|
||||
If bit 1 and 0 are all 1 and bit 4 is 0, the middle external
|
||||
button is pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: X coordinate (xpos[9:2])
|
||||
Byte 3: Y coordinate (ypos[9:2])
|
||||
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
|
||||
Bit3~Bit2 => X coordinate (ypos[1:0])
|
||||
Bit4 => 4th mouse button(forward one page)
|
||||
Bit5 => 5th mouse button(backward one page)
|
||||
Bit6 => scroll left button
|
||||
Bit7 => scroll right button
|
||||
|
||||
When one of the two fingers is up, the device will output four consecutive
|
||||
MFMC#0 report packets with zero X and Y to represent 1st finger is up or
|
||||
four consecutive MFMC#1 report packets with zero X and Y to represent that
|
||||
the 2nd finger is up. On the other hand, if both fingers are up, the device
|
||||
will output four consecutive single-finger, absolute coordinate(SFAC) packets
|
||||
with zero X and Y.
|
||||
|
||||
Notify Packet for STL3888-Cx/Dx
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |1|0|0|P|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |0|0|F|F|0|0|0|i| 4 |r|l|u|d|0|0|0|0|
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
Byte 1: Bit7~Bit6 => 00, Normal data packet
|
||||
=> 01, Absolute coordinates packet
|
||||
=> 10, Notify packet
|
||||
Bit5 => Always 0
|
||||
Bit4 => 0: The LEFT button is generated by on-pad command(OPC)
|
||||
1: The LEFT button is generated by external button
|
||||
Default is 1 even if the LEFT button is not pressed.
|
||||
Bit3 => 1
|
||||
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
|
||||
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
|
||||
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
|
||||
Byte 2: Message type:
|
||||
0xba => gesture information
|
||||
0xc0 => one finger hold-rotating gesture
|
||||
Byte 3: The first parameter for the received message:
|
||||
0xba => gesture ID (refer to the 'Gesture ID' section)
|
||||
0xc0 => region ID
|
||||
Byte 4: The second parameter for the received message:
|
||||
0xba => N/A
|
||||
0xc0 => finger up/down information
|
||||
|
||||
Sample sequence of Multi-finger, Multi-coordinates mode:
|
||||
|
||||
notify packet (valid bit == 1), MFMC packet 1 (byte 1, bit 2 == 0),
|
||||
MFMC packet 2 (byte 1, bit 2 == 1), MFMC packet 1, MFMC packet 2,
|
||||
..., notify packet (valid bit == 0)
|
||||
|
||||
That is, when the device is in MFMC mode, the host will receive
|
||||
interleaved absolute coordinate packets for each finger.
|
||||
|
||||
==============================================================================
|
||||
* FSP Enable/Disable packet
|
||||
==============================================================================
|
||||
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
|
||||
1 |Y|X|0|0|1|M|R|L| 2 |0|1|0|1|1|0|1|E| 3 | | | | | | | | | 4 | | | | | | | | |
|
||||
|---------------| |---------------| |---------------| |---------------|
|
||||
|
||||
FSP will send out enable/disable packet when FSP receive PS/2 enable/disable
|
||||
command. Host will receive the packet which Middle, Right, Left button will
|
||||
be set. The packet only use byte 0 and byte 1 as a pattern of original packet.
|
||||
Ignore the other bytes of the packet.
|
||||
|
||||
Byte 1: Bit7 => 0, Y overflow
|
||||
Bit6 => 0, X overflow
|
||||
Bit5 => 0, Y sign bit
|
||||
Bit4 => 0, X sign bit
|
||||
Bit3 => 1
|
||||
Bit2 => 1, Middle Button
|
||||
Bit1 => 1, Right Button
|
||||
Bit0 => 1, Left Button
|
||||
Byte 2: Bit7~1 => (0101101b)
|
||||
Bit0 => 1 = Enable
|
||||
0 = Disable
|
||||
Byte 3: Don't care
|
||||
Byte 4: Don't care (MOUSE ID 3, 4)
|
||||
Byte 5~8: Don't care (Absolute packet)
|
||||
|
||||
==============================================================================
|
||||
* PS/2 Command Set
|
||||
==============================================================================
|
||||
|
||||
FSP supports basic PS/2 commanding set and modes, refer to following URL for
|
||||
details about PS/2 commands:
|
||||
|
||||
http://www.computer-engineering.org/ps2mouse/
|
||||
|
||||
==============================================================================
|
||||
* Programming Sequence for Determining Packet Parsing Flow
|
||||
==============================================================================
|
||||
1. Identify FSP by reading device ID(0x00) and version(0x01) register
|
||||
|
||||
2a. For FSP version < STL3888 Cx, determine number of buttons by reading
|
||||
the 'test mode status' (0x20) register:
|
||||
|
||||
buttons = reg[0x20] & 0x30
|
||||
|
||||
if buttons == 0x30 or buttons == 0x20:
|
||||
# two/four buttons
|
||||
Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
|
||||
section A for packet parsing detail(ignore byte 4, bit ~ 7)
|
||||
elif buttons == 0x10:
|
||||
# 6 buttons
|
||||
Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
|
||||
section B for packet parsing detail
|
||||
elif buttons == 0x00:
|
||||
# 6 buttons
|
||||
Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
|
||||
section A for packet parsing detail
|
||||
|
||||
2b. For FSP version >= STL3888 Cx:
|
||||
Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
|
||||
section A for packet parsing detail (ignore byte 4, bit ~ 7)
|
||||
|
||||
==============================================================================
|
||||
* Programming Sequence for Register Reading/Writing
|
||||
==============================================================================
|
||||
|
||||
Register inversion requirement:
|
||||
|
||||
Following values needed to be inverted(the '~' operator in C) before being
|
||||
sent to FSP:
|
||||
|
||||
0xe8, 0xe9, 0xee, 0xf2, 0xf3 and 0xff.
|
||||
|
||||
Register swapping requirement:
|
||||
|
||||
Following values needed to have their higher 4 bits and lower 4 bits being
|
||||
swapped before being sent to FSP:
|
||||
|
||||
10, 20, 40, 60, 80, 100 and 200.
|
||||
|
||||
Register reading sequence:
|
||||
|
||||
1. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
2. send 0x66 PS/2 command to FSP;
|
||||
|
||||
3. send 0x88 PS/2 command to FSP;
|
||||
|
||||
4. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
5. if the register address being to read is not required to be
|
||||
inverted(refer to the 'Register inversion requirement' section),
|
||||
goto step 6
|
||||
|
||||
5a. send 0x68 PS/2 command to FSP;
|
||||
|
||||
5b. send the inverted register address to FSP and goto step 8;
|
||||
|
||||
6. if the register address being to read is not required to be
|
||||
swapped(refer to the 'Register swapping requirement' section),
|
||||
goto step 7
|
||||
|
||||
6a. send 0xcc PS/2 command to FSP;
|
||||
|
||||
6b. send the swapped register address to FSP and goto step 8;
|
||||
|
||||
7. send 0x66 PS/2 command to FSP;
|
||||
|
||||
7a. send the original register address to FSP and goto step 8;
|
||||
|
||||
8. send 0xe9(status request) PS/2 command to FSP;
|
||||
|
||||
9. the 4th byte of the response read from FSP should be the
|
||||
requested register value(?? indicates don't care byte):
|
||||
|
||||
host: 0xe9
|
||||
3888: 0xfa (??) (??) (val)
|
||||
|
||||
* Note that since the Cx release, the hardware will return 1's
|
||||
complement of the register value at the 3rd byte of status request
|
||||
result:
|
||||
|
||||
host: 0xe9
|
||||
3888: 0xfa (??) (~val) (val)
|
||||
|
||||
Register writing sequence:
|
||||
|
||||
1. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
2. if the register address being to write is not required to be
|
||||
inverted(refer to the 'Register inversion requirement' section),
|
||||
goto step 3
|
||||
|
||||
2a. send 0x74 PS/2 command to FSP;
|
||||
|
||||
2b. send the inverted register address to FSP and goto step 5;
|
||||
|
||||
3. if the register address being to write is not required to be
|
||||
swapped(refer to the 'Register swapping requirement' section),
|
||||
goto step 4
|
||||
|
||||
3a. send 0x77 PS/2 command to FSP;
|
||||
|
||||
3b. send the swapped register address to FSP and goto step 5;
|
||||
|
||||
4. send 0x55 PS/2 command to FSP;
|
||||
|
||||
4a. send the register address to FSP and goto step 5;
|
||||
|
||||
5. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
6. if the register value being to write is not required to be
|
||||
inverted(refer to the 'Register inversion requirement' section),
|
||||
goto step 7
|
||||
|
||||
6a. send 0x47 PS/2 command to FSP;
|
||||
|
||||
6b. send the inverted register value to FSP and goto step 9;
|
||||
|
||||
7. if the register value being to write is not required to be
|
||||
swapped(refer to the 'Register swapping requirement' section),
|
||||
goto step 8
|
||||
|
||||
7a. send 0x44 PS/2 command to FSP;
|
||||
|
||||
7b. send the swapped register value to FSP and goto step 9;
|
||||
|
||||
8. send 0x33 PS/2 command to FSP;
|
||||
|
||||
8a. send the register value to FSP;
|
||||
|
||||
9. the register writing sequence is completed.
|
||||
|
||||
* Note that since the Cx release, the hardware will return 1's
|
||||
complement of the register value at the 3rd byte of status request
|
||||
result. Host can optionally send another 0xe9 (status request) PS/2
|
||||
command to FSP at the end of register writing to verify that the
|
||||
register writing operation is successful (?? indicates don't care
|
||||
byte):
|
||||
|
||||
host: 0xe9
|
||||
3888: 0xfa (??) (~val) (val)
|
||||
|
||||
==============================================================================
|
||||
* Programming Sequence for Page Register Reading/Writing
|
||||
==============================================================================
|
||||
|
||||
In order to overcome the limitation of maximum number of registers
|
||||
supported, the hardware separates register into different groups called
|
||||
'pages.' Each page is able to include up to 255 registers.
|
||||
|
||||
The default page after power up is 0x82; therefore, if one has to get
|
||||
access to register 0x8301, one has to use following sequence to switch
|
||||
to page 0x83, then start reading/writing from/to offset 0x01 by using
|
||||
the register read/write sequence described in previous section.
|
||||
|
||||
Page register reading sequence:
|
||||
|
||||
1. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
2. send 0x66 PS/2 command to FSP;
|
||||
|
||||
3. send 0x88 PS/2 command to FSP;
|
||||
|
||||
4. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
5. send 0x83 PS/2 command to FSP;
|
||||
|
||||
6. send 0x88 PS/2 command to FSP;
|
||||
|
||||
7. send 0xe9(status request) PS/2 command to FSP;
|
||||
|
||||
8. the response read from FSP should be the requested page value.
|
||||
|
||||
Page register writing sequence:
|
||||
|
||||
1. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
2. send 0x38 PS/2 command to FSP;
|
||||
|
||||
3. send 0x88 PS/2 command to FSP;
|
||||
|
||||
4. send 0xf3 PS/2 command to FSP;
|
||||
|
||||
5. if the page address being written is not required to be
|
||||
inverted(refer to the 'Register inversion requirement' section),
|
||||
goto step 6
|
||||
|
||||
5a. send 0x47 PS/2 command to FSP;
|
||||
|
||||
5b. send the inverted page address to FSP and goto step 9;
|
||||
|
||||
6. if the page address being written is not required to be
|
||||
swapped(refer to the 'Register swapping requirement' section),
|
||||
goto step 7
|
||||
|
||||
6a. send 0x44 PS/2 command to FSP;
|
||||
|
||||
6b. send the swapped page address to FSP and goto step 9;
|
||||
|
||||
7. send 0x33 PS/2 command to FSP;
|
||||
|
||||
8. send the page address to FSP;
|
||||
|
||||
9. the page register writing sequence is completed.
|
||||
|
||||
==============================================================================
|
||||
* Gesture ID
|
||||
==============================================================================
|
||||
|
||||
Unlike other devices which sends multiple fingers' coordinates to host,
|
||||
FSP processes multiple fingers' coordinates internally and convert them
|
||||
into a 8 bits integer, namely 'Gesture ID.' Following is a list of
|
||||
supported gesture IDs:
|
||||
|
||||
ID Description
|
||||
0x86 2 finger straight up
|
||||
0x82 2 finger straight down
|
||||
0x80 2 finger straight right
|
||||
0x84 2 finger straight left
|
||||
0x8f 2 finger zoom in
|
||||
0x8b 2 finger zoom out
|
||||
0xc0 2 finger curve, counter clockwise
|
||||
0xc4 2 finger curve, clockwise
|
||||
0x2e 3 finger straight up
|
||||
0x2a 3 finger straight down
|
||||
0x28 3 finger straight right
|
||||
0x2c 3 finger straight left
|
||||
0x38 palm
|
||||
|
||||
==============================================================================
|
||||
* Register Listing
|
||||
==============================================================================
|
||||
|
||||
Registers are represented in 16 bits values. The higher 8 bits represent
|
||||
the page address and the lower 8 bits represent the relative offset within
|
||||
that particular page. Refer to the 'Programming Sequence for Page Register
|
||||
Reading/Writing' section for instructions on how to change current page
|
||||
address.
|
||||
|
||||
offset width default r/w name
|
||||
0x8200 bit7~bit0 0x01 RO device ID
|
||||
|
||||
0x8201 bit7~bit0 RW version ID
|
||||
0xc1: STL3888 Ax
|
||||
0xd0 ~ 0xd2: STL3888 Bx
|
||||
0xe0 ~ 0xe1: STL3888 Cx
|
||||
0xe2 ~ 0xe3: STL3888 Dx
|
||||
|
||||
0x8202 bit7~bit0 0x01 RO vendor ID
|
||||
|
||||
0x8203 bit7~bit0 0x01 RO product ID
|
||||
|
||||
0x8204 bit3~bit0 0x01 RW revision ID
|
||||
|
||||
0x820b test mode status 1
|
||||
bit3 1 RO 0: rotate 180 degree
|
||||
1: no rotation
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x820f register file page control
|
||||
bit2 0 RW 1: rotate 180 degree
|
||||
0: no rotation
|
||||
*supported since Cx
|
||||
|
||||
bit0 0 RW 1 to enable page 1 register files
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8210 RW system control 1
|
||||
bit0 1 RW Reserved, must be 1
|
||||
bit1 0 RW Reserved, must be 0
|
||||
bit4 0 RW Reserved, must be 0
|
||||
bit5 1 RW register clock gating enable
|
||||
0: read only, 1: read/write enable
|
||||
(Note that following registers does not require clock gating being
|
||||
enabled prior to write: 05 06 07 08 09 0c 0f 10 11 12 16 17 18 23 2e
|
||||
40 41 42 43. In addition to that, this bit must be 1 when gesture
|
||||
mode is enabled)
|
||||
|
||||
0x8220 test mode status
|
||||
bit5~bit4 RO number of buttons
|
||||
11 => 2, lbtn/rbtn
|
||||
10 => 4, lbtn/rbtn/scru/scrd
|
||||
01 => 6, lbtn/rbtn/scru/scrd/scrl/scrr
|
||||
00 => 6, lbtn/rbtn/scru/scrd/fbtn/bbtn
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8231 RW on-pad command detection
|
||||
bit7 0 RW on-pad command left button down tag
|
||||
enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8234 RW on-pad command control 5
|
||||
bit4~bit0 0x05 RW XLO in 0s/4/1, so 03h = 0010.1b = 2.5
|
||||
(Note that position unit is in 0.5 scanline)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit7 0 RW on-pad tap zone enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8235 RW on-pad command control 6
|
||||
bit4~bit0 0x1d RW XHI in 0s/4/1, so 19h = 1100.1b = 12.5
|
||||
(Note that position unit is in 0.5 scanline)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8236 RW on-pad command control 7
|
||||
bit4~bit0 0x04 RW YLO in 0s/4/1, so 03h = 0010.1b = 2.5
|
||||
(Note that position unit is in 0.5 scanline)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8237 RW on-pad command control 8
|
||||
bit4~bit0 0x13 RW YHI in 0s/4/1, so 11h = 1000.1b = 8.5
|
||||
(Note that position unit is in 0.5 scanline)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8240 RW system control 5
|
||||
bit1 0 RW FSP Intellimouse mode enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit2 0 RW movement + abs. coordinate mode enable
|
||||
0: disable, 1: enable
|
||||
(Note that this function has the functionality of bit 1 even when
|
||||
bit 1 is not set. However, the format is different from that of bit 1.
|
||||
In addition, when bit 1 and bit 2 are set at the same time, bit 2 will
|
||||
override bit 1.)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit3 0 RW abs. coordinate only mode enable
|
||||
0: disable, 1: enable
|
||||
(Note that this function has the functionality of bit 1 even when
|
||||
bit 1 is not set. However, the format is different from that of bit 1.
|
||||
In addition, when bit 1, bit 2 and bit 3 are set at the same time,
|
||||
bit 3 will override bit 1 and 2.)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit5 0 RW auto switch enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit6 0 RW G0 abs. + notify packet format enable
|
||||
0: disable, 1: enable
|
||||
(Note that the absolute/relative coordinate output still depends on
|
||||
bit 2 and 3. That is, if any of those bit is 1, host will receive
|
||||
absolute coordinates; otherwise, host only receives packets with
|
||||
relative coordinate.)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit7 0 RW EN_PS2_F2: PS/2 gesture mode 2nd
|
||||
finger packet enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8243 RW on-pad control
|
||||
bit0 0 RW on-pad control enable
|
||||
0: disable, 1: enable
|
||||
(Note that if this bit is cleared, bit 3/5 will be ineffective)
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit3 0 RW on-pad fix vertical scrolling enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
bit5 0 RW on-pad fix horizontal scrolling enable
|
||||
0: disable, 1: enable
|
||||
*only supported by H/W prior to Cx
|
||||
|
||||
0x8290 RW software control register 1
|
||||
bit0 0 RW absolute coordination mode
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit1 0 RW gesture ID output
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit2 0 RW two fingers' coordinates output
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit3 0 RW finger up one packet output
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit4 0 RW absolute coordination continuous mode
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
bit6~bit5 00 RW gesture group selection
|
||||
00: basic
|
||||
01: suite
|
||||
10: suite pro
|
||||
11: advanced
|
||||
*supported since Cx
|
||||
|
||||
bit7 0 RW Bx packet output compatible mode
|
||||
0: disable, 1: enable *supported since Cx
|
||||
*supported since Cx
|
||||
|
||||
|
||||
0x833d RW on-pad command control 1
|
||||
bit7 1 RW on-pad command detection enable
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
||||
|
||||
0x833e RW on-pad command detection
|
||||
bit7 0 RW on-pad command left button down tag
|
||||
enable. Works only in H/W based PS/2
|
||||
data packet mode.
|
||||
0: disable, 1: enable
|
||||
*supported since Cx
|
|
@ -1,65 +0,0 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 6
|
||||
4200 3600 4200 3075 4950 2325 7425 2325 8250 3150 8250 3600
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
4200 3675 4200 5400
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
8250 3675 8250 5400
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
3675 3600 8700 3600
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
8775 3600 10200 3600
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
8325 3150 9075 3150
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
7500 2325 10200 2325
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
3600 3600 3000 3600
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
4125 3075 3000 3075
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
0 0 1.00 60.00 120.00
|
||||
4200 5400 8175 5400
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
0 0 1.00 60.00 120.00
|
||||
10125 2325 10125 3600
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
0 0 1.00 60.00 120.00
|
||||
3000 3150 3000 3600
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
0 0 1.00 60.00 120.00
|
||||
9075 3150 9075 3600
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
4950 2325 4950 1200
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
|
||||
7425 2325 7425 1200
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 4
|
||||
4200 3075 4200 2400 3600 1800 3600 1200
|
||||
2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 4
|
||||
8250 3150 8250 2475 8775 1950 8775 1200
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
0 0 1.00 60.00 120.00
|
||||
3600 1275 4950 1275
|
||||
2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
|
||||
0 0 1.00 60.00 120.00
|
||||
0 0 1.00 60.00 120.00
|
||||
7425 1275 8700 1275
|
||||
4 1 0 50 0 0 12 0.0000 4 135 1140 6075 5325 Effect duration\001
|
||||
4 0 0 50 0 0 12 0.0000 4 180 1305 10200 3000 Effect magnitude\001
|
||||
4 0 0 50 0 0 12 0.0000 4 135 780 9150 3450 Fade level\001
|
||||
4 1 0 50 0 0 12 0.0000 4 180 1035 4275 1200 Attack length\001
|
||||
4 1 0 50 0 0 12 0.0000 4 180 885 8175 1200 Fade length\001
|
||||
4 2 0 50 0 0 12 0.0000 4 135 930 2925 3375 Attack level\001
|
|
@ -0,0 +1,39 @@
|
|||
<svg width="7.95in" height="3.70in" version="1.1" viewBox="1956 1041 9354.492 4306.001" xmlns="http://www.w3.org/2000/svg">
|
||||
<polyline transform="translate(-121.88 -68.4)" points="4200 3600 4200 3075 4950 2325 7425 2325 8250 3150 8250 3600" fill="none" stroke="#000" stroke-width="15"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="4200 3675 4200 5400" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="8250 3675 8250 5400" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="3675 3600 8700 3600" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="8775 3600 10200 3600" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="8325 3150 9075 3150" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="7500 2325 10200 2325" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="3600 3600 3e3 3600" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="4125 3075 3e3 3075" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="4217 5400 8158 5400" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="8053 5430 8173 5400 8053 5370" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="4322 5370 4202 5400 4322 5430" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="10125 2342 10125 3583" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="10095 3478 10125 3598 10155 3478" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="10155 2447 10125 2327 10095 2447" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="3e3 3167 3e3 3583" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="2970 3478 3e3 3598 3030 3478" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="3030 3272 3e3 3152 2970 3272" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="9075 3167 9075 3583" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="9045 3478 9075 3598 9105 3478" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="9105 3272 9075 3152 9045 3272" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="4950 2325 4950 1200" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="7425 2325 7425 1200" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="4200 3075 4200 2400 3600 1800 3600 1200" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="8250 3150 8250 2475 8775 1950 8775 1200" fill="none" stroke="#000" stroke-dasharray="40, 40" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="3617 1275 4933 1275" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="4828 1305 4948 1275 4828 1245" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="3722 1245 3602 1275 3722 1305" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="7442 1275 8683 1275" fill="none" stroke="#000" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="8578 1305 8698 1275 8578 1245" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<polyline transform="translate(-121.88 -68.4)" points="7547 1245 7427 1275 7547 1305" fill="none" stroke="#000" stroke-miterlimit="8" stroke-width="7"/>
|
||||
<text x="5953.125" y="5256.6001" fill="#000000" font-family="sans-serif" font-size="144px" stroke-width=".025in" text-anchor="middle" xml:space="preserve">Effect duration</text>
|
||||
<text x="10078.125" y="2931.5999" fill="#000000" font-family="sans-serif" font-size="144px" stroke-width=".025in" xml:space="preserve">Effect magnitude</text>
|
||||
<text x="9028.125" y="3381.5999" fill="#000000" font-family="sans-serif" font-size="144px" stroke-width=".025in" xml:space="preserve">Fade level</text>
|
||||
<text x="4153.125" y="1131.6" fill="#000000" font-family="sans-serif" font-size="144px" stroke-width=".025in" text-anchor="middle" xml:space="preserve">Attack length</text>
|
||||
<text x="8053.125" y="1131.6" fill="#000000" font-family="sans-serif" font-size="144px" stroke-width=".025in" text-anchor="middle" xml:space="preserve">Fade length</text>
|
||||
<text x="2803.125" y="3306.5999" fill="#000000" font-family="sans-serif" font-size="144px" stroke-width=".025in" text-anchor="end" xml:space="preserve">Attack level</text>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 5.5 KiB |
|
@ -0,0 +1,245 @@
|
|||
=============
|
||||
uinput module
|
||||
=============
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
uinput is a kernel module that makes it possible to emulate input devices
|
||||
from userspace. By writing to /dev/uinput (or /dev/input/uinput) device, a
|
||||
process can create a virtual input device with specific capabilities. Once
|
||||
this virtual device is created, the process can send events through it,
|
||||
that will be delivered to userspace and in-kernel consumers.
|
||||
|
||||
Interface
|
||||
=========
|
||||
|
||||
::
|
||||
|
||||
linux/uinput.h
|
||||
|
||||
The uinput header defines ioctls to create, set up, and destroy virtual
|
||||
devices.
|
||||
|
||||
libevdev
|
||||
========
|
||||
|
||||
libevdev is a wrapper library for evdev devices that provides interfaces to
|
||||
create uinput devices and send events. libevdev is less error-prone than
|
||||
accessing uinput directly, and should be considered for new software.
|
||||
|
||||
For examples and more information about libevdev:
|
||||
https://www.freedesktop.org/software/libevdev/doc/latest/
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
Keyboard events
|
||||
---------------
|
||||
|
||||
This first example shows how to create a new virtual device, and how to
|
||||
send a key event. All default imports and error handlers were removed for
|
||||
the sake of simplicity.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <linux/uinput.h>
|
||||
|
||||
void emit(int fd, int type, int code, int val)
|
||||
{
|
||||
struct input_event ie;
|
||||
|
||||
ie.type = type;
|
||||
ie.code = code;
|
||||
ie.value = val;
|
||||
/* timestamp values below are ignored */
|
||||
ie.time.tv_sec = 0;
|
||||
ie.time.tv_usec = 0;
|
||||
|
||||
write(fd, &ie, sizeof(ie));
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct uinput_setup usetup;
|
||||
|
||||
int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
||||
|
||||
|
||||
/*
|
||||
* The ioctls below will enable the device that is about to be
|
||||
* created, to pass key events, in this case the space key.
|
||||
*/
|
||||
ioctl(fd, UI_SET_EVBIT, EV_KEY);
|
||||
ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
|
||||
|
||||
memset(&usetup, 0, sizeof(usetup));
|
||||
usetup.id.bustype = BUS_USB;
|
||||
usetup.id.vendor = 0x1234; /* sample vendor */
|
||||
usetup.id.product = 0x5678; /* sample product */
|
||||
strcpy(usetup.name, "Example device");
|
||||
|
||||
ioctl(fd, UI_DEV_SETUP, &usetup);
|
||||
ioctl(fd, UI_DEV_CREATE);
|
||||
|
||||
/*
|
||||
* On UI_DEV_CREATE the kernel will create the device node for this
|
||||
* device. We are inserting a pause here so that userspace has time
|
||||
* to detect, initialize the new device, and can start listening to
|
||||
* the event, otherwise it will not notice the event we are about
|
||||
* to send. This pause is only needed in our example code!
|
||||
*/
|
||||
sleep(1);
|
||||
|
||||
/* Key press, report the event, send key release, and report again */
|
||||
emit(fd, EV_KEY, KEY_SPACE, 1);
|
||||
emit(fd, EV_SYN, SYN_REPORT, 0);
|
||||
emit(fd, EV_KEY, KEY_SPACE, 0);
|
||||
emit(fd, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
/*
|
||||
* Give userspace some time to read the events before we destroy the
|
||||
* device with UI_DEV_DESTOY.
|
||||
*/
|
||||
sleep(1);
|
||||
|
||||
ioctl(fd, UI_DEV_DESTROY);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Mouse movements
|
||||
---------------
|
||||
|
||||
This example shows how to create a virtual device that behaves like a physical
|
||||
mouse.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <linux/uinput.h>
|
||||
|
||||
/* emit function is identical to of the first example */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct uinput_setup usetup;
|
||||
int i = 50;
|
||||
|
||||
int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
||||
|
||||
/* enable mouse button left and relative events */
|
||||
ioctl(fd, UI_SET_EVBIT, EV_KEY);
|
||||
ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
|
||||
|
||||
ioctl(fd, UI_SET_EVBIT, EV_REL);
|
||||
ioctl(fd, UI_SET_RELBIT, REL_X);
|
||||
ioctl(fd, UI_SET_RELBIT, REL_Y);
|
||||
|
||||
memset(&usetup, 0, sizeof(usetup));
|
||||
usetup.id.bustype = BUS_USB;
|
||||
usetup.id.vendor = 0x1234; /* sample vendor */
|
||||
usetup.id.product = 0x5678; /* sample product */
|
||||
strcpy(usetup.name, "Example device");
|
||||
|
||||
ioctl(fd, UI_DEV_SETUP, &usetup);
|
||||
ioctl(fd, UI_DEV_CREATE);
|
||||
|
||||
/*
|
||||
* On UI_DEV_CREATE the kernel will create the device node for this
|
||||
* device. We are inserting a pause here so that userspace has time
|
||||
* to detect, initialize the new device, and can start listening to
|
||||
* the event, otherwise it will not notice the event we are about
|
||||
* to send. This pause is only needed in our example code!
|
||||
*/
|
||||
sleep(1);
|
||||
|
||||
/* Move the mouse diagonally, 5 units per axis */
|
||||
while (i--) {
|
||||
emit(fd, EV_REL, REL_X, 5);
|
||||
emit(fd, EV_REL, REL_Y, 5);
|
||||
emit(fd, EV_SYN, SYN_REPORT, 0);
|
||||
usleep(15000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Give userspace some time to read the events before we destroy the
|
||||
* device with UI_DEV_DESTOY.
|
||||
*/
|
||||
sleep(1);
|
||||
|
||||
ioctl(fd, UI_DEV_DESTROY);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uinput old interface
|
||||
--------------------
|
||||
|
||||
Before uinput version 5, there wasn't a dedicated ioctl to set up a virtual
|
||||
device. Programs supportinf older versions of uinput interface need to fill
|
||||
a uinput_user_dev structure and write it to the uinput file descriptor to
|
||||
configure the new uinput device. New code should not use the old interface
|
||||
but interact with uinput via ioctl calls, or use libevdev.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <linux/uinput.h>
|
||||
|
||||
/* emit function is identical to of the first example */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct uinput_user_dev uud;
|
||||
int version, rc, fd;
|
||||
|
||||
fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
||||
rc = ioctl(fd, UI_GET_VERSION, &version);
|
||||
|
||||
if (rc == 0 && version >= 5) {
|
||||
/* use UI_DEV_SETUP */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The ioctls below will enable the device that is about to be
|
||||
* created, to pass key events, in this case the space key.
|
||||
*/
|
||||
ioctl(fd, UI_SET_EVBIT, EV_KEY);
|
||||
ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);
|
||||
|
||||
memset(&uud, 0, sizeof(uud));
|
||||
snprintf(uud.name, UINPUT_MAX_NAME_SIZE, "uinput old interface");
|
||||
write(fd, &uud, sizeof(uud));
|
||||
|
||||
ioctl(fd, UI_DEV_CREATE);
|
||||
|
||||
/*
|
||||
* On UI_DEV_CREATE the kernel will create the device node for this
|
||||
* device. We are inserting a pause here so that userspace has time
|
||||
* to detect, initialize the new device, and can start listening to
|
||||
* the event, otherwise it will not notice the event we are about
|
||||
* to send. This pause is only needed in our example code!
|
||||
*/
|
||||
sleep(1);
|
||||
|
||||
/* Key press, report the event, send key release, and report again */
|
||||
emit(fd, EV_KEY, KEY_SPACE, 1);
|
||||
emit(fd, EV_SYN, SYN_REPORT, 0);
|
||||
emit(fd, EV_KEY, KEY_SPACE, 0);
|
||||
emit(fd, EV_SYN, SYN_REPORT, 0);
|
||||
|
||||
/*
|
||||
* Give userspace some time to read the events before we destroy the
|
||||
* device with UI_DEV_DESTOY.
|
||||
*/
|
||||
sleep(1);
|
||||
|
||||
ioctl(fd, UI_DEV_DESTROY);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,37 +1,47 @@
|
|||
The userio Protocol
|
||||
(c) 2015 Stephen Chandler Paul <thatslyude@gmail.com>
|
||||
Sponsored by Red Hat
|
||||
--------------------------------------------------------------------------------
|
||||
.. include:: <isonum.txt>
|
||||
|
||||
1. Introduction
|
||||
~~~~~~~~~~~~~~~
|
||||
This module is intended to try to make the lives of input driver developers
|
||||
===================
|
||||
The userio Protocol
|
||||
===================
|
||||
|
||||
|
||||
:Copyright: |copy| 2015 Stephen Chandler Paul <thatslyude@gmail.com>
|
||||
|
||||
Sponsored by Red Hat
|
||||
|
||||
|
||||
Introduction
|
||||
=============
|
||||
|
||||
This module is intended to try to make the lives of input driver developers
|
||||
easier by allowing them to test various serio devices (mainly the various
|
||||
touchpads found on laptops) without having to have the physical device in front
|
||||
of them. userio accomplishes this by allowing any privileged userspace program
|
||||
to directly interact with the kernel's serio driver and control a virtual serio
|
||||
port from there.
|
||||
|
||||
2. Usage overview
|
||||
~~~~~~~~~~~~~~~~~
|
||||
In order to interact with the userio kernel module, one simply opens the
|
||||
Usage overview
|
||||
==============
|
||||
|
||||
In order to interact with the userio kernel module, one simply opens the
|
||||
/dev/userio character device in their applications. Commands are sent to the
|
||||
kernel module by writing to the device, and any data received from the serio
|
||||
driver is read as-is from the /dev/userio device. All of the structures and
|
||||
macros you need to interact with the device are defined in <linux/userio.h> and
|
||||
<linux/serio.h>.
|
||||
|
||||
3. Command Structure
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
The struct used for sending commands to /dev/userio is as follows:
|
||||
Command Structure
|
||||
=================
|
||||
|
||||
The struct used for sending commands to /dev/userio is as follows::
|
||||
|
||||
struct userio_cmd {
|
||||
__u8 type;
|
||||
__u8 data;
|
||||
};
|
||||
|
||||
"type" describes the type of command that is being sent. This can be any one
|
||||
of the USERIO_CMD macros defined in <linux/userio.h>. "data" is the argument
|
||||
``type`` describes the type of command that is being sent. This can be any one
|
||||
of the USERIO_CMD macros defined in <linux/userio.h>. ``data`` is the argument
|
||||
that goes along with the command. In the event that the command doesn't have an
|
||||
argument, this field can be left untouched and will be ignored by the kernel.
|
||||
Each command should be sent by writing the struct directly to the character
|
||||
|
@ -39,31 +49,36 @@ device. In the event that the command you send is invalid, an error will be
|
|||
returned by the character device and a more descriptive error will be printed
|
||||
to the kernel log. Only one command can be sent at a time, any additional data
|
||||
written to the character device after the initial command will be ignored.
|
||||
To close the virtual serio port, just close /dev/userio.
|
||||
|
||||
4. Commands
|
||||
~~~~~~~~~~~
|
||||
To close the virtual serio port, just close /dev/userio.
|
||||
|
||||
4.1 USERIO_CMD_REGISTER
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Registers the port with the serio driver and begins transmitting data back and
|
||||
Commands
|
||||
========
|
||||
|
||||
USERIO_CMD_REGISTER
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Registers the port with the serio driver and begins transmitting data back and
|
||||
forth. Registration can only be performed once a port type is set with
|
||||
USERIO_CMD_SET_PORT_TYPE. Has no argument.
|
||||
|
||||
4.2 USERIO_CMD_SET_PORT_TYPE
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sets the type of port we're emulating, where "data" is the port type being
|
||||
USERIO_CMD_SET_PORT_TYPE
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sets the type of port we're emulating, where ``data`` is the port type being
|
||||
set. Can be any of the macros from <linux/serio.h>. For example: SERIO_8042
|
||||
would set the port type to be a normal PS/2 port.
|
||||
|
||||
4.3 USERIO_CMD_SEND_INTERRUPT
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sends an interrupt through the virtual serio port to the serio driver, where
|
||||
"data" is the interrupt data being sent.
|
||||
USERIO_CMD_SEND_INTERRUPT
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
5. Userspace tools
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
The userio userspace tools are able to record PS/2 devices using some of the
|
||||
Sends an interrupt through the virtual serio port to the serio driver, where
|
||||
``data`` is the interrupt data being sent.
|
||||
|
||||
Userspace tools
|
||||
===============
|
||||
|
||||
The userio userspace tools are able to record PS/2 devices using some of the
|
||||
debugging information from i8042, and play back the devices on /dev/userio. The
|
||||
latest version of these tools can be found at:
|
||||
|
|
@ -6551,7 +6551,7 @@ INPUT MULTITOUCH (MT) PROTOCOL
|
|||
M: Henrik Rydberg <rydberg@bitmath.org>
|
||||
L: linux-input@vger.kernel.org
|
||||
S: Odd fixes
|
||||
F: Documentation/input/multi-touch-protocol.txt
|
||||
F: Documentation/input/multi-touch-protocol.rst
|
||||
F: drivers/input/input-mt.c
|
||||
K: \b(ABS|SYN)_MT_
|
||||
|
||||
|
@ -13963,7 +13963,7 @@ YEALINK PHONE DRIVER
|
|||
M: Henk Vergonet <Henk.Vergonet@gmail.com>
|
||||
L: usbb2k-api-dev@nongnu.org
|
||||
S: Maintained
|
||||
F: Documentation/input/yealink.txt
|
||||
F: Documentation/input/yealink.rst
|
||||
F: drivers/input/misc/yealink.*
|
||||
|
||||
Z8530 DRIVER FOR AX.25
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <linux/smsc911x.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input/eeti_ts.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/w1-gpio.h>
|
||||
#include <linux/sched.h>
|
||||
|
@ -965,15 +964,28 @@ static struct i2c_board_info raumfeld_connector_i2c_board_info __initdata = {
|
|||
.addr = 0x48,
|
||||
};
|
||||
|
||||
static struct eeti_ts_platform_data eeti_ts_pdata = {
|
||||
.irq_active_high = 1,
|
||||
.irq_gpio = GPIO_TOUCH_IRQ,
|
||||
static struct gpiod_lookup_table raumfeld_controller_gpios_table = {
|
||||
.dev_id = "0-000a",
|
||||
.table = {
|
||||
GPIO_LOOKUP("gpio-pxa",
|
||||
GPIO_TOUCH_IRQ, "attn", GPIO_ACTIVE_HIGH),
|
||||
{ },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct resource raumfeld_controller_resources[] __initconst = {
|
||||
{
|
||||
.start = PXA_GPIO_TO_IRQ(GPIO_TOUCH_IRQ),
|
||||
.end = PXA_GPIO_TO_IRQ(GPIO_TOUCH_IRQ),
|
||||
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
|
||||
},
|
||||
};
|
||||
|
||||
static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = {
|
||||
.type = "eeti_ts",
|
||||
.addr = 0x0a,
|
||||
.platform_data = &eeti_ts_pdata,
|
||||
.resources = raumfeld_controller_resources,
|
||||
.num_resources = ARRAY_SIZE(raumfeld_controller_resources),
|
||||
};
|
||||
|
||||
static struct platform_device *raumfeld_common_devices[] = {
|
||||
|
@ -1064,6 +1076,8 @@ static void __init __maybe_unused raumfeld_controller_init(void)
|
|||
platform_device_register(&rotary_encoder_device);
|
||||
|
||||
spi_register_board_info(ARRAY_AND_SIZE(controller_spi_devices));
|
||||
|
||||
gpiod_add_lookup_table(&raumfeld_controller_gpios_table);
|
||||
i2c_register_board_info(0, &raumfeld_controller_i2c_board_info, 1);
|
||||
|
||||
ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown");
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/export.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -55,6 +56,7 @@ EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num);
|
|||
*
|
||||
* The board info passed can safely be __initdata, but be careful of embedded
|
||||
* pointers (for platform_data, functions, etc) since that won't be copied.
|
||||
* Device properties are deep-copied though.
|
||||
*/
|
||||
int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len)
|
||||
{
|
||||
|
@ -78,6 +80,28 @@ int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsig
|
|||
|
||||
devinfo->busnum = busnum;
|
||||
devinfo->board_info = *info;
|
||||
|
||||
if (info->properties) {
|
||||
devinfo->board_info.properties =
|
||||
property_entries_dup(info->properties);
|
||||
if (IS_ERR(devinfo->board_info.properties)) {
|
||||
status = PTR_ERR(devinfo->board_info.properties);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->resources) {
|
||||
devinfo->board_info.resources =
|
||||
kmemdup(info->resources,
|
||||
info->num_resources *
|
||||
sizeof(*info->resources),
|
||||
GFP_KERNEL);
|
||||
if (!devinfo->board_info.resources) {
|
||||
status = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_add_tail(&devinfo->list, &__i2c_board_list);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@
|
|||
static DEFINE_MUTEX(core_lock);
|
||||
static DEFINE_IDR(i2c_adapter_idr);
|
||||
|
||||
static struct device_type i2c_client_type;
|
||||
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
|
||||
|
||||
static struct static_key i2c_trace_msg = STATIC_KEY_INIT_FALSE;
|
||||
|
@ -1153,11 +1152,12 @@ struct bus_type i2c_bus_type = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(i2c_bus_type);
|
||||
|
||||
static struct device_type i2c_client_type = {
|
||||
struct device_type i2c_client_type = {
|
||||
.groups = i2c_dev_groups,
|
||||
.uevent = i2c_device_uevent,
|
||||
.release = i2c_client_dev_release,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(i2c_client_type);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1334,6 +1334,32 @@ static void i2c_dev_set_name(struct i2c_adapter *adap,
|
|||
i2c_encode_flags_to_addr(client));
|
||||
}
|
||||
|
||||
static int i2c_dev_irq_from_resources(const struct resource *resources,
|
||||
unsigned int num_resources)
|
||||
{
|
||||
struct irq_data *irqd;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_resources; i++) {
|
||||
const struct resource *r = &resources[i];
|
||||
|
||||
if (resource_type(r) != IORESOURCE_IRQ)
|
||||
continue;
|
||||
|
||||
if (r->flags & IORESOURCE_BITS) {
|
||||
irqd = irq_get_irq_data(r->start);
|
||||
if (!irqd)
|
||||
break;
|
||||
|
||||
irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS);
|
||||
}
|
||||
|
||||
return r->start;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i2c_new_device - instantiate an i2c device
|
||||
* @adap: the adapter managing the device
|
||||
|
@ -1369,7 +1395,11 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
|
|||
|
||||
client->flags = info->flags;
|
||||
client->addr = info->addr;
|
||||
|
||||
client->irq = info->irq;
|
||||
if (!client->irq)
|
||||
client->irq = i2c_dev_irq_from_resources(info->resources,
|
||||
info->num_resources);
|
||||
|
||||
strlcpy(client->name, info->type, sizeof(client->name));
|
||||
|
||||
|
|
|
@ -385,8 +385,8 @@ static int gameport_queue_event(void *object, struct module *owner,
|
|||
}
|
||||
|
||||
if (!try_module_get(owner)) {
|
||||
pr_warning("Can't get module reference, dropping event %d\n",
|
||||
event_type);
|
||||
pr_warn("Can't get module reference, dropping event %d\n",
|
||||
event_type);
|
||||
kfree(event);
|
||||
retval = -EINVAL;
|
||||
goto out;
|
||||
|
@ -542,9 +542,8 @@ static void gameport_init_port(struct gameport *gameport)
|
|||
|
||||
INIT_LIST_HEAD(&gameport->node);
|
||||
spin_lock_init(&gameport->timer_lock);
|
||||
init_timer(&gameport->poll_timer);
|
||||
gameport->poll_timer.function = gameport_run_poll_handler;
|
||||
gameport->poll_timer.data = (unsigned long)gameport;
|
||||
setup_timer(&gameport->poll_timer, gameport_run_poll_handler,
|
||||
(unsigned long)gameport);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -609,9 +609,7 @@ static void db9_attach(struct parport *pp)
|
|||
db9->pd = pd;
|
||||
db9->mode = mode;
|
||||
db9->parportno = pp->number;
|
||||
init_timer(&db9->timer);
|
||||
db9->timer.data = (long) db9;
|
||||
db9->timer.function = db9_timer;
|
||||
setup_timer(&db9->timer, db9_timer, (long)db9);
|
||||
|
||||
for (i = 0; i < (min(db9_mode->n_pads, DB9_MAX_DEVICES)); i++) {
|
||||
|
||||
|
|
|
@ -870,7 +870,8 @@ static int gc_setup_pad(struct gc *gc, int idx, int pad_type)
|
|||
|
||||
err = gc_n64_init_ff(input_dev, idx);
|
||||
if (err) {
|
||||
pr_warning("Failed to initiate rumble for N64 device %d\n", idx);
|
||||
pr_warn("Failed to initiate rumble for N64 device %d\n",
|
||||
idx);
|
||||
goto err_free_dev;
|
||||
}
|
||||
|
||||
|
|
|
@ -200,9 +200,7 @@ static void tgfx_attach(struct parport *pp)
|
|||
mutex_init(&tgfx->sem);
|
||||
tgfx->pd = pd;
|
||||
tgfx->parportno = pp->number;
|
||||
init_timer(&tgfx->timer);
|
||||
tgfx->timer.data = (long) tgfx;
|
||||
tgfx->timer.function = tgfx_timer;
|
||||
setup_timer(&tgfx->timer, tgfx_timer, (long)tgfx);
|
||||
|
||||
for (i = 0; i < n_devs; i++) {
|
||||
if (n_buttons[i] < 1)
|
||||
|
|
|
@ -339,6 +339,64 @@ static struct usb_device_id xpad_table[] = {
|
|||
|
||||
MODULE_DEVICE_TABLE(usb, xpad_table);
|
||||
|
||||
struct xboxone_init_packet {
|
||||
u16 idVendor;
|
||||
u16 idProduct;
|
||||
const u8 *data;
|
||||
u8 len;
|
||||
};
|
||||
|
||||
#define XBOXONE_INIT_PKT(_vid, _pid, _data) \
|
||||
{ \
|
||||
.idVendor = (_vid), \
|
||||
.idProduct = (_pid), \
|
||||
.data = (_data), \
|
||||
.len = ARRAY_SIZE(_data), \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This packet is required for all Xbox One pads with 2015
|
||||
* or later firmware installed (or present from the factory).
|
||||
*/
|
||||
static const u8 xboxone_fw2015_init[] = {
|
||||
0x05, 0x20, 0x00, 0x01, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* This packet is required for the Titanfall 2 Xbox One pads
|
||||
* (0x0e6f:0x0165) to finish initialization and for Hori pads
|
||||
* (0x0f0d:0x0067) to make the analog sticks work.
|
||||
*/
|
||||
static const u8 xboxone_hori_init[] = {
|
||||
0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a,
|
||||
0x00, 0x00, 0x00, 0x80, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* A rumble packet is required for some PowerA pads to start
|
||||
* sending input reports. One of those pads is (0x24c6:0x543a).
|
||||
*/
|
||||
static const u8 xboxone_zerorumble_init[] = {
|
||||
0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* This specifies the selection of init packets that a gamepad
|
||||
* will be sent on init *and* the order in which they will be
|
||||
* sent. The correct sequence number will be added when the
|
||||
* packet is going to be sent.
|
||||
*/
|
||||
static const struct xboxone_init_packet xboxone_init_packets[] = {
|
||||
XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
|
||||
XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
|
||||
XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
|
||||
XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_zerorumble_init),
|
||||
XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_zerorumble_init),
|
||||
XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_zerorumble_init),
|
||||
};
|
||||
|
||||
struct xpad_output_packet {
|
||||
u8 data[XPAD_PKT_LEN];
|
||||
u8 len;
|
||||
|
@ -375,6 +433,7 @@ struct usb_xpad {
|
|||
|
||||
struct xpad_output_packet out_packets[XPAD_NUM_OUT_PACKETS];
|
||||
int last_out_packet;
|
||||
int init_seq;
|
||||
|
||||
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
|
||||
struct xpad_led *led;
|
||||
|
@ -749,12 +808,48 @@ exit:
|
|||
__func__, retval);
|
||||
}
|
||||
|
||||
/* Callers must hold xpad->odata_lock spinlock */
|
||||
static bool xpad_prepare_next_init_packet(struct usb_xpad *xpad)
|
||||
{
|
||||
const struct xboxone_init_packet *init_packet;
|
||||
|
||||
if (xpad->xtype != XTYPE_XBOXONE)
|
||||
return false;
|
||||
|
||||
/* Perform initialization sequence for Xbox One pads that require it */
|
||||
while (xpad->init_seq < ARRAY_SIZE(xboxone_init_packets)) {
|
||||
init_packet = &xboxone_init_packets[xpad->init_seq++];
|
||||
|
||||
if (init_packet->idVendor != 0 &&
|
||||
init_packet->idVendor != xpad->dev->id.vendor)
|
||||
continue;
|
||||
|
||||
if (init_packet->idProduct != 0 &&
|
||||
init_packet->idProduct != xpad->dev->id.product)
|
||||
continue;
|
||||
|
||||
/* This packet applies to our device, so prepare to send it */
|
||||
memcpy(xpad->odata, init_packet->data, init_packet->len);
|
||||
xpad->irq_out->transfer_buffer_length = init_packet->len;
|
||||
|
||||
/* Update packet with current sequence number */
|
||||
xpad->odata[2] = xpad->odata_serial++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* We may have init packets to send before we can send user commands */
|
||||
if (xpad_prepare_next_init_packet(xpad))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) {
|
||||
if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS)
|
||||
xpad->last_out_packet = 0;
|
||||
|
@ -940,24 +1035,17 @@ static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
|
|||
|
||||
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;
|
||||
|
||||
spin_lock_irqsave(&xpad->odata_lock, flags);
|
||||
|
||||
/* 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;
|
||||
/*
|
||||
* Begin the init sequence by attempting to send a packet.
|
||||
* We will cycle through the init packet sequence before
|
||||
* sending any packets from the output ring.
|
||||
*/
|
||||
xpad->init_seq = 0;
|
||||
retval = xpad_try_sending_next_out_packet(xpad);
|
||||
|
||||
spin_unlock_irqrestore(&xpad->odata_lock, flags);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <linux/notifier.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysrq.h>
|
||||
#include <linux/input/matrix_keypad.h>
|
||||
#include <linux/mfd/cros_ec.h>
|
||||
#include <linux/mfd/cros_ec_commands.h>
|
||||
|
@ -260,6 +261,12 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
|
|||
ckdev->ec->event_size);
|
||||
break;
|
||||
|
||||
case EC_MKBP_EVENT_SYSRQ:
|
||||
val = get_unaligned_le32(&ckdev->ec->event_data.data.sysrq);
|
||||
dev_dbg(ckdev->dev, "sysrq code from EC: %#x\n", val);
|
||||
handle_sysrq(val);
|
||||
break;
|
||||
|
||||
case EC_MKBP_EVENT_BUTTON:
|
||||
case EC_MKBP_EVENT_SWITCH:
|
||||
/*
|
||||
|
|
|
@ -264,9 +264,8 @@ static int locomokbd_probe(struct locomo_dev *dev)
|
|||
|
||||
spin_lock_init(&locomokbd->lock);
|
||||
|
||||
init_timer(&locomokbd->timer);
|
||||
locomokbd->timer.function = locomokbd_timer_callback;
|
||||
locomokbd->timer.data = (unsigned long) locomokbd;
|
||||
setup_timer(&locomokbd->timer, locomokbd_timer_callback,
|
||||
(unsigned long)locomokbd);
|
||||
|
||||
locomokbd->suspend_jiffies = jiffies;
|
||||
|
||||
|
|
|
@ -42,9 +42,10 @@ struct matrix_keypad {
|
|||
};
|
||||
|
||||
/*
|
||||
* NOTE: normally the GPIO has to be put into HiZ when de-activated to cause
|
||||
* minmal side effect when scanning other columns, here it is configured to
|
||||
* be input, and it should work on most platforms.
|
||||
* NOTE: If drive_inactive_cols is false, then the GPIO has to be put into
|
||||
* HiZ when de-activated to cause minmal side effect when scanning other
|
||||
* columns. In that case it is configured here to be input, otherwise it is
|
||||
* driven with the inactive value.
|
||||
*/
|
||||
static void __activate_col(const struct matrix_keypad_platform_data *pdata,
|
||||
int col, bool on)
|
||||
|
@ -55,7 +56,8 @@ static void __activate_col(const struct matrix_keypad_platform_data *pdata,
|
|||
gpio_direction_output(pdata->col_gpios[col], level_on);
|
||||
} else {
|
||||
gpio_set_value_cansleep(pdata->col_gpios[col], !level_on);
|
||||
gpio_direction_input(pdata->col_gpios[col]);
|
||||
if (!pdata->drive_inactive_cols)
|
||||
gpio_direction_input(pdata->col_gpios[col]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,6 +434,9 @@ matrix_keypad_parse_dt(struct device *dev)
|
|||
if (of_get_property(np, "gpio-activelow", NULL))
|
||||
pdata->active_low = true;
|
||||
|
||||
pdata->drive_inactive_cols =
|
||||
of_property_read_bool(np, "drive-inactive-cols");
|
||||
|
||||
of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms);
|
||||
of_property_read_u32(np, "col-scan-delay-us",
|
||||
&pdata->col_scan_delay_us);
|
||||
|
|
|
@ -358,7 +358,7 @@ static int omap4_keypad_probe(struct platform_device *pdev)
|
|||
"omap4-keypad", keypad_data);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "failed to register interrupt\n");
|
||||
goto err_free_input;
|
||||
goto err_free_keymap;
|
||||
}
|
||||
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
|
|
|
@ -274,9 +274,18 @@ static const struct i2c_device_id qt1070_id[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(i2c, qt1070_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id qt1070_of_match[] = {
|
||||
{ .compatible = "qt1070", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qt1070_of_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver qt1070_driver = {
|
||||
.driver = {
|
||||
.name = "qt1070",
|
||||
.of_match_table = of_match_ptr(qt1070_of_match),
|
||||
.pm = &qt1070_pm_ops,
|
||||
},
|
||||
.id_table = qt1070_id,
|
||||
|
|
|
@ -188,8 +188,6 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
|
|||
input_event(input, EV_MSC, MSC_SCAN, code);
|
||||
input_report_key(input, keymap[code], state);
|
||||
|
||||
/* Read for next loop */
|
||||
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®);
|
||||
} while (1);
|
||||
|
||||
input_sync(input);
|
||||
|
|
|
@ -143,7 +143,7 @@ config INPUT_PM8941_PWRKEY
|
|||
|
||||
config INPUT_PM8XXX_VIBRATOR
|
||||
tristate "Qualcomm PM8XXX vibrator support"
|
||||
depends on MFD_PM8XXX
|
||||
depends on MFD_PM8XXX || MFD_SPMI_PMIC
|
||||
select INPUT_FF_MEMLESS
|
||||
help
|
||||
This option enables device driver support for the vibrator
|
||||
|
|
|
@ -314,7 +314,8 @@ static int __init apanel_init(void)
|
|||
if (devno >= APANEL_DEV_MAX)
|
||||
pr_notice(APANEL ": unknown device %u found\n", devno);
|
||||
else if (device_chip[devno] != CHIP_NONE)
|
||||
pr_warning(APANEL ": duplicate entry for devno %u\n", devno);
|
||||
pr_warn(APANEL ": duplicate entry for devno %u\n",
|
||||
devno);
|
||||
|
||||
else if (method != 1 && method != 2 && method != 4) {
|
||||
pr_notice(APANEL ": unknown method %u for devno %u\n",
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -188,21 +189,13 @@ static void axp20x_remove_sysfs_group(void *_data)
|
|||
sysfs_remove_group(&dev->kobj, &axp20x_attribute_group);
|
||||
}
|
||||
|
||||
static int axp20x_pek_probe(struct platform_device *pdev)
|
||||
static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct axp20x_pek *axp20x_pek;
|
||||
struct axp20x_dev *axp20x;
|
||||
struct axp20x_dev *axp20x = axp20x_pek->axp20x;
|
||||
struct input_dev *idev;
|
||||
int error;
|
||||
|
||||
axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek),
|
||||
GFP_KERNEL);
|
||||
if (!axp20x_pek)
|
||||
return -ENOMEM;
|
||||
|
||||
axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
|
||||
axp20x = axp20x_pek->axp20x;
|
||||
|
||||
axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
|
||||
if (axp20x_pek->irq_dbr < 0) {
|
||||
dev_err(&pdev->dev, "No IRQ for PEK_DBR, error=%d\n",
|
||||
|
@ -239,7 +232,7 @@ static int axp20x_pek_probe(struct platform_device *pdev)
|
|||
axp20x_pek_irq, 0,
|
||||
"axp20x-pek-dbr", idev);
|
||||
if (error < 0) {
|
||||
dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n",
|
||||
dev_err(&pdev->dev, "Failed to request dbr IRQ#%d: %d\n",
|
||||
axp20x_pek->irq_dbr, error);
|
||||
return error;
|
||||
}
|
||||
|
@ -248,14 +241,48 @@ static int axp20x_pek_probe(struct platform_device *pdev)
|
|||
axp20x_pek_irq, 0,
|
||||
"axp20x-pek-dbf", idev);
|
||||
if (error < 0) {
|
||||
dev_err(axp20x->dev, "Failed to request dbf IRQ#%d: %d\n",
|
||||
dev_err(&pdev->dev, "Failed to request dbf IRQ#%d: %d\n",
|
||||
axp20x_pek->irq_dbf, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(idev);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "Can't register input device: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp20x_pek_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct axp20x_pek *axp20x_pek;
|
||||
int error;
|
||||
|
||||
axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek),
|
||||
GFP_KERNEL);
|
||||
if (!axp20x_pek)
|
||||
return -ENOMEM;
|
||||
|
||||
axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
|
||||
|
||||
/*
|
||||
* Do not register the input device if there is an "INTCFD9"
|
||||
* gpio button ACPI device, that handles the power button too,
|
||||
* and otherwise we end up reporting all presses twice.
|
||||
*/
|
||||
if (!acpi_dev_found("INTCFD9") ||
|
||||
!IS_ENABLED(CONFIG_INPUT_SOC_BUTTON_ARRAY)) {
|
||||
error = axp20x_pek_probe_input_device(axp20x_pek, pdev);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
error = sysfs_create_group(&pdev->dev.kobj, &axp20x_attribute_group);
|
||||
if (error) {
|
||||
dev_err(axp20x->dev, "Failed to create sysfs attributes: %d\n",
|
||||
dev_err(&pdev->dev, "Failed to create sysfs attributes: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
@ -269,13 +296,6 @@ static int axp20x_pek_probe(struct platform_device *pdev)
|
|||
return error;
|
||||
}
|
||||
|
||||
error = input_register_device(idev);
|
||||
if (error) {
|
||||
dev_err(axp20x->dev, "Can't register input device: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, axp20x_pek);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
#define BMA150_CFG_5_REG 0x11
|
||||
|
||||
#define BMA150_CHIP_ID 2
|
||||
#define BMA180_CHIP_ID 3
|
||||
#define BMA150_CHIP_ID_REG BMA150_DATA_0_REG
|
||||
|
||||
#define BMA150_ACC_X_LSB_REG BMA150_DATA_2_REG
|
||||
|
@ -538,13 +537,8 @@ static int bma150_probe(struct i2c_client *client,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note if the IIO CONFIG_BMA180 driver is enabled we want to fail
|
||||
* the probe for the bma180 as the iio driver is preferred.
|
||||
*/
|
||||
chip_id = i2c_smbus_read_byte_data(client, BMA150_CHIP_ID_REG);
|
||||
if (chip_id != BMA150_CHIP_ID &&
|
||||
(IS_ENABLED(CONFIG_BMA180) || chip_id != BMA180_CHIP_ID)) {
|
||||
if (chip_id != BMA150_CHIP_ID) {
|
||||
dev_err(&client->dev, "BMA150 chip id error: %d\n", chip_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -648,9 +642,6 @@ static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL);
|
|||
|
||||
static const struct i2c_device_id bma150_id[] = {
|
||||
{ "bma150", 0 },
|
||||
#if !IS_ENABLED(CONFIG_BMA180)
|
||||
{ "bma180", 0 },
|
||||
#endif
|
||||
{ "smb380", 0 },
|
||||
{ "bma023", 0 },
|
||||
{ }
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
struct dm355evm_keys {
|
||||
struct input_dev *input;
|
||||
struct device *dev;
|
||||
int irq;
|
||||
};
|
||||
|
||||
/* These initial keycodes can be remapped */
|
||||
|
@ -176,74 +175,49 @@ static int dm355evm_keys_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct dm355evm_keys *keys;
|
||||
struct input_dev *input;
|
||||
int status;
|
||||
int irq;
|
||||
int error;
|
||||
|
||||
/* allocate instance struct and input dev */
|
||||
keys = kzalloc(sizeof *keys, GFP_KERNEL);
|
||||
input = input_allocate_device();
|
||||
if (!keys || !input) {
|
||||
status = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
keys = devm_kzalloc(&pdev->dev, sizeof (*keys), GFP_KERNEL);
|
||||
if (!keys)
|
||||
return -ENOMEM;
|
||||
|
||||
input = devm_input_allocate_device(&pdev->dev);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
||||
keys->dev = &pdev->dev;
|
||||
keys->input = input;
|
||||
|
||||
/* set up "threaded IRQ handler" */
|
||||
status = platform_get_irq(pdev, 0);
|
||||
if (status < 0)
|
||||
goto fail1;
|
||||
keys->irq = status;
|
||||
|
||||
input->name = "DM355 EVM Controls";
|
||||
input->phys = "dm355evm/input0";
|
||||
input->dev.parent = &pdev->dev;
|
||||
|
||||
input->id.bustype = BUS_I2C;
|
||||
input->id.product = 0x0355;
|
||||
input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
|
||||
|
||||
status = sparse_keymap_setup(input, dm355evm_keys, NULL);
|
||||
if (status)
|
||||
goto fail1;
|
||||
error = sparse_keymap_setup(input, dm355evm_keys, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* REVISIT: flush the event queue? */
|
||||
|
||||
status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
dev_name(&pdev->dev), keys);
|
||||
if (status < 0)
|
||||
goto fail2;
|
||||
/* set up "threaded IRQ handler" */
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
error = devm_request_threaded_irq(&pdev->dev, irq,
|
||||
NULL, dm355evm_keys_irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
dev_name(&pdev->dev), keys);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* register */
|
||||
status = input_register_device(input);
|
||||
if (status < 0)
|
||||
goto fail3;
|
||||
|
||||
platform_set_drvdata(pdev, keys);
|
||||
|
||||
return 0;
|
||||
|
||||
fail3:
|
||||
free_irq(keys->irq, keys);
|
||||
fail2:
|
||||
sparse_keymap_free(input);
|
||||
fail1:
|
||||
input_free_device(input);
|
||||
kfree(keys);
|
||||
dev_err(&pdev->dev, "can't register, err %d\n", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int dm355evm_keys_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct dm355evm_keys *keys = platform_get_drvdata(pdev);
|
||||
|
||||
free_irq(keys->irq, keys);
|
||||
sparse_keymap_free(keys->input);
|
||||
input_unregister_device(keys->input);
|
||||
kfree(keys);
|
||||
error = input_register_device(input);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -259,7 +233,6 @@ static int dm355evm_keys_remove(struct platform_device *pdev)
|
|||
*/
|
||||
static struct platform_driver dm355evm_keys_driver = {
|
||||
.probe = dm355evm_keys_probe,
|
||||
.remove = dm355evm_keys_remove,
|
||||
.driver = {
|
||||
.name = "dm355evm_keys",
|
||||
},
|
||||
|
|
|
@ -652,7 +652,6 @@ static const struct i2c_device_id drv260x_id[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(i2c, drv260x_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id drv260x_of_match[] = {
|
||||
{ .compatible = "ti,drv2604", },
|
||||
{ .compatible = "ti,drv2604l", },
|
||||
|
@ -661,13 +660,12 @@ static const struct of_device_id drv260x_of_match[] = {
|
|||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, drv260x_of_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver drv260x_driver = {
|
||||
.probe = drv260x_probe,
|
||||
.driver = {
|
||||
.name = "drv260x-haptics",
|
||||
.of_match_table = of_match_ptr(drv260x_of_match),
|
||||
.of_match_table = drv260x_of_match,
|
||||
.pm = &drv260x_pm_ops,
|
||||
},
|
||||
.id_table = drv260x_id,
|
||||
|
|
|
@ -10,19 +10,15 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define VIB_DRV 0x4A
|
||||
|
||||
#define VIB_DRV_SEL_MASK 0xf8
|
||||
#define VIB_DRV_SEL_SHIFT 0x03
|
||||
#define VIB_DRV_EN_MANUAL_MASK 0xfc
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define VIB_MAX_LEVEL_mV (3100)
|
||||
#define VIB_MIN_LEVEL_mV (1200)
|
||||
|
@ -30,20 +26,48 @@
|
|||
|
||||
#define MAX_FF_SPEED 0xff
|
||||
|
||||
struct pm8xxx_regs {
|
||||
unsigned int enable_addr;
|
||||
unsigned int enable_mask;
|
||||
|
||||
unsigned int drv_addr;
|
||||
unsigned int drv_mask;
|
||||
unsigned int drv_shift;
|
||||
unsigned int drv_en_manual_mask;
|
||||
};
|
||||
|
||||
static const struct pm8xxx_regs pm8058_regs = {
|
||||
.drv_addr = 0x4A,
|
||||
.drv_mask = 0xf8,
|
||||
.drv_shift = 3,
|
||||
.drv_en_manual_mask = 0xfc,
|
||||
};
|
||||
|
||||
static struct pm8xxx_regs pm8916_regs = {
|
||||
.enable_addr = 0xc046,
|
||||
.enable_mask = BIT(7),
|
||||
.drv_addr = 0xc041,
|
||||
.drv_mask = 0x1F,
|
||||
.drv_shift = 0,
|
||||
.drv_en_manual_mask = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct pm8xxx_vib - structure to hold vibrator data
|
||||
* @vib_input_dev: input device supporting force feedback
|
||||
* @work: work structure to set the vibration parameters
|
||||
* @regmap: regmap for register read/write
|
||||
* @regs: registers' info
|
||||
* @speed: speed of vibration set from userland
|
||||
* @active: state of vibrator
|
||||
* @level: level of vibration to set in the chip
|
||||
* @reg_vib_drv: VIB_DRV register value
|
||||
* @reg_vib_drv: regs->drv_addr register value
|
||||
*/
|
||||
struct pm8xxx_vib {
|
||||
struct input_dev *vib_input_dev;
|
||||
struct work_struct work;
|
||||
struct regmap *regmap;
|
||||
const struct pm8xxx_regs *regs;
|
||||
int speed;
|
||||
int level;
|
||||
bool active;
|
||||
|
@ -59,18 +83,24 @@ static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
|
|||
{
|
||||
int rc;
|
||||
unsigned int val = vib->reg_vib_drv;
|
||||
const struct pm8xxx_regs *regs = vib->regs;
|
||||
|
||||
if (on)
|
||||
val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
|
||||
val |= (vib->level << regs->drv_shift) & regs->drv_mask;
|
||||
else
|
||||
val &= ~VIB_DRV_SEL_MASK;
|
||||
val &= ~regs->drv_mask;
|
||||
|
||||
rc = regmap_write(vib->regmap, VIB_DRV, val);
|
||||
rc = regmap_write(vib->regmap, regs->drv_addr, val);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
vib->reg_vib_drv = val;
|
||||
return 0;
|
||||
|
||||
if (regs->enable_mask)
|
||||
rc = regmap_update_bits(vib->regmap, regs->enable_addr,
|
||||
on ? regs->enable_mask : 0, val);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,10 +110,11 @@ static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
|
|||
static void pm8xxx_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
|
||||
const struct pm8xxx_regs *regs = vib->regs;
|
||||
int rc;
|
||||
unsigned int val;
|
||||
|
||||
rc = regmap_read(vib->regmap, VIB_DRV, &val);
|
||||
rc = regmap_read(vib->regmap, regs->drv_addr, &val);
|
||||
if (rc < 0)
|
||||
return;
|
||||
|
||||
|
@ -147,6 +178,7 @@ static int pm8xxx_vib_probe(struct platform_device *pdev)
|
|||
struct input_dev *input_dev;
|
||||
int error;
|
||||
unsigned int val;
|
||||
const struct pm8xxx_regs *regs;
|
||||
|
||||
vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL);
|
||||
if (!vib)
|
||||
|
@ -163,16 +195,19 @@ static int pm8xxx_vib_probe(struct platform_device *pdev)
|
|||
INIT_WORK(&vib->work, pm8xxx_work_handler);
|
||||
vib->vib_input_dev = input_dev;
|
||||
|
||||
regs = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
/* operate in manual mode */
|
||||
error = regmap_read(vib->regmap, VIB_DRV, &val);
|
||||
error = regmap_read(vib->regmap, regs->drv_addr, &val);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
val &= ~VIB_DRV_EN_MANUAL_MASK;
|
||||
error = regmap_write(vib->regmap, VIB_DRV, val);
|
||||
val &= regs->drv_en_manual_mask;
|
||||
error = regmap_write(vib->regmap, regs->drv_addr, val);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
vib->regs = regs;
|
||||
vib->reg_vib_drv = val;
|
||||
|
||||
input_dev->name = "pm8xxx_vib_ffmemless";
|
||||
|
@ -212,8 +247,9 @@ static int __maybe_unused pm8xxx_vib_suspend(struct device *dev)
|
|||
static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
|
||||
|
||||
static const struct of_device_id pm8xxx_vib_id_table[] = {
|
||||
{ .compatible = "qcom,pm8058-vib" },
|
||||
{ .compatible = "qcom,pm8921-vib" },
|
||||
{ .compatible = "qcom,pm8058-vib", .data = &pm8058_regs },
|
||||
{ .compatible = "qcom,pm8921-vib", .data = &pm8058_regs },
|
||||
{ .compatible = "qcom,pm8916-vib", .data = &pm8916_regs },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pm8xxx_vib_id_table);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
@ -29,6 +30,7 @@ struct pwm_beeper {
|
|||
struct regulator *amplifier;
|
||||
struct work_struct work;
|
||||
unsigned long period;
|
||||
unsigned int bell_frequency;
|
||||
bool suspended;
|
||||
bool amplifier_on;
|
||||
};
|
||||
|
@ -94,7 +96,7 @@ static int pwm_beeper_event(struct input_dev *input,
|
|||
|
||||
switch (code) {
|
||||
case SND_BELL:
|
||||
value = value ? 1000 : 0;
|
||||
value = value ? beeper->bell_frequency : 0;
|
||||
break;
|
||||
case SND_TONE:
|
||||
break;
|
||||
|
@ -131,6 +133,7 @@ static int pwm_beeper_probe(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct pwm_beeper *beeper;
|
||||
struct pwm_state state;
|
||||
u32 bell_frequency;
|
||||
int error;
|
||||
|
||||
beeper = devm_kzalloc(dev, sizeof(*beeper), GFP_KERNEL);
|
||||
|
@ -167,6 +170,16 @@ static int pwm_beeper_probe(struct platform_device *pdev)
|
|||
|
||||
INIT_WORK(&beeper->work, pwm_beeper_work);
|
||||
|
||||
error = device_property_read_u32(dev, "beeper-hz", &bell_frequency);
|
||||
if (error) {
|
||||
bell_frequency = 1000;
|
||||
dev_dbg(dev,
|
||||
"failed to parse 'beeper-hz' property, using default: %uHz\n",
|
||||
bell_frequency);
|
||||
}
|
||||
|
||||
beeper->bell_frequency = bell_frequency;
|
||||
|
||||
beeper->input = devm_input_allocate_device(dev);
|
||||
if (!beeper->input) {
|
||||
dev_err(dev, "Failed to allocate input device\n");
|
||||
|
|
|
@ -20,13 +20,6 @@
|
|||
#include <linux/gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/*
|
||||
* Definition of buttons on the tablet. The ACPI index of each button
|
||||
* is defined in section 2.8.7.2 of "Windows ACPI Design Guide for SoC
|
||||
* Platforms"
|
||||
*/
|
||||
#define MAX_NBUTTONS 5
|
||||
|
||||
struct soc_button_info {
|
||||
const char *name;
|
||||
int acpi_index;
|
||||
|
@ -55,7 +48,7 @@ static int soc_button_lookup_gpio(struct device *dev, int acpi_index)
|
|||
struct gpio_desc *desc;
|
||||
int gpio;
|
||||
|
||||
desc = gpiod_get_index(dev, KBUILD_MODNAME, acpi_index, GPIOD_ASIS);
|
||||
desc = gpiod_get_index(dev, NULL, acpi_index, GPIOD_ASIS);
|
||||
if (IS_ERR(desc))
|
||||
return PTR_ERR(desc);
|
||||
|
||||
|
@ -79,14 +72,19 @@ soc_button_device_create(struct platform_device *pdev,
|
|||
int gpio;
|
||||
int error;
|
||||
|
||||
for (info = button_info; info->name; info++)
|
||||
if (info->autorepeat == autorepeat)
|
||||
n_buttons++;
|
||||
|
||||
gpio_keys_pdata = devm_kzalloc(&pdev->dev,
|
||||
sizeof(*gpio_keys_pdata) +
|
||||
sizeof(*gpio_keys) * MAX_NBUTTONS,
|
||||
sizeof(*gpio_keys) * n_buttons,
|
||||
GFP_KERNEL);
|
||||
if (!gpio_keys_pdata)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
gpio_keys = (void *)(gpio_keys_pdata + 1);
|
||||
n_buttons = 0;
|
||||
|
||||
for (info = button_info; info->name; info++) {
|
||||
if (info->autorepeat != autorepeat)
|
||||
|
@ -140,6 +138,153 @@ err_free_mem:
|
|||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
static int soc_button_get_acpi_object_int(const union acpi_object *obj)
|
||||
{
|
||||
if (obj->type != ACPI_TYPE_INTEGER)
|
||||
return -1;
|
||||
|
||||
return obj->integer.value;
|
||||
}
|
||||
|
||||
/* Parse a single ACPI0011 _DSD button descriptor */
|
||||
static int soc_button_parse_btn_desc(struct device *dev,
|
||||
const union acpi_object *desc,
|
||||
int collection_uid,
|
||||
struct soc_button_info *info)
|
||||
{
|
||||
int upage, usage;
|
||||
|
||||
if (desc->type != ACPI_TYPE_PACKAGE ||
|
||||
desc->package.count != 5 ||
|
||||
/* First byte should be 1 (control) */
|
||||
soc_button_get_acpi_object_int(&desc->package.elements[0]) != 1 ||
|
||||
/* Third byte should be collection uid */
|
||||
soc_button_get_acpi_object_int(&desc->package.elements[2]) !=
|
||||
collection_uid) {
|
||||
dev_err(dev, "Invalid ACPI Button Descriptor\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
info->event_type = EV_KEY;
|
||||
info->acpi_index =
|
||||
soc_button_get_acpi_object_int(&desc->package.elements[1]);
|
||||
upage = soc_button_get_acpi_object_int(&desc->package.elements[3]);
|
||||
usage = soc_button_get_acpi_object_int(&desc->package.elements[4]);
|
||||
|
||||
/*
|
||||
* The UUID: fa6bd625-9ce8-470d-a2c7-b3ca36c4282e descriptors use HID
|
||||
* usage page and usage codes, but otherwise the device is not HID
|
||||
* compliant: it uses one irq per button instead of generating HID
|
||||
* input reports and some buttons should generate wakeups where as
|
||||
* others should not, so we cannot use the HID subsystem.
|
||||
*
|
||||
* Luckily all devices only use a few usage page + usage combinations,
|
||||
* so we can simply check for the known combinations here.
|
||||
*/
|
||||
if (upage == 0x01 && usage == 0x81) {
|
||||
info->name = "power";
|
||||
info->event_code = KEY_POWER;
|
||||
info->wakeup = true;
|
||||
} else if (upage == 0x07 && usage == 0xe3) {
|
||||
info->name = "home";
|
||||
info->event_code = KEY_LEFTMETA;
|
||||
info->wakeup = true;
|
||||
} else if (upage == 0x0c && usage == 0xe9) {
|
||||
info->name = "volume_up";
|
||||
info->event_code = KEY_VOLUMEUP;
|
||||
info->autorepeat = true;
|
||||
} else if (upage == 0x0c && usage == 0xea) {
|
||||
info->name = "volume_down";
|
||||
info->event_code = KEY_VOLUMEDOWN;
|
||||
info->autorepeat = true;
|
||||
} else {
|
||||
dev_warn(dev, "Unknown button index %d upage %02x usage %02x, ignoring\n",
|
||||
info->acpi_index, upage, usage);
|
||||
info->name = "unknown";
|
||||
info->event_code = KEY_RESERVED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ACPI0011 _DSD btns descriptors UUID: fa6bd625-9ce8-470d-a2c7-b3ca36c4282e */
|
||||
static const u8 btns_desc_uuid[16] = {
|
||||
0x25, 0xd6, 0x6b, 0xfa, 0xe8, 0x9c, 0x0d, 0x47,
|
||||
0xa2, 0xc7, 0xb3, 0xca, 0x36, 0xc4, 0x28, 0x2e
|
||||
};
|
||||
|
||||
/* Parse ACPI0011 _DSD button descriptors */
|
||||
static struct soc_button_info *soc_button_get_button_info(struct device *dev)
|
||||
{
|
||||
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
|
||||
const union acpi_object *desc, *el0, *uuid, *btns_desc = NULL;
|
||||
struct soc_button_info *button_info;
|
||||
acpi_status status;
|
||||
int i, btn, collection_uid = -1;
|
||||
|
||||
status = acpi_evaluate_object_typed(ACPI_HANDLE(dev), "_DSD", NULL,
|
||||
&buf, ACPI_TYPE_PACKAGE);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(dev, "ACPI _DSD object not found\n");
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
/* Look for the Button Descriptors UUID */
|
||||
desc = buf.pointer;
|
||||
for (i = 0; (i + 1) < desc->package.count; i += 2) {
|
||||
uuid = &desc->package.elements[i];
|
||||
|
||||
if (uuid->type != ACPI_TYPE_BUFFER ||
|
||||
uuid->buffer.length != 16 ||
|
||||
desc->package.elements[i + 1].type != ACPI_TYPE_PACKAGE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (memcmp(uuid->buffer.pointer, btns_desc_uuid, 16) == 0) {
|
||||
btns_desc = &desc->package.elements[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!btns_desc) {
|
||||
dev_err(dev, "ACPI Button Descriptors not found\n");
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
/* The first package describes the collection */
|
||||
el0 = &btns_desc->package.elements[0];
|
||||
if (el0->type == ACPI_TYPE_PACKAGE &&
|
||||
el0->package.count == 5 &&
|
||||
/* First byte should be 0 (collection) */
|
||||
soc_button_get_acpi_object_int(&el0->package.elements[0]) == 0 &&
|
||||
/* Third byte should be 0 (top level collection) */
|
||||
soc_button_get_acpi_object_int(&el0->package.elements[2]) == 0) {
|
||||
collection_uid = soc_button_get_acpi_object_int(
|
||||
&el0->package.elements[1]);
|
||||
}
|
||||
if (collection_uid == -1) {
|
||||
dev_err(dev, "Invalid Button Collection Descriptor\n");
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
/* There are package.count - 1 buttons + 1 terminating empty entry */
|
||||
button_info = devm_kcalloc(dev, btns_desc->package.count,
|
||||
sizeof(*button_info), GFP_KERNEL);
|
||||
if (!button_info)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* Parse the button descriptors */
|
||||
for (i = 1, btn = 0; i < btns_desc->package.count; i++, btn++) {
|
||||
if (soc_button_parse_btn_desc(dev,
|
||||
&btns_desc->package.elements[i],
|
||||
collection_uid,
|
||||
&button_info[btn]))
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
return button_info;
|
||||
}
|
||||
|
||||
static int soc_button_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct soc_button_data *priv = platform_get_drvdata(pdev);
|
||||
|
@ -167,9 +312,15 @@ static int soc_button_probe(struct platform_device *pdev)
|
|||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
button_info = (struct soc_button_info *)id->driver_data;
|
||||
if (!id->driver_data) {
|
||||
button_info = soc_button_get_button_info(dev);
|
||||
if (IS_ERR(button_info))
|
||||
return PTR_ERR(button_info);
|
||||
} else {
|
||||
button_info = (struct soc_button_info *)id->driver_data;
|
||||
}
|
||||
|
||||
if (gpiod_count(dev, KBUILD_MODNAME) <= 0) {
|
||||
if (gpiod_count(dev, NULL) <= 0) {
|
||||
dev_dbg(dev, "no GPIO attached, ignoring...\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -197,9 +348,17 @@ static int soc_button_probe(struct platform_device *pdev)
|
|||
if (!priv->children[0] && !priv->children[1])
|
||||
return -ENODEV;
|
||||
|
||||
if (!id->driver_data)
|
||||
devm_kfree(dev, button_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Definition of buttons on the tablet. The ACPI index of each button
|
||||
* is defined in section 2.8.7.2 of "Windows ACPI Design Guide for SoC
|
||||
* Platforms"
|
||||
*/
|
||||
static struct soc_button_info soc_button_PNP0C40[] = {
|
||||
{ "power", 0, EV_KEY, KEY_POWER, false, true },
|
||||
{ "home", 1, EV_KEY, KEY_LEFTMETA, false, true },
|
||||
|
@ -211,6 +370,7 @@ static struct soc_button_info soc_button_PNP0C40[] = {
|
|||
|
||||
static const struct acpi_device_id soc_button_acpi_match[] = {
|
||||
{ "PNP0C40", (unsigned long)soc_button_PNP0C40 },
|
||||
{ "ACPI0011", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -64,13 +64,12 @@ static int twl4030_pwrbutton_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pwr->evbit[0] = BIT_MASK(EV_KEY);
|
||||
pwr->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
|
||||
input_set_capability(pwr, EV_KEY, KEY_POWER);
|
||||
pwr->name = "twl4030_pwrbutton";
|
||||
pwr->phys = "twl4030_pwrbutton/input0";
|
||||
pwr->dev.parent = &pdev->dev;
|
||||
|
||||
err = devm_request_threaded_irq(&pwr->dev, irq, NULL, powerbutton_irq,
|
||||
err = devm_request_threaded_irq(&pdev->dev, irq, NULL, powerbutton_irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
|
||||
IRQF_ONESHOT,
|
||||
"twl4030_pwrbutton", pwr);
|
||||
|
|
|
@ -1243,12 +1243,10 @@ static int setup_input_dev(void)
|
|||
|
||||
error = input_register_polled_device(wistron_idev);
|
||||
if (error)
|
||||
goto err_free_keymap;
|
||||
goto err_free_dev;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_keymap:
|
||||
sparse_keymap_free(input_dev);
|
||||
err_free_dev:
|
||||
input_free_polled_device(wistron_idev);
|
||||
return error;
|
||||
|
@ -1300,7 +1298,6 @@ static int wistron_remove(struct platform_device *dev)
|
|||
{
|
||||
wistron_led_remove();
|
||||
input_unregister_polled_device(wistron_idev);
|
||||
sparse_keymap_free(wistron_idev->input);
|
||||
input_free_polled_device(wistron_idev);
|
||||
bios_detach();
|
||||
|
||||
|
|
|
@ -41,6 +41,12 @@ struct xenkbd_info {
|
|||
char phys[32];
|
||||
};
|
||||
|
||||
enum { KPARAM_X, KPARAM_Y, KPARAM_CNT };
|
||||
static int ptr_size[KPARAM_CNT] = { XENFB_WIDTH, XENFB_HEIGHT };
|
||||
module_param_array(ptr_size, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(ptr_size,
|
||||
"Pointing device width, height in pixels (default 800,600)");
|
||||
|
||||
static int xenkbd_remove(struct xenbus_device *);
|
||||
static int xenkbd_connect_backend(struct xenbus_device *, struct xenkbd_info *);
|
||||
static void xenkbd_disconnect_backend(struct xenkbd_info *);
|
||||
|
@ -84,8 +90,8 @@ static irqreturn_t input_handler(int rq, void *dev_id)
|
|||
input_report_key(dev, event->key.keycode,
|
||||
event->key.pressed);
|
||||
else
|
||||
pr_warning("unhandled keycode 0x%x\n",
|
||||
event->key.keycode);
|
||||
pr_warn("unhandled keycode 0x%x\n",
|
||||
event->key.keycode);
|
||||
break;
|
||||
case XENKBD_TYPE_POS:
|
||||
input_report_abs(dev, ABS_X, event->pos.abs_x);
|
||||
|
@ -128,12 +134,17 @@ static int xenkbd_probe(struct xenbus_device *dev,
|
|||
if (!info->page)
|
||||
goto error_nomem;
|
||||
|
||||
/* Set input abs params to match backend screen res */
|
||||
abs = xenbus_read_unsigned(dev->otherend, "feature-abs-pointer", 0);
|
||||
ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, "width",
|
||||
ptr_size[KPARAM_X]);
|
||||
ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, "height",
|
||||
ptr_size[KPARAM_Y]);
|
||||
if (abs) {
|
||||
ret = xenbus_write(XBT_NIL, dev->nodename,
|
||||
"request-abs-pointer", "1");
|
||||
if (ret) {
|
||||
pr_warning("xenkbd: can't request abs-pointer");
|
||||
pr_warn("xenkbd: can't request abs-pointer\n");
|
||||
abs = 0;
|
||||
}
|
||||
}
|
||||
|
@ -174,8 +185,8 @@ static int xenkbd_probe(struct xenbus_device *dev,
|
|||
|
||||
if (abs) {
|
||||
__set_bit(EV_ABS, ptr->evbit);
|
||||
input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
|
||||
input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
|
||||
input_set_abs_params(ptr, ABS_X, 0, ptr_size[KPARAM_X], 0, 0);
|
||||
input_set_abs_params(ptr, ABS_Y, 0, ptr_size[KPARAM_Y], 0, 0);
|
||||
} else {
|
||||
input_set_capability(ptr, EV_REL, REL_X);
|
||||
input_set_capability(ptr, EV_REL, REL_Y);
|
||||
|
@ -309,9 +320,6 @@ static void xenkbd_disconnect_backend(struct xenkbd_info *info)
|
|||
static void xenkbd_backend_changed(struct xenbus_device *dev,
|
||||
enum xenbus_state backend_state)
|
||||
{
|
||||
struct xenkbd_info *info = dev_get_drvdata(&dev->dev);
|
||||
int ret, val;
|
||||
|
||||
switch (backend_state) {
|
||||
case XenbusStateInitialising:
|
||||
case XenbusStateInitialised:
|
||||
|
@ -321,15 +329,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
|
|||
break;
|
||||
|
||||
case XenbusStateInitWait:
|
||||
InitWait:
|
||||
if (xenbus_read_unsigned(info->xbdev->otherend,
|
||||
"feature-abs-pointer", 0)) {
|
||||
ret = xenbus_write(XBT_NIL, info->xbdev->nodename,
|
||||
"request-abs-pointer", "1");
|
||||
if (ret)
|
||||
pr_warning("xenkbd: can't request abs-pointer");
|
||||
}
|
||||
|
||||
xenbus_switch_state(dev, XenbusStateConnected);
|
||||
break;
|
||||
|
||||
|
@ -340,17 +339,7 @@ InitWait:
|
|||
* get Connected twice here.
|
||||
*/
|
||||
if (dev->state != XenbusStateConnected)
|
||||
goto InitWait; /* no InitWait seen yet, fudge it */
|
||||
|
||||
/* Set input abs params to match backend screen res */
|
||||
if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
|
||||
"width", "%d", &val) > 0)
|
||||
input_set_abs_params(info->ptr, ABS_X, 0, val, 0, 0);
|
||||
|
||||
if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
|
||||
"height", "%d", &val) > 0)
|
||||
input_set_abs_params(info->ptr, ABS_Y, 0, val, 0, 0);
|
||||
|
||||
xenbus_switch_state(dev, XenbusStateConnected);
|
||||
break;
|
||||
|
||||
case XenbusStateClosed:
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
struct yld_ctl_packet {
|
||||
u8 cmd; /* command code, see below */
|
||||
u8 size; /* 1-11, size of used data bytes. */
|
||||
u16 offset; /* internal packet offset */
|
||||
__be16 offset; /* internal packet offset */
|
||||
u8 data[11];
|
||||
s8 sum; /* negative sum of 15 preceding bytes */
|
||||
} __attribute__ ((packed));
|
||||
|
|
|
@ -78,6 +78,18 @@ config MOUSE_PS2_SYNAPTICS
|
|||
|
||||
If unsure, say Y.
|
||||
|
||||
config MOUSE_PS2_SYNAPTICS_SMBUS
|
||||
bool "Synaptics PS/2 SMbus companion" if EXPERT
|
||||
default y
|
||||
depends on MOUSE_PS2
|
||||
depends on I2C=y || I2C=MOUSE_PS2
|
||||
select MOUSE_PS2_SMBUS
|
||||
help
|
||||
Say Y here if you have a Synaptics RMI4 touchpad connected to
|
||||
to an SMBus, but enumerated through PS/2.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config MOUSE_PS2_CYPRESS
|
||||
bool "Cypress PS/2 mouse protocol extension" if EXPERT
|
||||
default y
|
||||
|
@ -171,6 +183,10 @@ config MOUSE_PS2_VMMOUSE
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config MOUSE_PS2_SMBUS
|
||||
bool
|
||||
depends on MOUSE_PS2
|
||||
|
||||
config MOUSE_SERIAL
|
||||
tristate "Serial mouse"
|
||||
select SERIO
|
||||
|
|
|
@ -39,6 +39,8 @@ psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o
|
|||
psmouse-$(CONFIG_MOUSE_PS2_CYPRESS) += cypress_ps2.o
|
||||
psmouse-$(CONFIG_MOUSE_PS2_VMMOUSE) += vmmouse.o
|
||||
|
||||
psmouse-$(CONFIG_MOUSE_PS2_SMBUS) += psmouse-smbus.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_SMBUS) += elan_i2c_smbus.o
|
||||
|
|
|
@ -106,39 +106,36 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
|
|||
#define ALPS_DUALPOINT_WITH_PRESSURE 0x400 /* device can report trackpoint pressure */
|
||||
|
||||
static const struct alps_model_info alps_model_data[] = {
|
||||
{ { 0x32, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* Toshiba Salellite Pro M10 */
|
||||
{ { 0x33, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V1, 0x88, 0xf8, 0 } }, /* UMAX-530T */
|
||||
{ { 0x53, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x53, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x60, 0x03, 0xc8 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, /* HP ze1115 */
|
||||
{ { 0x63, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x63, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x63, 0x02, 0x28 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Fujitsu Siemens S6010 */
|
||||
{ { 0x63, 0x02, 0x3c }, 0x00, { ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL } }, /* Toshiba Satellite S2400-103 */
|
||||
{ { 0x63, 0x02, 0x50 }, 0x00, { ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 } }, /* NEC Versa L320 */
|
||||
{ { 0x63, 0x02, 0x64 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x63, 0x03, 0xc8 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D800 */
|
||||
{ { 0x73, 0x00, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT } }, /* ThinkPad R61 8918-5QG */
|
||||
{ { 0x73, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x73, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Ahtec Laptop */
|
||||
|
||||
/*
|
||||
* XXX This entry is suspicious. First byte has zero lower nibble,
|
||||
* which is what a normal mouse would report. Also, the value 0x0e
|
||||
* isn't valid per PS/2 spec.
|
||||
*/
|
||||
{ { 0x20, 0x02, 0x0e }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },
|
||||
{ { 0x20, 0x02, 0x0e }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },
|
||||
|
||||
{ { 0x22, 0x02, 0x0a }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },
|
||||
{ { 0x22, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D600 */
|
||||
/* Dell Latitude E5500, E6400, E6500, Precision M4400 */
|
||||
{ { 0x62, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xcf, 0xcf,
|
||||
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED } },
|
||||
{ { 0x73, 0x00, 0x14 }, 0x00, { ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT } }, /* Dell XT2 */
|
||||
{ { 0x73, 0x02, 0x50 }, 0x00, { ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS } }, /* Dell Vostro 1400 */
|
||||
{ { 0x52, 0x01, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xff, 0xff,
|
||||
{ { 0x22, 0x02, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },
|
||||
{ { 0x22, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D600 */
|
||||
{ { 0x32, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* Toshiba Salellite Pro M10 */
|
||||
{ { 0x33, 0x02, 0x0a }, { ALPS_PROTO_V1, 0x88, 0xf8, 0 } }, /* UMAX-530T */
|
||||
{ { 0x52, 0x01, 0x14 }, { ALPS_PROTO_V2, 0xff, 0xff,
|
||||
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED } }, /* Toshiba Tecra A11-11L */
|
||||
{ { 0x73, 0x02, 0x64 }, 0x8a, { ALPS_PROTO_V4, 0x8f, 0x8f, 0 } },
|
||||
{ { 0x53, 0x02, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x53, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x60, 0x03, 0xc8 }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } }, /* HP ze1115 */
|
||||
{ { 0x62, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xcf, 0xcf,
|
||||
ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED } }, /* Dell Latitude E5500, E6400, E6500, Precision M4400 */
|
||||
{ { 0x63, 0x02, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x63, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x63, 0x02, 0x28 }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Fujitsu Siemens S6010 */
|
||||
{ { 0x63, 0x02, 0x3c }, { ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL } }, /* Toshiba Satellite S2400-103 */
|
||||
{ { 0x63, 0x02, 0x50 }, { ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 } }, /* NEC Versa L320 */
|
||||
{ { 0x63, 0x02, 0x64 }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x63, 0x03, 0xc8 }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } }, /* Dell Latitude D800 */
|
||||
{ { 0x73, 0x00, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT } }, /* ThinkPad R61 8918-5QG */
|
||||
{ { 0x73, 0x00, 0x14 }, { ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT } }, /* Dell XT2 */
|
||||
{ { 0x73, 0x02, 0x0a }, { ALPS_PROTO_V2, 0xf8, 0xf8, 0 } },
|
||||
{ { 0x73, 0x02, 0x14 }, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 } }, /* Ahtec Laptop */
|
||||
{ { 0x73, 0x02, 0x50 }, { ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS } }, /* Dell Vostro 1400 */
|
||||
};
|
||||
|
||||
static const struct alps_protocol_info alps_v3_protocol_data = {
|
||||
|
@ -149,6 +146,10 @@ static const struct alps_protocol_info alps_v3_rushmore_data = {
|
|||
ALPS_PROTO_V3_RUSHMORE, 0x8f, 0x8f, ALPS_DUALPOINT
|
||||
};
|
||||
|
||||
static const struct alps_protocol_info alps_v4_protocol_data = {
|
||||
ALPS_PROTO_V4, 0x8f, 0x8f, 0
|
||||
};
|
||||
|
||||
static const struct alps_protocol_info alps_v5_protocol_data = {
|
||||
ALPS_PROTO_V5, 0xc8, 0xd8, 0
|
||||
};
|
||||
|
@ -161,6 +162,10 @@ static const struct alps_protocol_info alps_v8_protocol_data = {
|
|||
ALPS_PROTO_V8, 0x18, 0x18, 0
|
||||
};
|
||||
|
||||
static const struct alps_protocol_info alps_v9_protocol_data = {
|
||||
ALPS_PROTO_V9, 0xc8, 0xc8, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Some v2 models report the stick buttons in separate bits
|
||||
*/
|
||||
|
@ -2806,12 +2811,8 @@ static const struct alps_protocol_info *alps_match_table(unsigned char *e7,
|
|||
for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
|
||||
model = &alps_model_data[i];
|
||||
|
||||
if (!memcmp(e7, model->signature, sizeof(model->signature)) &&
|
||||
(!model->command_mode_resp ||
|
||||
model->command_mode_resp == ec[2])) {
|
||||
|
||||
if (!memcmp(e7, model->signature, sizeof(model->signature)))
|
||||
return &model->protocol_info;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -2849,7 +2850,10 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
|
|||
|
||||
protocol = alps_match_table(e7, ec);
|
||||
if (!protocol) {
|
||||
if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
|
||||
if (e7[0] == 0x73 && e7[1] == 0x02 && e7[2] == 0x64 &&
|
||||
ec[2] == 0x8a) {
|
||||
protocol = &alps_v4_protocol_data;
|
||||
} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
|
||||
ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) {
|
||||
protocol = &alps_v5_protocol_data;
|
||||
} else if (ec[0] == 0x88 &&
|
||||
|
@ -2863,6 +2867,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
|
|||
} else if (e7[0] == 0x73 && e7[1] == 0x03 &&
|
||||
(e7[2] == 0x14 || e7[2] == 0x28)) {
|
||||
protocol = &alps_v8_protocol_data;
|
||||
} else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0xc8) {
|
||||
protocol = &alps_v9_protocol_data;
|
||||
psmouse_warn(psmouse,
|
||||
"Unsupported ALPS V9 touchpad: E7=%3ph, EC=%3ph\n",
|
||||
e7, ec);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
psmouse_dbg(psmouse,
|
||||
"Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define ALPS_PROTO_V6 0x600
|
||||
#define ALPS_PROTO_V7 0x700 /* t3btl t4s */
|
||||
#define ALPS_PROTO_V8 0x800 /* SS4btl SS4s */
|
||||
#define ALPS_PROTO_V9 0x900 /* ss3btl */
|
||||
|
||||
#define MAX_TOUCHES 4
|
||||
|
||||
|
@ -172,10 +173,6 @@ struct alps_protocol_info {
|
|||
/**
|
||||
* struct alps_model_info - touchpad ID table
|
||||
* @signature: E7 response string to match.
|
||||
* @command_mode_resp: For V3/V4 touchpads, the final byte of the EC response
|
||||
* (aka command mode response) identifies the firmware minor version. This
|
||||
* can be used to distinguish different hardware models which are not
|
||||
* uniquely identifiable through their E7 responses.
|
||||
* @protocol_info: information about protocol used by the device.
|
||||
*
|
||||
* Many (but not all) ALPS touchpads can be identified by looking at the
|
||||
|
@ -184,7 +181,6 @@ struct alps_protocol_info {
|
|||
*/
|
||||
struct alps_model_info {
|
||||
u8 signature[3];
|
||||
u8 command_mode_resp;
|
||||
struct alps_protocol_info protocol_info;
|
||||
};
|
||||
|
||||
|
|
|
@ -116,17 +116,6 @@ static DEFINE_MUTEX(psmouse_mutex);
|
|||
|
||||
static struct workqueue_struct *kpsmoused_wq;
|
||||
|
||||
struct psmouse_protocol {
|
||||
enum psmouse_type type;
|
||||
bool maxproto;
|
||||
bool ignore_parity; /* Protocol should ignore parity errors from KBC */
|
||||
bool try_passthru; /* Try protocol also on passthrough ports */
|
||||
const char *name;
|
||||
const char *alias;
|
||||
int (*detect)(struct psmouse *, bool);
|
||||
int (*init)(struct psmouse *);
|
||||
};
|
||||
|
||||
static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
|
||||
{
|
||||
input_report_key(dev, BTN_LEFT, buttons & BIT(0));
|
||||
|
@ -148,7 +137,7 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
|
|||
|
||||
/* Full packet accumulated, process it */
|
||||
|
||||
switch (psmouse->type) {
|
||||
switch (psmouse->protocol->type) {
|
||||
case PSMOUSE_IMPS:
|
||||
/* IntelliMouse has scroll wheel */
|
||||
input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]);
|
||||
|
@ -325,7 +314,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
|
|||
goto out;
|
||||
|
||||
if (unlikely((flags & SERIO_TIMEOUT) ||
|
||||
((flags & SERIO_PARITY) && !psmouse->ignore_parity))) {
|
||||
((flags & SERIO_PARITY) &&
|
||||
!psmouse->protocol->ignore_parity))) {
|
||||
|
||||
if (psmouse->state == PSMOUSE_ACTIVATED)
|
||||
psmouse_warn(psmouse,
|
||||
|
@ -372,7 +362,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
|
|||
}
|
||||
|
||||
if (psmouse->packet[1] == PSMOUSE_RET_ID ||
|
||||
(psmouse->type == PSMOUSE_HGPK &&
|
||||
(psmouse->protocol->type == PSMOUSE_HGPK &&
|
||||
psmouse->packet[1] == PSMOUSE_RET_BAT)) {
|
||||
__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
|
||||
serio_reconnect(serio);
|
||||
|
@ -783,7 +773,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
|
|||
.name = "SynPS/2",
|
||||
.alias = "synaptics",
|
||||
.detect = synaptics_detect,
|
||||
.init = synaptics_init,
|
||||
.init = synaptics_init_absolute,
|
||||
},
|
||||
{
|
||||
.type = PSMOUSE_SYNAPTICS_RELATIVE,
|
||||
|
@ -793,6 +783,16 @@ static const struct psmouse_protocol psmouse_protocols[] = {
|
|||
.init = synaptics_init_relative,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS
|
||||
{
|
||||
.type = PSMOUSE_SYNAPTICS_SMBUS,
|
||||
.name = "SynSMBus",
|
||||
.alias = "synaptics-smbus",
|
||||
.detect = synaptics_detect,
|
||||
.init = synaptics_init_smbus,
|
||||
.smbus_companion = true,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_MOUSE_PS2_ALPS
|
||||
{
|
||||
.type = PSMOUSE_ALPS,
|
||||
|
@ -959,6 +959,8 @@ static void psmouse_apply_defaults(struct psmouse *psmouse)
|
|||
|
||||
__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
|
||||
|
||||
psmouse->protocol = &psmouse_protocols[0];
|
||||
|
||||
psmouse->set_rate = psmouse_set_rate;
|
||||
psmouse->set_resolution = psmouse_set_resolution;
|
||||
psmouse->set_scale = psmouse_set_scale;
|
||||
|
@ -966,6 +968,7 @@ static void psmouse_apply_defaults(struct psmouse *psmouse)
|
|||
psmouse->protocol_handler = psmouse_process_byte;
|
||||
psmouse->pktsize = 3;
|
||||
psmouse->reconnect = NULL;
|
||||
psmouse->fast_reconnect = NULL;
|
||||
psmouse->disconnect = NULL;
|
||||
psmouse->cleanup = NULL;
|
||||
psmouse->pt_activate = NULL;
|
||||
|
@ -1018,6 +1021,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
unsigned int max_proto, bool set_properties)
|
||||
{
|
||||
bool synaptics_hardware = false;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Always check for focaltech, this is safe as it uses pnp-id
|
||||
|
@ -1080,9 +1084,14 @@ static int psmouse_extensions(struct psmouse *psmouse,
|
|||
* enabled first, since we try detecting Synaptics
|
||||
* even when protocol is disabled.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS) &&
|
||||
(!set_properties || synaptics_init(psmouse) == 0)) {
|
||||
return PSMOUSE_SYNAPTICS;
|
||||
if (IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS) ||
|
||||
IS_ENABLED(CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS)) {
|
||||
if (!set_properties)
|
||||
return PSMOUSE_SYNAPTICS;
|
||||
|
||||
ret = synaptics_init(psmouse);
|
||||
if (ret >= 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1431,9 +1440,8 @@ static void psmouse_cleanup(struct serio *serio)
|
|||
*/
|
||||
static void psmouse_disconnect(struct serio *serio)
|
||||
{
|
||||
struct psmouse *psmouse, *parent = NULL;
|
||||
|
||||
psmouse = serio_get_drvdata(serio);
|
||||
struct psmouse *psmouse = serio_get_drvdata(serio);
|
||||
struct psmouse *parent = NULL;
|
||||
|
||||
sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group);
|
||||
|
||||
|
@ -1461,7 +1469,10 @@ static void psmouse_disconnect(struct serio *serio)
|
|||
|
||||
serio_close(serio);
|
||||
serio_set_drvdata(serio, NULL);
|
||||
input_unregister_device(psmouse->dev);
|
||||
|
||||
if (psmouse->dev)
|
||||
input_unregister_device(psmouse->dev);
|
||||
|
||||
kfree(psmouse);
|
||||
|
||||
if (parent)
|
||||
|
@ -1475,6 +1486,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
|
|||
{
|
||||
const struct psmouse_protocol *selected_proto;
|
||||
struct input_dev *input_dev = psmouse->dev;
|
||||
enum psmouse_type type;
|
||||
|
||||
input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
|
||||
|
||||
|
@ -1487,15 +1499,13 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
|
|||
if (proto->init && proto->init(psmouse) < 0)
|
||||
return -1;
|
||||
|
||||
psmouse->type = proto->type;
|
||||
selected_proto = proto;
|
||||
} else {
|
||||
psmouse->type = psmouse_extensions(psmouse,
|
||||
psmouse_max_proto, true);
|
||||
selected_proto = psmouse_protocol_by_type(psmouse->type);
|
||||
type = psmouse_extensions(psmouse, psmouse_max_proto, true);
|
||||
selected_proto = psmouse_protocol_by_type(type);
|
||||
}
|
||||
|
||||
psmouse->ignore_parity = selected_proto->ignore_parity;
|
||||
psmouse->protocol = selected_proto;
|
||||
|
||||
/*
|
||||
* If mouse's packet size is 3 there is no point in polling the
|
||||
|
@ -1521,7 +1531,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
|
|||
input_dev->phys = psmouse->phys;
|
||||
input_dev->id.bustype = BUS_I8042;
|
||||
input_dev->id.vendor = 0x0002;
|
||||
input_dev->id.product = psmouse->type;
|
||||
input_dev->id.product = psmouse->protocol->type;
|
||||
input_dev->id.version = psmouse->model;
|
||||
|
||||
return 0;
|
||||
|
@ -1583,12 +1593,18 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
|
|||
|
||||
psmouse_switch_protocol(psmouse, NULL);
|
||||
|
||||
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
||||
psmouse_initialize(psmouse);
|
||||
if (!psmouse->protocol->smbus_companion) {
|
||||
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
||||
psmouse_initialize(psmouse);
|
||||
|
||||
error = input_register_device(psmouse->dev);
|
||||
if (error)
|
||||
goto err_protocol_disconnect;
|
||||
error = input_register_device(input_dev);
|
||||
if (error)
|
||||
goto err_protocol_disconnect;
|
||||
} else {
|
||||
/* Smbus companion will be reporting events, not us. */
|
||||
input_free_device(input_dev);
|
||||
psmouse->dev = input_dev = NULL;
|
||||
}
|
||||
|
||||
if (parent && parent->pt_activate)
|
||||
parent->pt_activate(parent);
|
||||
|
@ -1597,7 +1613,12 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
|
|||
if (error)
|
||||
goto err_pt_deactivate;
|
||||
|
||||
psmouse_activate(psmouse);
|
||||
/*
|
||||
* PS/2 devices having SMBus companions should stay disabled
|
||||
* on PS/2 side, in order to have SMBus part operable.
|
||||
*/
|
||||
if (!psmouse->protocol->smbus_companion)
|
||||
psmouse_activate(psmouse);
|
||||
|
||||
out:
|
||||
/* If this is a pass-through port the parent needs to be re-activated */
|
||||
|
@ -1610,8 +1631,10 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
|
|||
err_pt_deactivate:
|
||||
if (parent && parent->pt_deactivate)
|
||||
parent->pt_deactivate(parent);
|
||||
input_unregister_device(psmouse->dev);
|
||||
input_dev = NULL; /* so we don't try to free it below */
|
||||
if (input_dev) {
|
||||
input_unregister_device(input_dev);
|
||||
input_dev = NULL; /* so we don't try to free it below */
|
||||
}
|
||||
err_protocol_disconnect:
|
||||
if (psmouse->disconnect)
|
||||
psmouse->disconnect(psmouse);
|
||||
|
@ -1628,15 +1651,26 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
|
|||
goto out;
|
||||
}
|
||||
|
||||
static int psmouse_reconnect(struct serio *serio)
|
||||
static int __psmouse_reconnect(struct serio *serio, bool fast_reconnect)
|
||||
{
|
||||
struct psmouse *psmouse = serio_get_drvdata(serio);
|
||||
struct psmouse *parent = NULL;
|
||||
unsigned char type;
|
||||
int (*reconnect_handler)(struct psmouse *);
|
||||
enum psmouse_type type;
|
||||
int rc = -1;
|
||||
|
||||
mutex_lock(&psmouse_mutex);
|
||||
|
||||
if (fast_reconnect) {
|
||||
reconnect_handler = psmouse->fast_reconnect;
|
||||
if (!reconnect_handler) {
|
||||
rc = -ENOENT;
|
||||
goto out_unlock;
|
||||
}
|
||||
} else {
|
||||
reconnect_handler = psmouse->reconnect;
|
||||
}
|
||||
|
||||
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
|
||||
parent = serio_get_drvdata(serio->parent);
|
||||
psmouse_deactivate(parent);
|
||||
|
@ -1644,8 +1678,8 @@ static int psmouse_reconnect(struct serio *serio)
|
|||
|
||||
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
|
||||
|
||||
if (psmouse->reconnect) {
|
||||
if (psmouse->reconnect(psmouse))
|
||||
if (reconnect_handler) {
|
||||
if (reconnect_handler(psmouse))
|
||||
goto out;
|
||||
} else {
|
||||
psmouse_reset(psmouse);
|
||||
|
@ -1654,7 +1688,7 @@ static int psmouse_reconnect(struct serio *serio)
|
|||
goto out;
|
||||
|
||||
type = psmouse_extensions(psmouse, psmouse_max_proto, false);
|
||||
if (psmouse->type != type)
|
||||
if (psmouse->protocol->type != type)
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1662,14 +1696,21 @@ static int psmouse_reconnect(struct serio *serio)
|
|||
* OK, the device type (and capabilities) match the old one,
|
||||
* we can continue using it, complete initialization
|
||||
*/
|
||||
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
||||
|
||||
psmouse_initialize(psmouse);
|
||||
if (!psmouse->protocol->smbus_companion) {
|
||||
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
||||
psmouse_initialize(psmouse);
|
||||
}
|
||||
|
||||
if (parent && parent->pt_activate)
|
||||
parent->pt_activate(parent);
|
||||
|
||||
psmouse_activate(psmouse);
|
||||
/*
|
||||
* PS/2 devices having SMBus companions should stay disabled
|
||||
* on PS/2 side, in order to have SMBus part operable.
|
||||
*/
|
||||
if (!psmouse->protocol->smbus_companion)
|
||||
psmouse_activate(psmouse);
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
|
@ -1677,10 +1718,21 @@ out:
|
|||
if (parent)
|
||||
psmouse_activate(parent);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&psmouse_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int psmouse_reconnect(struct serio *serio)
|
||||
{
|
||||
return __psmouse_reconnect(serio, false);
|
||||
}
|
||||
|
||||
static int psmouse_fast_reconnect(struct serio *serio)
|
||||
{
|
||||
return __psmouse_reconnect(serio, true);
|
||||
}
|
||||
|
||||
static struct serio_device_id psmouse_serio_ids[] = {
|
||||
{
|
||||
.type = SERIO_8042,
|
||||
|
@ -1708,6 +1760,7 @@ static struct serio_driver psmouse_drv = {
|
|||
.interrupt = psmouse_interrupt,
|
||||
.connect = psmouse_connect,
|
||||
.reconnect = psmouse_reconnect,
|
||||
.fast_reconnect = psmouse_fast_reconnect,
|
||||
.disconnect = psmouse_disconnect,
|
||||
.cleanup = psmouse_cleanup,
|
||||
};
|
||||
|
@ -1717,9 +1770,11 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *de
|
|||
{
|
||||
struct serio *serio = to_serio_port(dev);
|
||||
struct psmouse_attribute *attr = to_psmouse_attr(devattr);
|
||||
struct psmouse *psmouse;
|
||||
struct psmouse *psmouse = serio_get_drvdata(serio);
|
||||
|
||||
psmouse = serio_get_drvdata(serio);
|
||||
if (psmouse->protocol->smbus_companion &&
|
||||
devattr != &psmouse_attr_protocol.dattr)
|
||||
return -ENOENT;
|
||||
|
||||
return attr->show(psmouse, attr->data, buf);
|
||||
}
|
||||
|
@ -1738,6 +1793,12 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
|
|||
|
||||
psmouse = serio_get_drvdata(serio);
|
||||
|
||||
if (psmouse->protocol->smbus_companion &&
|
||||
devattr != &psmouse_attr_protocol.dattr) {
|
||||
retval = -ENOENT;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (attr->protect) {
|
||||
if (psmouse->state == PSMOUSE_IGNORE) {
|
||||
retval = -ENODEV;
|
||||
|
@ -1749,13 +1810,14 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
|
|||
psmouse_deactivate(parent);
|
||||
}
|
||||
|
||||
psmouse_deactivate(psmouse);
|
||||
if (!psmouse->protocol->smbus_companion)
|
||||
psmouse_deactivate(psmouse);
|
||||
}
|
||||
|
||||
retval = attr->set(psmouse, attr->data, buf, count);
|
||||
|
||||
if (attr->protect) {
|
||||
if (retval != -ENODEV)
|
||||
if (retval != -ENODEV && !psmouse->protocol->smbus_companion)
|
||||
psmouse_activate(psmouse);
|
||||
|
||||
if (parent)
|
||||
|
@ -1792,7 +1854,7 @@ static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const
|
|||
|
||||
static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, void *data, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name);
|
||||
return sprintf(buf, "%s\n", psmouse->protocol->name);
|
||||
}
|
||||
|
||||
static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, const char *buf, size_t count)
|
||||
|
@ -1808,7 +1870,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
|
|||
if (!proto)
|
||||
return -EINVAL;
|
||||
|
||||
if (psmouse->type == proto->type)
|
||||
if (psmouse->protocol == proto)
|
||||
return count;
|
||||
|
||||
new_dev = input_allocate_device();
|
||||
|
@ -1832,7 +1894,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (psmouse->type == proto->type) {
|
||||
if (psmouse->protocol == proto) {
|
||||
input_free_device(new_dev);
|
||||
return count; /* switched by other thread */
|
||||
}
|
||||
|
@ -1845,7 +1907,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
|
|||
}
|
||||
|
||||
old_dev = psmouse->dev;
|
||||
old_proto = psmouse_protocol_by_type(psmouse->type);
|
||||
old_proto = psmouse->protocol;
|
||||
|
||||
if (psmouse->disconnect)
|
||||
psmouse->disconnect(psmouse);
|
||||
|
@ -1864,23 +1926,29 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
|
|||
psmouse_initialize(psmouse);
|
||||
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
||||
|
||||
error = input_register_device(psmouse->dev);
|
||||
if (error) {
|
||||
if (psmouse->disconnect)
|
||||
psmouse->disconnect(psmouse);
|
||||
if (psmouse->protocol->smbus_companion) {
|
||||
input_free_device(psmouse->dev);
|
||||
psmouse->dev = NULL;
|
||||
} else {
|
||||
error = input_register_device(psmouse->dev);
|
||||
if (error) {
|
||||
if (psmouse->disconnect)
|
||||
psmouse->disconnect(psmouse);
|
||||
|
||||
psmouse_set_state(psmouse, PSMOUSE_IGNORE);
|
||||
input_free_device(new_dev);
|
||||
psmouse->dev = old_dev;
|
||||
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
|
||||
psmouse_switch_protocol(psmouse, old_proto);
|
||||
psmouse_initialize(psmouse);
|
||||
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
||||
psmouse_set_state(psmouse, PSMOUSE_IGNORE);
|
||||
input_free_device(new_dev);
|
||||
psmouse->dev = old_dev;
|
||||
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
|
||||
psmouse_switch_protocol(psmouse, old_proto);
|
||||
psmouse_initialize(psmouse);
|
||||
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
|
||||
|
||||
return error;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
input_unregister_device(old_dev);
|
||||
if (old_dev)
|
||||
input_unregister_device(old_dev);
|
||||
|
||||
if (parent && parent->pt_activate)
|
||||
parent->pt_activate(parent);
|
||||
|
@ -1947,16 +2015,27 @@ static int __init psmouse_init(void)
|
|||
synaptics_module_init();
|
||||
hgpk_module_init();
|
||||
|
||||
err = psmouse_smbus_module_init();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
kpsmoused_wq = alloc_ordered_workqueue("kpsmoused", 0);
|
||||
if (!kpsmoused_wq) {
|
||||
pr_err("failed to create kpsmoused workqueue\n");
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto err_smbus_exit;
|
||||
}
|
||||
|
||||
err = serio_register_driver(&psmouse_drv);
|
||||
if (err)
|
||||
destroy_workqueue(kpsmoused_wq);
|
||||
goto err_destroy_wq;
|
||||
|
||||
return 0;
|
||||
|
||||
err_destroy_wq:
|
||||
destroy_workqueue(kpsmoused_wq);
|
||||
err_smbus_exit:
|
||||
psmouse_smbus_module_exit();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1964,6 +2043,7 @@ static void __exit psmouse_exit(void)
|
|||
{
|
||||
serio_unregister_driver(&psmouse_drv);
|
||||
destroy_workqueue(kpsmoused_wq);
|
||||
psmouse_smbus_module_exit();
|
||||
}
|
||||
|
||||
module_init(psmouse_init);
|
||||
|
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Red Hat, Inc
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/libps2.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include "psmouse.h"
|
||||
|
||||
struct psmouse_smbus_dev {
|
||||
struct i2c_board_info board;
|
||||
struct psmouse *psmouse;
|
||||
struct i2c_client *client;
|
||||
struct list_head node;
|
||||
bool dead;
|
||||
};
|
||||
|
||||
static LIST_HEAD(psmouse_smbus_list);
|
||||
static DEFINE_MUTEX(psmouse_smbus_mutex);
|
||||
|
||||
static void psmouse_smbus_check_adapter(struct i2c_adapter *adapter)
|
||||
{
|
||||
struct psmouse_smbus_dev *smbdev;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY))
|
||||
return;
|
||||
|
||||
mutex_lock(&psmouse_smbus_mutex);
|
||||
|
||||
list_for_each_entry(smbdev, &psmouse_smbus_list, node) {
|
||||
if (smbdev->dead)
|
||||
continue;
|
||||
|
||||
if (smbdev->client)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Here would be a good place to check if device is actually
|
||||
* present, but it seems that SMBus will not respond unless we
|
||||
* fully reset PS/2 connection. So cross our fingers, and try
|
||||
* to switch over, hopefully our system will not have too many
|
||||
* "host notify" I2C adapters.
|
||||
*/
|
||||
psmouse_dbg(smbdev->psmouse,
|
||||
"SMBus candidate adapter appeared, triggering rescan\n");
|
||||
serio_rescan(smbdev->psmouse->ps2dev.serio);
|
||||
}
|
||||
|
||||
mutex_unlock(&psmouse_smbus_mutex);
|
||||
}
|
||||
|
||||
static void psmouse_smbus_detach_i2c_client(struct i2c_client *client)
|
||||
{
|
||||
struct psmouse_smbus_dev *smbdev, *tmp;
|
||||
|
||||
mutex_lock(&psmouse_smbus_mutex);
|
||||
|
||||
list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
|
||||
if (smbdev->client != client)
|
||||
continue;
|
||||
|
||||
kfree(client->dev.platform_data);
|
||||
client->dev.platform_data = NULL;
|
||||
|
||||
if (!smbdev->dead) {
|
||||
psmouse_dbg(smbdev->psmouse,
|
||||
"Marking SMBus companion %s as gone\n",
|
||||
dev_name(&smbdev->client->dev));
|
||||
smbdev->dead = true;
|
||||
serio_rescan(smbdev->psmouse->ps2dev.serio);
|
||||
} else {
|
||||
list_del(&smbdev->node);
|
||||
kfree(smbdev);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&psmouse_smbus_mutex);
|
||||
}
|
||||
|
||||
static int psmouse_smbus_notifier_call(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct device *dev = data;
|
||||
|
||||
switch (action) {
|
||||
case BUS_NOTIFY_ADD_DEVICE:
|
||||
if (dev->type == &i2c_adapter_type)
|
||||
psmouse_smbus_check_adapter(to_i2c_adapter(dev));
|
||||
break;
|
||||
|
||||
case BUS_NOTIFY_REMOVED_DEVICE:
|
||||
if (dev->type == &i2c_client_type)
|
||||
psmouse_smbus_detach_i2c_client(to_i2c_client(dev));
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block psmouse_smbus_notifier = {
|
||||
.notifier_call = psmouse_smbus_notifier_call,
|
||||
};
|
||||
|
||||
static psmouse_ret_t psmouse_smbus_process_byte(struct psmouse *psmouse)
|
||||
{
|
||||
return PSMOUSE_FULL_PACKET;
|
||||
}
|
||||
|
||||
static int psmouse_smbus_reconnect(struct psmouse *psmouse)
|
||||
{
|
||||
psmouse_deactivate(psmouse);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct psmouse_smbus_removal_work {
|
||||
struct work_struct work;
|
||||
struct i2c_client *client;
|
||||
};
|
||||
|
||||
static void psmouse_smbus_remove_i2c_device(struct work_struct *work)
|
||||
{
|
||||
struct psmouse_smbus_removal_work *rwork =
|
||||
container_of(work, struct psmouse_smbus_removal_work, work);
|
||||
|
||||
dev_dbg(&rwork->client->dev, "destroying SMBus companion device\n");
|
||||
i2c_unregister_device(rwork->client);
|
||||
|
||||
kfree(rwork);
|
||||
}
|
||||
|
||||
/*
|
||||
* This schedules removal of SMBus companion device. We have to do
|
||||
* it in a separate tread to avoid deadlocking on psmouse_mutex in
|
||||
* case the device has a trackstick (which is also driven by psmouse).
|
||||
*
|
||||
* Note that this may be racing with i2c adapter removal, but we
|
||||
* can't do anything about that: i2c automatically destroys clients
|
||||
* attached to an adapter that is being removed. This has to be
|
||||
* fixed in i2c core.
|
||||
*/
|
||||
static void psmouse_smbus_schedule_remove(struct i2c_client *client)
|
||||
{
|
||||
struct psmouse_smbus_removal_work *rwork;
|
||||
|
||||
rwork = kzalloc(sizeof(*rwork), GFP_KERNEL);
|
||||
if (rwork) {
|
||||
INIT_WORK(&rwork->work, psmouse_smbus_remove_i2c_device);
|
||||
rwork->client = client;
|
||||
|
||||
schedule_work(&rwork->work);
|
||||
}
|
||||
}
|
||||
|
||||
static void psmouse_smbus_disconnect(struct psmouse *psmouse)
|
||||
{
|
||||
struct psmouse_smbus_dev *smbdev = psmouse->private;
|
||||
|
||||
mutex_lock(&psmouse_smbus_mutex);
|
||||
|
||||
if (smbdev->dead) {
|
||||
list_del(&smbdev->node);
|
||||
kfree(smbdev);
|
||||
} else {
|
||||
smbdev->dead = true;
|
||||
psmouse_dbg(smbdev->psmouse,
|
||||
"posting removal request for SMBus companion %s\n",
|
||||
dev_name(&smbdev->client->dev));
|
||||
psmouse_smbus_schedule_remove(smbdev->client);
|
||||
}
|
||||
|
||||
mutex_unlock(&psmouse_smbus_mutex);
|
||||
|
||||
psmouse->private = NULL;
|
||||
}
|
||||
|
||||
static int psmouse_smbus_create_companion(struct device *dev, void *data)
|
||||
{
|
||||
struct psmouse_smbus_dev *smbdev = data;
|
||||
unsigned short addr_list[] = { smbdev->board.addr, I2C_CLIENT_END };
|
||||
struct i2c_adapter *adapter;
|
||||
|
||||
adapter = i2c_verify_adapter(dev);
|
||||
if (!adapter)
|
||||
return 0;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HOST_NOTIFY))
|
||||
return 0;
|
||||
|
||||
smbdev->client = i2c_new_probed_device(adapter, &smbdev->board,
|
||||
addr_list, NULL);
|
||||
if (!smbdev->client)
|
||||
return 0;
|
||||
|
||||
/* We have our(?) device, stop iterating i2c bus. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
void psmouse_smbus_cleanup(struct psmouse *psmouse)
|
||||
{
|
||||
struct psmouse_smbus_dev *smbdev, *tmp;
|
||||
|
||||
mutex_lock(&psmouse_smbus_mutex);
|
||||
|
||||
list_for_each_entry_safe(smbdev, tmp, &psmouse_smbus_list, node) {
|
||||
if (psmouse == smbdev->psmouse) {
|
||||
list_del(&smbdev->node);
|
||||
kfree(smbdev);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&psmouse_smbus_mutex);
|
||||
}
|
||||
|
||||
int psmouse_smbus_init(struct psmouse *psmouse,
|
||||
const struct i2c_board_info *board,
|
||||
const void *pdata, size_t pdata_size,
|
||||
bool leave_breadcrumbs)
|
||||
{
|
||||
struct psmouse_smbus_dev *smbdev;
|
||||
int error;
|
||||
|
||||
smbdev = kzalloc(sizeof(*smbdev), GFP_KERNEL);
|
||||
if (!smbdev)
|
||||
return -ENOMEM;
|
||||
|
||||
smbdev->psmouse = psmouse;
|
||||
smbdev->board = *board;
|
||||
|
||||
smbdev->board.platform_data = kmemdup(pdata, pdata_size, GFP_KERNEL);
|
||||
if (!smbdev->board.platform_data) {
|
||||
kfree(smbdev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
psmouse->private = smbdev;
|
||||
psmouse->protocol_handler = psmouse_smbus_process_byte;
|
||||
psmouse->reconnect = psmouse_smbus_reconnect;
|
||||
psmouse->fast_reconnect = psmouse_smbus_reconnect;
|
||||
psmouse->disconnect = psmouse_smbus_disconnect;
|
||||
psmouse->resync_time = 0;
|
||||
|
||||
psmouse_deactivate(psmouse);
|
||||
|
||||
mutex_lock(&psmouse_smbus_mutex);
|
||||
list_add_tail(&smbdev->node, &psmouse_smbus_list);
|
||||
mutex_unlock(&psmouse_smbus_mutex);
|
||||
|
||||
/* Bind to already existing adapters right away */
|
||||
error = i2c_for_each_dev(smbdev, psmouse_smbus_create_companion);
|
||||
|
||||
if (smbdev->client) {
|
||||
/* We have our companion device */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we did not create i2c device we will not need platform
|
||||
* data even if we are leaving breadcrumbs.
|
||||
*/
|
||||
kfree(smbdev->board.platform_data);
|
||||
smbdev->board.platform_data = NULL;
|
||||
|
||||
if (error < 0 || !leave_breadcrumbs) {
|
||||
mutex_lock(&psmouse_smbus_mutex);
|
||||
list_del(&smbdev->node);
|
||||
mutex_unlock(&psmouse_smbus_mutex);
|
||||
|
||||
kfree(smbdev);
|
||||
}
|
||||
|
||||
return error < 0 ? error : -EAGAIN;
|
||||
}
|
||||
|
||||
int __init psmouse_smbus_module_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = bus_register_notifier(&i2c_bus_type, &psmouse_smbus_notifier);
|
||||
if (error) {
|
||||
pr_err("failed to register i2c bus notifier: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void psmouse_smbus_module_exit(void)
|
||||
{
|
||||
bus_unregister_notifier(&i2c_bus_type, &psmouse_smbus_notifier);
|
||||
flush_scheduled_work();
|
||||
}
|
|
@ -44,50 +44,6 @@ enum psmouse_scale {
|
|||
PSMOUSE_SCALE21
|
||||
};
|
||||
|
||||
struct psmouse {
|
||||
void *private;
|
||||
struct input_dev *dev;
|
||||
struct ps2dev ps2dev;
|
||||
struct delayed_work resync_work;
|
||||
char *vendor;
|
||||
char *name;
|
||||
unsigned char packet[8];
|
||||
unsigned char badbyte;
|
||||
unsigned char pktcnt;
|
||||
unsigned char pktsize;
|
||||
unsigned char type;
|
||||
unsigned char oob_data_type;
|
||||
unsigned char extra_buttons;
|
||||
bool ignore_parity;
|
||||
bool acks_disable_command;
|
||||
unsigned int model;
|
||||
unsigned long last;
|
||||
unsigned long out_of_sync_cnt;
|
||||
unsigned long num_resyncs;
|
||||
enum psmouse_state state;
|
||||
char devname[64];
|
||||
char phys[32];
|
||||
|
||||
unsigned int rate;
|
||||
unsigned int resolution;
|
||||
unsigned int resetafter;
|
||||
unsigned int resync_time;
|
||||
bool smartscroll; /* Logitech only */
|
||||
|
||||
psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse);
|
||||
void (*set_rate)(struct psmouse *psmouse, unsigned int rate);
|
||||
void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution);
|
||||
void (*set_scale)(struct psmouse *psmouse, enum psmouse_scale scale);
|
||||
|
||||
int (*reconnect)(struct psmouse *psmouse);
|
||||
void (*disconnect)(struct psmouse *psmouse);
|
||||
void (*cleanup)(struct psmouse *psmouse);
|
||||
int (*poll)(struct psmouse *psmouse);
|
||||
|
||||
void (*pt_activate)(struct psmouse *psmouse);
|
||||
void (*pt_deactivate)(struct psmouse *psmouse);
|
||||
};
|
||||
|
||||
enum psmouse_type {
|
||||
PSMOUSE_NONE,
|
||||
PSMOUSE_PS2,
|
||||
|
@ -110,9 +66,68 @@ enum psmouse_type {
|
|||
PSMOUSE_FOCALTECH,
|
||||
PSMOUSE_VMMOUSE,
|
||||
PSMOUSE_BYD,
|
||||
PSMOUSE_SYNAPTICS_SMBUS,
|
||||
PSMOUSE_AUTO /* This one should always be last */
|
||||
};
|
||||
|
||||
struct psmouse;
|
||||
|
||||
struct psmouse_protocol {
|
||||
enum psmouse_type type;
|
||||
bool maxproto;
|
||||
bool ignore_parity; /* Protocol should ignore parity errors from KBC */
|
||||
bool try_passthru; /* Try protocol also on passthrough ports */
|
||||
bool smbus_companion; /* "Protocol" is a stub, device is on SMBus */
|
||||
const char *name;
|
||||
const char *alias;
|
||||
int (*detect)(struct psmouse *, bool);
|
||||
int (*init)(struct psmouse *);
|
||||
};
|
||||
|
||||
struct psmouse {
|
||||
void *private;
|
||||
struct input_dev *dev;
|
||||
struct ps2dev ps2dev;
|
||||
struct delayed_work resync_work;
|
||||
const char *vendor;
|
||||
const char *name;
|
||||
const struct psmouse_protocol *protocol;
|
||||
unsigned char packet[8];
|
||||
unsigned char badbyte;
|
||||
unsigned char pktcnt;
|
||||
unsigned char pktsize;
|
||||
unsigned char oob_data_type;
|
||||
unsigned char extra_buttons;
|
||||
bool acks_disable_command;
|
||||
unsigned int model;
|
||||
unsigned long last;
|
||||
unsigned long out_of_sync_cnt;
|
||||
unsigned long num_resyncs;
|
||||
enum psmouse_state state;
|
||||
char devname[64];
|
||||
char phys[32];
|
||||
|
||||
unsigned int rate;
|
||||
unsigned int resolution;
|
||||
unsigned int resetafter;
|
||||
unsigned int resync_time;
|
||||
bool smartscroll; /* Logitech only */
|
||||
|
||||
psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse);
|
||||
void (*set_rate)(struct psmouse *psmouse, unsigned int rate);
|
||||
void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution);
|
||||
void (*set_scale)(struct psmouse *psmouse, enum psmouse_scale scale);
|
||||
|
||||
int (*reconnect)(struct psmouse *psmouse);
|
||||
int (*fast_reconnect)(struct psmouse *psmouse);
|
||||
void (*disconnect)(struct psmouse *psmouse);
|
||||
void (*cleanup)(struct psmouse *psmouse);
|
||||
int (*poll)(struct psmouse *psmouse);
|
||||
|
||||
void (*pt_activate)(struct psmouse *psmouse);
|
||||
void (*pt_deactivate)(struct psmouse *psmouse);
|
||||
};
|
||||
|
||||
void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
|
||||
unsigned long delay);
|
||||
int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
|
||||
|
@ -195,5 +210,34 @@ static struct psmouse_attribute psmouse_attr_##_name = { \
|
|||
&(psmouse)->ps2dev.serio->dev, \
|
||||
psmouse_fmt(format), ##__VA_ARGS__)
|
||||
|
||||
#ifdef CONFIG_MOUSE_PS2_SMBUS
|
||||
|
||||
int psmouse_smbus_module_init(void);
|
||||
void psmouse_smbus_module_exit(void);
|
||||
|
||||
struct i2c_board_info;
|
||||
|
||||
int psmouse_smbus_init(struct psmouse *psmouse,
|
||||
const struct i2c_board_info *board,
|
||||
const void *pdata, size_t pdata_size,
|
||||
bool leave_breadcrumbs);
|
||||
void psmouse_smbus_cleanup(struct psmouse *psmouse);
|
||||
|
||||
#else /* !CONFIG_MOUSE_PS2_SMBUS */
|
||||
|
||||
static inline int psmouse_smbus_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void psmouse_smbus_module_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void psmouse_smbus_cleanup(struct psmouse *psmouse)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MOUSE_PS2_SMBUS */
|
||||
|
||||
#endif /* _PSMOUSE_H */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -25,36 +25,37 @@
|
|||
#define SYN_QUE_MEXT_CAPAB_10 0x10
|
||||
|
||||
/* synatics modes */
|
||||
#define SYN_BIT_ABSOLUTE_MODE (1 << 7)
|
||||
#define SYN_BIT_HIGH_RATE (1 << 6)
|
||||
#define SYN_BIT_SLEEP_MODE (1 << 3)
|
||||
#define SYN_BIT_DISABLE_GESTURE (1 << 2)
|
||||
#define SYN_BIT_FOUR_BYTE_CLIENT (1 << 1)
|
||||
#define SYN_BIT_W_MODE (1 << 0)
|
||||
#define SYN_BIT_ABSOLUTE_MODE BIT(7)
|
||||
#define SYN_BIT_HIGH_RATE BIT(6)
|
||||
#define SYN_BIT_SLEEP_MODE BIT(3)
|
||||
#define SYN_BIT_DISABLE_GESTURE BIT(2)
|
||||
#define SYN_BIT_FOUR_BYTE_CLIENT BIT(1)
|
||||
#define SYN_BIT_W_MODE BIT(0)
|
||||
|
||||
/* synaptics model ID bits */
|
||||
#define SYN_MODEL_ROT180(m) ((m) & (1 << 23))
|
||||
#define SYN_MODEL_PORTRAIT(m) ((m) & (1 << 22))
|
||||
#define SYN_MODEL_SENSOR(m) (((m) >> 16) & 0x3f)
|
||||
#define SYN_MODEL_HARDWARE(m) (((m) >> 9) & 0x7f)
|
||||
#define SYN_MODEL_NEWABS(m) ((m) & (1 << 7))
|
||||
#define SYN_MODEL_PEN(m) ((m) & (1 << 6))
|
||||
#define SYN_MODEL_SIMPLIC(m) ((m) & (1 << 5))
|
||||
#define SYN_MODEL_GEOMETRY(m) ((m) & 0x0f)
|
||||
#define SYN_MODEL_ROT180(m) ((m) & BIT(23))
|
||||
#define SYN_MODEL_PORTRAIT(m) ((m) & BIT(22))
|
||||
#define SYN_MODEL_SENSOR(m) (((m) & GENMASK(21, 16)) >> 16)
|
||||
#define SYN_MODEL_HARDWARE(m) (((m) & GENMASK(15, 9)) >> 9)
|
||||
#define SYN_MODEL_NEWABS(m) ((m) & BIT(7))
|
||||
#define SYN_MODEL_PEN(m) ((m) & BIT(6))
|
||||
#define SYN_MODEL_SIMPLIC(m) ((m) & BIT(5))
|
||||
#define SYN_MODEL_GEOMETRY(m) ((m) & GENMASK(3, 0))
|
||||
|
||||
/* synaptics capability bits */
|
||||
#define SYN_CAP_EXTENDED(c) ((c) & (1 << 23))
|
||||
#define SYN_CAP_MIDDLE_BUTTON(c) ((c) & (1 << 18))
|
||||
#define SYN_CAP_PASS_THROUGH(c) ((c) & (1 << 7))
|
||||
#define SYN_CAP_SLEEP(c) ((c) & (1 << 4))
|
||||
#define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3))
|
||||
#define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1))
|
||||
#define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0))
|
||||
#define SYN_CAP_SUBMODEL_ID(c) (((c) & 0x00ff00) >> 8)
|
||||
#define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20)
|
||||
#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12)
|
||||
#define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16)
|
||||
#define SYN_MEXT_CAP_BIT(m) ((m) & (1 << 1))
|
||||
#define SYN_CAP_EXTENDED(c) ((c) & BIT(23))
|
||||
#define SYN_CAP_MIDDLE_BUTTON(c) ((c) & BIT(18))
|
||||
#define SYN_CAP_PASS_THROUGH(c) ((c) & BIT(7))
|
||||
#define SYN_CAP_SLEEP(c) ((c) & BIT(4))
|
||||
#define SYN_CAP_FOUR_BUTTON(c) ((c) & BIT(3))
|
||||
#define SYN_CAP_MULTIFINGER(c) ((c) & BIT(1))
|
||||
#define SYN_CAP_PALMDETECT(c) ((c) & BIT(0))
|
||||
#define SYN_CAP_SUBMODEL_ID(c) (((c) & GENMASK(15, 8)) >> 8)
|
||||
#define SYN_EXT_CAP_REQUESTS(c) (((c) & GENMASK(22, 20)) >> 20)
|
||||
#define SYN_CAP_MB_MASK GENMASK(15, 12)
|
||||
#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & SYN_CAP_MB_MASK) >> 12)
|
||||
#define SYN_CAP_PRODUCT_ID(ec) (((ec) & GENMASK(23, 16)) >> 16)
|
||||
#define SYN_MEXT_CAP_BIT(m) ((m) & BIT(1))
|
||||
|
||||
/*
|
||||
* The following describes response for the 0x0c query.
|
||||
|
@ -83,13 +84,14 @@
|
|||
* hinged at the top.
|
||||
* 2 0x20 report min query 0x0f gives min coord reported
|
||||
*/
|
||||
#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */
|
||||
#define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */
|
||||
#define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000)
|
||||
#define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000)
|
||||
#define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000)
|
||||
#define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400)
|
||||
#define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800)
|
||||
#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & BIT(20)) /* 1-button ClickPad */
|
||||
#define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & BIT(8)) /* 2-button ClickPad */
|
||||
#define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & BIT(17))
|
||||
#define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & BIT(13))
|
||||
#define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & BIT(19))
|
||||
#define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & BIT(10))
|
||||
#define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & BIT(11))
|
||||
#define SYN_CAP_INTERTOUCH(ex0c) ((ex0c) & BIT(14))
|
||||
|
||||
/*
|
||||
* The following descibes response for the 0x10 query.
|
||||
|
@ -108,42 +110,44 @@
|
|||
* 3 0xff SecurePad height the height of the SecurePad fingerprint
|
||||
* reader.
|
||||
*/
|
||||
#define SYN_CAP_EXT_BUTTONS_STICK(ex10) ((ex10) & 0x010000)
|
||||
#define SYN_CAP_SECUREPAD(ex10) ((ex10) & 0x020000)
|
||||
#define SYN_CAP_EXT_BUTTONS_STICK(ex10) ((ex10) & BIT(16))
|
||||
#define SYN_CAP_SECUREPAD(ex10) ((ex10) & BIT(17))
|
||||
|
||||
#define SYN_CAP_EXT_BUTTON_STICK_L(eb) (!!((eb) & 0x01))
|
||||
#define SYN_CAP_EXT_BUTTON_STICK_M(eb) (!!((eb) & 0x02))
|
||||
#define SYN_CAP_EXT_BUTTON_STICK_R(eb) (!!((eb) & 0x04))
|
||||
#define SYN_EXT_BUTTON_STICK_L(eb) (((eb) & BIT(0)) >> 0)
|
||||
#define SYN_EXT_BUTTON_STICK_M(eb) (((eb) & BIT(1)) >> 1)
|
||||
#define SYN_EXT_BUTTON_STICK_R(eb) (((eb) & BIT(2)) >> 2)
|
||||
|
||||
/* synaptics modes query bits */
|
||||
#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
|
||||
#define SYN_MODE_RATE(m) ((m) & (1 << 6))
|
||||
#define SYN_MODE_BAUD_SLEEP(m) ((m) & (1 << 3))
|
||||
#define SYN_MODE_DISABLE_GESTURE(m) ((m) & (1 << 2))
|
||||
#define SYN_MODE_PACKSIZE(m) ((m) & (1 << 1))
|
||||
#define SYN_MODE_WMODE(m) ((m) & (1 << 0))
|
||||
#define SYN_MODE_ABSOLUTE(m) ((m) & BIT(7))
|
||||
#define SYN_MODE_RATE(m) ((m) & BIT(6))
|
||||
#define SYN_MODE_BAUD_SLEEP(m) ((m) & BIT(3))
|
||||
#define SYN_MODE_DISABLE_GESTURE(m) ((m) & BIT(2))
|
||||
#define SYN_MODE_PACKSIZE(m) ((m) & BIT(1))
|
||||
#define SYN_MODE_WMODE(m) ((m) & BIT(0))
|
||||
|
||||
/* synaptics identify query bits */
|
||||
#define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f)
|
||||
#define SYN_ID_MAJOR(i) ((i) & 0x0f)
|
||||
#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff)
|
||||
#define SYN_ID_MODEL(i) (((i) & GENMASK(7, 4)) >> 4)
|
||||
#define SYN_ID_MAJOR(i) (((i) & GENMASK(3, 0)) >> 0)
|
||||
#define SYN_ID_MINOR(i) (((i) & GENMASK(23, 16)) >> 16)
|
||||
#define SYN_ID_FULL(i) ((SYN_ID_MAJOR(i) << 8) | SYN_ID_MINOR(i))
|
||||
#define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47)
|
||||
#define SYN_ID_IS_SYNAPTICS(i) (((i) & GENMASK(15, 8)) == 0x004700U)
|
||||
#define SYN_ID_DISGEST_SUPPORTED(i) (SYN_ID_MAJOR(i) >= 4)
|
||||
|
||||
/* synaptics special commands */
|
||||
#define SYN_PS_SET_MODE2 0x14
|
||||
#define SYN_PS_CLIENT_CMD 0x28
|
||||
|
||||
/* synaptics packet types */
|
||||
#define SYN_NEWABS 0
|
||||
#define SYN_NEWABS_STRICT 1
|
||||
#define SYN_NEWABS_RELAXED 2
|
||||
#define SYN_OLDABS 3
|
||||
|
||||
/* amount to fuzz position data when touchpad reports reduced filtering */
|
||||
#define SYN_REDUCED_FILTER_FUZZ 8
|
||||
|
||||
/* synaptics packet types */
|
||||
enum synaptics_pkt_type {
|
||||
SYN_NEWABS,
|
||||
SYN_NEWABS_STRICT,
|
||||
SYN_NEWABS_RELAXED,
|
||||
SYN_OLDABS,
|
||||
};
|
||||
|
||||
/*
|
||||
* A structure to describe the state of the touchpad hardware (buttons and pad)
|
||||
*/
|
||||
|
@ -157,26 +161,30 @@ struct synaptics_hw_state {
|
|||
unsigned int middle:1;
|
||||
unsigned int up:1;
|
||||
unsigned int down:1;
|
||||
unsigned char ext_buttons;
|
||||
signed char scroll;
|
||||
u8 ext_buttons;
|
||||
s8 scroll;
|
||||
};
|
||||
|
||||
/* Data read from the touchpad */
|
||||
struct synaptics_device_info {
|
||||
u32 model_id; /* Model-ID */
|
||||
u32 firmware_id; /* Firmware-ID */
|
||||
u32 board_id; /* Board-ID */
|
||||
u32 capabilities; /* Capabilities */
|
||||
u32 ext_cap; /* Extended Capabilities */
|
||||
u32 ext_cap_0c; /* Ext Caps from 0x0c query */
|
||||
u32 ext_cap_10; /* Ext Caps from 0x10 query */
|
||||
u32 identity; /* Identification */
|
||||
u32 x_res, y_res; /* X/Y resolution in units/mm */
|
||||
u32 x_max, y_max; /* Max coordinates (from FW) */
|
||||
u32 x_min, y_min; /* Min coordinates (from FW) */
|
||||
};
|
||||
|
||||
struct synaptics_data {
|
||||
/* Data read from the touchpad */
|
||||
unsigned long int model_id; /* Model-ID */
|
||||
unsigned long int firmware_id; /* Firmware-ID */
|
||||
unsigned long int board_id; /* Board-ID */
|
||||
unsigned long int capabilities; /* Capabilities */
|
||||
unsigned long int ext_cap; /* Extended Capabilities */
|
||||
unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */
|
||||
unsigned long int ext_cap_10; /* Ext Caps from 0x10 query */
|
||||
unsigned long int identity; /* Identification */
|
||||
unsigned int x_res, y_res; /* X/Y resolution in units/mm */
|
||||
unsigned int x_max, y_max; /* Max coordinates (from FW) */
|
||||
unsigned int x_min, y_min; /* Min coordinates (from FW) */
|
||||
struct synaptics_device_info info;
|
||||
|
||||
unsigned char pkt_type; /* packet type - old, new, etc */
|
||||
unsigned char mode; /* current mode byte */
|
||||
enum synaptics_pkt_type pkt_type; /* packet type - old, new, etc */
|
||||
u8 mode; /* current mode byte */
|
||||
int scroll;
|
||||
|
||||
bool absolute_mode; /* run in Absolute mode */
|
||||
|
@ -200,8 +208,10 @@ struct synaptics_data {
|
|||
|
||||
void synaptics_module_init(void);
|
||||
int synaptics_detect(struct psmouse *psmouse, bool set_properties);
|
||||
int synaptics_init(struct psmouse *psmouse);
|
||||
int synaptics_init_absolute(struct psmouse *psmouse);
|
||||
int synaptics_init_relative(struct psmouse *psmouse);
|
||||
int synaptics_init_smbus(struct psmouse *psmouse);
|
||||
int synaptics_init(struct psmouse *psmouse);
|
||||
void synaptics_reset(struct psmouse *psmouse);
|
||||
|
||||
#endif /* _SYNAPTICS_H */
|
||||
|
|
|
@ -652,9 +652,18 @@ static const struct i2c_device_id synaptics_i2c_id_table[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(i2c, synaptics_i2c_id_table);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id synaptics_i2c_of_match[] = {
|
||||
{ .compatible = "synaptics,synaptics_i2c", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, synaptics_i2c_of_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver synaptics_i2c_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = of_match_ptr(synaptics_i2c_of_match),
|
||||
.pm = &synaptics_i2c_pm,
|
||||
},
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ static int rmi_irq_init(struct rmi_device *rmi_dev)
|
|||
|
||||
ret = devm_request_threaded_irq(&rmi_dev->dev, pdata->irq, NULL,
|
||||
rmi_irq_fn, irq_flags | IRQF_ONESHOT,
|
||||
dev_name(rmi_dev->xport->dev),
|
||||
dev_driver_string(rmi_dev->xport->dev),
|
||||
rmi_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&rmi_dev->dev, "Failed to register interrupt %d\n",
|
||||
|
@ -1234,16 +1234,21 @@ static int rmi_driver_probe(struct device *dev)
|
|||
if (retval < 0)
|
||||
goto err_destroy_functions;
|
||||
|
||||
if (data->f01_container->dev.driver)
|
||||
if (data->f01_container->dev.driver) {
|
||||
/* Driver already bound, so enable ATTN now. */
|
||||
return rmi_enable_sensor(rmi_dev);
|
||||
retval = rmi_enable_sensor(rmi_dev);
|
||||
if (retval)
|
||||
goto err_disable_irq;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_irq:
|
||||
rmi_disable_irq(rmi_dev, false);
|
||||
err_destroy_functions:
|
||||
rmi_free_function_list(rmi_dev);
|
||||
err:
|
||||
return retval < 0 ? retval : 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct rmi_driver rmi_physical_driver = {
|
||||
|
|
|
@ -113,20 +113,16 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
|
|||
}
|
||||
|
||||
if (rmi_register_desc_has_subpacket(item, 2)) {
|
||||
sensor->axis_align.clip_x_low = buf[offset];
|
||||
sensor->axis_align.clip_x_high = sensor->max_x
|
||||
- buf[offset + 1];
|
||||
sensor->axis_align.clip_y_low = buf[offset + 2];
|
||||
sensor->axis_align.clip_y_high = sensor->max_y
|
||||
- buf[offset + 3];
|
||||
/* Units 1/128 sensor pitch */
|
||||
rmi_dbg(RMI_DEBUG_FN, &fn->dev,
|
||||
"%s: Inactive Border xlo:%d xhi:%d ylo:%d yhi:%d\n",
|
||||
__func__,
|
||||
buf[offset], buf[offset + 1],
|
||||
buf[offset + 2], buf[offset + 3]);
|
||||
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: x low: %d x high: %d y low: %d y high: %d\n",
|
||||
__func__,
|
||||
sensor->axis_align.clip_x_low, sensor->axis_align.clip_x_high,
|
||||
sensor->axis_align.clip_y_low, sensor->axis_align.clip_y_high);
|
||||
|
||||
if (rmi_register_desc_has_subpacket(item, 3)) {
|
||||
rx_receivers = buf[offset];
|
||||
tx_receivers = buf[offset + 1];
|
||||
|
|
|
@ -105,16 +105,27 @@ static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits)
|
|||
{
|
||||
struct f34_data *f34 = dev_get_drvdata(&fn->dev);
|
||||
int ret;
|
||||
u8 status;
|
||||
|
||||
if (f34->bl_version != 5)
|
||||
return 0;
|
||||
if (f34->bl_version == 5) {
|
||||
ret = rmi_read(f34->fn->rmi_dev, f34->v5.ctrl_address,
|
||||
&status);
|
||||
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: status: %#02x, ret: %d\n",
|
||||
__func__, status, ret);
|
||||
|
||||
ret = rmi_read(f34->fn->rmi_dev, f34->v5.ctrl_address, &f34->v5.status);
|
||||
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: status: %#02x, ret: %d\n",
|
||||
__func__, f34->v5.status, ret);
|
||||
if (!ret && !(status & 0x7f))
|
||||
complete(&f34->v5.cmd_done);
|
||||
} else {
|
||||
ret = rmi_read_block(f34->fn->rmi_dev,
|
||||
f34->fn->fd.data_base_addr +
|
||||
f34->v7.off.flash_status,
|
||||
&status, sizeof(status));
|
||||
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s: status: %#02x, ret: %d\n",
|
||||
__func__, status, ret);
|
||||
|
||||
if (!ret && !(f34->v5.status & 0x7f))
|
||||
complete(&f34->v5.cmd_done);
|
||||
if (!ret && !(status & 0x1f))
|
||||
complete(&f34->v7.cmd_done);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define F34_IDLE_WAIT_MS 500
|
||||
#define F34_ENABLE_WAIT_MS 300
|
||||
#define F34_ERASE_WAIT_MS 5000
|
||||
#define F34_WRITE_WAIT_MS 3000
|
||||
|
||||
#define F34_BOOTLOADER_ID_LEN 2
|
||||
|
||||
|
@ -47,11 +48,6 @@
|
|||
#define CONFIG_ID_SIZE 32
|
||||
#define PRODUCT_ID_SIZE 10
|
||||
|
||||
#define ENABLE_WAIT_MS (1 * 1000)
|
||||
#define WRITE_WAIT_MS (3 * 1000)
|
||||
|
||||
#define MIN_SLEEP_TIME_US 50
|
||||
#define MAX_SLEEP_TIME_US 100
|
||||
|
||||
#define HAS_BSR BIT(5)
|
||||
#define HAS_CONFIG_ID BIT(3)
|
||||
|
@ -292,6 +288,7 @@ struct f34v7_data {
|
|||
|
||||
const void *config_data;
|
||||
const void *image;
|
||||
struct completion cmd_done;
|
||||
};
|
||||
|
||||
struct f34_data {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <asm/unaligned.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include "rmi_driver.h"
|
||||
#include "rmi_f34.h"
|
||||
|
@ -31,7 +32,7 @@ static int rmi_f34v7_read_flash_status(struct f34_data *f34)
|
|||
sizeof(status));
|
||||
if (ret < 0) {
|
||||
rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
|
||||
"%s: Failed to read flash status\n", __func__);
|
||||
"%s: Error %d reading flash status\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -60,28 +61,17 @@ static int rmi_f34v7_read_flash_status(struct f34_data *f34)
|
|||
|
||||
static int rmi_f34v7_wait_for_idle(struct f34_data *f34, int timeout_ms)
|
||||
{
|
||||
int count = 0;
|
||||
int timeout_count = ((timeout_ms * 1000) / MAX_SLEEP_TIME_US) + 1;
|
||||
unsigned long timeout;
|
||||
|
||||
do {
|
||||
usleep_range(MIN_SLEEP_TIME_US, MAX_SLEEP_TIME_US);
|
||||
timeout = msecs_to_jiffies(timeout_ms);
|
||||
|
||||
count++;
|
||||
if (!wait_for_completion_timeout(&f34->v7.cmd_done, timeout)) {
|
||||
dev_warn(&f34->fn->dev, "%s: Timed out waiting for idle status\n",
|
||||
__func__);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
rmi_f34v7_read_flash_status(f34);
|
||||
|
||||
if ((f34->v7.command == v7_CMD_IDLE)
|
||||
&& (f34->v7.flash_status == 0x00)) {
|
||||
rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
|
||||
"Idle status detected\n");
|
||||
return 0;
|
||||
}
|
||||
} while (count < timeout_count);
|
||||
|
||||
dev_err(&f34->fn->dev,
|
||||
"%s: Timed out waiting for idle status\n", __func__);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rmi_f34v7_write_command_single_transaction(struct f34_data *f34,
|
||||
|
@ -285,9 +275,10 @@ static int rmi_f34v7_write_partition_id(struct f34_data *f34, u8 cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rmi_f34v7_read_f34v7_partition_table(struct f34_data *f34)
|
||||
static int rmi_f34v7_read_partition_table(struct f34_data *f34)
|
||||
{
|
||||
int ret;
|
||||
unsigned long timeout;
|
||||
u8 base;
|
||||
__le16 length;
|
||||
u16 block_number = 0;
|
||||
|
@ -320,6 +311,8 @@ static int rmi_f34v7_read_f34v7_partition_table(struct f34_data *f34)
|
|||
return ret;
|
||||
}
|
||||
|
||||
init_completion(&f34->v7.cmd_done);
|
||||
|
||||
ret = rmi_f34v7_write_command(f34, v7_CMD_READ_CONFIG);
|
||||
if (ret < 0) {
|
||||
dev_err(&f34->fn->dev, "%s: Failed to write command\n",
|
||||
|
@ -327,11 +320,15 @@ static int rmi_f34v7_read_f34v7_partition_table(struct f34_data *f34)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = rmi_f34v7_wait_for_idle(f34, WRITE_WAIT_MS);
|
||||
if (ret < 0) {
|
||||
dev_err(&f34->fn->dev, "%s: Failed to wait for idle status\n",
|
||||
__func__);
|
||||
return ret;
|
||||
timeout = msecs_to_jiffies(F34_WRITE_WAIT_MS);
|
||||
while (time_before(jiffies, timeout)) {
|
||||
usleep_range(5000, 6000);
|
||||
rmi_f34v7_read_flash_status(f34);
|
||||
|
||||
if (f34->v7.command == v7_CMD_IDLE &&
|
||||
f34->v7.flash_status == 0x00) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = rmi_read_block(f34->fn->rmi_dev,
|
||||
|
@ -570,7 +567,7 @@ static int rmi_f34v7_read_queries(struct f34_data *f34)
|
|||
f34->v7.read_config_buf_size = f34->v7.partition_table_bytes;
|
||||
ptable = f34->v7.read_config_buf;
|
||||
|
||||
ret = rmi_f34v7_read_f34v7_partition_table(f34);
|
||||
ret = rmi_f34v7_read_partition_table(f34);
|
||||
if (ret < 0) {
|
||||
dev_err(&f34->fn->dev, "%s: Failed to read partition table\n",
|
||||
__func__);
|
||||
|
@ -666,6 +663,8 @@ static int rmi_f34v7_erase_config(struct f34_data *f34)
|
|||
|
||||
dev_info(&f34->fn->dev, "Erasing config...\n");
|
||||
|
||||
init_completion(&f34->v7.cmd_done);
|
||||
|
||||
switch (f34->v7.config_area) {
|
||||
case v7_UI_CONFIG_AREA:
|
||||
ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_CONFIG);
|
||||
|
@ -684,11 +683,11 @@ static int rmi_f34v7_erase_config(struct f34_data *f34)
|
|||
break;
|
||||
}
|
||||
|
||||
ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
|
||||
ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rmi_f34v7_erase_guest_code(struct f34_data *f34)
|
||||
|
@ -697,11 +696,13 @@ static int rmi_f34v7_erase_guest_code(struct f34_data *f34)
|
|||
|
||||
dev_info(&f34->fn->dev, "Erasing guest code...\n");
|
||||
|
||||
init_completion(&f34->v7.cmd_done);
|
||||
|
||||
ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_GUEST_CODE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
|
||||
ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -714,11 +715,13 @@ static int rmi_f34v7_erase_all(struct f34_data *f34)
|
|||
|
||||
dev_info(&f34->fn->dev, "Erasing firmware...\n");
|
||||
|
||||
init_completion(&f34->v7.cmd_done);
|
||||
|
||||
ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_FIRMWARE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
|
||||
ret = rmi_f34v7_wait_for_idle(f34, F34_ERASE_WAIT_MS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -743,8 +746,8 @@ static int rmi_f34v7_erase_all(struct f34_data *f34)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rmi_f34v7_read_f34v7_blocks(struct f34_data *f34, u16 block_cnt,
|
||||
u8 command)
|
||||
static int rmi_f34v7_read_blocks(struct f34_data *f34,
|
||||
u16 block_cnt, u8 command)
|
||||
{
|
||||
int ret;
|
||||
u8 base;
|
||||
|
@ -787,17 +790,15 @@ static int rmi_f34v7_read_f34v7_blocks(struct f34_data *f34, u16 block_cnt,
|
|||
return ret;
|
||||
}
|
||||
|
||||
init_completion(&f34->v7.cmd_done);
|
||||
|
||||
ret = rmi_f34v7_write_command(f34, command);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
|
||||
if (ret < 0) {
|
||||
dev_err(&f34->fn->dev,
|
||||
"%s: Wait for idle failed (%d blks remaining)\n",
|
||||
__func__, remaining);
|
||||
ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rmi_read_block(f34->fn->rmi_dev,
|
||||
base + f34->v7.off.payload,
|
||||
|
@ -853,6 +854,8 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
|
|||
transfer = min(remaining, max_transfer);
|
||||
put_unaligned_le16(transfer, &length);
|
||||
|
||||
init_completion(&f34->v7.cmd_done);
|
||||
|
||||
ret = rmi_write_block(f34->fn->rmi_dev,
|
||||
base + f34->v7.off.transfer_length,
|
||||
&length, sizeof(length));
|
||||
|
@ -877,13 +880,9 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
|
||||
if (ret < 0) {
|
||||
dev_err(&f34->fn->dev,
|
||||
"%s: Failed wait for idle (%d blks remaining)\n",
|
||||
__func__, remaining);
|
||||
ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
block_ptr += (transfer * f34->v7.block_size);
|
||||
remaining -= transfer;
|
||||
|
@ -945,6 +944,8 @@ static int rmi_f34v7_write_flash_config(struct f34_data *f34)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
init_completion(&f34->v7.cmd_done);
|
||||
|
||||
ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_FLASH_CONFIG);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -952,7 +953,7 @@ static int rmi_f34v7_write_flash_config(struct f34_data *f34)
|
|||
rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
|
||||
"%s: Erase flash config command written\n", __func__);
|
||||
|
||||
ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
|
||||
ret = rmi_f34v7_wait_for_idle(f34, F34_WRITE_WAIT_MS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -981,7 +982,7 @@ static int rmi_f34v7_write_partition_table(struct f34_data *f34)
|
|||
|
||||
f34->v7.read_config_buf_size = f34->v7.config_size;
|
||||
|
||||
ret = rmi_f34v7_read_f34v7_blocks(f34, block_count, v7_CMD_READ_CONFIG);
|
||||
ret = rmi_f34v7_read_blocks(f34, block_count, v7_CMD_READ_CONFIG);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -1287,6 +1288,8 @@ static int rmi_f34v7_enter_flash_prog(struct f34_data *f34)
|
|||
{
|
||||
int ret;
|
||||
|
||||
f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev, f34->fn->irq_mask);
|
||||
|
||||
ret = rmi_f34v7_read_flash_status(f34);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -1294,19 +1297,16 @@ static int rmi_f34v7_enter_flash_prog(struct f34_data *f34)
|
|||
if (f34->v7.in_bl_mode)
|
||||
return 0;
|
||||
|
||||
init_completion(&f34->v7.cmd_done);
|
||||
|
||||
ret = rmi_f34v7_write_command(f34, v7_CMD_ENABLE_FLASH_PROG);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
|
||||
ret = rmi_f34v7_wait_for_idle(f34, F34_ENABLE_WAIT_MS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!f34->v7.in_bl_mode) {
|
||||
dev_err(&f34->fn->dev, "%s: BL mode not entered\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1314,6 +1314,8 @@ int rmi_f34v7_start_reflash(struct f34_data *f34, const struct firmware *fw)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev, f34->fn->irq_mask);
|
||||
|
||||
f34->v7.config_area = v7_UI_CONFIG_AREA;
|
||||
f34->v7.image = fw->data;
|
||||
|
||||
|
@ -1376,8 +1378,13 @@ int rmi_f34v7_probe(struct f34_data *f34)
|
|||
|
||||
memset(&f34->v7.blkcount, 0x00, sizeof(f34->v7.blkcount));
|
||||
memset(&f34->v7.phyaddr, 0x00, sizeof(f34->v7.phyaddr));
|
||||
rmi_f34v7_read_queries(f34);
|
||||
|
||||
f34->v7.force_update = false;
|
||||
init_completion(&f34->v7.cmd_done);
|
||||
|
||||
ret = rmi_f34v7_read_queries(f34);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
f34->v7.force_update = true;
|
||||
return 0;
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче