diff options
Diffstat (limited to 'drivers/input/joystick/sidewinder.c')
-rw-r--r-- | drivers/input/joystick/sidewinder.c | 70 |
1 files changed, 42 insertions, 28 deletions
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 9e0353721a35..eaaad45cc750 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c | |||
@@ -113,7 +113,7 @@ static struct { | |||
113 | 113 | ||
114 | struct sw { | 114 | struct sw { |
115 | struct gameport *gameport; | 115 | struct gameport *gameport; |
116 | struct input_dev dev[4]; | 116 | struct input_dev *dev[4]; |
117 | char name[64]; | 117 | char name[64]; |
118 | char phys[4][32]; | 118 | char phys[4][32]; |
119 | int length; | 119 | int length; |
@@ -301,7 +301,7 @@ static int sw_check(__u64 t) | |||
301 | static int sw_parse(unsigned char *buf, struct sw *sw) | 301 | static int sw_parse(unsigned char *buf, struct sw *sw) |
302 | { | 302 | { |
303 | int hat, i, j; | 303 | int hat, i, j; |
304 | struct input_dev *dev = sw->dev; | 304 | struct input_dev *dev; |
305 | 305 | ||
306 | switch (sw->type) { | 306 | switch (sw->type) { |
307 | 307 | ||
@@ -310,6 +310,8 @@ static int sw_parse(unsigned char *buf, struct sw *sw) | |||
310 | if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8) | 310 | if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8) |
311 | return -1; | 311 | return -1; |
312 | 312 | ||
313 | dev = sw->dev[0]; | ||
314 | |||
313 | input_report_abs(dev, ABS_X, (GB( 3,3) << 7) | GB(16,7)); | 315 | input_report_abs(dev, ABS_X, (GB( 3,3) << 7) | GB(16,7)); |
314 | input_report_abs(dev, ABS_Y, (GB( 0,3) << 7) | GB(24,7)); | 316 | input_report_abs(dev, ABS_Y, (GB( 0,3) << 7) | GB(24,7)); |
315 | input_report_abs(dev, ABS_RZ, (GB(35,2) << 7) | GB(40,7)); | 317 | input_report_abs(dev, ABS_RZ, (GB(35,2) << 7) | GB(40,7)); |
@@ -335,13 +337,13 @@ static int sw_parse(unsigned char *buf, struct sw *sw) | |||
335 | if (sw_parity(GB(i*15,15))) | 337 | if (sw_parity(GB(i*15,15))) |
336 | return -1; | 338 | return -1; |
337 | 339 | ||
338 | input_report_abs(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1)); | 340 | input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1)); |
339 | input_report_abs(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1)); | 341 | input_report_abs(sw->dev[i], ABS_Y, GB(i*15+0,1) - GB(i*15+1,1)); |
340 | 342 | ||
341 | for (j = 0; j < 10; j++) | 343 | for (j = 0; j < 10; j++) |
342 | input_report_key(dev + i, sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1)); | 344 | input_report_key(sw->dev[i], sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1)); |
343 | 345 | ||
344 | input_sync(dev + i); | 346 | input_sync(sw->dev[i]); |
345 | } | 347 | } |
346 | 348 | ||
347 | return 0; | 349 | return 0; |
@@ -352,6 +354,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw) | |||
352 | if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8) | 354 | if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8) |
353 | return -1; | 355 | return -1; |
354 | 356 | ||
357 | dev = sw->dev[0]; | ||
355 | input_report_abs(dev, ABS_X, GB( 9,10)); | 358 | input_report_abs(dev, ABS_X, GB( 9,10)); |
356 | input_report_abs(dev, ABS_Y, GB(19,10)); | 359 | input_report_abs(dev, ABS_Y, GB(19,10)); |
357 | input_report_abs(dev, ABS_RZ, GB(36, 6)); | 360 | input_report_abs(dev, ABS_RZ, GB(36, 6)); |
@@ -372,6 +375,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw) | |||
372 | if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8) | 375 | if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8) |
373 | return -1; | 376 | return -1; |
374 | 377 | ||
378 | dev = sw->dev[0]; | ||
375 | input_report_abs(dev, ABS_X, GB( 0,10)); | 379 | input_report_abs(dev, ABS_X, GB( 0,10)); |
376 | input_report_abs(dev, ABS_Y, GB(16,10)); | 380 | input_report_abs(dev, ABS_Y, GB(16,10)); |
377 | input_report_abs(dev, ABS_THROTTLE, GB(32, 6)); | 381 | input_report_abs(dev, ABS_THROTTLE, GB(32, 6)); |
@@ -396,6 +400,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw) | |||
396 | if (!sw_parity(GB(0,33))) | 400 | if (!sw_parity(GB(0,33))) |
397 | return -1; | 401 | return -1; |
398 | 402 | ||
403 | dev = sw->dev[0]; | ||
399 | input_report_abs(dev, ABS_RX, GB( 0,10)); | 404 | input_report_abs(dev, ABS_RX, GB( 0,10)); |
400 | input_report_abs(dev, ABS_RUDDER, GB(10, 6)); | 405 | input_report_abs(dev, ABS_RUDDER, GB(10, 6)); |
401 | input_report_abs(dev, ABS_THROTTLE, GB(16, 6)); | 406 | input_report_abs(dev, ABS_THROTTLE, GB(16, 6)); |
@@ -581,6 +586,7 @@ static int sw_guess_mode(unsigned char *buf, int len) | |||
581 | static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) | 586 | static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) |
582 | { | 587 | { |
583 | struct sw *sw; | 588 | struct sw *sw; |
589 | struct input_dev *input_dev; | ||
584 | int i, j, k, l; | 590 | int i, j, k, l; |
585 | int err; | 591 | int err; |
586 | unsigned char *buf = NULL; /* [SW_LENGTH] */ | 592 | unsigned char *buf = NULL; /* [SW_LENGTH] */ |
@@ -729,42 +735,50 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) | |||
729 | sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]); | 735 | sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]); |
730 | sprintf(sw->phys[i], "%s/input%d", gameport->phys, i); | 736 | sprintf(sw->phys[i], "%s/input%d", gameport->phys, i); |
731 | 737 | ||
732 | sw->dev[i].private = sw; | 738 | input_dev = input_allocate_device(); |
739 | if (!input_dev) { | ||
740 | err = -ENOMEM; | ||
741 | goto fail3; | ||
742 | } | ||
733 | 743 | ||
734 | sw->dev[i].open = sw_open; | 744 | input_dev->name = sw->name; |
735 | sw->dev[i].close = sw_close; | 745 | input_dev->phys = sw->phys[i]; |
746 | input_dev->id.bustype = BUS_GAMEPORT; | ||
747 | input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT; | ||
748 | input_dev->id.product = sw->type; | ||
749 | input_dev->id.version = 0x0100; | ||
750 | input_dev->cdev.dev = &gameport->dev; | ||
751 | input_dev->private = sw; | ||
736 | 752 | ||
737 | sw->dev[i].name = sw->name; | 753 | input_dev->open = sw_open; |
738 | sw->dev[i].phys = sw->phys[i]; | 754 | input_dev->close = sw_close; |
739 | sw->dev[i].id.bustype = BUS_GAMEPORT; | ||
740 | sw->dev[i].id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT; | ||
741 | sw->dev[i].id.product = sw->type; | ||
742 | sw->dev[i].id.version = 0x0100; | ||
743 | 755 | ||
744 | sw->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 756 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
745 | 757 | ||
746 | for (j = 0; (bits = sw_bit[sw->type][j]); j++) { | 758 | for (j = 0; (bits = sw_bit[sw->type][j]); j++) { |
747 | code = sw_abs[sw->type][j]; | 759 | code = sw_abs[sw->type][j]; |
748 | set_bit(code, sw->dev[i].absbit); | 760 | set_bit(code, input_dev->absbit); |
749 | sw->dev[i].absmax[code] = (1 << bits) - 1; | 761 | input_dev->absmax[code] = (1 << bits) - 1; |
750 | sw->dev[i].absmin[code] = (bits == 1) ? -1 : 0; | 762 | input_dev->absmin[code] = (bits == 1) ? -1 : 0; |
751 | sw->dev[i].absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0; | 763 | input_dev->absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0; |
752 | if (code != ABS_THROTTLE) | 764 | if (code != ABS_THROTTLE) |
753 | sw->dev[i].absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0; | 765 | input_dev->absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0; |
754 | } | 766 | } |
755 | 767 | ||
756 | for (j = 0; (code = sw_btn[sw->type][j]); j++) | 768 | for (j = 0; (code = sw_btn[sw->type][j]); j++) |
757 | set_bit(code, sw->dev[i].keybit); | 769 | set_bit(code, input_dev->keybit); |
770 | |||
771 | dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k); | ||
758 | 772 | ||
759 | input_register_device(sw->dev + i); | 773 | input_register_device(sw->dev[i]); |
760 | printk(KERN_INFO "input: %s%s on %s [%d-bit id %d data %d]\n", | ||
761 | sw->name, comment, gameport->phys, m, l, k); | ||
762 | } | 774 | } |
763 | 775 | ||
764 | return 0; | 776 | return 0; |
765 | 777 | ||
766 | fail2: gameport_close(gameport); | 778 | fail3: while (--i >= 0) |
767 | fail1: gameport_set_drvdata(gameport, NULL); | 779 | input_unregister_device(sw->dev[i]); |
780 | fail2: gameport_close(gameport); | ||
781 | fail1: gameport_set_drvdata(gameport, NULL); | ||
768 | kfree(sw); | 782 | kfree(sw); |
769 | kfree(buf); | 783 | kfree(buf); |
770 | kfree(idbuf); | 784 | kfree(idbuf); |
@@ -777,7 +791,7 @@ static void sw_disconnect(struct gameport *gameport) | |||
777 | int i; | 791 | int i; |
778 | 792 | ||
779 | for (i = 0; i < sw->number; i++) | 793 | for (i = 0; i < sw->number; i++) |
780 | input_unregister_device(sw->dev + i); | 794 | input_unregister_device(sw->dev[i]); |
781 | gameport_close(gameport); | 795 | gameport_close(gameport); |
782 | gameport_set_drvdata(gameport, NULL); | 796 | gameport_set_drvdata(gameport, NULL); |
783 | kfree(sw); | 797 | kfree(sw); |