aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/joystick/sidewinder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/joystick/sidewinder.c')
-rw-r--r--drivers/input/joystick/sidewinder.c70
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
114struct sw { 114struct 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)
301static int sw_parse(unsigned char *buf, struct sw *sw) 301static 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)
581static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) 586static 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
766fail2: gameport_close(gameport); 778 fail3: while (--i >= 0)
767fail1: 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);