Commit 20a380e2 authored by Vojtech Pavlik's avatar Vojtech Pavlik

input: Make gameport digital joysticks work on 2.6 and x86_64 again.

Signed-off-by: default avatarVojtech Pavlik <vojtech@suse.cz>
parent cf934d18
......@@ -59,7 +59,7 @@ static void gameport_destroy_port(struct gameport *gameport);
static void gameport_reconnect_port(struct gameport *gameport);
static void gameport_disconnect_port(struct gameport *gameport);
#ifdef __i386__
#if defined(__i386__)
#define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0))
#define GET_TIME(x) do { x = get_time_pit(); } while (0)
......@@ -81,13 +81,15 @@ static unsigned int get_time_pit(void)
#endif
/*
* gameport_measure_speed() measures the gameport i/o speed.
*/
static int gameport_measure_speed(struct gameport *gameport)
{
#ifdef __i386__
#if defined(__i386__)
unsigned int i, t, t1, t2, t3, tx;
unsigned long flags;
......@@ -100,7 +102,7 @@ static int gameport_measure_speed(struct gameport *gameport)
for(i = 0; i < 50; i++) {
local_irq_save(flags);
GET_TIME(t1);
for(t = 0; t < 50; t++) gameport_read(gameport);
for (t = 0; t < 50; t++) gameport_read(gameport);
GET_TIME(t2);
GET_TIME(t3);
local_irq_restore(flags);
......@@ -111,10 +113,36 @@ static int gameport_measure_speed(struct gameport *gameport)
gameport_close(gameport);
return 59659 / (tx < 1 ? 1 : tx);
#elif defined (__x86_64__)
unsigned int i, t;
unsigned long tx, t1, t2, flags;
if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW))
return 0;
tx = 1 << 30;
for(i = 0; i < 50; i++) {
local_irq_save(flags);
rdtscl(t1);
for (t = 0; t < 50; t++) gameport_read(gameport);
rdtscl(t2);
local_irq_restore(flags);
udelay(i * 10);
if (t2 - t1 < tx) tx = t2 - t1;
}
gameport_close(gameport);
return (cpu_data[_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
#else
unsigned int j, t = 0;
if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW))
return 0;
j = jiffies; while (j == jiffies);
j = jiffies; while (j == jiffies) { t++; gameport_read(gameport); }
......
......@@ -41,9 +41,8 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
#define A3D_MAX_START 400 /* 400 us */
#define A3D_MAX_STROBE 60 /* 40 us */
#define A3D_DELAY_READ 3 /* 3 ms */
#define A3D_MAX_START 600 /* 600 us */
#define A3D_MAX_STROBE 80 /* 80 us */
#define A3D_MAX_LENGTH 40 /* 40*3 bits */
#define A3D_MODE_A3D 1 /* Assassin 3D */
......
/*
* $Id: adi.c,v 1.23 2002/01/22 20:26:17 vojtech Exp $
*
* Copyright (c) 1998-2001 Vojtech Pavlik
* Copyright (c) 1998-2005 Vojtech Pavlik
*/
/*
......@@ -58,7 +56,7 @@ MODULE_LICENSE("GPL");
#define ADI_MIN_ID_LENGTH 66
#define ADI_MAX_NAME_LENGTH 48
#define ADI_MAX_CNAME_LENGTH 16
#define ADI_MAX_PHYS_LENGTH 32
#define ADI_MAX_PHYS_LENGTH 64
#define ADI_FLAG_HAT 0x04
#define ADI_FLAG_10BIT 0x08
......@@ -315,13 +313,16 @@ static void adi_close(struct input_dev *dev)
static void adi_init_digital(struct gameport *gameport)
{
int seq[] = { 3, -2, -3, 10, -6, -11, -7, -9, 11, 0 };
int seq[] = { 4, -2, -3, 10, -6, -11, -7, -9, 11, 0 };
int i;
for (i = 0; seq[i]; i++) {
gameport_trigger(gameport);
if (seq[i] > 0) msleep(seq[i]);
if (seq[i] < 0) mdelay(-seq[i]);
if (seq[i] < 0) {
mdelay(-seq[i]);
udelay(-seq[i]*14); /* It looks like mdelay() is off by approx 1.4% */
}
}
}
......@@ -407,9 +408,9 @@ static void adi_init_input(struct adi *adi, struct adi_port *port, int half)
t = adi->id < ADI_ID_MAX ? adi->id : ADI_ID_MAX;
sprintf(buf, adi_names[t], adi->id);
sprintf(adi->name, "Logitech %s", buf);
sprintf(adi->phys, "%s/input%d", port->gameport->phys, half);
snprintf(buf, ADI_MAX_PHYS_LENGTH, adi_names[t], adi->id);
snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s", buf);
snprintf(adi->phys, ADI_MAX_PHYS_LENGTH, "%s/input%d", port->gameport->phys, half);
adi->abs = adi_abs[t];
adi->key = adi_key[t];
......
......@@ -376,7 +376,7 @@ static void analog_calibrate_timer(struct analog_port *port)
#ifdef FAKE_TIME
analog_faketime += 830;
#endif
udelay(1000);
mdelay(1);
GET_TIME(t2);
GET_TIME(t3);
local_irq_restore(flags);
......
......@@ -45,8 +45,8 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
#define INTERACT_MAX_START 400 /* 400 us */
#define INTERACT_MAX_STROBE 40 /* 40 us */
#define INTERACT_MAX_START 600 /* 400 us */
#define INTERACT_MAX_STROBE 60 /* 40 us */
#define INTERACT_MAX_LENGTH 32 /* 32 bits */
#define INTERACT_TYPE_HHFX 0 /* HammerHead/FX */
......
/*
* $Id: sidewinder.c,v 1.29 2002/01/22 20:28:51 vojtech Exp $
*
* Copyright (c) 1998-2001 Vojtech Pavlik
* Copyright (c) 1998-2005 Vojtech Pavlik
*/
/*
......@@ -47,11 +45,12 @@ MODULE_LICENSE("GPL");
* as well as break everything.
*/
/* #define SW_DEBUG */
#undef SW_DEBUG
#undef SW_DEBUG_DATA
#define SW_START 400 /* The time we wait for the first bit [400 us] */
#define SW_STROBE 45 /* Max time per bit [45 us] */
#define SW_TIMEOUT 4000 /* Wait for everything to settle [4 ms] */
#define SW_START 600 /* The time we wait for the first bit [600 us] */
#define SW_STROBE 60 /* Max time per bit [60 us] */
#define SW_TIMEOUT 6 /* Wait for everything to settle [6 ms] */
#define SW_KICK 45 /* Wait after A0 fall till kick [45 us] */
#define SW_END 8 /* Number of bits before end of packet to kick */
#define SW_FAIL 16 /* Number of packet read errors to fail and reinitialize */
......@@ -140,7 +139,7 @@ static int sw_read_packet(struct gameport *gameport, unsigned char *buf, int len
unsigned char pending, u, v;
i = -id; /* Don't care about data, only want ID */
timeout = id ? gameport_time(gameport, SW_TIMEOUT) : 0; /* Set up global timeout for ID packet */
timeout = id ? gameport_time(gameport, SW_TIMEOUT * 1000) : 0; /* Set up global timeout for ID packet */
kick = id ? gameport_time(gameport, SW_KICK) : 0; /* Set up kick timeout for ID packet */
start = gameport_time(gameport, SW_START);
strobe = gameport_time(gameport, SW_STROBE);
......@@ -194,7 +193,7 @@ static int sw_read_packet(struct gameport *gameport, unsigned char *buf, int len
local_irq_restore(flags); /* Done - relax */
#ifdef SW_DEBUG
#ifdef SW_DEBUG_DATA
{
int j;
printk(KERN_DEBUG "sidewinder.c: Read %d triplets. [", i);
......@@ -249,7 +248,7 @@ static void sw_init_digital(struct gameport *gameport)
i = 0;
do {
gameport_trigger(gameport); /* Trigger */
t = gameport_time(gameport, SW_TIMEOUT);
t = gameport_time(gameport, SW_TIMEOUT * 1000);
while ((gameport_read(gameport) & 1) && t) t--; /* Wait for axis to fall back to 0 */
udelay(seq[i]); /* Delay magic time */
} while (seq[++i]);
......@@ -479,13 +478,13 @@ static int sw_read(struct sw *sw)
" - reinitializing joystick.\n", sw->gameport->phys);
if (!i && sw->type == SW_ID_3DP) { /* 3D Pro can be in analog mode */
udelay(3 * SW_TIMEOUT);
mdelay(3 * SW_TIMEOUT);
sw_init_digital(sw->gameport);
}
udelay(SW_TIMEOUT);
mdelay(SW_TIMEOUT);
i = sw_read_packet(sw->gameport, buf, SW_LENGTH, 0); /* Read normal data packet */
udelay(SW_TIMEOUT);
mdelay(SW_TIMEOUT);
sw_read_packet(sw->gameport, buf, SW_LENGTH, i); /* Read ID packet, this initializes the stick */
sw->fail = SW_FAIL;
......@@ -611,14 +610,14 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
gameport->phys, gameport->io, gameport->speed);
i = sw_read_packet(gameport, buf, SW_LENGTH, 0); /* Read normal packet */
udelay(SW_TIMEOUT);
msleep(SW_TIMEOUT);
dbg("Init 1: Mode %d. Length %d.", m , i);
if (!i) { /* No data. 3d Pro analog mode? */
sw_init_digital(gameport); /* Switch to digital */
udelay(SW_TIMEOUT);
msleep(SW_TIMEOUT);
i = sw_read_packet(gameport, buf, SW_LENGTH, 0); /* Retry reading packet */
udelay(SW_TIMEOUT);
msleep(SW_TIMEOUT);
dbg("Init 1b: Length %d.", i);
if (!i) { /* No data -> FAIL */
err = -ENODEV;
......@@ -628,17 +627,18 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
j = sw_read_packet(gameport, idbuf, SW_LENGTH, i); /* Read ID. This initializes the stick */
m |= sw_guess_mode(idbuf, j); /* ID packet should carry mode info [3DP] */
dbg("Init 2: Mode %d. ID Length %d.", m , j);
dbg("Init 2: Mode %d. ID Length %d.", m, j);
if (!j) { /* Read ID failed. Happens in 1-bit mode on PP */
udelay(SW_TIMEOUT);
if (j <= 0) { /* Read ID failed. Happens in 1-bit mode on PP */
msleep(SW_TIMEOUT);
i = sw_read_packet(gameport, buf, SW_LENGTH, 0); /* Retry reading packet */
m |= sw_guess_mode(buf, i);
dbg("Init 2b: Mode %d. Length %d.", m, i);
if (!i) {
err = -ENODEV;
goto fail2;
}
udelay(SW_TIMEOUT);
msleep(SW_TIMEOUT);
j = sw_read_packet(gameport, idbuf, SW_LENGTH, i); /* Retry reading ID */
dbg("Init 2c: ID Length %d.", j);
}
......@@ -649,7 +649,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
do {
k--;
udelay(SW_TIMEOUT);
msleep(SW_TIMEOUT);
i = sw_read_packet(gameport, buf, SW_LENGTH, 0); /* Read data packet */
dbg("Init 3: Mode %d. Length %d. Last %d. Tries %d.", m, i, l, k);
......
......@@ -45,8 +45,8 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
#define TMDC_MAX_START 400 /* 400 us */
#define TMDC_MAX_STROBE 45 /* 45 us */
#define TMDC_MAX_START 600 /* 600 us */
#define TMDC_MAX_STROBE 60 /* 60 us */
#define TMDC_MAX_LENGTH 13
#define TMDC_MODE_M3DI 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment