Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
9d9226df
Commit
9d9226df
authored
Sep 20, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/jgarzik/net-drivers-2.5
into home.osdl.org:/home/torvalds/v2.5/linux
parents
422614a5
aac0e012
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
844 additions
and
251 deletions
+844
-251
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+4
-0
drivers/char/keyboard.c
drivers/char/keyboard.c
+1
-1
drivers/input/evdev.c
drivers/input/evdev.c
+5
-7
drivers/input/input.c
drivers/input/input.c
+4
-2
drivers/input/joystick/db9.c
drivers/input/joystick/db9.c
+269
-44
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/iforce/iforce-packets.c
+2
-3
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/joystick/iforce/iforce-usb.c
+2
-4
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Kconfig
+2
-1
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/atkbd.c
+95
-78
drivers/input/mouse/Kconfig
drivers/input/mouse/Kconfig
+17
-3
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse-base.c
+88
-15
drivers/input/mouse/psmouse.h
drivers/input/mouse/psmouse.h
+15
-7
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.c
+285
-78
drivers/input/mouse/synaptics.h
drivers/input/mouse/synaptics.h
+22
-5
drivers/input/serio/serio.c
drivers/input/serio/serio.c
+29
-2
include/linux/input.h
include/linux/input.h
+1
-1
include/linux/serio.h
include/linux/serio.h
+3
-0
No files found.
Documentation/kernel-parameters.txt
View file @
9d9226df
...
...
@@ -788,6 +788,10 @@ running once the system is up.
psmouse_noext [HW,MOUSE] Disable probing for PS2 mouse protocol extensions
psmouse_resetafter=
[HW,MOUSE] Try to reset Synaptics Touchpad after so many
bad packets (0 = never).
pss= [HW,OSS] Personal Sound System (ECHO ESC614)
Format: <io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
...
...
drivers/char/keyboard.c
View file @
9d9226df
...
...
@@ -205,7 +205,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
INPUT_KEYCODE
(
dev
,
scancode
)
=
keycode
;
for
(
i
=
0
;
i
<
dev
->
keycodemax
;
i
++
)
if
(
INPUT_KEYCODE
(
dev
,
scancode
)
==
oldkey
)
if
(
keycode
==
oldkey
)
break
;
if
(
i
==
dev
->
keycodemax
)
clear_bit
(
oldkey
,
dev
->
keybit
);
...
...
drivers/input/evdev.c
View file @
9d9226df
...
...
@@ -208,7 +208,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
struct
evdev
*
evdev
=
list
->
evdev
;
struct
input_dev
*
dev
=
evdev
->
handle
.
dev
;
struct
input_absinfo
abs
;
int
i
,
t
,
u
;
int
i
,
t
,
u
,
v
;
if
(
!
evdev
->
exist
)
return
-
ENODEV
;
...
...
@@ -239,14 +239,12 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case
EVIOCSKEYCODE
:
if
(
get_user
(
t
,
((
int
*
)
arg
)
+
0
))
return
-
EFAULT
;
if
(
t
<
0
||
t
>
dev
->
keycodemax
||
!
dev
->
keycodesize
)
return
-
EINVAL
;
if
(
get_user
(
v
,
((
int
*
)
arg
)
+
1
))
return
-
EFAULT
;
u
=
INPUT_KEYCODE
(
dev
,
t
);
if
(
get_user
(
INPUT_KEYCODE
(
dev
,
t
),
((
int
*
)
arg
)
+
1
))
return
-
EFAULT
;
for
(
i
=
0
;
i
<
dev
->
keycodemax
;
i
++
)
if
(
INPUT_KEYCODE
(
dev
,
t
)
==
u
)
break
;
INPUT_KEYCODE
(
dev
,
t
)
=
v
;
for
(
i
=
0
;
i
<
dev
->
keycodemax
;
i
++
)
if
(
v
==
u
)
break
;
if
(
i
==
dev
->
keycodemax
)
clear_bit
(
u
,
dev
->
keybit
);
set_bit
(
INPUT_KEYCODE
(
dev
,
t
),
dev
->
keybit
);
set_bit
(
v
,
dev
->
keybit
);
return
0
;
case
EVIOCSFF
:
...
...
drivers/input/input.c
View file @
9d9226df
...
...
@@ -426,7 +426,9 @@ void input_register_device(struct input_dev *dev)
init_timer
(
&
dev
->
timer
);
dev
->
timer
.
data
=
(
long
)
dev
;
dev
->
timer
.
function
=
input_repeat_key
;
if
(
!
dev
->
rep
[
REP_DELAY
])
dev
->
rep
[
REP_DELAY
]
=
HZ
/
4
;
if
(
!
dev
->
rep
[
REP_PERIOD
])
dev
->
rep
[
REP_PERIOD
]
=
HZ
/
33
;
INIT_LIST_HEAD
(
&
dev
->
h_list
);
...
...
drivers/input/joystick/db9.c
View file @
9d9226df
...
...
@@ -55,7 +55,9 @@ MODULE_PARM(db9_3, "2i");
#define DB9_MULTI_0802 0x08
#define DB9_MULTI_0802_2 0x09
#define DB9_CD32_PAD 0x0A
#define DB9_MAX_PAD 0x0B
#define DB9_SATURN_DPP 0x0B
#define DB9_SATURN_DPP_2 0x0C
#define DB9_MAX_PAD 0x0D
#define DB9_UP 0x01
#define DB9_DOWN 0x02
...
...
@@ -69,10 +71,7 @@ MODULE_PARM(db9_3, "2i");
#define DB9_NORMAL 0x0a
#define DB9_NOSELECT 0x08
#define DB9_SATURN0 0x00
#define DB9_SATURN1 0x02
#define DB9_SATURN2 0x04
#define DB9_SATURN3 0x06
#define DB9_MAX_DEVICES 2
#define DB9_GENESIS6_DELAY 14
#define DB9_REFRESH_TIME HZ/100
...
...
@@ -82,7 +81,7 @@ static int db9_2[] __initdata = { -1, 0 };
static
int
db9_3
[]
__initdata
=
{
-
1
,
0
};
struct
db9
{
struct
input_dev
dev
[
2
];
struct
input_dev
dev
[
DB9_MAX_DEVICES
];
struct
timer_list
timer
;
struct
pardevice
*
pd
;
int
mode
;
...
...
@@ -96,12 +95,247 @@ static short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
static
short
db9_genesis_btn
[]
=
{
BTN_START
,
BTN_A
,
BTN_B
,
BTN_C
,
BTN_X
,
BTN_Y
,
BTN_Z
,
BTN_MODE
};
static
short
db9_cd32_btn
[]
=
{
BTN_A
,
BTN_B
,
BTN_C
,
BTN_X
,
BTN_Y
,
BTN_Z
,
BTN_TL
,
BTN_TR
,
BTN_START
};
static
char
db9_buttons
[
DB9_MAX_PAD
]
=
{
0
,
1
,
2
,
4
,
0
,
6
,
8
,
8
,
1
,
1
,
7
};
static
char
db9_buttons
[
DB9_MAX_PAD
]
=
{
0
,
1
,
2
,
4
,
0
,
6
,
8
,
9
,
1
,
1
,
7
,
9
,
9
};
static
short
*
db9_btn
[
DB9_MAX_PAD
]
=
{
NULL
,
db9_multi_btn
,
db9_multi_btn
,
db9_genesis_btn
,
NULL
,
db9_genesis_btn
,
db9_genesis_btn
,
db9_cd32_btn
,
db9_multi_btn
,
db9_multi_btn
,
db9_cd32_btn
};
db9_genesis_btn
,
db9_cd32_btn
,
db9_multi_btn
,
db9_multi_btn
,
db9_cd32_btn
,
db9_cd32_btn
,
db9_cd32_btn
};
static
char
*
db9_name
[
DB9_MAX_PAD
]
=
{
NULL
,
"Multisystem joystick"
,
"Multisystem joystick (2 fire)"
,
"Genesis pad"
,
NULL
,
"Genesis 5 pad"
,
"Genesis 6 pad"
,
"Saturn pad"
,
"Multisystem (0.8.0.2) joystick"
,
"Multisystem (0.8.0.2-dual) joystick"
,
"Amiga CD-32 pad"
};
"Multisystem (0.8.0.2-dual) joystick"
,
"Amiga CD-32 pad"
,
"Saturn dpp"
,
"Saturn dpp dual"
};
static
const
int
db9_max_pads
[
DB9_MAX_PAD
]
=
{
0
,
1
,
1
,
1
,
0
,
1
,
1
,
6
,
1
,
2
,
1
,
6
,
12
};
static
const
int
db9_num_axis
[
DB9_MAX_PAD
]
=
{
0
,
2
,
2
,
2
,
0
,
2
,
2
,
7
,
2
,
2
,
2
,
7
,
7
};
static
const
short
db9_abs
[]
=
{
ABS_X
,
ABS_Y
,
ABS_RX
,
ABS_RY
,
ABS_RZ
,
ABS_Z
,
ABS_HAT0X
,
ABS_HAT0Y
,
ABS_HAT1X
,
ABS_HAT1Y
};
static
const
int
db9_bidirectional
[
DB9_MAX_PAD
]
=
{
0
,
1
,
1
,
1
,
0
,
1
,
1
,
1
,
0
,
1
,
1
,
0
,
0
};
static
const
int
db9_reverse
[
DB9_MAX_PAD
]
=
{
0
,
1
,
1
,
1
,
0
,
1
,
1
,
1
,
1
,
1
,
1
,
0
,
0
};
/*
* Saturn controllers
*/
#define DB9_SATURN_DELAY 300
static
const
int
db9_saturn_byte
[]
=
{
1
,
1
,
1
,
2
,
2
,
2
,
2
,
2
,
1
};
static
const
unsigned
char
db9_saturn_mask
[]
=
{
0x04
,
0x01
,
0x02
,
0x40
,
0x20
,
0x10
,
0x08
,
0x80
,
0x08
};
/*
* db9_saturn_write_sub() writes 2 bit data.
*/
static
void
db9_saturn_write_sub
(
struct
parport
*
port
,
int
type
,
unsigned
char
data
,
int
powered
,
int
pwr_sub
)
{
unsigned
char
c
;
switch
(
type
)
{
case
1
:
/* DPP1 */
c
=
0x80
|
0x30
|
(
powered
?
0x08
:
0
)
|
(
pwr_sub
?
0x04
:
0
)
|
data
;
parport_write_data
(
port
,
c
);
break
;
case
2
:
/* DPP2 */
c
=
0x40
|
data
<<
4
|
(
powered
?
0x08
:
0
)
|
(
pwr_sub
?
0x04
:
0
)
|
0x03
;
parport_write_data
(
port
,
c
);
break
;
case
0
:
/* DB9 */
c
=
((((
data
&
2
)
?
2
:
0
)
|
((
data
&
1
)
?
4
:
0
))
^
0x02
)
|
!
powered
;
parport_write_control
(
port
,
c
);
break
;
}
}
/*
* gc_saturn_read_sub() reads 4 bit data.
*/
static
unsigned
char
db9_saturn_read_sub
(
struct
parport
*
port
,
int
type
)
{
unsigned
char
data
;
if
(
type
)
{
/* DPP */
data
=
parport_read_status
(
port
)
^
0x80
;
return
(
data
&
0x80
?
1
:
0
)
|
(
data
&
0x40
?
2
:
0
)
|
(
data
&
0x20
?
4
:
0
)
|
(
data
&
0x10
?
8
:
0
);
}
else
{
/* DB9 */
data
=
parport_read_data
(
port
)
&
0x0f
;
return
(
data
&
0x8
?
1
:
0
)
|
(
data
&
0x4
?
2
:
0
)
|
(
data
&
0x2
?
4
:
0
)
|
(
data
&
0x1
?
8
:
0
);
}
}
/*
* db9_saturn_read_analog() sends clock and reads 8 bit data.
*/
static
unsigned
char
db9_saturn_read_analog
(
struct
parport
*
port
,
int
type
,
int
powered
)
{
unsigned
char
data
;
db9_saturn_write_sub
(
port
,
type
,
0
,
powered
,
0
);
udelay
(
DB9_SATURN_DELAY
);
data
=
db9_saturn_read_sub
(
port
,
type
)
<<
4
;
db9_saturn_write_sub
(
port
,
type
,
2
,
powered
,
0
);
udelay
(
DB9_SATURN_DELAY
);
data
|=
db9_saturn_read_sub
(
port
,
type
);
return
data
;
}
/*
* db9_saturn_read_packet() reads whole saturn packet at connector
* and returns device identifier code.
*/
static
unsigned
char
db9_saturn_read_packet
(
struct
parport
*
port
,
unsigned
char
*
data
,
int
type
,
int
powered
)
{
int
i
,
j
;
unsigned
char
tmp
;
db9_saturn_write_sub
(
port
,
type
,
3
,
powered
,
0
);
data
[
0
]
=
db9_saturn_read_sub
(
port
,
type
);
switch
(
data
[
0
]
&
0x0f
)
{
case
0xf
:
/* 1111 no pad */
return
data
[
0
]
=
0xff
;
case
0x4
:
case
0x4
|
0x8
:
/* ?100 : digital controller */
db9_saturn_write_sub
(
port
,
type
,
0
,
powered
,
1
);
data
[
2
]
=
db9_saturn_read_sub
(
port
,
type
)
<<
4
;
db9_saturn_write_sub
(
port
,
type
,
2
,
powered
,
1
);
data
[
1
]
=
db9_saturn_read_sub
(
port
,
type
)
<<
4
;
db9_saturn_write_sub
(
port
,
type
,
1
,
powered
,
1
);
data
[
1
]
|=
db9_saturn_read_sub
(
port
,
type
);
db9_saturn_write_sub
(
port
,
type
,
3
,
powered
,
1
);
/* data[2] |= db9_saturn_read_sub(port, type); */
data
[
2
]
|=
data
[
0
];
return
data
[
0
]
=
0x02
;
case
0x1
:
/* 0001 : analog controller or multitap */
db9_saturn_write_sub
(
port
,
type
,
2
,
powered
,
0
);
udelay
(
DB9_SATURN_DELAY
);
data
[
0
]
=
db9_saturn_read_analog
(
port
,
type
,
powered
);
if
(
data
[
0
]
!=
0x41
)
{
/* read analog controller */
for
(
i
=
0
;
i
<
(
data
[
0
]
&
0x0f
);
i
++
)
data
[
i
+
1
]
=
db9_saturn_read_analog
(
port
,
type
,
powered
);
db9_saturn_write_sub
(
port
,
type
,
3
,
powered
,
0
);
return
data
[
0
];
}
else
{
/* read multitap */
if
(
db9_saturn_read_analog
(
port
,
type
,
powered
)
!=
0x60
)
return
data
[
0
]
=
0xff
;
for
(
i
=
0
;
i
<
60
;
i
+=
10
)
{
data
[
i
]
=
db9_saturn_read_analog
(
port
,
type
,
powered
);
if
(
data
[
i
]
!=
0xff
)
/* read each pad */
for
(
j
=
0
;
j
<
(
data
[
i
]
&
0x0f
);
j
++
)
data
[
i
+
j
+
1
]
=
db9_saturn_read_analog
(
port
,
type
,
powered
);
}
db9_saturn_write_sub
(
port
,
type
,
3
,
powered
,
0
);
return
0x41
;
}
case
0x0
:
/* 0000 : mouse */
db9_saturn_write_sub
(
port
,
type
,
2
,
powered
,
0
);
udelay
(
DB9_SATURN_DELAY
);
tmp
=
db9_saturn_read_analog
(
port
,
type
,
powered
);
if
(
tmp
==
0xff
)
{
for
(
i
=
0
;
i
<
3
;
i
++
)
data
[
i
+
1
]
=
db9_saturn_read_analog
(
port
,
type
,
powered
);
db9_saturn_write_sub
(
port
,
type
,
3
,
powered
,
0
);
return
data
[
0
]
=
0xe3
;
}
default:
return
data
[
0
];
}
}
/*
* db9_saturn_report() analyzes packet and reports.
*/
static
int
db9_saturn_report
(
unsigned
char
id
,
unsigned
char
data
[
60
],
struct
input_dev
*
dev
,
int
n
,
int
max_pads
)
{
int
tmp
,
i
,
j
;
tmp
=
(
id
==
0x41
)
?
60
:
10
;
for
(
j
=
0
;
(
j
<
tmp
)
&&
(
n
<
max_pads
);
j
+=
10
,
n
++
)
{
switch
(
data
[
j
])
{
case
0x16
:
/* multi controller (analog 4 axis) */
input_report_abs
(
dev
+
n
,
db9_abs
[
5
],
data
[
j
+
6
]);
case
0x15
:
/* mission stick (analog 3 axis) */
input_report_abs
(
dev
+
n
,
db9_abs
[
3
],
data
[
j
+
4
]);
input_report_abs
(
dev
+
n
,
db9_abs
[
4
],
data
[
j
+
5
]);
case
0x13
:
/* racing controller (analog 1 axis) */
input_report_abs
(
dev
+
n
,
db9_abs
[
2
],
data
[
j
+
3
]);
case
0x34
:
/* saturn keyboard (udlr ZXC ASD QE Esc) */
case
0x02
:
/* digital pad (digital 2 axis + buttons) */
input_report_abs
(
dev
+
n
,
db9_abs
[
0
],
!
(
data
[
j
+
1
]
&
128
)
-
!
(
data
[
j
+
1
]
&
64
));
input_report_abs
(
dev
+
n
,
db9_abs
[
1
],
!
(
data
[
j
+
1
]
&
32
)
-
!
(
data
[
j
+
1
]
&
16
));
for
(
i
=
0
;
i
<
9
;
i
++
)
input_report_key
(
dev
+
n
,
db9_cd32_btn
[
i
],
~
data
[
j
+
db9_saturn_byte
[
i
]]
&
db9_saturn_mask
[
i
]);
break
;
case
0x19
:
/* mission stick x2 (analog 6 axis + buttons) */
input_report_abs
(
dev
+
n
,
db9_abs
[
0
],
!
(
data
[
j
+
1
]
&
128
)
-
!
(
data
[
j
+
1
]
&
64
));
input_report_abs
(
dev
+
n
,
db9_abs
[
1
],
!
(
data
[
j
+
1
]
&
32
)
-
!
(
data
[
j
+
1
]
&
16
));
for
(
i
=
0
;
i
<
9
;
i
++
)
input_report_key
(
dev
+
n
,
db9_cd32_btn
[
i
],
~
data
[
j
+
db9_saturn_byte
[
i
]]
&
db9_saturn_mask
[
i
]);
input_report_abs
(
dev
+
n
,
db9_abs
[
2
],
data
[
j
+
3
]);
input_report_abs
(
dev
+
n
,
db9_abs
[
3
],
data
[
j
+
4
]);
input_report_abs
(
dev
+
n
,
db9_abs
[
4
],
data
[
j
+
5
]);
/*
input_report_abs(dev + n, db9_abs[8], (data[j + 6] & 128 ? 0 : 1) - (data[j + 6] & 64 ? 0 : 1));
input_report_abs(dev + n, db9_abs[9], (data[j + 6] & 32 ? 0 : 1) - (data[j + 6] & 16 ? 0 : 1));
*/
input_report_abs
(
dev
+
n
,
db9_abs
[
6
],
data
[
j
+
7
]);
input_report_abs
(
dev
+
n
,
db9_abs
[
7
],
data
[
j
+
8
]);
input_report_abs
(
dev
+
n
,
db9_abs
[
5
],
data
[
j
+
9
]);
break
;
case
0xd3
:
/* sankyo ff (analog 1 axis + stop btn) */
input_report_key
(
dev
+
n
,
BTN_A
,
data
[
j
+
3
]
&
0x80
);
input_report_abs
(
dev
+
n
,
db9_abs
[
2
],
data
[
j
+
3
]
&
0x7f
);
break
;
case
0xe3
:
/* shuttle mouse (analog 2 axis + buttons. signed value) */
input_report_key
(
dev
+
n
,
BTN_START
,
data
[
j
+
1
]
&
0x08
);
input_report_key
(
dev
+
n
,
BTN_A
,
data
[
j
+
1
]
&
0x04
);
input_report_key
(
dev
+
n
,
BTN_C
,
data
[
j
+
1
]
&
0x02
);
input_report_key
(
dev
+
n
,
BTN_B
,
data
[
j
+
1
]
&
0x01
);
input_report_abs
(
dev
+
n
,
db9_abs
[
2
],
data
[
j
+
2
]
^
0x80
);
input_report_abs
(
dev
+
n
,
db9_abs
[
3
],
(
0xff
-
(
data
[
j
+
3
]
^
0x80
))
+
1
);
/* */
break
;
case
0xff
:
default:
/* no pad */
input_report_abs
(
dev
+
n
,
db9_abs
[
0
],
0
);
input_report_abs
(
dev
+
n
,
db9_abs
[
1
],
0
);
for
(
i
=
0
;
i
<
9
;
i
++
)
input_report_key
(
dev
+
n
,
db9_cd32_btn
[
i
],
0
);
break
;
}
}
return
n
;
}
static
int
db9_saturn
(
int
mode
,
struct
parport
*
port
,
struct
input_dev
*
dev
)
{
unsigned
char
id
,
data
[
60
];
int
type
,
n
,
max_pads
;
int
tmp
,
i
;
switch
(
mode
)
{
case
DB9_SATURN_PAD
:
type
=
0
;
n
=
1
;
break
;
case
DB9_SATURN_DPP
:
type
=
1
;
n
=
1
;
break
;
case
DB9_SATURN_DPP_2
:
type
=
1
;
n
=
2
;
break
;
default:
return
-
1
;
}
max_pads
=
min
(
db9_max_pads
[
mode
],
DB9_MAX_DEVICES
);
for
(
tmp
=
0
,
i
=
0
;
i
<
n
;
i
++
)
{
id
=
db9_saturn_read_packet
(
port
,
data
,
type
+
i
,
1
);
tmp
=
db9_saturn_report
(
id
,
data
,
dev
,
tmp
,
max_pads
);
}
return
0
;
}
static
void
db9_timer
(
unsigned
long
private
)
{
...
...
@@ -222,28 +456,10 @@ static void db9_timer(unsigned long private)
break
;
case
DB9_SATURN_PAD
:
case
DB9_SATURN_DPP
:
case
DB9_SATURN_DPP_2
:
parport_write_control
(
port
,
DB9_SATURN0
);
data
=
parport_read_data
(
port
);
input_report_key
(
dev
,
BTN_Y
,
~
data
&
DB9_LEFT
);
input_report_key
(
dev
,
BTN_Z
,
~
data
&
DB9_DOWN
);
input_report_key
(
dev
,
BTN_TL
,
~
data
&
DB9_UP
);
input_report_key
(
dev
,
BTN_TR
,
~
data
&
DB9_RIGHT
);
parport_write_control
(
port
,
DB9_SATURN2
);
data
=
parport_read_data
(
port
);
input_report_abs
(
dev
,
ABS_X
,
(
data
&
DB9_RIGHT
?
0
:
1
)
-
(
data
&
DB9_LEFT
?
0
:
1
));
input_report_abs
(
dev
,
ABS_Y
,
(
data
&
DB9_DOWN
?
0
:
1
)
-
(
data
&
DB9_UP
?
0
:
1
));
parport_write_control
(
port
,
DB9_NORMAL
);
data
=
parport_read_data
(
port
);
input_report_key
(
dev
,
BTN_A
,
~
data
&
DB9_LEFT
);
input_report_key
(
dev
,
BTN_B
,
~
data
&
DB9_UP
);
input_report_key
(
dev
,
BTN_C
,
~
data
&
DB9_DOWN
);
input_report_key
(
dev
,
BTN_X
,
~
data
&
DB9_RIGHT
);
db9_saturn
(
db9
->
mode
,
port
,
dev
);
break
;
case
DB9_CD32_PAD
:
...
...
@@ -279,8 +495,10 @@ static int db9_open(struct input_dev *dev)
if
(
!
db9
->
used
++
)
{
parport_claim
(
db9
->
pd
);
parport_write_data
(
port
,
0xff
);
if
(
db9_reverse
[
db9
->
mode
])
{
parport_data_reverse
(
port
);
parport_write_control
(
port
,
DB9_NORMAL
);
}
mod_timer
(
&
db9
->
timer
,
jiffies
+
DB9_REFRESH_TIME
);
}
...
...
@@ -321,10 +539,12 @@ static struct db9 __init *db9_probe(int *config)
return
NULL
;
}
if
(
!
(
pp
->
modes
&
PARPORT_MODE_TRISTATE
)
&&
config
[
1
]
!=
DB9_MULTI_0802
)
{
if
(
db9_bidirectional
[
config
[
1
]])
{
if
(
!
(
pp
->
modes
&
PARPORT_MODE_TRISTATE
))
{
printk
(
KERN_ERR
"db9.c: specified parport is not bidirectional
\n
"
);
return
NULL
;
}
}
if
(
!
(
db9
=
kmalloc
(
sizeof
(
struct
db9
),
GFP_KERNEL
)))
return
NULL
;
...
...
@@ -343,7 +563,7 @@ static struct db9 __init *db9_probe(int *config)
return
NULL
;
}
for
(
i
=
0
;
i
<
1
+
(
db9
->
mode
==
DB9_MULTI_0802_2
);
i
++
)
{
for
(
i
=
0
;
i
<
(
min
(
db9_max_pads
[
db9
->
mode
],
DB9_MAX_DEVICES
)
);
i
++
)
{
sprintf
(
db9
->
phys
[
i
],
"%s/input%d"
,
db9
->
pd
->
port
->
name
,
i
);
...
...
@@ -359,14 +579,19 @@ static struct db9 __init *db9_probe(int *config)
db9
->
dev
[
i
].
id
.
version
=
0x0100
;
db9
->
dev
[
i
].
evbit
[
0
]
=
BIT
(
EV_KEY
)
|
BIT
(
EV_ABS
);
db9
->
dev
[
i
].
absbit
[
0
]
=
BIT
(
ABS_X
)
|
BIT
(
ABS_Y
);
for
(
j
=
0
;
j
<
db9_buttons
[
db9
->
mode
];
j
++
)
set_bit
(
db9_btn
[
db9
->
mode
][
j
],
db9
->
dev
[
i
].
keybit
);
db9
->
dev
[
i
].
absmin
[
ABS_X
]
=
-
1
;
db9
->
dev
[
i
].
absmax
[
ABS_X
]
=
1
;
db9
->
dev
[
i
].
absmin
[
ABS_Y
]
=
-
1
;
db9
->
dev
[
i
].
absmax
[
ABS_Y
]
=
1
;
for
(
j
=
0
;
j
<
db9_num_axis
[
db9
->
mode
];
j
++
)
{
set_bit
(
db9_abs
[
j
],
db9
->
dev
[
i
].
absbit
);
if
(
j
<
2
)
{
db9
->
dev
[
i
].
absmin
[
db9_abs
[
j
]]
=
-
1
;
db9
->
dev
[
i
].
absmax
[
db9_abs
[
j
]]
=
1
;
}
else
{
db9
->
dev
[
i
].
absmin
[
db9_abs
[
j
]]
=
1
;
db9
->
dev
[
i
].
absmax
[
db9_abs
[
j
]]
=
255
;
db9
->
dev
[
i
].
absflat
[
db9_abs
[
j
]]
=
0
;
}
}
input_register_device
(
db9
->
dev
+
i
);
printk
(
KERN_INFO
"input: %s on %s
\n
"
,
db9
->
dev
[
i
].
name
,
db9
->
pd
->
port
->
name
);
}
...
...
@@ -419,7 +644,7 @@ void __exit db9_exit(void)
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
db9_base
[
i
])
{
for
(
j
=
0
;
j
<
1
+
(
db9_base
[
i
]
->
mode
==
DB9_MULTI_0802_2
);
j
++
)
for
(
j
=
0
;
j
<
min
(
db9_max_pads
[
db9_base
[
i
]
->
mode
],
DB9_MAX_DEVICES
);
j
++
)
input_unregister_device
(
db9_base
[
i
]
->
dev
+
j
);
parport_unregister_device
(
db9_base
[
i
]
->
pd
);
}
...
...
drivers/input/joystick/iforce/iforce-packets.c
View file @
9d9226df
...
...
@@ -166,7 +166,6 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data,
iforce
->
expect_packet
=
0
;
iforce
->
ecmd
=
cmd
;
memcpy
(
iforce
->
edata
,
data
,
IFORCE_MAX_LENGTH
);
if
(
waitqueue_active
(
&
iforce
->
wait
))
wake_up
(
&
iforce
->
wait
);
}
#endif
...
...
@@ -264,7 +263,7 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet)
set_current_state
(
TASK_INTERRUPTIBLE
);
add_wait_queue
(
&
iforce
->
wait
,
&
wait
);
if
(
usb_submit_urb
(
iforce
->
ctrl
,
GFP_
KERNEL
))
{
if
(
usb_submit_urb
(
iforce
->
ctrl
,
GFP_
ATOMIC
))
{
set_current_state
(
TASK_RUNNING
);
remove_wait_queue
(
&
iforce
->
wait
,
&
wait
);
return
-
1
;
...
...
drivers/input/joystick/iforce/iforce-usb.c
View file @
9d9226df
...
...
@@ -116,7 +116,6 @@ static void iforce_usb_out(struct urb *urb, struct pt_regs *regs)
iforce_usb_xmit
(
iforce
);
if
(
waitqueue_active
(
&
iforce
->
wait
))
wake_up
(
&
iforce
->
wait
);
}
...
...
@@ -125,7 +124,6 @@ static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs)
struct
iforce
*
iforce
=
urb
->
context
;
if
(
urb
->
status
)
return
;
iforce
->
ecmd
=
0xff00
|
urb
->
actual_length
;
if
(
waitqueue_active
(
&
iforce
->
wait
))
wake_up
(
&
iforce
->
wait
);
}
...
...
drivers/input/keyboard/Kconfig
View file @
9d9226df
...
...
@@ -13,7 +13,8 @@ config INPUT_KEYBOARD
config KEYBOARD_ATKBD
tristate "AT keyboard support" if EMBEDDED || !X86
default y
default y if INPUT=y && INPUT_KEYBOARD=y && SERIO=y
default m
depends on INPUT && INPUT_KEYBOARD && SERIO
help
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
...
...
drivers/input/keyboard/atkbd.c
View file @
9d9226df
...
...
@@ -18,6 +18,7 @@
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
MODULE_AUTHOR
(
"Vojtech Pavlik <vojtech@suse.cz>"
);
MODULE_DESCRIPTION
(
"AT and PS/2 keyboard driver"
);
...
...
@@ -40,8 +41,8 @@ static int atkbd_reset = 1;
static
unsigned
char
atkbd_set2_keycode
[
512
]
=
{
0
,
67
,
65
,
63
,
61
,
59
,
60
,
88
,
0
,
68
,
66
,
64
,
62
,
15
,
41
,
85
,
0
,
56
,
42
,
182
,
29
,
16
,
2
,
89
,
0
,
0
,
44
,
31
,
30
,
17
,
3
,
90
,
0
,
46
,
45
,
32
,
18
,
5
,
4
,
91
,
0
,
57
,
47
,
33
,
20
,
19
,
6
,
0
,
0
,
49
,
48
,
35
,
34
,
21
,
7
,
0
,
0
,
0
,
50
,
36
,
22
,
8
,
9
,
0
,
0
,
46
,
45
,
32
,
18
,
5
,
4
,
91
,
9
0
,
57
,
47
,
33
,
20
,
19
,
6
,
0
,
91
,
49
,
48
,
35
,
34
,
21
,
7
,
0
,
0
,
0
,
50
,
36
,
22
,
8
,
9
,
0
,
0
,
51
,
37
,
23
,
24
,
11
,
10
,
0
,
0
,
52
,
53
,
38
,
39
,
25
,
12
,
0
,
122
,
89
,
40
,
120
,
26
,
13
,
0
,
0
,
58
,
54
,
28
,
27
,
0
,
43
,
0
,
0
,
85
,
86
,
90
,
91
,
92
,
93
,
14
,
94
,
95
,
79
,
183
,
75
,
71
,
121
,
0
,
123
,
...
...
@@ -87,10 +88,10 @@ static unsigned char atkbd_set3_keycode[512] = {
#define ATKBD_CMD_GSCANSET 0x11f0
#define ATKBD_CMD_SSCANSET 0x10f0
#define ATKBD_CMD_GETID 0x02f2
#define ATKBD_CMD_SETREP 0x10f3
#define ATKBD_CMD_ENABLE 0x00f4
#define ATKBD_CMD_RESET_DIS 0x00f5
#define ATKBD_CMD_RESET_BAT 0x02ff
#define ATKBD_CMD_SETALL_MB 0x00f8
#define ATKBD_CMD_RESEND 0x00fe
#define ATKBD_CMD_EX_ENABLE 0x10ea
#define ATKBD_CMD_EX_SETLEDS 0x20eb
...
...
@@ -114,12 +115,14 @@ struct atkbd {
unsigned
char
keycode
[
512
];
struct
input_dev
dev
;
struct
serio
*
serio
;
struct
timer_list
timer
;
char
name
[
64
];
char
phys
[
32
];
unsigned
char
cmdbuf
[
4
];
unsigned
char
cmdcnt
;
unsigned
char
set
;
unsigned
char
release
;
int
lastkey
;
volatile
signed
char
ack
;
unsigned
char
emul
;
unsigned
short
id
;
...
...
@@ -142,6 +145,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
printk
(
KERN_DEBUG
"atkbd.c: Received %02x flags %02x
\n
"
,
data
,
flags
);
#endif
#if !defined(__i386__) && !defined (__x86_64__)
if
((
flags
&
(
SERIO_FRAME
|
SERIO_PARITY
))
&&
(
~
flags
&
SERIO_TIMEOUT
)
&&
!
atkbd
->
resend
&&
atkbd
->
write
)
{
printk
(
"atkbd.c: frame/parity error: %02x
\n
"
,
flags
);
serio_write
(
serio
,
ATKBD_CMD_RESEND
);
...
...
@@ -151,6 +155,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
if
(
!
flags
)
atkbd
->
resend
=
0
;
#endif
switch
(
code
)
{
case
ATKBD_RET_ACK
:
...
...
@@ -195,6 +200,14 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
atkbd
->
set
,
code
,
serio
->
phys
,
atkbd
->
release
?
"released"
:
"pressed"
);
break
;
default:
if
(
!
atkbd
->
release
)
{
mod_timer
(
&
atkbd
->
timer
,
jiffies
+
(
test_bit
(
atkbd
->
keycode
[
code
],
&
atkbd
->
dev
.
key
)
?
HZ
/
33
:
HZ
/
4
)
+
HZ
/
100
);
atkbd
->
lastkey
=
atkbd
->
keycode
[
code
];
}
input_regs
(
&
atkbd
->
dev
,
regs
);
input_report_key
(
&
atkbd
->
dev
,
atkbd
->
keycode
[
code
],
!
atkbd
->
release
);
input_sync
(
&
atkbd
->
dev
);
...
...
@@ -205,6 +218,13 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
return
IRQ_HANDLED
;
}
static
void
atkbd_force_key_up
(
unsigned
long
data
)
{
struct
atkbd
*
atkbd
=
(
void
*
)
data
;
input_report_key
(
&
atkbd
->
dev
,
atkbd
->
lastkey
,
0
);
input_sync
(
&
atkbd
->
dev
);
}
/*
* atkbd_sendbyte() sends a byte to the keyboard, and waits for
* acknowledge. It doesn't handle resends according to the keyboard
...
...
@@ -214,7 +234,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
static
int
atkbd_sendbyte
(
struct
atkbd
*
atkbd
,
unsigned
char
byte
)
{
int
timeout
=
10000
;
/* 1
00 msec */
int
timeout
=
20000
;
/* 2
00 msec */
atkbd
->
ack
=
0
;
#ifdef ATKBD_DEBUG
...
...
@@ -322,13 +342,50 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co
}
/*
*
Enable keyboard
.
*
atkbd_probe() probes for an AT keyboard on a serio port
.
*/
static
void
atkbd_enable
(
struct
atkbd
*
atkbd
)
static
int
atkbd_probe
(
struct
atkbd
*
atkbd
)
{
if
(
atkbd_command
(
atkbd
,
NULL
,
ATKBD_CMD_ENABLE
))
printk
(
KERN_ERR
"atkbd.c: Failed to enable keyboard on %s
\n
"
,
atkbd
->
serio
->
phys
);
unsigned
char
param
[
2
];
/*
* Some systems, where the bit-twiddling when testing the io-lines of the
* controller may confuse the keyboard need a full reset of the keyboard. On
* these systems the BIOS also usually doesn't do it for us.
*/
if
(
atkbd_reset
)
if
(
atkbd_command
(
atkbd
,
NULL
,
ATKBD_CMD_RESET_BAT
))
printk
(
KERN_WARNING
"atkbd.c: keyboard reset failed on %s
\n
"
,
atkbd
->
serio
->
phys
);
/*
* Then we check the keyboard ID. We should get 0xab83 under normal conditions.
* Some keyboards report different values, but the first byte is always 0xab or
* 0xac. Some old AT keyboards don't report anything. If a mouse is connected, this
* should make sure we don't try to set the LEDs on it.
*/
if
(
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_GETID
))
{
/*
* If the get ID command failed, we check if we can at least set the LEDs on
* the keyboard. This should work on every keyboard out there. It also turns
* the LEDs off, which we want anyway.
*/
param
[
0
]
=
0
;
if
(
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_SETLEDS
))
return
-
1
;
atkbd
->
id
=
0xabba
;
return
0
;
}
if
(
param
[
0
]
!=
0xab
&&
param
[
0
]
!=
0xac
)
return
-
1
;
atkbd
->
id
=
(
param
[
0
]
<<
8
)
|
param
[
1
];
return
0
;
}
/*
...
...
@@ -365,102 +422,56 @@ static int atkbd_set_3(struct atkbd *atkbd)
return
4
;
}
/*
* Try to set the set we want.
*/
if
(
atkbd_set
!=
3
)
return
2
;
param
[
0
]
=
atkbd_set
;
param
[
0
]
=
3
;
if
(
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_SSCANSET
))
return
2
;
/*
* Read set number. Beware here. Some keyboards always send '2'
* or some other number regardless into what mode they have been
* attempted to be set. Other keyboards treat the '0' command as
* 'set to set 0', and not 'report current set' as they should.
* In that case we time out, and return 2.
*/
param
[
0
]
=
0
;
if
(
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_GSCANSET
))
return
2
;
/*
* Here we return the set number the keyboard reports about
* itself.
*/
if
(
param
[
0
]
!=
3
)
return
2
;
return
(
param
[
0
]
==
3
)
?
3
:
2
;
return
3
;
}
/*
* atkbd_probe() probes for an AT keyboard on a serio port.
*/
static
int
atkbd_probe
(
struct
atkbd
*
atkbd
)
static
int
atkbd_enable
(
struct
atkbd
*
atkbd
)
{
unsigned
char
param
[
2
];
unsigned
char
param
[
1
];
/*
* Some systems, where the bit-twiddling when testing the io-lines of the
* controller may confuse the keyboard need a full reset of the keyboard. On
* these systems the BIOS also usually doesn't do it for us.
* Set the LEDs to a defined state.
*/
if
(
atkbd_reset
)
if
(
atkbd_command
(
atkbd
,
NULL
,
ATKBD_CMD_RESET_BAT
))
printk
(
KERN_WARNING
"atkbd.c: keyboard reset failed on %s
\n
"
,
atkbd
->
serio
->
phys
);
param
[
0
]
=
0
;
if
(
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_SETLEDS
))
return
-
1
;
/*
* Then we check the keyboard ID. We should get 0xab83 under normal conditions.
* Some keyboards report different values, but the first byte is always 0xab or
* 0xac. Some old AT keyboards don't report anything.
* Set autorepeat to fastest possible.
*/
if
(
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_GETID
))
{
/*
* If the get ID command failed, we check if we can at least set the LEDs on
* the keyboard. This should work on every keyboard out there. It also turns
* the LEDs off, which we want anyway.
*/
param
[
0
]
=
0
;
if
(
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_SETLEDS
))
return
-
1
;
atkbd
->
id
=
0xabba
;
return
0
;
}
if
(
param
[
0
]
!=
0xab
&&
param
[
0
]
!=
0xac
)
if
(
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_SETREP
))
return
-
1
;
atkbd
->
id
=
(
param
[
0
]
<<
8
)
|
param
[
1
];
/*
*
Set the LEDs to a defined state
.
*
Enable the keyboard to receive keystrokes
.
*/
param
[
0
]
=
0
;
if
(
atkbd_command
(
atkbd
,
param
,
ATKBD_CMD_SETLEDS
))
if
(
atkbd_command
(
atkbd
,
NULL
,
ATKBD_CMD_ENABLE
))
{
printk
(
KERN_ERR
"atkbd.c: Failed to enable keyboard on %s
\n
"
,
atkbd
->
serio
->
phys
);
return
-
1
;
}
return
0
;
}
/*
* Disable autorepeat. We don't need it, as we do it in software anyway,
* because that way can get faster repeat, and have less system load (less
* accesses to the slow ISA hardware). If this fails, we don't care, and will
* just ignore the repeated keys.
*
* This command is for scancode set 3 only.
*/
static
void
atkbd_disable_autorepeat
(
struct
atkbd
*
atkbd
)
{
atkbd_command
(
atkbd
,
NULL
,
ATKBD_CMD_SETALL_MB
);
}
/*
* atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
* reboot.
...
...
@@ -485,7 +496,7 @@ static void atkbd_disconnect(struct serio *serio)
}
/*
* atkbd_connect() is called when the serio module finds an interface
* atkbd_connect() is called when the serio module finds an
d
interface
* that isn't handled yet by an appropriate device driver. We check if
* there is an AT keyboard out there and if yes, we register ourselves
* to the input module.
...
...
@@ -513,6 +524,9 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
atkbd
->
dev
.
ledbit
[
0
]
=
BIT
(
LED_NUML
)
|
BIT
(
LED_CAPSL
)
|
BIT
(
LED_SCROLLL
);
}
else
atkbd
->
dev
.
evbit
[
0
]
=
BIT
(
EV_KEY
)
|
BIT
(
EV_REP
);
atkbd
->
dev
.
rep
[
REP_DELAY
]
=
HZ
/
4
+
HZ
/
50
;
atkbd
->
dev
.
rep
[
REP_PERIOD
]
=
HZ
/
33
;
atkbd
->
serio
=
serio
;
init_input_dev
(
&
atkbd
->
dev
);
...
...
@@ -525,6 +539,10 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
serio
->
private
=
atkbd
;
init_timer
(
&
atkbd
->
timer
);
atkbd
->
timer
.
data
=
(
long
)
atkbd
;
atkbd
->
timer
.
function
=
atkbd_force_key_up
;
if
(
serio_open
(
serio
,
dev
))
{
kfree
(
atkbd
);
return
;
...
...
@@ -539,9 +557,8 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
}
atkbd
->
set
=
atkbd_set_3
(
atkbd
);
if
(
atkbd
->
set
==
3
)
atkbd_disable_autorepeat
(
atkbd
);
atkbd_enable
(
atkbd
);
}
else
{
atkbd
->
set
=
2
;
atkbd
->
id
=
0xab00
;
...
...
drivers/input/mouse/Kconfig
View file @
9d9226df
...
...
@@ -19,9 +19,7 @@ config MOUSE_PS2
Say Y here if you have a PS/2 mouse connected to your system. This
includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
mice with wheels and extra buttons, Microsoft, Logitech or Genius
compatible. Support for Synaptics TouchPads is also included.
For Synaptics TouchPad support in XFree86 you'll need this XFree86
driver: http://w1.894.telia.com/~u89404340/touchpad/index.html
compatible.
If unsure, say Y.
...
...
@@ -30,6 +28,22 @@ config MOUSE_PS2
The module will be called psmouse. If you want to compile it as a
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://w1.894.telia.com/~u89404340/touchpad/index.html
The gpm program is not yet able to interpret the data from this
driver, so if you need to use the touchpad in the console, you have to
say N for now.
config MOUSE_SERIAL
tristate "Serial mouse"
depends on INPUT && INPUT_MOUSE && SERIO
...
...
drivers/input/mouse/psmouse-base.c
View file @
9d9226df
...
...
@@ -17,6 +17,7 @@
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>
#include <linux/pm.h>
#include "psmouse.h"
#include "synaptics.h"
#include "logips2pp.h"
...
...
@@ -29,6 +30,8 @@ MODULE_PARM(psmouse_resolution, "i");
MODULE_PARM_DESC
(
psmouse_resolution
,
"Resolution, in dpi."
);
MODULE_PARM
(
psmouse_smartscroll
,
"i"
);
MODULE_PARM_DESC
(
psmouse_smartscroll
,
"Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."
);
MODULE_PARM
(
psmouse_resetafter
,
"i"
);
MODULE_PARM_DESC
(
psmouse_resetafter
,
"Reset Synaptics Touchpad after so many bad packets (0 = never)."
);
MODULE_LICENSE
(
"GPL"
);
#define PSMOUSE_LOGITECH_SMARTSCROLL 1
...
...
@@ -36,11 +39,12 @@ MODULE_LICENSE("GPL");
static
int
psmouse_noext
;
int
psmouse_resolution
;
int
psmouse_smartscroll
=
PSMOUSE_LOGITECH_SMARTSCROLL
;
unsigned
int
psmouse_resetafter
;
static
char
*
psmouse_protocols
[]
=
{
"None"
,
"PS/2"
,
"PS2++"
,
"PS2T++"
,
"GenPS/2"
,
"ImPS/2"
,
"ImExPS/2"
,
"Syn
aptics
"
};
static
char
*
psmouse_protocols
[]
=
{
"None"
,
"PS/2"
,
"PS2++"
,
"PS2T++"
,
"GenPS/2"
,
"ImPS/2"
,
"ImExPS/2"
,
"Syn
PS/2
"
};
/*
* psmouse_process_packet() anlyzes the PS/2 mouse packet contents and
* psmouse_process_packet() an
a
lyzes the PS/2 mouse packet contents and
* reports relevant events to the input module.
*/
...
...
@@ -108,6 +112,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
{
struct
psmouse
*
psmouse
=
serio
->
private
;
if
(
psmouse
->
state
==
PSMOUSE_IGNORE
)
goto
out
;
if
(
psmouse
->
acking
)
{
switch
(
data
)
{
case
PSMOUSE_RET_ACK
:
...
...
@@ -132,20 +139,35 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
}
if
(
psmouse
->
pktcnt
&&
time_after
(
jiffies
,
psmouse
->
last
+
HZ
/
2
))
{
printk
(
KERN_WARNING
"psmouse.c: Lost synchronization, throwing %d bytes away.
\n
"
,
psmouse
->
pktcnt
);
printk
(
KERN_WARNING
"psmouse.c: %s at %s lost synchronization, throwing %d bytes away.
\n
"
,
psmouse
->
name
,
psmouse
->
phys
,
psmouse
->
pktcnt
);
psmouse
->
pktcnt
=
0
;
}
psmouse
->
last
=
jiffies
;
psmouse
->
packet
[
psmouse
->
pktcnt
++
]
=
data
;
if
(
psmouse
->
pktcnt
==
3
+
(
psmouse
->
type
>=
PSMOUSE_GENPS
))
{
psmouse_process_packet
(
psmouse
,
regs
);
if
(
psmouse
->
packet
[
0
]
==
PSMOUSE_RET_BAT
)
{
if
(
psmouse
->
pktcnt
==
1
)
goto
out
;
if
(
psmouse
->
pktcnt
==
2
)
{
if
(
psmouse
->
packet
[
1
]
==
PSMOUSE_RET_ID
)
{
psmouse
->
state
=
PSMOUSE_IGNORE
;
serio_rescan
(
serio
);
goto
out
;
}
if
(
psmouse
->
type
==
PSMOUSE_SYNAPTICS
)
{
/* neither 0xAA nor 0x00 are valid first bytes
* for a packet in absolute mode
*/
psmouse
->
pktcnt
=
0
;
goto
out
;
}
}
}
if
(
psmouse
->
pktcnt
==
1
&&
psmouse
->
type
==
PSMOUSE_SYNAPTICS
)
{
if
(
psmouse
->
type
==
PSMOUSE_SYNAPTICS
)
{
/*
* The synaptics driver has its own resync logic,
* so it needs to receive all bytes one at a time.
...
...
@@ -155,8 +177,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
goto
out
;
}
if
(
psmouse
->
pktcnt
==
1
&&
psmouse
->
packet
[
0
]
==
PSMOUSE_RET_BAT
)
{
serio_rescan
(
serio
);
if
(
psmouse
->
pktcnt
==
3
+
(
psmouse
->
type
>=
PSMOUSE_GENPS
))
{
psmouse_process_packet
(
psmouse
,
regs
);
psmouse
->
pktcnt
=
0
;
goto
out
;
}
out:
...
...
@@ -200,7 +223,7 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
psmouse
->
cmdcnt
=
receive
;
if
(
command
==
PSMOUSE_CMD_RESET_BAT
)
timeout
=
2000000
;
/* 2
sec */
timeout
=
4000000
;
/* 4
sec */
if
(
command
&
0xff
)
if
(
psmouse_sendbyte
(
psmouse
,
command
&
0xff
))
...
...
@@ -450,14 +473,18 @@ static void psmouse_initialize(struct psmouse *psmouse)
*/
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETSTREAM
);
}
/*
*
Last, we enable the mouse so that we get
reports from it.
*
psmouse_activate() enables the mouse so that we get motion
reports from it.
*/
static
void
psmouse_activate
(
struct
psmouse
*
psmouse
)
{
if
(
psmouse_command
(
psmouse
,
NULL
,
PSMOUSE_CMD_ENABLE
))
printk
(
KERN_WARNING
"psmouse.c: Failed to enable mouse on %s
\n
"
,
psmouse
->
serio
->
phys
);
psmouse
->
state
=
PSMOUSE_ACTIVATED
;
}
/*
...
...
@@ -478,12 +505,38 @@ static void psmouse_cleanup(struct serio *serio)
static
void
psmouse_disconnect
(
struct
serio
*
serio
)
{
struct
psmouse
*
psmouse
=
serio
->
private
;
psmouse
->
state
=
PSMOUSE_IGNORE
;
synaptics_disconnect
(
psmouse
);
input_unregister_device
(
&
psmouse
->
dev
);
serio_close
(
serio
);
synaptics_disconnect
(
psmouse
);
kfree
(
psmouse
);
}
/*
* Reinitialize mouse hardware after software suspend.
*/
static
int
psmouse_pm_callback
(
struct
pm_dev
*
dev
,
pm_request_t
request
,
void
*
data
)
{
struct
psmouse
*
psmouse
=
dev
->
data
;
struct
serio_dev
*
ser_dev
=
psmouse
->
serio
->
dev
;
synaptics_disconnect
(
psmouse
);
/* We need to reopen the serio port to reinitialize the i8042 controller */
serio_close
(
psmouse
->
serio
);
serio_open
(
psmouse
->
serio
,
ser_dev
);
/* Probe and re-initialize the mouse */
psmouse_probe
(
psmouse
);
psmouse_initialize
(
psmouse
);
synaptics_pt_init
(
psmouse
);
psmouse_activate
(
psmouse
);
return
0
;
}
/*
* psmouse_connect() is a callback from the serio module when
* an unhandled serio port is found.
...
...
@@ -492,8 +545,10 @@ static void psmouse_disconnect(struct serio *serio)
static
void
psmouse_connect
(
struct
serio
*
serio
,
struct
serio_dev
*
dev
)
{
struct
psmouse
*
psmouse
;
struct
pm_dev
*
pmdev
;
if
((
serio
->
type
&
SERIO_TYPE
)
!=
SERIO_8042
)
if
((
serio
->
type
&
SERIO_TYPE
)
!=
SERIO_8042
&&
(
serio
->
type
&
SERIO_TYPE
)
!=
SERIO_PS_PSTHRU
)
return
;
if
(
!
(
psmouse
=
kmalloc
(
sizeof
(
struct
psmouse
),
GFP_KERNEL
)))
...
...
@@ -506,6 +561,7 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
psmouse
->
dev
.
keybit
[
LONG
(
BTN_MOUSE
)]
=
BIT
(
BTN_LEFT
)
|
BIT
(
BTN_MIDDLE
)
|
BIT
(
BTN_RIGHT
);
psmouse
->
dev
.
relbit
[
0
]
=
BIT
(
REL_X
)
|
BIT
(
REL_Y
);
psmouse
->
state
=
PSMOUSE_NEW_DEVICE
;
psmouse
->
serio
=
serio
;
psmouse
->
dev
.
private
=
psmouse
;
...
...
@@ -522,6 +578,12 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
return
;
}
pmdev
=
pm_register
(
PM_SYS_DEV
,
PM_SYS_UNKNOWN
,
psmouse_pm_callback
);
if
(
pmdev
)
{
psmouse
->
dev
.
pm_dev
=
pmdev
;
pmdev
->
data
=
psmouse
;
}
sprintf
(
psmouse
->
devname
,
"%s %s %s"
,
psmouse_protocols
[
psmouse
->
type
],
psmouse
->
vendor
,
psmouse
->
name
);
sprintf
(
psmouse
->
phys
,
"%s/input0"
,
...
...
@@ -539,6 +601,10 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
printk
(
KERN_INFO
"input: %s on %s
\n
"
,
psmouse
->
devname
,
serio
->
phys
);
psmouse_initialize
(
psmouse
);
synaptics_pt_init
(
psmouse
);
psmouse_activate
(
psmouse
);
}
static
struct
serio_dev
psmouse_dev
=
{
...
...
@@ -567,9 +633,16 @@ static int __init psmouse_smartscroll_setup(char *str)
return
1
;
}
static
int
__init
psmouse_resetafter_setup
(
char
*
str
)
{
get_option
(
&
str
,
&
psmouse_resetafter
);
return
1
;
}
__setup
(
"psmouse_noext"
,
psmouse_noext_setup
);
__setup
(
"psmouse_resolution="
,
psmouse_resolution_setup
);
__setup
(
"psmouse_smartscroll="
,
psmouse_smartscroll_setup
);
__setup
(
"psmouse_resetafter="
,
psmouse_resetafter_setup
);
#endif
...
...
drivers/input/mouse/psmouse.h
View file @
9d9226df
...
...
@@ -13,9 +13,15 @@
#define PSMOUSE_CMD_RESET_BAT 0x02ff
#define PSMOUSE_RET_BAT 0xaa
#define PSMOUSE_RET_ID 0x00
#define PSMOUSE_RET_ACK 0xfa
#define PSMOUSE_RET_NAK 0xfe
/* psmouse states */
#define PSMOUSE_NEW_DEVICE 0
#define PSMOUSE_ACTIVATED 1
#define PSMOUSE_IGNORE 2
struct
psmouse
{
void
*
private
;
struct
input_dev
dev
;
...
...
@@ -29,6 +35,7 @@ struct psmouse {
unsigned
char
type
;
unsigned
char
model
;
unsigned
long
last
;
unsigned
char
state
;
char
acking
;
volatile
char
ack
;
char
error
;
...
...
@@ -47,5 +54,6 @@ struct psmouse {
int
psmouse_command
(
struct
psmouse
*
psmouse
,
unsigned
char
*
param
,
int
command
);
extern
int
psmouse_smartscroll
;
extern
unsigned
int
psmouse_resetafter
;
#endif
/* _PSMOUSE_H */
drivers/input/mouse/synaptics.c
View file @
9d9226df
/*
* Synaptics TouchPad PS/2 mouse driver
*
* 2003 Dmitry Torokhov <dtor@mail.ru>
* Added support for pass-through port
*
* 2003 Peter Osterlund <petero2@telia.com>
* Ported to 2.5 input device infrastructure.
*
...
...
@@ -21,6 +24,7 @@
#include <linux/module.h>
#include <linux/input.h>
#include <linux/serio.h>
#include "psmouse.h"
#include "synaptics.h"
...
...
@@ -71,7 +75,7 @@ static int synaptics_set_mode(struct psmouse *psmouse, unsigned char mode)
if
(
synaptics_special_cmd
(
psmouse
,
mode
))
return
-
1
;
param
[
0
]
=
0x14
;
param
[
0
]
=
SYN_PS_SET_MODE2
;
if
(
psmouse_command
(
psmouse
,
param
,
PSMOUSE_CMD_SETRATE
))
return
-
1
;
return
0
;
...
...
@@ -83,7 +87,7 @@ static int synaptics_reset(struct psmouse *psmouse)
if
(
psmouse_command
(
psmouse
,
r
,
PSMOUSE_CMD_RESET_BAT
))
return
-
1
;
if
(
r
[
0
]
==
0xAA
&&
r
[
1
]
==
0x00
)
if
(
r
[
0
]
==
PSMOUSE_RET_BAT
&&
r
[
1
]
==
PSMOUSE_RET_ID
)
return
0
;
return
-
1
;
}
...
...
@@ -106,16 +110,25 @@ static int synaptics_model_id(struct psmouse *psmouse, unsigned long int *model_
* Read the capability-bits from the touchpad
* see also the SYN_CAP_* macros
*/
static
int
synaptics_capability
(
struct
psmouse
*
psmouse
,
unsigned
long
int
*
capability
)
static
int
synaptics_capability
(
struct
psmouse
*
psmouse
,
unsigned
long
int
*
capability
,
unsigned
long
int
*
ext_cap
)
{
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
;
*
ext_cap
=
0
;
if
(
!
SYN_CAP_VALID
(
*
capability
))
return
-
1
;
if
(
SYN_EXT_CAP_REQUESTS
(
*
capability
))
{
if
(
synaptics_send_cmd
(
psmouse
,
SYN_QUE_EXT_CAPAB
,
cap
))
{
printk
(
KERN_ERR
"Synaptics claims to have extended capabilities,"
" but I'm not able to read them."
);
}
else
*
ext_cap
=
(
cap
[
0
]
<<
16
)
|
(
cap
[
1
]
<<
8
)
|
cap
[
2
];
}
return
0
;
}
/*
...
...
@@ -134,19 +147,11 @@ static int synaptics_identify(struct psmouse *psmouse, unsigned long int *ident)
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
),
printk
(
KERN_INFO
" Fir
m
ware: %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
))
...
...
@@ -159,12 +164,17 @@ static void print_ident(struct synaptics_data *priv)
if
(
SYN_CAP_EXTENDED
(
priv
->
capabilities
))
{
printk
(
KERN_INFO
" Touchpad has extended capability bits
\n
"
);
if
(
SYN_CAP_FOUR_BUTTON
(
priv
->
capabilities
))
if
(
SYN_CAP_MULTI_BUTTON_NO
(
priv
->
ext_cap
))
printk
(
KERN_INFO
" -> %d multi-buttons, i.e. besides standard buttons
\n
"
,
(
int
)(
SYN_CAP_MULTI_BUTTON_NO
(
priv
->
ext_cap
)));
else
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
"
);
if
(
SYN_CAP_PASS_THROUGH
(
priv
->
capabilities
))
printk
(
KERN_INFO
" -> pass-through port
\n
"
);
}
}
...
...
@@ -172,6 +182,7 @@ static int query_hardware(struct psmouse *psmouse)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
int
retries
=
0
;
int
mode
;
while
((
retries
++
<
3
)
&&
synaptics_reset
(
psmouse
))
printk
(
KERN_ERR
"synaptics reset failed
\n
"
);
...
...
@@ -180,17 +191,107 @@ static int query_hardware(struct psmouse *psmouse)
return
-
1
;
if
(
synaptics_model_id
(
psmouse
,
&
priv
->
model_id
))
return
-
1
;
if
(
synaptics_capability
(
psmouse
,
&
priv
->
capabilities
))
if
(
synaptics_capability
(
psmouse
,
&
priv
->
capabilities
,
&
priv
->
ext_cap
))
return
-
1
;
mode
=
SYN_BIT_ABSOLUTE_MODE
|
SYN_BIT_HIGH_RATE
;
if
(
SYN_ID_MAJOR
(
priv
->
identity
)
>=
4
)
mode
|=
SYN_BIT_DISABLE_GESTURE
;
if
(
SYN_CAP_EXTENDED
(
priv
->
capabilities
))
mode
|=
SYN_BIT_W_MODE
;
if
(
synaptics_set_mode
(
psmouse
,
mode
))
return
-
1
;
return
0
;
}
/*****************************************************************************
* Synaptics pass-through PS/2 port support
****************************************************************************/
static
int
synaptics_pt_open
(
struct
serio
*
port
)
{
return
0
;
}
static
void
synaptics_pt_close
(
struct
serio
*
port
)
{
}
static
int
synaptics_pt_write
(
struct
serio
*
port
,
unsigned
char
c
)
{
struct
psmouse
*
parent
=
port
->
driver
;
char
rate_param
=
SYN_PS_CLIENT_CMD
;
/* indicates that we want pass-through port */
if
(
synaptics_special_cmd
(
parent
,
c
))
return
-
1
;
if
(
psmouse_command
(
parent
,
&
rate_param
,
PSMOUSE_CMD_SETRATE
))
return
-
1
;
return
0
;
}
static
inline
int
synaptics_is_pt_packet
(
unsigned
char
*
buf
)
{
return
(
buf
[
0
]
&
0xFC
)
==
0x84
&&
(
buf
[
3
]
&
0xCC
)
==
0xC4
;
}
static
void
synaptics_pass_pt_packet
(
struct
serio
*
ptport
,
unsigned
char
*
packet
)
{
struct
psmouse
*
child
=
ptport
->
private
;
if
(
child
)
{
if
(
child
->
state
==
PSMOUSE_ACTIVATED
)
{
serio_interrupt
(
ptport
,
packet
[
1
],
0
,
NULL
);
serio_interrupt
(
ptport
,
packet
[
4
],
0
,
NULL
);
serio_interrupt
(
ptport
,
packet
[
5
],
0
,
NULL
);
if
(
child
->
type
>=
PSMOUSE_GENPS
)
serio_interrupt
(
ptport
,
packet
[
2
],
0
,
NULL
);
}
else
if
(
child
->
state
!=
PSMOUSE_IGNORE
)
{
serio_interrupt
(
ptport
,
packet
[
1
],
0
,
NULL
);
}
}
}
int
synaptics_pt_init
(
struct
psmouse
*
psmouse
)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
struct
serio
*
port
;
struct
psmouse
*
child
;
if
(
psmouse
->
type
!=
PSMOUSE_SYNAPTICS
)
return
-
1
;
if
(
!
SYN_CAP_EXTENDED
(
priv
->
capabilities
))
return
-
1
;
if
(
!
SYN_CAP_PASS_THROUGH
(
priv
->
capabilities
))
return
-
1
;
priv
->
ptport
=
port
=
kmalloc
(
sizeof
(
struct
serio
),
GFP_KERNEL
);
if
(
!
port
)
{
printk
(
KERN_ERR
"synaptics: not enough memory to allocate serio port
\n
"
);
return
-
1
;
}
memset
(
port
,
0
,
sizeof
(
struct
serio
));
port
->
type
=
SERIO_PS_PSTHRU
;
port
->
name
=
"Synaptics pass-through"
;
port
->
phys
=
"synaptics-pt/serio0"
;
port
->
write
=
synaptics_pt_write
;
port
->
open
=
synaptics_pt_open
;
port
->
close
=
synaptics_pt_close
;
port
->
driver
=
psmouse
;
printk
(
KERN_INFO
"serio: %s port at %s
\n
"
,
port
->
name
,
psmouse
->
phys
);
serio_register_slave_port
(
port
);
/* adjust the touchpad to child's choice of protocol */
child
=
port
->
private
;
if
(
child
&&
child
->
type
>=
PSMOUSE_GENPS
)
{
if
(
synaptics_set_mode
(
psmouse
,
(
SYN_BIT_ABSOLUTE_MODE
|
SYN_BIT_HIGH_RATE
|
SYN_BIT_DISABLE_GESTURE
|
SYN_BIT_FOUR_BYTE_CLIENT
|
SYN_BIT_W_MODE
)))
return
-
1
;
synaptics_enable_device
(
psmouse
);
print_ident
(
priv
);
printk
(
KERN_INFO
"synaptics: failed to enable 4-byte guest protocol
\n
"
);
}
return
0
;
}
...
...
@@ -213,22 +314,27 @@ int synaptics_init(struct psmouse *psmouse)
{
struct
synaptics_data
*
priv
;
#ifndef CONFIG_MOUSE_PS2_SYNAPTICS
return
-
1
;
#endif
psmouse
->
private
=
priv
=
kmalloc
(
sizeof
(
struct
synaptics_data
),
GFP_KERNEL
);
if
(
!
priv
)
return
-
1
;
memset
(
priv
,
0
,
sizeof
(
struct
synaptics_data
));
priv
->
inSync
=
1
;
priv
->
out_of_sync
=
0
;
if
(
query_hardware
(
psmouse
))
{
printk
(
KERN_ERR
"Unable to query/initialize Synaptics hardware.
\n
"
);
goto
init_fail
;
}
print_ident
(
priv
);
/*
* 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 sens
e
r.
* the sens
o
r.
*/
set_bit
(
EV_ABS
,
psmouse
->
dev
.
evbit
);
set_abs_params
(
&
psmouse
->
dev
,
ABS_X
,
1472
,
5472
,
0
,
0
);
...
...
@@ -243,7 +349,24 @@ int synaptics_init(struct psmouse *psmouse)
set_bit
(
BTN_RIGHT
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_FORWARD
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_BACK
,
psmouse
->
dev
.
keybit
);
if
(
SYN_CAP_MULTI_BUTTON_NO
(
priv
->
ext_cap
))
switch
(
SYN_CAP_MULTI_BUTTON_NO
(
priv
->
ext_cap
)
&
~
0x01
)
{
default:
printk
(
KERN_ERR
"This touchpad reports more than 8 multi-buttons, don't know how to handle.
\n
"
);
case
8
:
set_bit
(
BTN_7
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_6
,
psmouse
->
dev
.
keybit
);
case
6
:
set_bit
(
BTN_5
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_4
,
psmouse
->
dev
.
keybit
);
case
4
:
set_bit
(
BTN_3
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_2
,
psmouse
->
dev
.
keybit
);
case
2
:
set_bit
(
BTN_1
,
psmouse
->
dev
.
keybit
);
set_bit
(
BTN_0
,
psmouse
->
dev
.
keybit
);
break
;
}
clear_bit
(
EV_REL
,
psmouse
->
dev
.
evbit
);
clear_bit
(
REL_X
,
psmouse
->
dev
.
relbit
);
clear_bit
(
REL_Y
,
psmouse
->
dev
.
relbit
);
...
...
@@ -259,17 +382,34 @@ void synaptics_disconnect(struct psmouse *psmouse)
{
struct
synaptics_data
*
priv
=
psmouse
->
private
;
if
(
psmouse
->
type
==
PSMOUSE_SYNAPTICS
&&
priv
)
{
synaptics_set_mode
(
psmouse
,
0
);
if
(
priv
->
ptport
)
{
serio_unregister_slave_port
(
priv
->
ptport
);
kfree
(
priv
->
ptport
);
}
kfree
(
priv
);
}
}
/*****************************************************************************
* Functions to interpret the absolute mode packets
****************************************************************************/
static
void
synaptics_parse_hw_state
(
struct
synaptics_data
*
priv
,
struct
synaptics_hw_state
*
hw
)
static
void
synaptics_parse_hw_state
(
unsigned
char
buf
[],
struct
synaptics_data
*
priv
,
struct
synaptics_hw_state
*
hw
)
{
unsigned
char
*
buf
=
priv
->
proto_buf
;
hw
->
up
=
0
;
hw
->
down
=
0
;
hw
->
b0
=
0
;
hw
->
b1
=
0
;
hw
->
b2
=
0
;
hw
->
b3
=
0
;
hw
->
b4
=
0
;
hw
->
b5
=
0
;
hw
->
b6
=
0
;
hw
->
b7
=
0
;
if
(
SYN_MODEL_NEWABS
(
priv
->
model_id
))
{
hw
->
x
=
(((
buf
[
3
]
&
0x10
)
<<
8
)
|
((
buf
[
1
]
&
0x0f
)
<<
8
)
|
buf
[
4
]);
...
...
@@ -283,10 +423,7 @@ static void synaptics_parse_hw_state(struct synaptics_data *priv, struct synapti
((
buf
[
3
]
&
0x04
)
>>
2
));
hw
->
left
=
(
buf
[
0
]
&
0x01
)
?
1
:
0
;
hw
->
right
=
(
buf
[
0
]
&
0x2
)
?
1
:
0
;
hw
->
up
=
0
;
hw
->
down
=
0
;
hw
->
right
=
(
buf
[
0
]
&
0x02
)
?
1
:
0
;
if
(
SYN_CAP_EXTENDED
(
priv
->
capabilities
)
&&
(
SYN_CAP_FOUR_BUTTON
(
priv
->
capabilities
)))
{
hw
->
up
=
((
buf
[
3
]
&
0x01
))
?
1
:
0
;
...
...
@@ -296,6 +433,35 @@ static void synaptics_parse_hw_state(struct synaptics_data *priv, struct synapti
if
(
hw
->
right
)
hw
->
down
=
!
hw
->
down
;
}
if
(
SYN_CAP_MULTI_BUTTON_NO
(
priv
->
ext_cap
)
&&
((
buf
[
3
]
&
2
)
?
!
hw
->
right
:
hw
->
right
))
{
switch
(
SYN_CAP_MULTI_BUTTON_NO
(
priv
->
ext_cap
)
&
~
0x01
)
{
default:
;
/* we did comment while initialising... */
case
8
:
hw
->
b7
=
((
buf
[
5
]
&
0x08
))
?
1
:
0
;
hw
->
b6
=
((
buf
[
4
]
&
0x08
))
?
1
:
0
;
case
6
:
hw
->
b5
=
((
buf
[
5
]
&
0x04
))
?
1
:
0
;
hw
->
b4
=
((
buf
[
4
]
&
0x04
))
?
1
:
0
;
case
4
:
hw
->
b3
=
((
buf
[
5
]
&
0x02
))
?
1
:
0
;
hw
->
b2
=
((
buf
[
4
]
&
0x02
))
?
1
:
0
;
case
2
:
hw
->
b1
=
((
buf
[
5
]
&
0x01
))
?
1
:
0
;
hw
->
b0
=
((
buf
[
4
]
&
0x01
))
?
1
:
0
;
}
}
}
else
{
hw
->
x
=
(((
buf
[
1
]
&
0x1f
)
<<
8
)
|
buf
[
2
]);
hw
->
y
=
(((
buf
[
4
]
&
0x1f
)
<<
8
)
|
buf
[
5
]);
hw
->
z
=
(((
buf
[
0
]
&
0x30
)
<<
2
)
|
(
buf
[
3
]
&
0x3F
));
hw
->
w
=
(((
buf
[
1
]
&
0x80
)
>>
4
)
|
((
buf
[
0
]
&
0x04
)
>>
1
));
hw
->
left
=
(
buf
[
0
]
&
0x01
)
?
1
:
0
;
hw
->
right
=
(
buf
[
0
]
&
0x02
)
?
1
:
0
;
}
}
/*
...
...
@@ -307,7 +473,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
struct
synaptics_data
*
priv
=
psmouse
->
private
;
struct
synaptics_hw_state
hw
;
synaptics_parse_hw_state
(
priv
,
&
hw
);
synaptics_parse_hw_state
(
p
smouse
->
packet
,
p
riv
,
&
hw
);
if
(
hw
.
z
>
0
)
{
int
w_ok
=
0
;
...
...
@@ -347,7 +513,24 @@ static void synaptics_process_packet(struct psmouse *psmouse)
input_report_key
(
dev
,
BTN_RIGHT
,
hw
.
right
);
input_report_key
(
dev
,
BTN_FORWARD
,
hw
.
up
);
input_report_key
(
dev
,
BTN_BACK
,
hw
.
down
);
if
(
SYN_CAP_MULTI_BUTTON_NO
(
priv
->
ext_cap
))
switch
(
SYN_CAP_MULTI_BUTTON_NO
(
priv
->
ext_cap
)
&
~
0x01
)
{
default:
;
/* we did comment while initialising... */
case
8
:
input_report_key
(
dev
,
BTN_7
,
hw
.
b7
);
input_report_key
(
dev
,
BTN_6
,
hw
.
b6
);
case
6
:
input_report_key
(
dev
,
BTN_5
,
hw
.
b5
);
input_report_key
(
dev
,
BTN_4
,
hw
.
b4
);
case
4
:
input_report_key
(
dev
,
BTN_3
,
hw
.
b3
);
input_report_key
(
dev
,
BTN_2
,
hw
.
b2
);
case
2
:
input_report_key
(
dev
,
BTN_1
,
hw
.
b1
);
input_report_key
(
dev
,
BTN_0
,
hw
.
b0
);
break
;
}
input_sync
(
dev
);
}
...
...
@@ -355,35 +538,59 @@ 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
]
;
unsigned
char
data
=
psmouse
->
packet
[
psmouse
->
pktcnt
-
1
]
;
int
newabs
=
SYN_MODEL_NEWABS
(
priv
->
model_id
)
;
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
;
switch
(
psmouse
->
pktcnt
)
{
case
1
:
if
(
newabs
?
((
data
&
0xC8
)
!=
0x80
)
:
((
data
&
0xC0
)
!=
0xC0
))
{
printk
(
KERN_WARNING
"Synaptics driver lost sync at 1st byte
\n
"
);
return
;
goto
bad_sync
;
}
/* check 4th byte */
if
((
priv
->
proto_buf_tail
==
4
)
&&
((
u
&
0xc8
)
!=
0xc0
))
{
priv
->
inSync
=
0
;
priv
->
proto_buf_tail
=
0
;
break
;
case
2
:
if
(
!
newabs
&&
((
data
&
0x60
)
!=
0x00
))
{
printk
(
KERN_WARNING
"Synaptics driver lost sync at 2nd byte
\n
"
);
goto
bad_sync
;
}
break
;
case
4
:
if
(
newabs
?
((
data
&
0xC8
)
!=
0xC0
)
:
((
data
&
0xC0
)
!=
0x80
))
{
printk
(
KERN_WARNING
"Synaptics driver lost sync at 4th byte
\n
"
);
return
;
goto
bad_sync
;
}
if
(
priv
->
proto_buf_tail
>=
6
)
{
/* Full packet received */
if
(
!
priv
->
inSync
)
{
priv
->
inSync
=
1
;
break
;
case
5
:
if
(
!
newabs
&&
((
data
&
0x60
)
!=
0x00
))
{
printk
(
KERN_WARNING
"Synaptics driver lost sync at 5th byte
\n
"
);
goto
bad_sync
;
}
break
;
default:
if
(
psmouse
->
pktcnt
>=
6
)
{
/* Full packet received */
if
(
priv
->
out_of_sync
)
{
priv
->
out_of_sync
=
0
;
printk
(
KERN_NOTICE
"Synaptics driver resynced.
\n
"
);
}
if
(
priv
->
ptport
&&
synaptics_is_pt_packet
(
psmouse
->
packet
))
synaptics_pass_pt_packet
(
priv
->
ptport
,
psmouse
->
packet
);
else
synaptics_process_packet
(
psmouse
);
priv
->
proto_buf_tail
=
0
;
psmouse
->
pktcnt
=
0
;
}
break
;
}
return
;
bad_sync:
priv
->
out_of_sync
++
;
psmouse
->
pktcnt
=
0
;
if
(
psmouse_resetafter
>
0
&&
priv
->
out_of_sync
==
psmouse_resetafter
)
{
psmouse
->
state
=
PSMOUSE_IGNORE
;
serio_rescan
(
psmouse
->
serio
);
}
}
drivers/input/mouse/synaptics.h
View file @
9d9226df
...
...
@@ -12,6 +12,7 @@
extern
void
synaptics_process_byte
(
struct
psmouse
*
psmouse
,
struct
pt_regs
*
regs
);
extern
int
synaptics_init
(
struct
psmouse
*
psmouse
);
extern
int
synaptics_pt_init
(
struct
psmouse
*
psmouse
);
extern
void
synaptics_disconnect
(
struct
psmouse
*
psmouse
);
/* synaptics queries */
...
...
@@ -22,12 +23,14 @@ extern void synaptics_disconnect(struct psmouse *psmouse);
#define SYN_QUE_SERIAL_NUMBER_PREFIX 0x06
#define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07
#define SYN_QUE_RESOLUTION 0x08
#define SYN_QUE_EXT_CAPAB 0x09
/* 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)
/* synaptics model ID bits */
...
...
@@ -42,11 +45,14 @@ extern void synaptics_disconnect(struct psmouse *psmouse);
/* synaptics capability bits */
#define SYN_CAP_EXTENDED(c) ((c) & (1 << 23))
#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_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47)
#define SYN_EXT_CAP_REQUESTS(c) ((((c) & 0x700000) >> 20) == 1)
#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12)
/* synaptics modes query bits */
#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
...
...
@@ -62,6 +68,10 @@ extern void synaptics_disconnect(struct psmouse *psmouse);
#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff)
#define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47)
/* synaptics special commands */
#define SYN_PS_SET_MODE2 0x14
#define SYN_PS_CLIENT_CMD 0x28
/*
* A structure to describe the state of the touchpad hardware (buttons and pad)
*/
...
...
@@ -75,21 +85,28 @@ struct synaptics_hw_state {
int
right
;
int
up
;
int
down
;
int
b0
;
int
b1
;
int
b2
;
int
b3
;
int
b4
;
int
b5
;
int
b6
;
int
b7
;
};
struct
synaptics_data
{
/* Data read from the touchpad */
unsigned
long
int
model_id
;
/* Model-ID */
unsigned
long
int
capabilities
;
/* Capabilities */
unsigned
long
int
ext_cap
;
/* Extended 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
;
unsigned
int
out_of_sync
;
/* # of packets out of sync */
int
old_w
;
/* Previous w value */
struct
serio
*
ptport
;
/* pass-through port */
};
#endif
/* _SYNAPTICS_H */
drivers/input/serio/serio.c
View file @
9d9226df
...
...
@@ -49,7 +49,9 @@ MODULE_LICENSE("GPL");
EXPORT_SYMBOL
(
serio_interrupt
);
EXPORT_SYMBOL
(
serio_register_port
);
EXPORT_SYMBOL
(
serio_register_slave_port
);
EXPORT_SYMBOL
(
serio_unregister_port
);
EXPORT_SYMBOL
(
serio_unregister_slave_port
);
EXPORT_SYMBOL
(
serio_register_device
);
EXPORT_SYMBOL
(
serio_unregister_device
);
EXPORT_SYMBOL
(
serio_open
);
...
...
@@ -166,6 +168,17 @@ void serio_register_port(struct serio *serio)
up
(
&
serio_sem
);
}
/*
* Same as serio_register_port but does not try to acquire serio_sem.
* Should be used when registering a serio from other input device's
* connect() function.
*/
void
serio_register_slave_port
(
struct
serio
*
serio
)
{
list_add_tail
(
&
serio
->
node
,
&
serio_list
);
serio_find_dev
(
serio
);
}
void
serio_unregister_port
(
struct
serio
*
serio
)
{
down
(
&
serio_sem
);
...
...
@@ -175,6 +188,18 @@ void serio_unregister_port(struct serio *serio)
up
(
&
serio_sem
);
}
/*
* Same as serio_unregister_port but does not try to acquire serio_sem.
* Should be used when unregistering a serio from other input device's
* disconnect() function.
*/
void
serio_unregister_slave_port
(
struct
serio
*
serio
)
{
list_del_init
(
&
serio
->
node
);
if
(
serio
->
dev
&&
serio
->
dev
->
disconnect
)
serio
->
dev
->
disconnect
(
serio
);
}
void
serio_register_device
(
struct
serio_dev
*
dev
)
{
struct
serio
*
serio
;
...
...
@@ -204,9 +229,11 @@ void serio_unregister_device(struct serio_dev *dev)
/* called from serio_dev->connect/disconnect methods under serio_sem */
int
serio_open
(
struct
serio
*
serio
,
struct
serio_dev
*
dev
)
{
if
(
serio
->
open
(
serio
))
return
-
1
;
serio
->
dev
=
dev
;
if
(
serio
->
open
(
serio
))
{
serio
->
dev
=
NULL
;
return
-
1
;
}
return
0
;
}
...
...
include/linux/input.h
View file @
9d9226df
...
...
@@ -751,7 +751,7 @@ struct ff_effect {
#define LONG(x) ((x)/BITS_PER_LONG)
#define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \
((dev->keycodesize ==
1
) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
((dev->keycodesize ==
2
) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
#define init_input_dev(dev) do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0)
...
...
include/linux/serio.h
View file @
9d9226df
...
...
@@ -65,7 +65,9 @@ void serio_rescan(struct serio *serio);
irqreturn_t
serio_interrupt
(
struct
serio
*
serio
,
unsigned
char
data
,
unsigned
int
flags
,
struct
pt_regs
*
regs
);
void
serio_register_port
(
struct
serio
*
serio
);
void
serio_register_slave_port
(
struct
serio
*
serio
);
void
serio_unregister_port
(
struct
serio
*
serio
);
void
serio_unregister_slave_port
(
struct
serio
*
serio
);
void
serio_register_device
(
struct
serio_dev
*
dev
);
void
serio_unregister_device
(
struct
serio_dev
*
dev
);
...
...
@@ -104,6 +106,7 @@ static __inline__ void serio_cleanup(struct serio *serio)
#define SERIO_RS232 0x02000000UL
#define SERIO_HIL_MLC 0x03000000UL
#define SERIO_PC9800 0x04000000UL
#define SERIO_PS_PSTHRU 0x05000000UL
#define SERIO_PROTO 0xFFUL
#define SERIO_MSC 0x01
...
...
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