diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-01-29 21:52:04 -0500 |
---|---|---|
committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-01-29 21:52:04 -0500 |
commit | c7fd018d75cae2b0c1cf03003b38f4c76e3df826 (patch) | |
tree | 6ce8412cea8ecdd0fcdb2f78a82359266c43bc6d | |
parent | 07cf779c0098fd0007d2348e1cf948cc07bfe096 (diff) |
Input: gamecon - fix crash when accessing device
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r-- | drivers/input/joystick/gamecon.c | 343 |
1 files changed, 194 insertions, 149 deletions
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 7df2d82f2c83..d9757452c93a 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c | |||
@@ -159,6 +159,48 @@ static void gc_n64_read_packet(struct gc *gc, unsigned char *data) | |||
159 | 159 | ||
160 | } | 160 | } |
161 | 161 | ||
162 | static void gc_n64_process_packet(struct gc *gc) | ||
163 | { | ||
164 | unsigned char data[GC_N64_LENGTH]; | ||
165 | signed char axes[2]; | ||
166 | struct input_dev *dev; | ||
167 | int i, j, s; | ||
168 | |||
169 | gc_n64_read_packet(gc, data); | ||
170 | |||
171 | for (i = 0; i < GC_MAX_DEVICES; i++) { | ||
172 | |||
173 | dev = gc->dev[i]; | ||
174 | if (!dev) | ||
175 | continue; | ||
176 | |||
177 | s = gc_status_bit[i]; | ||
178 | |||
179 | if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) { | ||
180 | |||
181 | axes[0] = axes[1] = 0; | ||
182 | |||
183 | for (j = 0; j < 8; j++) { | ||
184 | if (data[23 - j] & s) | ||
185 | axes[0] |= 1 << j; | ||
186 | if (data[31 - j] & s) | ||
187 | axes[1] |= 1 << j; | ||
188 | } | ||
189 | |||
190 | input_report_abs(dev, ABS_X, axes[0]); | ||
191 | input_report_abs(dev, ABS_Y, -axes[1]); | ||
192 | |||
193 | input_report_abs(dev, ABS_HAT0X, !(s & data[6]) - !(s & data[7])); | ||
194 | input_report_abs(dev, ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); | ||
195 | |||
196 | for (j = 0; j < 10; j++) | ||
197 | input_report_key(dev, gc_n64_btn[j], s & data[gc_n64_bytes[j]]); | ||
198 | |||
199 | input_sync(dev); | ||
200 | } | ||
201 | } | ||
202 | } | ||
203 | |||
162 | /* | 204 | /* |
163 | * NES/SNES support. | 205 | * NES/SNES support. |
164 | */ | 206 | */ |
@@ -198,6 +240,39 @@ static void gc_nes_read_packet(struct gc *gc, int length, unsigned char *data) | |||
198 | } | 240 | } |
199 | } | 241 | } |
200 | 242 | ||
243 | static void gc_nes_process_packet(struct gc *gc) | ||
244 | { | ||
245 | unsigned char data[GC_SNES_LENGTH]; | ||
246 | struct input_dev *dev; | ||
247 | int i, j, s; | ||
248 | |||
249 | gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data); | ||
250 | |||
251 | for (i = 0; i < GC_MAX_DEVICES; i++) { | ||
252 | |||
253 | dev = gc->dev[i]; | ||
254 | if (!dev) | ||
255 | continue; | ||
256 | |||
257 | s = gc_status_bit[i]; | ||
258 | |||
259 | if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) { | ||
260 | input_report_abs(dev, ABS_X, !(s & data[6]) - !(s & data[7])); | ||
261 | input_report_abs(dev, ABS_Y, !(s & data[4]) - !(s & data[5])); | ||
262 | } | ||
263 | |||
264 | if (s & gc->pads[GC_NES]) | ||
265 | for (j = 0; j < 4; j++) | ||
266 | input_report_key(dev, gc_snes_btn[j], s & data[gc_nes_bytes[j]]); | ||
267 | |||
268 | if (s & gc->pads[GC_SNES]) | ||
269 | for (j = 0; j < 8; j++) | ||
270 | input_report_key(dev, gc_snes_btn[j], s & data[gc_snes_bytes[j]]); | ||
271 | |||
272 | input_sync(dev); | ||
273 | } | ||
274 | } | ||
275 | |||
201 | /* | 276 | /* |
202 | * Multisystem joystick support | 277 | * Multisystem joystick support |
203 | */ | 278 | */ |
@@ -219,6 +294,35 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data) | |||
219 | } | 294 | } |
220 | } | 295 | } |
221 | 296 | ||
297 | static void gc_multi_process_packet(struct gc *gc) | ||
298 | { | ||
299 | unsigned char data[GC_MULTI2_LENGTH]; | ||
300 | struct input_dev *dev; | ||
301 | int i, s; | ||
302 | |||
303 | gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data); | ||
304 | |||
305 | for (i = 0; i < GC_MAX_DEVICES; i++) { | ||
306 | |||
307 | dev = gc->dev[i]; | ||
308 | if (!dev) | ||
309 | continue; | ||
310 | |||
311 | s = gc_status_bit[i]; | ||
312 | |||
313 | if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { | ||
314 | input_report_abs(dev, ABS_X, !(s & data[2]) - !(s & data[3])); | ||
315 | input_report_abs(dev, ABS_Y, !(s & data[0]) - !(s & data[1])); | ||
316 | input_report_key(dev, BTN_TRIGGER, s & data[4]); | ||
317 | } | ||
318 | |||
319 | if (s & gc->pads[GC_MULTI2]) | ||
320 | input_report_key(dev, BTN_THUMB, s & data[5]); | ||
321 | |||
322 | input_sync(dev); | ||
323 | } | ||
324 | } | ||
325 | |||
222 | /* | 326 | /* |
223 | * PSX support | 327 | * PSX support |
224 | * | 328 | * |
@@ -263,10 +367,11 @@ static short gc_psx_ddr_btn[] = { BTN_0, BTN_1, BTN_2, BTN_3 }; | |||
263 | * the psx pad. | 367 | * the psx pad. |
264 | */ | 368 | */ |
265 | 369 | ||
266 | static void gc_psx_command(struct gc *gc, int b, unsigned char data[5]) | 370 | static void gc_psx_command(struct gc *gc, int b, unsigned char data[GC_MAX_DEVICES]) |
267 | { | 371 | { |
268 | int i, j, cmd, read; | 372 | int i, j, cmd, read; |
269 | for (i = 0; i < 5; i++) | 373 | |
374 | for (i = 0; i < GC_MAX_DEVICES; i++) | ||
270 | data[i] = 0; | 375 | data[i] = 0; |
271 | 376 | ||
272 | for (i = 0; i < GC_PSX_LENGTH; i++, b >>= 1) { | 377 | 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 | parport_write_data(gc->pd->port, cmd | GC_PSX_POWER); | 379 | parport_write_data(gc->pd->port, cmd | GC_PSX_POWER); |
275 | udelay(gc_psx_delay); | 380 | udelay(gc_psx_delay); |
276 | read = parport_read_status(gc->pd->port) ^ 0x80; | 381 | read = parport_read_status(gc->pd->port) ^ 0x80; |
277 | for (j = 0; j < 5; j++) | 382 | for (j = 0; j < GC_MAX_DEVICES; j++) |
278 | data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0; | 383 | data[j] |= (read & gc_status_bit[j] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) ? (1 << i) : 0; |
279 | parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); | 384 | parport_write_data(gc->pd->port, cmd | GC_PSX_CLOCK | GC_PSX_POWER); |
280 | udelay(gc_psx_delay); | 385 | udelay(gc_psx_delay); |
@@ -286,11 +391,12 @@ static void gc_psx_command(struct gc *gc, int b, unsigned char data[5]) | |||
286 | * device identifier code. | 391 | * device identifier code. |
287 | */ | 392 | */ |
288 | 393 | ||
289 | static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES], unsigned char id[5]) | 394 | static void gc_psx_read_packet(struct gc *gc, unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES], |
395 | unsigned char id[GC_MAX_DEVICES]) | ||
290 | { | 396 | { |
291 | int i, j, max_len = 0; | 397 | int i, j, max_len = 0; |
292 | unsigned long flags; | 398 | unsigned long flags; |
293 | unsigned char data2[5]; | 399 | unsigned char data2[GC_MAX_DEVICES]; |
294 | 400 | ||
295 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ | 401 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); /* Select pad */ |
296 | udelay(gc_psx_delay); | 402 | 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 | gc_psx_command(gc, 0x42, id); /* Get device ids */ | 409 | gc_psx_command(gc, 0x42, id); /* Get device ids */ |
304 | gc_psx_command(gc, 0, data2); /* Dump status */ | 410 | gc_psx_command(gc, 0, data2); /* Dump status */ |
305 | 411 | ||
306 | for (i =0; i < 5; i++) /* Find the longest pad */ | 412 | for (i =0; i < GC_MAX_DEVICES; i++) /* Find the longest pad */ |
307 | if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) | 413 | if((gc_status_bit[i] & (gc->pads[GC_PSX] | gc->pads[GC_DDR])) |
308 | && (GC_PSX_LEN(id[i]) > max_len) | 414 | && (GC_PSX_LEN(id[i]) > max_len) |
309 | && (GC_PSX_LEN(id[i]) <= GC_PSX_BYTES)) | 415 | && (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 | 417 | ||
312 | for (i = 0; i < max_len; i++) { /* Read in all the data */ | 418 | for (i = 0; i < max_len; i++) { /* Read in all the data */ |
313 | gc_psx_command(gc, 0, data2); | 419 | gc_psx_command(gc, 0, data2); |
314 | for (j = 0; j < 5; j++) | 420 | for (j = 0; j < GC_MAX_DEVICES; j++) |
315 | data[j][i] = data2[j]; | 421 | data[j][i] = data2[j]; |
316 | } | 422 | } |
317 | 423 | ||
@@ -319,185 +425,124 @@ static void gc_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES | |||
319 | 425 | ||
320 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); | 426 | parport_write_data(gc->pd->port, GC_PSX_CLOCK | GC_PSX_SELECT | GC_PSX_POWER); |
321 | 427 | ||
322 | for(i = 0; i < 5; i++) /* Set id's to the real value */ | 428 | for(i = 0; i < GC_MAX_DEVICES; i++) /* Set id's to the real value */ |
323 | id[i] = GC_PSX_ID(id[i]); | 429 | id[i] = GC_PSX_ID(id[i]); |
324 | } | 430 | } |
325 | 431 | ||
326 | /* | 432 | static void gc_psx_process_packet(struct gc *gc) |
327 | * gc_timer() reads and analyzes console pads data. | 433 | { |
328 | */ | 434 | unsigned char data[GC_MAX_DEVICES][GC_PSX_BYTES]; |
435 | unsigned char id[GC_MAX_DEVICES]; | ||
436 | struct input_dev *dev; | ||
437 | int i, j; | ||
329 | 438 | ||
330 | #define GC_MAX_LENGTH GC_N64_LENGTH | 439 | gc_psx_read_packet(gc, data, id); |
331 | 440 | ||
332 | static void gc_timer(unsigned long private) | 441 | for (i = 0; i < GC_MAX_DEVICES; i++) { |
333 | { | ||
334 | struct gc *gc = (void *) private; | ||
335 | unsigned char data[GC_MAX_LENGTH]; | ||
336 | unsigned char data_psx[5][GC_PSX_BYTES]; | ||
337 | int i, j, s; | ||
338 | 442 | ||
339 | /* | 443 | dev = gc->dev[i]; |
340 | * N64 pads - must be read first, any read confuses them for 200 us | 444 | if (!dev) |
341 | */ | 445 | continue; |
342 | 446 | ||
343 | if (gc->pads[GC_N64]) { | 447 | switch (id[i]) { |
344 | 448 | ||
345 | gc_n64_read_packet(gc, data); | 449 | case GC_PSX_RUMBLE: |
346 | 450 | ||
347 | for (i = 0; i < 5; i++) { | 451 | input_report_key(dev, BTN_THUMBL, ~data[i][0] & 0x04); |
452 | input_report_key(dev, BTN_THUMBR, ~data[i][0] & 0x02); | ||
348 | 453 | ||
349 | s = gc_status_bit[i]; | 454 | case GC_PSX_NEGCON: |
455 | case GC_PSX_ANALOG: | ||
350 | 456 | ||
351 | if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) { | 457 | if (gc->pads[GC_DDR] & gc_status_bit[i]) { |
458 | for(j = 0; j < 4; j++) | ||
459 | input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); | ||
460 | } else { | ||
461 | for (j = 0; j < 4; j++) | ||
462 | input_report_abs(dev, gc_psx_abs[j + 2], data[i][j + 2]); | ||
352 | 463 | ||
353 | signed char axes[2]; | 464 | input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); |
354 | axes[0] = axes[1] = 0; | 465 | input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); |
466 | } | ||
355 | 467 | ||
356 | for (j = 0; j < 8; j++) { | 468 | for (j = 0; j < 8; j++) |
357 | if (data[23 - j] & s) axes[0] |= 1 << j; | 469 | input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); |
358 | if (data[31 - j] & s) axes[1] |= 1 << j; | 470 | |
471 | input_report_key(dev, BTN_START, ~data[i][0] & 0x08); | ||
472 | input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); | ||
473 | |||
474 | input_sync(dev); | ||
475 | |||
476 | break; | ||
477 | |||
478 | case GC_PSX_NORMAL: | ||
479 | if (gc->pads[GC_DDR] & gc_status_bit[i]) { | ||
480 | for(j = 0; j < 4; j++) | ||
481 | input_report_key(dev, gc_psx_ddr_btn[j], ~data[i][0] & (0x10 << j)); | ||
482 | } else { | ||
483 | input_report_abs(dev, ABS_X, 128 + !(data[i][0] & 0x20) * 127 - !(data[i][0] & 0x80) * 128); | ||
484 | input_report_abs(dev, ABS_Y, 128 + !(data[i][0] & 0x40) * 127 - !(data[i][0] & 0x10) * 128); | ||
485 | |||
486 | /* for some reason if the extra axes are left unset they drift */ | ||
487 | /* for (j = 0; j < 4; j++) | ||
488 | input_report_abs(dev, gc_psx_abs[j + 2], 128); | ||
489 | * This needs to be debugged properly, | ||
490 | * maybe fuzz processing needs to be done in input_sync() | ||
491 | * --vojtech | ||
492 | */ | ||
359 | } | 493 | } |
360 | 494 | ||
361 | input_report_abs(gc->dev[i], ABS_X, axes[0]); | 495 | for (j = 0; j < 8; j++) |
362 | input_report_abs(gc->dev[i], ABS_Y, -axes[1]); | 496 | input_report_key(dev, gc_psx_btn[j], ~data[i][1] & (1 << j)); |
363 | 497 | ||
364 | input_report_abs(gc->dev[i], ABS_HAT0X, !(s & data[6]) - !(s & data[7])); | 498 | input_report_key(dev, BTN_START, ~data[i][0] & 0x08); |
365 | input_report_abs(gc->dev[i], ABS_HAT0Y, !(s & data[4]) - !(s & data[5])); | 499 | input_report_key(dev, BTN_SELECT, ~data[i][0] & 0x01); |
366 | 500 | ||
367 | for (j = 0; j < 10; j++) | 501 | input_sync(dev); |
368 | input_report_key(gc->dev[i], gc_n64_btn[j], s & data[gc_n64_bytes[j]]); | ||
369 | 502 | ||
370 | input_sync(gc->dev[i]); | 503 | break; |
371 | } | 504 | |
505 | case 0: /* not a pad, ignore */ | ||
506 | break; | ||
372 | } | 507 | } |
373 | } | 508 | } |
509 | } | ||
374 | 510 | ||
375 | /* | 511 | /* |
376 | * NES and SNES pads | 512 | * gc_timer() initiates reads of console pads data. |
377 | */ | 513 | */ |
378 | 514 | ||
379 | if (gc->pads[GC_NES] || gc->pads[GC_SNES]) { | 515 | static void gc_timer(unsigned long private) |
380 | 516 | { | |
381 | gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data); | 517 | struct gc *gc = (void *) private; |
382 | |||
383 | for (i = 0; i < 5; i++) { | ||
384 | |||
385 | s = gc_status_bit[i]; | ||
386 | 518 | ||
387 | if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) { | 519 | /* |
388 | input_report_abs(gc->dev[i], ABS_X, !(s & data[6]) - !(s & data[7])); | 520 | * N64 pads - must be read first, any read confuses them for 200 us |
389 | input_report_abs(gc->dev[i], ABS_Y, !(s & data[4]) - !(s & data[5])); | 521 | */ |
390 | } | ||
391 | 522 | ||
392 | if (s & gc->pads[GC_NES]) | 523 | if (gc->pads[GC_N64]) |
393 | for (j = 0; j < 4; j++) | 524 | gc_n64_process_packet(gc); |
394 | input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_nes_bytes[j]]); | ||
395 | 525 | ||
396 | if (s & gc->pads[GC_SNES]) | 526 | /* |
397 | for (j = 0; j < 8; j++) | 527 | * NES and SNES pads |
398 | input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_snes_bytes[j]]); | 528 | */ |
399 | 529 | ||
400 | input_sync(gc->dev[i]); | 530 | if (gc->pads[GC_NES] || gc->pads[GC_SNES]) |
401 | } | 531 | gc_nes_process_packet(gc); |
402 | } | ||
403 | 532 | ||
404 | /* | 533 | /* |
405 | * Multi and Multi2 joysticks | 534 | * Multi and Multi2 joysticks |
406 | */ | 535 | */ |
407 | 536 | ||
408 | if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2]) { | 537 | if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2]) |
409 | 538 | gc_multi_process_packet(gc); | |
410 | gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data); | ||
411 | |||
412 | for (i = 0; i < 5; i++) { | ||
413 | |||
414 | s = gc_status_bit[i]; | ||
415 | |||
416 | if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) { | ||
417 | input_report_abs(gc->dev[i], ABS_X, !(s & data[2]) - !(s & data[3])); | ||
418 | input_report_abs(gc->dev[i], ABS_Y, !(s & data[0]) - !(s & data[1])); | ||
419 | input_report_key(gc->dev[i], BTN_TRIGGER, s & data[4]); | ||
420 | } | ||
421 | |||
422 | if (s & gc->pads[GC_MULTI2]) | ||
423 | input_report_key(gc->dev[i], BTN_THUMB, s & data[5]); | ||
424 | |||
425 | input_sync(gc->dev[i]); | ||
426 | } | ||
427 | } | ||
428 | 539 | ||
429 | /* | 540 | /* |
430 | * PSX controllers | 541 | * PSX controllers |
431 | */ | 542 | */ |
432 | 543 | ||
433 | if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) { | 544 | if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) |
434 | 545 | gc_psx_process_packet(gc); | |
435 | gc_psx_read_packet(gc, data_psx, data); | ||
436 | |||
437 | for (i = 0; i < 5; i++) { | ||
438 | switch (data[i]) { | ||
439 | |||
440 | case GC_PSX_RUMBLE: | ||
441 | |||
442 | input_report_key(gc->dev[i], BTN_THUMBL, ~data_psx[i][0] & 0x04); | ||
443 | input_report_key(gc->dev[i], BTN_THUMBR, ~data_psx[i][0] & 0x02); | ||
444 | |||
445 | case GC_PSX_NEGCON: | ||
446 | case GC_PSX_ANALOG: | ||
447 | |||
448 | if (gc->pads[GC_DDR] & gc_status_bit[i]) { | ||
449 | for(j = 0; j < 4; j++) | ||
450 | input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); | ||
451 | } else { | ||
452 | for (j = 0; j < 4; j++) | ||
453 | input_report_abs(gc->dev[i], gc_psx_abs[j+2], data_psx[i][j + 2]); | ||
454 | |||
455 | input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); | ||
456 | input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); | ||
457 | } | ||
458 | |||
459 | for (j = 0; j < 8; j++) | ||
460 | input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); | ||
461 | |||
462 | input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08); | ||
463 | input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01); | ||
464 | |||
465 | input_sync(gc->dev[i]); | ||
466 | |||
467 | break; | ||
468 | |||
469 | case GC_PSX_NORMAL: | ||
470 | if (gc->pads[GC_DDR] & gc_status_bit[i]) { | ||
471 | for(j = 0; j < 4; j++) | ||
472 | input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j)); | ||
473 | } else { | ||
474 | input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128); | ||
475 | input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128); | ||
476 | |||
477 | /* for some reason if the extra axes are left unset they drift */ | ||
478 | /* for (j = 0; j < 4; j++) | ||
479 | input_report_abs(gc->dev[i], gc_psx_abs[j+2], 128); | ||
480 | * This needs to be debugged properly, | ||
481 | * maybe fuzz processing needs to be done in input_sync() | ||
482 | * --vojtech | ||
483 | */ | ||
484 | } | ||
485 | |||
486 | for (j = 0; j < 8; j++) | ||
487 | input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j)); | ||
488 | |||
489 | input_report_key(gc->dev[i], BTN_START, ~data_psx[i][0] & 0x08); | ||
490 | input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01); | ||
491 | |||
492 | input_sync(gc->dev[i]); | ||
493 | |||
494 | break; | ||
495 | |||
496 | case 0: /* not a pad, ignore */ | ||
497 | break; | ||
498 | } | ||
499 | } | ||
500 | } | ||
501 | 546 | ||
502 | mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); | 547 | mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME); |
503 | } | 548 | } |
@@ -654,7 +699,7 @@ static struct gc __init *gc_probe(int parport, int *pads, int n_pads) | |||
654 | gc->timer.data = (long) gc; | 699 | gc->timer.data = (long) gc; |
655 | gc->timer.function = gc_timer; | 700 | gc->timer.function = gc_timer; |
656 | 701 | ||
657 | for (i = 0; i < n_pads; i++) { | 702 | for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) { |
658 | if (!pads[i]) | 703 | if (!pads[i]) |
659 | continue; | 704 | continue; |
660 | 705 | ||