Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci-2.6.23
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci-2.6.23
Commits
c7fd018d
Commit
c7fd018d
authored
Jan 29, 2006
by
Dmitry Torokhov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Input: gamecon - fix crash when accessing device
Signed-off-by:
Dmitry Torokhov
<
dtor@mail.ru
>
parent
07cf779c
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
194 additions
and
149 deletions
+194
-149
drivers/input/joystick/gamecon.c
drivers/input/joystick/gamecon.c
+194
-149
No files found.
drivers/input/joystick/gamecon.c
View file @
c7fd018d
...
@@ -159,6 +159,48 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data)
...
@@ -159,6 +159,48 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data)
}
}
static
void
gc_n64_process_packet
(
struct
gc
*
gc
)
{
unsigned
char
data
[
GC_N64_LENGTH
];
signed
char
axes
[
2
];
struct
input_dev
*
dev
;
int
i
,
j
,
s
;
gc_n64_read_packet
(
gc
,
data
);
for
(
i
=
0
;
i
<
GC_MAX_DEVICES
;
i
++
)
{
dev
=
gc
->
dev
[
i
];
if
(
!
dev
)
continue
;
s
=
gc_status_bit
[
i
];
if
(
s
&
gc
->
pads
[
GC_N64
]
&
~
(
data
[
8
]
|
data
[
9
]))
{
axes
[
0
]
=
axes
[
1
]
=
0
;
for
(
j
=
0
;
j
<
8
;
j
++
)
{
if
(
data
[
23
-
j
]
&
s
)
axes
[
0
]
|=
1
<<
j
;
if
(
data
[
31
-
j
]
&
s
)
axes
[
1
]
|=
1
<<
j
;
}
input_report_abs
(
dev
,
ABS_X
,
axes
[
0
]);
input_report_abs
(
dev
,
ABS_Y
,
-
axes
[
1
]);
input_report_abs
(
dev
,
ABS_HAT0X
,
!
(
s
&
data
[
6
])
-
!
(
s
&
data
[
7
]));
input_report_abs
(
dev
,
ABS_HAT0Y
,
!
(
s
&
data
[
4
])
-
!
(
s
&
data
[
5
]));
for
(
j
=
0
;
j
<
10
;
j
++
)
input_report_key
(
dev
,
gc_n64_btn
[
j
],
s
&
data
[
gc_n64_bytes
[
j
]]);
input_sync
(
dev
);
}
}
}
/*
/*
* NES/SNES support.
* NES/SNES support.
*/
*/
...
@@ -198,6 +240,39 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data)
...
@@ -198,6 +240,39 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data)
}
}
}
}
static
void
gc_nes_process_packet
(
struct
gc
*
gc
)
{
unsigned
char
data
[
GC_SNES_LENGTH
];
struct
input_dev
*
dev
;
int
i
,
j
,
s
;
gc_nes_read_packet
(
gc
,
gc
->
pads
[
GC_SNES
]
?
GC_SNES_LENGTH
:
GC_NES_LENGTH
,
data
);
for
(
i
=
0
;
i
<
GC_MAX_DEVICES
;
i
++
)
{
dev
=
gc
->
dev
[
i
];
if
(
!
dev
)
continue
;
s
=
gc_status_bit
[
i
];
if
(
s
&
(
gc
->
pads
[
GC_NES
]
|
gc
->
pads
[
GC_SNES
]))
{
input_report_abs
(
dev
,
ABS_X
,
!
(
s
&
data
[
6
])
-
!
(
s
&
data
[
7
]));
input_report_abs
(
dev
,
ABS_Y
,
!
(
s
&
data
[
4
])
-
!
(
s
&
data
[
5
]));
}
if
(
s
&
gc
->
pads
[
GC_NES
])
for
(
j
=
0
;
j
<
4
;
j
++
)
input_report_key
(
dev
,
gc_snes_btn
[
j
],
s
&
data
[
gc_nes_bytes
[
j
]]);
if
(
s
&
gc
->
pads
[
GC_SNES
])
for
(
j
=
0
;
j
<
8
;
j
++
)
input_report_key
(
dev
,
gc_snes_btn
[
j
],
s
&
data
[
gc_snes_bytes
[
j
]]);
input_sync
(
dev
);
}
}
/*
/*
* Multisystem joystick support
* Multisystem joystick support
*/
*/
...
@@ -219,6 +294,35 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data)
...
@@ -219,6 +294,35 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data)
}
}
}
}
static
void
gc_multi_process_packet
(
struct
gc
*
gc
)
{
unsigned
char
data
[
GC_MULTI2_LENGTH
];
struct
input_dev
*
dev
;
int
i
,
s
;
gc_multi_read_packet
(
gc
,
gc
->
pads
[
GC_MULTI2
]
?
GC_MULTI2_LENGTH
:
GC_MULTI_LENGTH
,
data
);
for
(
i
=
0
;
i
<
GC_MAX_DEVICES
;
i
++
)
{
dev
=
gc
->
dev
[
i
];
if
(
!
dev
)
continue
;
s
=
gc_status_bit
[
i
];
if
(
s
&
(
gc
->
pads
[
GC_MULTI
]
|
gc
->
pads
[
GC_MULTI2
]))
{
input_report_abs
(
dev
,
ABS_X
,
!
(
s
&
data
[
2
])
-
!
(
s
&
data
[
3
]));
input_report_abs
(
dev
,
ABS_Y
,
!
(
s
&
data
[
0
])
-
!
(
s
&
data
[
1
]));
input_report_key
(
dev
,
BTN_TRIGGER
,
s
&
data
[
4
]);
}
if
(
s
&
gc
->
pads
[
GC_MULTI2
])
input_report_key
(
dev
,
BTN_THUMB
,
s
&
data
[
5
]);
input_sync
(
dev
);
}
}
/*
/*
* PSX support
* PSX support
*
*
...
@@ -263,10 +367,11 @@ static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 };
...
@@ -263,10 +367,11 @@ static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 };
* the psx pad.
* the psx pad.
*/
*/
static
void
gc_psx_command
(
struct
gc
*
gc
,
int
b
,
unsigned
char
data
[
5
])
static
void
gc_psx_command
(
struct
gc
*
gc
,
int
b
,
unsigned
char
data
[
GC_MAX_DEVICES
])
{
{
int
i
,
j
,
cmd
,
read
;
int
i
,
j
,
cmd
,
read
;
for
(
i
=
0
;
i
<
5
;
i
++
)
for
(
i
=
0
;
i
<
GC_MAX_DEVICES
;
i
++
)
data
[
i
]
=
0
;
data
[
i
]
=
0
;
for
(
i
=
0
;
i
<
GC_PSX_LENGTH
;
i
++
,
b
>>=
1
)
{
for
(
i
=
0
;
i
<
GC_PSX_LENGTH
;
i
++
,
b
>>=
1
)
{
...
@@ -274,7 +379,7 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char data[5])
...
@@ -274,7 +379,7 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char data[5])
parport_write_data
(
gc
->
pd
->
port
,
cmd
|
GC_PSX_POWER
);
parport_write_data
(
gc
->
pd
->
port
,
cmd
|
GC_PSX_POWER
);
udelay
(
gc_psx_delay
);
udelay
(
gc_psx_delay
);
read
=
parport_read_status
(
gc
->
pd
->
port
)
^
0x80
;
read
=
parport_read_status
(
gc
->
pd
->
port
)
^
0x80
;
for
(
j
=
0
;
j
<
5
;
j
++
)
for
(
j
=
0
;
j
<
GC_MAX_DEVICES
;
j
++
)
data
[
j
]
|=
(
read
&
gc_status_bit
[
j
]
&
(
gc
->
pads
[
GC_PSX
]
|
gc
->
pads
[
GC_DDR
]))
?
(
1
<<
i
)
:
0
;
data
[
j
]
|=
(
read
&
gc_status_bit
[
j
]
&
(
gc
->
pads
[
GC_PSX
]
|
gc
->
pads
[
GC_DDR
]))
?
(
1
<<
i
)
:
0
;
parport_write_data
(
gc
->
pd
->
port
,
cmd
|
GC_PSX_CLOCK
|
GC_PSX_POWER
);
parport_write_data
(
gc
->
pd
->
port
,
cmd
|
GC_PSX_CLOCK
|
GC_PSX_POWER
);
udelay
(
gc_psx_delay
);
udelay
(
gc_psx_delay
);
...
@@ -286,11 +391,12 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char data[5])
...
@@ -286,11 +391,12 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char data[5])
* device identifier code.
* device identifier code.
*/
*/
static
void
gc_psx_read_packet
(
struct
gc
*
gc
,
unsigned
char
data
[
5
][
GC_PSX_BYTES
],
unsigned
char
id
[
5
])
static
void
gc_psx_read_packet
(
struct
gc
*
gc
,
unsigned
char
data
[
GC_MAX_DEVICES
][
GC_PSX_BYTES
],
unsigned
char
id
[
GC_MAX_DEVICES
])
{
{
int
i
,
j
,
max_len
=
0
;
int
i
,
j
,
max_len
=
0
;
unsigned
long
flags
;
unsigned
long
flags
;
unsigned
char
data2
[
5
];
unsigned
char
data2
[
GC_MAX_DEVICES
];
parport_write_data
(
gc
->
pd
->
port
,
GC_PSX_CLOCK
|
GC_PSX_SELECT
|
GC_PSX_POWER
);
/* Select pad */
parport_write_data
(
gc
->
pd
->
port
,
GC_PSX_CLOCK
|
GC_PSX_SELECT
|
GC_PSX_POWER
);
/* Select pad */
udelay
(
gc_psx_delay
);
udelay
(
gc_psx_delay
);
...
@@ -303,7 +409,7 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES
...
@@ -303,7 +409,7 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES
gc_psx_command
(
gc
,
0x42
,
id
);
/* Get device ids */
gc_psx_command
(
gc
,
0x42
,
id
);
/* Get device ids */
gc_psx_command
(
gc
,
0
,
data2
);
/* Dump status */
gc_psx_command
(
gc
,
0
,
data2
);
/* Dump status */
for
(
i
=
0
;
i
<
5
;
i
++
)
/* Find the longest pad */
for
(
i
=
0
;
i
<
GC_MAX_DEVICES
;
i
++
)
/* Find the longest pad */
if
((
gc_status_bit
[
i
]
&
(
gc
->
pads
[
GC_PSX
]
|
gc
->
pads
[
GC_DDR
]))
if
((
gc_status_bit
[
i
]
&
(
gc
->
pads
[
GC_PSX
]
|
gc
->
pads
[
GC_DDR
]))
&&
(
GC_PSX_LEN
(
id
[
i
])
>
max_len
)
&&
(
GC_PSX_LEN
(
id
[
i
])
>
max_len
)
&&
(
GC_PSX_LEN
(
id
[
i
])
<=
GC_PSX_BYTES
))
&&
(
GC_PSX_LEN
(
id
[
i
])
<=
GC_PSX_BYTES
))
...
@@ -311,7 +417,7 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES
...
@@ -311,7 +417,7 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES
for
(
i
=
0
;
i
<
max_len
;
i
++
)
{
/* Read in all the data */
for
(
i
=
0
;
i
<
max_len
;
i
++
)
{
/* Read in all the data */
gc_psx_command
(
gc
,
0
,
data2
);
gc_psx_command
(
gc
,
0
,
data2
);
for
(
j
=
0
;
j
<
5
;
j
++
)
for
(
j
=
0
;
j
<
GC_MAX_DEVICES
;
j
++
)
data
[
j
][
i
]
=
data2
[
j
];
data
[
j
][
i
]
=
data2
[
j
];
}
}
...
@@ -319,185 +425,124 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES
...
@@ -319,185 +425,124 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES
parport_write_data
(
gc
->
pd
->
port
,
GC_PSX_CLOCK
|
GC_PSX_SELECT
|
GC_PSX_POWER
);
parport_write_data
(
gc
->
pd
->
port
,
GC_PSX_CLOCK
|
GC_PSX_SELECT
|
GC_PSX_POWER
);
for
(
i
=
0
;
i
<
5
;
i
++
)
/* Set id's to the real value */
for
(
i
=
0
;
i
<
GC_MAX_DEVICES
;
i
++
)
/* Set id's to the real value */
id
[
i
]
=
GC_PSX_ID
(
id
[
i
]);
id
[
i
]
=
GC_PSX_ID
(
id
[
i
]);
}
}
/*
static
void
gc_psx_process_packet
(
struct
gc
*
gc
)
* gc_timer() reads and analyzes console pads data.
{
*/
unsigned
char
data
[
GC_MAX_DEVICES
][
GC_PSX_BYTES
];
unsigned
char
id
[
GC_MAX_DEVICES
];
struct
input_dev
*
dev
;
int
i
,
j
;
#define GC_MAX_LENGTH GC_N64_LENGTH
gc_psx_read_packet
(
gc
,
data
,
id
);
static
void
gc_timer
(
unsigned
long
private
)
for
(
i
=
0
;
i
<
GC_MAX_DEVICES
;
i
++
)
{
{
struct
gc
*
gc
=
(
void
*
)
private
;
unsigned
char
data
[
GC_MAX_LENGTH
];
unsigned
char
data_psx
[
5
][
GC_PSX_BYTES
];
int
i
,
j
,
s
;
/*
dev
=
gc
->
dev
[
i
];
* N64 pads - must be read first, any read confuses them for 200 us
if
(
!
dev
)
*/
continue
;
if
(
gc
->
pads
[
GC_N64
])
{
switch
(
id
[
i
])
{
gc_n64_read_packet
(
gc
,
data
);
case
GC_PSX_RUMBLE
:
for
(
i
=
0
;
i
<
5
;
i
++
)
{
input_report_key
(
dev
,
BTN_THUMBL
,
~
data
[
i
][
0
]
&
0x04
);
input_report_key
(
dev
,
BTN_THUMBR
,
~
data
[
i
][
0
]
&
0x02
);
s
=
gc_status_bit
[
i
];
case
GC_PSX_NEGCON
:
case
GC_PSX_ANALOG
:
if
(
s
&
gc
->
pads
[
GC_N64
]
&
~
(
data
[
8
]
|
data
[
9
]))
{
if
(
gc
->
pads
[
GC_DDR
]
&
gc_status_bit
[
i
])
{
for
(
j
=
0
;
j
<
4
;
j
++
)
input_report_key
(
dev
,
gc_psx_ddr_btn
[
j
],
~
data
[
i
][
0
]
&
(
0x10
<<
j
));
}
else
{
for
(
j
=
0
;
j
<
4
;
j
++
)
input_report_abs
(
dev
,
gc_psx_abs
[
j
+
2
],
data
[
i
][
j
+
2
]);
signed
char
axes
[
2
];
input_report_abs
(
dev
,
ABS_X
,
128
+
!
(
data
[
i
][
0
]
&
0x20
)
*
127
-
!
(
data
[
i
][
0
]
&
0x80
)
*
128
);
axes
[
0
]
=
axes
[
1
]
=
0
;
input_report_abs
(
dev
,
ABS_Y
,
128
+
!
(
data
[
i
][
0
]
&
0x40
)
*
127
-
!
(
data
[
i
][
0
]
&
0x10
)
*
128
);
}
for
(
j
=
0
;
j
<
8
;
j
++
)
{
for
(
j
=
0
;
j
<
8
;
j
++
)
if
(
data
[
23
-
j
]
&
s
)
axes
[
0
]
|=
1
<<
j
;
input_report_key
(
dev
,
gc_psx_btn
[
j
],
~
data
[
i
][
1
]
&
(
1
<<
j
));
if
(
data
[
31
-
j
]
&
s
)
axes
[
1
]
|=
1
<<
j
;
input_report_key
(
dev
,
BTN_START
,
~
data
[
i
][
0
]
&
0x08
);
input_report_key
(
dev
,
BTN_SELECT
,
~
data
[
i
][
0
]
&
0x01
);
input_sync
(
dev
);
break
;
case
GC_PSX_NORMAL
:
if
(
gc
->
pads
[
GC_DDR
]
&
gc_status_bit
[
i
])
{
for
(
j
=
0
;
j
<
4
;
j
++
)
input_report_key
(
dev
,
gc_psx_ddr_btn
[
j
],
~
data
[
i
][
0
]
&
(
0x10
<<
j
));
}
else
{
input_report_abs
(
dev
,
ABS_X
,
128
+
!
(
data
[
i
][
0
]
&
0x20
)
*
127
-
!
(
data
[
i
][
0
]
&
0x80
)
*
128
);
input_report_abs
(
dev
,
ABS_Y
,
128
+
!
(
data
[
i
][
0
]
&
0x40
)
*
127
-
!
(
data
[
i
][
0
]
&
0x10
)
*
128
);
/* for some reason if the extra axes are left unset they drift */
/* for (j = 0; j < 4; j++)
input_report_abs(dev, gc_psx_abs[j + 2], 128);
* This needs to be debugged properly,
* maybe fuzz processing needs to be done in input_sync()
* --vojtech
*/
}
}
input_report_abs
(
gc
->
dev
[
i
],
ABS_X
,
axes
[
0
]);
for
(
j
=
0
;
j
<
8
;
j
++
)
input_report_abs
(
gc
->
dev
[
i
],
ABS_Y
,
-
axes
[
1
]
);
input_report_key
(
dev
,
gc_psx_btn
[
j
],
~
data
[
i
][
1
]
&
(
1
<<
j
)
);
input_report_
abs
(
gc
->
dev
[
i
],
ABS_HAT0X
,
!
(
s
&
data
[
6
])
-
!
(
s
&
data
[
7
])
);
input_report_
key
(
dev
,
BTN_START
,
~
data
[
i
][
0
]
&
0x08
);
input_report_
abs
(
gc
->
dev
[
i
],
ABS_HAT0Y
,
!
(
s
&
data
[
4
])
-
!
(
s
&
data
[
5
])
);
input_report_
key
(
dev
,
BTN_SELECT
,
~
data
[
i
][
0
]
&
0x01
);
for
(
j
=
0
;
j
<
10
;
j
++
)
input_sync
(
dev
);
input_report_key
(
gc
->
dev
[
i
],
gc_n64_btn
[
j
],
s
&
data
[
gc_n64_bytes
[
j
]]);
input_sync
(
gc
->
dev
[
i
]);
break
;
}
case
0
:
/* not a pad, ignore */
break
;
}
}
}
}
}
/*
/*
*
NES and SNES pads
*
gc_timer() initiates reads of console pads data.
*/
*/
if
(
gc
->
pads
[
GC_NES
]
||
gc
->
pads
[
GC_SNES
])
{
static
void
gc_timer
(
unsigned
long
private
)
{
gc_nes_read_packet
(
gc
,
gc
->
pads
[
GC_SNES
]
?
GC_SNES_LENGTH
:
GC_NES_LENGTH
,
data
);
struct
gc
*
gc
=
(
void
*
)
private
;
for
(
i
=
0
;
i
<
5
;
i
++
)
{
s
=
gc_status_bit
[
i
];
if
(
s
&
(
gc
->
pads
[
GC_NES
]
|
gc
->
pads
[
GC_SNES
]))
{
/*
input_report_abs
(
gc
->
dev
[
i
],
ABS_X
,
!
(
s
&
data
[
6
])
-
!
(
s
&
data
[
7
]));
* N64 pads - must be read first, any read confuses them for 200 us
input_report_abs
(
gc
->
dev
[
i
],
ABS_Y
,
!
(
s
&
data
[
4
])
-
!
(
s
&
data
[
5
]));
*/
}
if
(
s
&
gc
->
pads
[
GC_NES
])
if
(
gc
->
pads
[
GC_N64
])
for
(
j
=
0
;
j
<
4
;
j
++
)
gc_n64_process_packet
(
gc
);
input_report_key
(
gc
->
dev
[
i
],
gc_snes_btn
[
j
],
s
&
data
[
gc_nes_bytes
[
j
]]);
if
(
s
&
gc
->
pads
[
GC_SNES
])
/*
for
(
j
=
0
;
j
<
8
;
j
++
)
* NES and SNES pads
input_report_key
(
gc
->
dev
[
i
],
gc_snes_btn
[
j
],
s
&
data
[
gc_snes_bytes
[
j
]]);
*/
input_sync
(
gc
->
dev
[
i
]);
if
(
gc
->
pads
[
GC_NES
]
||
gc
->
pads
[
GC_SNES
])
}
gc_nes_process_packet
(
gc
);
}
/*
/*
* Multi and Multi2 joysticks
* Multi and Multi2 joysticks
*/
*/
if
(
gc
->
pads
[
GC_MULTI
]
||
gc
->
pads
[
GC_MULTI2
])
{
if
(
gc
->
pads
[
GC_MULTI
]
||
gc
->
pads
[
GC_MULTI2
])
gc_multi_process_packet
(
gc
);
gc_multi_read_packet
(
gc
,
gc
->
pads
[
GC_MULTI2
]
?
GC_MULTI2_LENGTH
:
GC_MULTI_LENGTH
,
data
);
for
(
i
=
0
;
i
<
5
;
i
++
)
{
s
=
gc_status_bit
[
i
];
if
(
s
&
(
gc
->
pads
[
GC_MULTI
]
|
gc
->
pads
[
GC_MULTI2
]))
{
input_report_abs
(
gc
->
dev
[
i
],
ABS_X
,
!
(
s
&
data
[
2
])
-
!
(
s
&
data
[
3
]));
input_report_abs
(
gc
->
dev
[
i
],
ABS_Y
,
!
(
s
&
data
[
0
])
-
!
(
s
&
data
[
1
]));
input_report_key
(
gc
->
dev
[
i
],
BTN_TRIGGER
,
s
&
data
[
4
]);
}
if
(
s
&
gc
->
pads
[
GC_MULTI2
])
input_report_key
(
gc
->
dev
[
i
],
BTN_THUMB
,
s
&
data
[
5
]);
input_sync
(
gc
->
dev
[
i
]);
}
}
/*
/*
* PSX controllers
* PSX controllers
*/
*/
if
(
gc
->
pads
[
GC_PSX
]
||
gc
->
pads
[
GC_DDR
])
{
if
(
gc
->
pads
[
GC_PSX
]
||
gc
->
pads
[
GC_DDR
])
gc_psx_process_packet
(
gc
);
gc_psx_read_packet
(
gc
,
data_psx
,
data
);
for
(
i
=
0
;
i
<
5
;
i
++
)
{
switch
(
data
[
i
])
{
case
GC_PSX_RUMBLE
:
input_report_key
(
gc
->
dev
[
i
],
BTN_THUMBL
,
~
data_psx
[
i
][
0
]
&
0x04
);
input_report_key
(
gc
->
dev
[
i
],
BTN_THUMBR
,
~
data_psx
[
i
][
0
]
&
0x02
);
case
GC_PSX_NEGCON
:
case
GC_PSX_ANALOG
:
if
(
gc
->
pads
[
GC_DDR
]
&
gc_status_bit
[
i
])
{
for
(
j
=
0
;
j
<
4
;
j
++
)
input_report_key
(
gc
->
dev
[
i
],
gc_psx_ddr_btn
[
j
],
~
data_psx
[
i
][
0
]
&
(
0x10
<<
j
));
}
else
{
for
(
j
=
0
;
j
<
4
;
j
++
)
input_report_abs
(
gc
->
dev
[
i
],
gc_psx_abs
[
j
+
2
],
data_psx
[
i
][
j
+
2
]);
input_report_abs
(
gc
->
dev
[
i
],
ABS_X
,
128
+
!
(
data_psx
[
i
][
0
]
&
0x20
)
*
127
-
!
(
data_psx
[
i
][
0
]
&
0x80
)
*
128
);
input_report_abs
(
gc
->
dev
[
i
],
ABS_Y
,
128
+
!
(
data_psx
[
i
][
0
]
&
0x40
)
*
127
-
!
(
data_psx
[
i
][
0
]
&
0x10
)
*
128
);
}
for
(
j
=
0
;
j
<
8
;
j
++
)
input_report_key
(
gc
->
dev
[
i
],
gc_psx_btn
[
j
],
~
data_psx
[
i
][
1
]
&
(
1
<<
j
));
input_report_key
(
gc
->
dev
[
i
],
BTN_START
,
~
data_psx
[
i
][
0
]
&
0x08
);
input_report_key
(
gc
->
dev
[
i
],
BTN_SELECT
,
~
data_psx
[
i
][
0
]
&
0x01
);
input_sync
(
gc
->
dev
[
i
]);
break
;
case
GC_PSX_NORMAL
:
if
(
gc
->
pads
[
GC_DDR
]
&
gc_status_bit
[
i
])
{
for
(
j
=
0
;
j
<
4
;
j
++
)
input_report_key
(
gc
->
dev
[
i
],
gc_psx_ddr_btn
[
j
],
~
data_psx
[
i
][
0
]
&
(
0x10
<<
j
));
}
else
{
input_report_abs
(
gc
->
dev
[
i
],
ABS_X
,
128
+
!
(
data_psx
[
i
][
0
]
&
0x20
)
*
127
-
!
(
data_psx
[
i
][
0
]
&
0x80
)
*
128
);
input_report_abs
(
gc
->
dev
[
i
],
ABS_Y
,
128
+
!
(
data_psx
[
i
][
0
]
&
0x40
)
*
127
-
!
(
data_psx
[
i
][
0
]
&
0x10
)
*
128
);
/* for some reason if the extra axes are left unset they drift */
/* for (j = 0; j < 4; j++)
input_report_abs(gc->dev[i], gc_psx_abs[j+2], 128);
* This needs to be debugged properly,
* maybe fuzz processing needs to be done in input_sync()
* --vojtech
*/
}
for
(
j
=
0
;
j
<
8
;
j
++
)
input_report_key
(
gc
->
dev
[
i
],
gc_psx_btn
[
j
],
~
data_psx
[
i
][
1
]
&
(
1
<<
j
));
input_report_key
(
gc
->
dev
[
i
],
BTN_START
,
~
data_psx
[
i
][
0
]
&
0x08
);
input_report_key
(
gc
->
dev
[
i
],
BTN_SELECT
,
~
data_psx
[
i
][
0
]
&
0x01
);
input_sync
(
gc
->
dev
[
i
]);
break
;
case
0
:
/* not a pad, ignore */
break
;
}
}
}
mod_timer
(
&
gc
->
timer
,
jiffies
+
GC_REFRESH_TIME
);
mod_timer
(
&
gc
->
timer
,
jiffies
+
GC_REFRESH_TIME
);
}
}
...
@@ -654,7 +699,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
...
@@ -654,7 +699,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
gc
->
timer
.
data
=
(
long
)
gc
;
gc
->
timer
.
data
=
(
long
)
gc
;
gc
->
timer
.
function
=
gc_timer
;
gc
->
timer
.
function
=
gc_timer
;
for
(
i
=
0
;
i
<
n_pads
;
i
++
)
{
for
(
i
=
0
;
i
<
n_pads
&&
i
<
GC_MAX_DEVICES
;
i
++
)
{
if
(
!
pads
[
i
])
if
(
!
pads
[
i
])
continue
;
continue
;
...
...
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