Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
e76b0d3f
Commit
e76b0d3f
authored
Jun 14, 2003
by
Peter Osterlund
Committed by
Vojtech Pavlik
Jun 14, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
input: Add Synaptics touchpad absolute mode support.
parent
f739babf
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
584 additions
and
49 deletions
+584
-49
drivers/input/mouse/Kconfig
drivers/input/mouse/Kconfig
+13
-0
drivers/input/mouse/Makefile
drivers/input/mouse/Makefile
+5
-0
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse-base.c
+21
-49
drivers/input/mouse/psmouse.h
drivers/input/mouse/psmouse.h
+49
-0
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.c
+390
-0
drivers/input/mouse/synaptics.h
drivers/input/mouse/synaptics.h
+105
-0
include/linux/input.h
include/linux/input.h
+1
-0
No files found.
drivers/input/mouse/Kconfig
View file @
e76b0d3f
...
@@ -28,6 +28,19 @@ config MOUSE_PS2
...
@@ -28,6 +28,19 @@ config MOUSE_PS2
The module will be called psmouse. If you want to compile it as a
The module will be called psmouse. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
module, say M here and read <file:Documentation/modules.txt>.
config MOUSE_PS2_SYNAPTICS
bool "Synaptics TouchPad"
default n
depends on INPUT && INPUT_MOUSE && SERIO && MOUSE_PS2
---help---
Say Y here if you have a Synaptics TouchPad connected to your system.
This touchpad is found on many modern laptop computers.
Note that you also need a user space driver to interpret the data
generated by the kernel. A compatible driver for XFree86 is available
from http://...
If unsure, say Y.
config MOUSE_SERIAL
config MOUSE_SERIAL
tristate "Serial mouse"
tristate "Serial mouse"
depends on INPUT && INPUT_MOUSE && SERIO
depends on INPUT && INPUT_MOUSE && SERIO
...
...
drivers/input/mouse/Makefile
View file @
e76b0d3f
...
@@ -13,3 +13,8 @@ obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o
...
@@ -13,3 +13,8 @@ obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o
obj-$(CONFIG_MOUSE_PC9800)
+=
98busmouse.o
obj-$(CONFIG_MOUSE_PC9800)
+=
98busmouse.o
obj-$(CONFIG_MOUSE_PS2)
+=
psmouse.o
obj-$(CONFIG_MOUSE_PS2)
+=
psmouse.o
obj-$(CONFIG_MOUSE_SERIAL)
+=
sermouse.o
obj-$(CONFIG_MOUSE_SERIAL)
+=
sermouse.o
psmouse-objs
:=
psmouse-base.o
ifeq
($(CONFIG_MOUSE_PS2_SYNAPTICS),y)
psmouse-objs
+=
synaptics.o
endif
drivers/input/mouse/psmouse.c
→
drivers/input/mouse/psmouse
-base
.c
View file @
e76b0d3f
...
@@ -17,6 +17,8 @@
...
@@ -17,6 +17,8 @@
#include <linux/input.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/serio.h>
#include <linux/init.h>
#include <linux/init.h>
#include "psmouse.h"
#include "synaptics.h"
MODULE_AUTHOR
(
"Vojtech Pavlik <vojtech@suse.cz>"
);
MODULE_AUTHOR
(
"Vojtech Pavlik <vojtech@suse.cz>"
);
MODULE_DESCRIPTION
(
"PS/2 mouse driver"
);
MODULE_DESCRIPTION
(
"PS/2 mouse driver"
);
...
@@ -25,48 +27,7 @@ MODULE_LICENSE("GPL");
...
@@ -25,48 +27,7 @@ MODULE_LICENSE("GPL");
static
int
psmouse_noext
;
static
int
psmouse_noext
;
#define PSMOUSE_CMD_SETSCALE11 0x00e6
static
char
*
psmouse_protocols
[]
=
{
"None"
,
"PS/2"
,
"PS2++"
,
"PS2T++"
,
"GenPS/2"
,
"ImPS/2"
,
"ImExPS/2"
,
"Synaptics"
};
#define PSMOUSE_CMD_SETRES 0x10e8
#define PSMOUSE_CMD_GETINFO 0x03e9
#define PSMOUSE_CMD_SETSTREAM 0x00ea
#define PSMOUSE_CMD_POLL 0x03eb
#define PSMOUSE_CMD_GETID 0x02f2
#define PSMOUSE_CMD_SETRATE 0x10f3
#define PSMOUSE_CMD_ENABLE 0x00f4
#define PSMOUSE_CMD_RESET_DIS 0x00f6
#define PSMOUSE_CMD_RESET_BAT 0x02ff
#define PSMOUSE_RET_BAT 0xaa
#define PSMOUSE_RET_ACK 0xfa
#define PSMOUSE_RET_NAK 0xfe
struct
psmouse
{
struct
input_dev
dev
;
struct
serio
*
serio
;
char
*
vendor
;
char
*
name
;
unsigned
char
cmdbuf
[
8
];
unsigned
char
packet
[
8
];
unsigned
char
cmdcnt
;
unsigned
char
pktcnt
;
unsigned
char
type
;
unsigned
char
model
;
unsigned
long
last
;
char
acking
;
volatile
char
ack
;
char
error
;
char
devname
[
64
];
char
phys
[
32
];
};
#define PSMOUSE_PS2 1
#define PSMOUSE_PS2PP 2
#define PSMOUSE_PS2TPP 3
#define PSMOUSE_GENPS 4
#define PSMOUSE_IMPS 5
#define PSMOUSE_IMEX 6
static
char
*
psmouse_protocols
[]
=
{
"None"
,
"PS/2"
,
"PS2++"
,
"PS2T++"
,
"GenPS/2"
,
"ImPS/2"
,
"ImExPS/2"
};
/*
/*
* psmouse_process_packet() anlyzes the PS/2 mouse packet contents and
* psmouse_process_packet() anlyzes the PS/2 mouse packet contents and
...
@@ -209,6 +170,16 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
...
@@ -209,6 +170,16 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
goto
out
;
goto
out
;
}
}
if
(
psmouse
->
pktcnt
==
1
&&
psmouse
->
type
==
PSMOUSE_SYNAPTICS
)
{
/*
* The synaptics driver has its own resync logic,
* so it needs to receive all bytes one at a time.
*/
synaptics_process_byte
(
psmouse
,
regs
);
psmouse
->
pktcnt
=
0
;
goto
out
;
}
if
(
psmouse
->
pktcnt
==
1
&&
psmouse
->
packet
[
0
]
==
PSMOUSE_RET_BAT
)
{
if
(
psmouse
->
pktcnt
==
1
&&
psmouse
->
packet
[
0
]
==
PSMOUSE_RET_BAT
)
{
serio_rescan
(
serio
);
serio_rescan
(
serio
);
goto
out
;
goto
out
;
...
@@ -244,7 +215,7 @@ static int psmouse_sendbyte(struct psmouse *psmouse, unsigned char byte)
...
@@ -244,7 +215,7 @@ static int psmouse_sendbyte(struct psmouse *psmouse, unsigned char byte)
* then waits for the response and puts it in the param array.
* then waits for the response and puts it in the param array.
*/
*/
static
int
psmouse_command
(
struct
psmouse
*
psmouse
,
unsigned
char
*
param
,
int
command
)
int
psmouse_command
(
struct
psmouse
*
psmouse
,
unsigned
char
*
param
,
int
command
)
{
{
int
timeout
=
500000
;
/* 500 msec */
int
timeout
=
500000
;
/* 500 msec */
int
send
=
(
command
>>
12
)
&
0xf
;
int
send
=
(
command
>>
12
)
&
0xf
;
...
@@ -343,12 +314,12 @@ static int psmouse_extensions(struct psmouse *psmouse)
...
@@ -343,12 +314,12 @@ static int psmouse_extensions(struct psmouse *psmouse)
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETINFO
);
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETINFO
);
if
(
param
[
1
]
==
0x47
)
{
if
(
param
[
1
]
==
0x47
)
{
/* We could do more here. But it's sufficient just
psmouse
->
vendor
=
"Synaptics"
;
to stop the subsequent probes from screwing the
psmouse
->
name
=
"TouchPad"
;
thing up. */
if
(
!
synaptics_init
(
psmouse
))
psmouse
->
vendor
=
"Synaptics"
;
return
PSMOUSE_SYNAPTICS
;
psmouse
->
name
=
"TouchPad"
;
else
return
PSMOUSE_PS2
;
return
PSMOUSE_PS2
;
}
}
/*
/*
...
@@ -598,6 +569,7 @@ static void psmouse_disconnect(struct serio *serio)
...
@@ -598,6 +569,7 @@ static void psmouse_disconnect(struct serio *serio)
struct
psmouse
*
psmouse
=
serio
->
private
;
struct
psmouse
*
psmouse
=
serio
->
private
;
input_unregister_device
(
&
psmouse
->
dev
);
input_unregister_device
(
&
psmouse
->
dev
);
serio_close
(
serio
);
serio_close
(
serio
);
synaptics_disconnect
(
psmouse
);
kfree
(
psmouse
);
kfree
(
psmouse
);
}
}
...
...
drivers/input/mouse/psmouse.h
0 → 100644
View file @
e76b0d3f
#ifndef _PSMOUSE_H
#define _PSMOUSE_H
#define PSMOUSE_CMD_SETSCALE11 0x00e6
#define PSMOUSE_CMD_SETRES 0x10e8
#define PSMOUSE_CMD_GETINFO 0x03e9
#define PSMOUSE_CMD_SETSTREAM 0x00ea
#define PSMOUSE_CMD_POLL 0x03eb
#define PSMOUSE_CMD_GETID 0x02f2
#define PSMOUSE_CMD_SETRATE 0x10f3
#define PSMOUSE_CMD_ENABLE 0x00f4
#define PSMOUSE_CMD_RESET_DIS 0x00f6
#define PSMOUSE_CMD_RESET_BAT 0x02ff
#define PSMOUSE_RET_BAT 0xaa
#define PSMOUSE_RET_ACK 0xfa
#define PSMOUSE_RET_NAK 0xfe
struct
psmouse
{
void
*
private
;
struct
input_dev
dev
;
struct
serio
*
serio
;
char
*
vendor
;
char
*
name
;
unsigned
char
cmdbuf
[
8
];
unsigned
char
packet
[
8
];
unsigned
char
cmdcnt
;
unsigned
char
pktcnt
;
unsigned
char
type
;
unsigned
char
model
;
unsigned
long
last
;
char
acking
;
volatile
char
ack
;
char
error
;
char
devname
[
64
];
char
phys
[
32
];
};
#define PSMOUSE_PS2 1
#define PSMOUSE_PS2PP 2
#define PSMOUSE_PS2TPP 3
#define PSMOUSE_GENPS 4
#define PSMOUSE_IMPS 5
#define PSMOUSE_IMEX 6
#define PSMOUSE_SYNAPTICS 7
int
psmouse_command
(
struct
psmouse
*
psmouse
,
unsigned
char
*
param
,
int
command
);
#endif
/* _PSMOUSE_H */
drivers/input/mouse/synaptics.c
0 → 100644
View file @
e76b0d3f
/*
* Synaptics TouchPad PS/2 mouse driver
*
* 2003 Peter Osterlund <petero2@telia.com>
* Ported to 2.5 input device infrastructure.
*
* Copyright (C) 2001 Stefan Gmeiner <riddlebox@freesurf.ch>
* start merging tpconfig and gpm code to a xfree-input module
* adding some changes and extensions (ex. 3rd and 4th button)
*
* Copyright (c) 1997 C. Scott Ananian <cananian@alumni.priceton.edu>
* Copyright (c) 1998-2000 Bruce Kalk <kall@compass.com>
* code for the special synaptics commands (from the tpconfig-source)
*
* 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.
*
* Trademarks are the property of their respective owners.
*/
#include <linux/module.h>
#include <linux/input.h>
#include "psmouse.h"
#include "synaptics.h"
/*****************************************************************************
* Synaptics communications functions
****************************************************************************/
/*
* Use the Synaptics extended ps/2 syntax to write a special command byte.
* special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
* is the command. A 0xF3 or 0xE9 must follow (see synaptics_send_cmd
* and synaptics_set_mode)
*/
static
int
synaptics_special_cmd
(
struct
psmouse
*
psmouse
,
unsigned
char
command
)
{
int
i
;
if
(
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_SETSCALE11
))
return
-
1
;
for
(
i
=
6
;
i
>=
0
;
i
-=
2
)
{
unsigned
char
d
=
(
command
>>
i
)
&
3
;
if
(
psmouse_command
(
psmouse
,
&
d
,
PSMOUSE_CMD_SETRES
))
return
-
1
;
}
return
0
;
}
/*
* Send a command to the synpatics touchpad by special commands
*/
static
int
synaptics_send_cmd
(
struct
psmouse
*
psmouse
,
unsigned
char
c
,
unsigned
char
*
param
)
{
if
(
synaptics_special_cmd
(
psmouse
,
c
))
return
-
1
;
if
(
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_GETINFO
))
return
-
1
;
return
0
;
}
/*
* Set the synaptics touchpad mode byte by special commands
*/
static
int
synaptics_set_mode
(
struct
psmouse
*
psmouse
,
unsigned
char
mode
)
{
unsigned
char
param
[
1
];
if
(
synaptics_special_cmd
(
psmouse
,
mode
))
return
-
1
;
param
[
0
]
=
0x14
;
if
(
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
))
return
-
1
;
return
0
;
}
static
int
synaptics_reset
(
struct
psmouse
*
psmouse
)
{
unsigned
char
r
[
2
];
if
(
psmouse_command
(
psmouse
,
r
,
PSMOUSE_CMD_RESET_BAT
))
return
-
1
;
if
(
r
[
0
]
==
0xAA
&&
r
[
1
]
==
0x00
)
return
0
;
return
-
1
;
}
/*
* Read the model-id bytes from the touchpad
* see also SYN_MODEL_* macros
*/
static
int
synaptics_model_id
(
struct
psmouse
*
psmouse
,
unsigned
long
int
*
model_id
)
{
unsigned
char
mi
[
3
];
if
(
synaptics_send_cmd
(
psmouse
,
SYN_QUE_MODEL
,
mi
))
return
-
1
;
*
model_id
=
(
mi
[
0
]
<<
16
)
|
(
mi
[
1
]
<<
8
)
|
mi
[
2
];
return
0
;
}
/*
* Read the capability-bits from the touchpad
* see also the SYN_CAP_* macros
*/
static
int
synaptics_capability
(
struct
psmouse
*
psmouse
,
unsigned
long
int
*
capability
)
{
unsigned
char
cap
[
3
];
if
(
synaptics_send_cmd
(
psmouse
,
SYN_QUE_CAPABILITIES
,
cap
))
return
-
1
;
*
capability
=
(
cap
[
0
]
<<
16
)
|
(
cap
[
1
]
<<
8
)
|
cap
[
2
];
if
(
SYN_CAP_VALID
(
*
capability
))
return
0
;
return
-
1
;
}
/*
* Identify Touchpad
* See also the SYN_ID_* macros
*/
static
int
synaptics_identify
(
struct
psmouse
*
psmouse
,
unsigned
long
int
*
ident
)
{
unsigned
char
id
[
3
];
if
(
synaptics_send_cmd
(
psmouse
,
SYN_QUE_IDENTIFY
,
id
))
return
-
1
;
*
ident
=
(
id
[
0
]
<<
16
)
|
(
id
[
1
]
<<
8
)
|
id
[
2
];
if
(
SYN_ID_IS_SYNAPTICS
(
*
ident
))
return
0
;
return
-
1
;
}
static
int
synaptics_enable_device
(
struct
psmouse
*
psmouse
)
{
if
(
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_ENABLE
))
return
-
1
;
return
0
;
}
static
void
print_ident
(
struct
synaptics_data
*
priv
)
{
printk
(
KERN_INFO
"Synaptics Touchpad, model: %ld
\n
"
,
SYN_ID_MODEL
(
priv
->
identity
));
printk
(
KERN_INFO
" Firware: %ld.%ld
\n
"
,
SYN_ID_MAJOR
(
priv
->
identity
),
SYN_ID_MINOR
(
priv
->
identity
));
if
(
SYN_MODEL_ROT180
(
priv
->
model_id
))
printk
(
KERN_INFO
" 180 degree mounted touchpad
\n
"
);
if
(
SYN_MODEL_PORTRAIT
(
priv
->
model_id
))
printk
(
KERN_INFO
" portrait touchpad
\n
"
);
printk
(
KERN_INFO
" Sensor: %ld
\n
"
,
SYN_MODEL_SENSOR
(
priv
->
model_id
));
if
(
SYN_MODEL_NEWABS
(
priv
->
model_id
))
printk
(
KERN_INFO
" new absolute packet format
\n
"
);
if
(
SYN_MODEL_PEN
(
priv
->
model_id
))
printk
(
KERN_INFO
" pen detection
\n
"
);
if
(
SYN_CAP_EXTENDED
(
priv
->
capabilities
))
{
printk
(
KERN_INFO
" Touchpad has extended capability bits
\n
"
);
if
(
SYN_CAP_FOUR_BUTTON
(
priv
->
capabilities
))
printk
(
KERN_INFO
" -> four buttons
\n
"
);
if
(
SYN_CAP_MULTIFINGER
(
priv
->
capabilities
))
printk
(
KERN_INFO
" -> multifinger detection
\n
"
);
if
(
SYN_CAP_PALMDETECT
(
priv
->
capabilities
))
printk
(
KERN_INFO
" -> palm detection
\n
"
);
}
}
static
int
query_hardware
(
struct
psmouse
*
psmouse
)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
int
retries
=
3
;
while
((
retries
++
<=
3
)
&&
synaptics_reset
(
psmouse
))
printk
(
KERN_ERR
"synaptics reset failed
\n
"
);
if
(
synaptics_identify
(
psmouse
,
&
priv
->
identity
))
return
-
1
;
if
(
synaptics_model_id
(
psmouse
,
&
priv
->
model_id
))
return
-
1
;
if
(
synaptics_capability
(
psmouse
,
&
priv
->
capabilities
))
return
-
1
;
if
(
synaptics_set_mode
(
psmouse
,
(
SYN_BIT_ABSOLUTE_MODE
|
SYN_BIT_HIGH_RATE
|
SYN_BIT_DISABLE_GESTURE
|
SYN_BIT_W_MODE
)))
return
-
1
;
synaptics_enable_device
(
psmouse
);
print_ident
(
priv
);
return
0
;
}
/*****************************************************************************
* Driver initialization/cleanup functions
****************************************************************************/
static
inline
void
set_abs_params
(
struct
input_dev
*
dev
,
int
axis
,
int
min
,
int
max
,
int
fuzz
,
int
flat
)
{
dev
->
absmin
[
axis
]
=
min
;
dev
->
absmax
[
axis
]
=
max
;
dev
->
absfuzz
[
axis
]
=
fuzz
;
dev
->
absflat
[
axis
]
=
flat
;
set_bit
(
axis
,
dev
->
absbit
);
}
int
synaptics_init
(
struct
psmouse
*
psmouse
)
{
struct
synaptics_data
*
priv
;
psmouse
->
private
=
priv
=
kmalloc
(
sizeof
(
struct
synaptics_data
),
GFP_KERNEL
);
if
(
!
priv
)
return
-
1
;
memset
(
priv
,
0
,
sizeof
(
struct
synaptics_data
));
priv
->
inSync
=
1
;
if
(
query_hardware
(
psmouse
))
{
printk
(
KERN_ERR
"Unable to query/initialize Synaptics hardware.
\n
"
);
goto
init_fail
;
}
/*
* The x/y limits are taken from the Synaptics TouchPad interfacing Guide,
* which says that they should be valid regardless of the actual size of
* the senser.
*/
set_bit
(
EV_ABS
,
psmouse
->
dev
.
evbit
);
set_abs_params
(
&
psmouse
->
dev
,
ABS_X
,
1472
,
5472
,
0
,
0
);
set_abs_params
(
&
psmouse
->
dev
,
ABS_Y
,
1408
,
4448
,
0
,
0
);
set_abs_params
(
&
psmouse
->
dev
,
ABS_PRESSURE
,
0
,
255
,
0
,
0
);
set_bit
(
EV_MSC
,
psmouse
->
dev
.
evbit
);
set_bit
(
MSC_GESTURE
,
psmouse
->
dev
.
mscbit
);
set_bit
(
EV_KEY
,
psmouse
->
dev
.
evbit
);
set_bit
(
BTN_LEFT
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_RIGHT
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_FORWARD
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_BACK
,
psmouse
->
dev
.
keybit
);
clear_bit
(
EV_REL
,
psmouse
->
dev
.
evbit
);
clear_bit
(
REL_X
,
psmouse
->
dev
.
relbit
);
clear_bit
(
REL_Y
,
psmouse
->
dev
.
relbit
);
return
0
;
init_fail:
kfree
(
priv
);
return
-
1
;
}
void
synaptics_disconnect
(
struct
psmouse
*
psmouse
)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
kfree
(
priv
);
}
/*****************************************************************************
* Functions to interpret the absolute mode packets
****************************************************************************/
static
void
synaptics_parse_hw_state
(
struct
synaptics_data
*
priv
,
struct
synaptics_hw_state
*
hw
)
{
unsigned
char
*
buf
=
priv
->
proto_buf
;
hw
->
x
=
(((
buf
[
3
]
&
0x10
)
<<
8
)
|
((
buf
[
1
]
&
0x0f
)
<<
8
)
|
buf
[
4
]);
hw
->
y
=
(((
buf
[
3
]
&
0x20
)
<<
7
)
|
((
buf
[
1
]
&
0xf0
)
<<
4
)
|
buf
[
5
]);
hw
->
z
=
buf
[
2
];
hw
->
w
=
(((
buf
[
0
]
&
0x30
)
>>
2
)
|
((
buf
[
0
]
&
0x04
)
>>
1
)
|
((
buf
[
3
]
&
0x04
)
>>
2
));
hw
->
left
=
(
buf
[
0
]
&
0x01
)
?
1
:
0
;
hw
->
right
=
(
buf
[
0
]
&
0x2
)
?
1
:
0
;
hw
->
up
=
0
;
hw
->
down
=
0
;
if
(
SYN_CAP_EXTENDED
(
priv
->
capabilities
)
&&
(
SYN_CAP_FOUR_BUTTON
(
priv
->
capabilities
)))
{
hw
->
up
=
((
buf
[
3
]
&
0x01
))
?
1
:
0
;
if
(
hw
->
left
)
hw
->
up
=
!
hw
->
up
;
hw
->
down
=
((
buf
[
3
]
&
0x02
))
?
1
:
0
;
if
(
hw
->
right
)
hw
->
down
=
!
hw
->
down
;
}
}
/*
* called for each full received packet from the touchpad
*/
static
void
synaptics_process_packet
(
struct
psmouse
*
psmouse
)
{
struct
input_dev
*
dev
=
&
psmouse
->
dev
;
struct
synaptics_data
*
priv
=
psmouse
->
private
;
struct
synaptics_hw_state
hw
;
synaptics_parse_hw_state
(
priv
,
&
hw
);
if
(
hw
.
z
>
0
)
{
int
w_ok
=
0
;
/*
* Use capability bits to decide if the w value is valid.
* If not, set it to 5, which corresponds to a finger of
* normal width.
*/
if
(
SYN_CAP_EXTENDED
(
priv
->
capabilities
))
{
switch
(
hw
.
w
)
{
case
0
...
1
:
w_ok
=
SYN_CAP_MULTIFINGER
(
priv
->
capabilities
);
break
;
case
2
:
w_ok
=
SYN_MODEL_PEN
(
priv
->
model_id
);
break
;
case
4
...
15
:
w_ok
=
SYN_CAP_PALMDETECT
(
priv
->
capabilities
);
break
;
}
}
if
(
!
w_ok
)
hw
.
w
=
5
;
}
/* Post events */
input_report_abs
(
dev
,
ABS_X
,
hw
.
x
);
input_report_abs
(
dev
,
ABS_Y
,
hw
.
y
);
input_report_abs
(
dev
,
ABS_PRESSURE
,
hw
.
z
);
if
(
hw
.
w
!=
priv
->
old_w
)
{
input_event
(
dev
,
EV_MSC
,
MSC_GESTURE
,
hw
.
w
);
priv
->
old_w
=
hw
.
w
;
}
input_report_key
(
dev
,
BTN_LEFT
,
hw
.
left
);
input_report_key
(
dev
,
BTN_RIGHT
,
hw
.
right
);
input_report_key
(
dev
,
BTN_FORWARD
,
hw
.
up
);
input_report_key
(
dev
,
BTN_BACK
,
hw
.
down
);
input_sync
(
dev
);
}
void
synaptics_process_byte
(
struct
psmouse
*
psmouse
,
struct
pt_regs
*
regs
)
{
struct
input_dev
*
dev
=
&
psmouse
->
dev
;
struct
synaptics_data
*
priv
=
psmouse
->
private
;
unsigned
char
*
pBuf
=
priv
->
proto_buf
;
unsigned
char
u
=
psmouse
->
packet
[
0
];
input_regs
(
dev
,
regs
);
pBuf
[
priv
->
proto_buf_tail
++
]
=
u
;
/* check first byte */
if
((
priv
->
proto_buf_tail
==
1
)
&&
((
u
&
0xC8
)
!=
0x80
))
{
priv
->
inSync
=
0
;
priv
->
proto_buf_tail
=
0
;
printk
(
KERN_WARNING
"Synaptics driver lost sync at 1st byte
\n
"
);
return
;
}
/* check 4th byte */
if
((
priv
->
proto_buf_tail
==
4
)
&&
((
u
&
0xc8
)
!=
0xc0
))
{
priv
->
inSync
=
0
;
priv
->
proto_buf_tail
=
0
;
printk
(
KERN_WARNING
"Synaptics driver lost sync at 4th byte
\n
"
);
return
;
}
if
(
priv
->
proto_buf_tail
>=
6
)
{
/* Full packet received */
if
(
!
priv
->
inSync
)
{
priv
->
inSync
=
1
;
printk
(
KERN_NOTICE
"Synaptics driver resynced.
\n
"
);
}
synaptics_process_packet
(
psmouse
);
priv
->
proto_buf_tail
=
0
;
}
}
drivers/input/mouse/synaptics.h
0 → 100644
View file @
e76b0d3f
/*
* Synaptics TouchPad PS/2 mouse driver
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#ifndef _SYNAPTICS_H
#define _SYNAPTICS_H
#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
extern
void
synaptics_process_byte
(
struct
psmouse
*
psmouse
,
struct
pt_regs
*
regs
);
extern
int
synaptics_init
(
struct
psmouse
*
psmouse
);
extern
void
synaptics_disconnect
(
struct
psmouse
*
psmouse
);
#else
static
inline
void
synaptics_process_byte
(
struct
psmouse
*
psmouse
,
struct
pt_regs
*
regs
)
{}
static
inline
int
synaptics_init
(
struct
psmouse
*
psmouse
)
{
return
-
1
;
}
static
inline
void
synaptics_disconnect
(
struct
psmouse
*
psmouse
)
{}
#endif
/* synaptics queries */
#define SYN_QUE_IDENTIFY 0x00
#define SYN_QUE_MODES 0x01
#define SYN_QUE_CAPABILITIES 0x02
#define SYN_QUE_MODEL 0x03
#define SYN_QUE_SERIAL_NUMBER_PREFIX 0x06
#define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07
#define SYN_QUE_RESOLUTION 0x08
/* 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_W_MODE (1 << 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)
/* synaptics capability bits */
#define SYN_CAP_EXTENDED(c) ((c) & (1 << 23))
#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_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47)
/* 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))
/* 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_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47)
/*
* A structure to describe the state of the touchpad hardware (buttons and pad)
*/
struct
synaptics_hw_state
{
int
x
;
int
y
;
int
z
;
int
w
;
int
left
;
int
right
;
int
up
;
int
down
;
};
struct
synaptics_data
{
/* Data read from the touchpad */
unsigned
long
int
model_id
;
/* Model-ID */
unsigned
long
int
capabilities
;
/* Capabilities */
unsigned
long
int
identity
;
/* Identification */
/* Data for normal processing */
unsigned
char
proto_buf
[
6
];
/* Buffer for Packet */
unsigned
char
last_byte
;
/* last received byte */
int
inSync
;
/* Packets in sync */
int
proto_buf_tail
;
int
old_w
;
/* Previous w value */
};
#endif
/* _SYNAPTICS_H */
include/linux/input.h
View file @
e76b0d3f
...
@@ -530,6 +530,7 @@ struct input_absinfo {
...
@@ -530,6 +530,7 @@ struct input_absinfo {
#define MSC_SERIAL 0x00
#define MSC_SERIAL 0x00
#define MSC_PULSELED 0x01
#define MSC_PULSELED 0x01
#define MSC_GESTURE 0x02
#define MSC_MAX 0x07
#define MSC_MAX 0x07
/*
/*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment