Merge tag 'v5.2' into next
[linux-2.6-microblaze.git] / drivers / input / joystick / iforce / iforce-main.c
index 55f5b7b..9a5f90d 100644 (file)
@@ -9,10 +9,11 @@
 /*
  */
 
+#include <asm/unaligned.h>
 #include "iforce.h"
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <johann.deneux@gmail.com>");
-MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver");
+MODULE_DESCRIPTION("Core I-Force joysticks and wheels driver");
 MODULE_LICENSE("GPL");
 
 static signed short btn_joystick[] =
@@ -55,6 +56,7 @@ static struct iforce_device iforce_device[] = {
        { 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel",   btn_wheel, abs_wheel, ff_iforce }, //?
        { 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce }, //?
        { 0x061c, 0xc084, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce },
+       { 0x06a3, 0xff04, "Saitek R440 Force Wheel",                    btn_wheel, abs_wheel, ff_iforce }, //?
        { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",       btn_wheel, abs_wheel, ff_iforce }, //?
        { 0x06f8, 0x0001, "Guillemot Jet Leader Force Feedback",        btn_joystick, abs_joystick_rudder, ff_iforce },
        { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",      btn_wheel, abs_wheel, ff_iforce }, //?
@@ -120,22 +122,21 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect,
  * Upload the effect
  */
        switch (effect->type) {
+       case FF_PERIODIC:
+               ret = iforce_upload_periodic(iforce, effect, old);
+               break;
 
-               case FF_PERIODIC:
-                       ret = iforce_upload_periodic(iforce, effect, old);
-                       break;
-
-               case FF_CONSTANT:
-                       ret = iforce_upload_constant(iforce, effect, old);
-                       break;
+       case FF_CONSTANT:
+               ret = iforce_upload_constant(iforce, effect, old);
+               break;
 
-               case FF_SPRING:
-               case FF_DAMPER:
-                       ret = iforce_upload_condition(iforce, effect, old);
-                       break;
+       case FF_SPRING:
+       case FF_DAMPER:
+               ret = iforce_upload_condition(iforce, effect, old);
+               break;
 
-               default:
-                       return -EINVAL;
+       default:
+               return -EINVAL;
        }
 
        if (ret == 0) {
@@ -173,15 +174,7 @@ static int iforce_open(struct input_dev *dev)
 {
        struct iforce *iforce = input_get_drvdata(dev);
 
-       switch (iforce->bus) {
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
-               case IFORCE_USB:
-                       iforce->irq->dev = iforce->usbdev;
-                       if (usb_submit_urb(iforce->irq, GFP_KERNEL))
-                               return -EIO;
-                       break;
-#endif
-       }
+       iforce->xport_ops->start_io(iforce);
 
        if (test_bit(EV_FF, dev->evbit)) {
                /* Enable force feedback */
@@ -214,27 +207,17 @@ static void iforce_close(struct input_dev *dev)
                        !test_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags));
        }
 
-       switch (iforce->bus) {
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
-       case IFORCE_USB:
-               usb_kill_urb(iforce->irq);
-               usb_kill_urb(iforce->out);
-               usb_kill_urb(iforce->ctrl);
-               break;
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_232
-       case IFORCE_232:
-               //TODO: Wait for the last packets to be sent
-               break;
-#endif
-       }
+       iforce->xport_ops->stop_io(iforce);
 }
 
-int iforce_init_device(struct iforce *iforce)
+int iforce_init_device(struct device *parent, u16 bustype,
+                      struct iforce *iforce)
 {
        struct input_dev *input_dev;
        struct ff_device *ff;
-       unsigned char c[] = "CEOV";
+       u8 c[] = "CEOV";
+       u8 buf[IFORCE_MAX_LENGTH];
+       size_t len;
        int i, error;
        int ff_effects = 0;
 
@@ -252,20 +235,8 @@ int iforce_init_device(struct iforce *iforce)
  * Input device fields.
  */
 
-       switch (iforce->bus) {
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
-       case IFORCE_USB:
-               input_dev->id.bustype = BUS_USB;
-               input_dev->dev.parent = &iforce->usbdev->dev;
-               break;
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_232
-       case IFORCE_232:
-               input_dev->id.bustype = BUS_RS232;
-               input_dev->dev.parent = &iforce->serio->dev;
-               break;
-#endif
-       }
+       input_dev->id.bustype = bustype;
+       input_dev->dev.parent = parent;
 
        input_set_drvdata(input_dev, iforce);
 
@@ -290,7 +261,7 @@ int iforce_init_device(struct iforce *iforce)
  */
 
        for (i = 0; i < 20; i++)
-               if (!iforce_get_id_packet(iforce, "O"))
+               if (!iforce_get_id_packet(iforce, 'O', buf, &len))
                        break;
 
        if (i == 20) { /* 5 seconds */
@@ -304,23 +275,23 @@ int iforce_init_device(struct iforce *iforce)
  * Get device info.
  */
 
-       if (!iforce_get_id_packet(iforce, "M"))
-               input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
+       if (!iforce_get_id_packet(iforce, 'M', buf, &len) || len < 3)
+               input_dev->id.vendor = get_unaligned_le16(buf + 1);
        else
                dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n");
 
-       if (!iforce_get_id_packet(iforce, "P"))
-               input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
+       if (!iforce_get_id_packet(iforce, 'P', buf, &len) || len < 3)
+               input_dev->id.product = get_unaligned_le16(buf + 1);
        else
                dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n");
 
-       if (!iforce_get_id_packet(iforce, "B"))
-               iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
+       if (!iforce_get_id_packet(iforce, 'B', buf, &len) || len < 3)
+               iforce->device_memory.end = get_unaligned_le16(buf + 1);
        else
                dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n");
 
-       if (!iforce_get_id_packet(iforce, "N"))
-               ff_effects = iforce->edata[1];
+       if (!iforce_get_id_packet(iforce, 'N', buf, &len) || len < 2)
+               ff_effects = buf[1];
        else
                dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n");
 
@@ -336,8 +307,9 @@ int iforce_init_device(struct iforce *iforce)
  */
 
        for (i = 0; c[i]; i++)
-               if (!iforce_get_id_packet(iforce, c + i))
-                       iforce_dump_packet(iforce, "info", iforce->ecmd, iforce->edata);
+               if (!iforce_get_id_packet(iforce, c[i], buf, &len))
+                       iforce_dump_packet(iforce, "info",
+                                          (FF_CMD_QUERY & 0xff00) | len, buf);
 
 /*
  * Disable spring, enable force feedback.
@@ -371,34 +343,29 @@ int iforce_init_device(struct iforce *iforce)
                signed short t = iforce->type->abs[i];
 
                switch (t) {
+               case ABS_X:
+               case ABS_Y:
+               case ABS_WHEEL:
+                       input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
+                       set_bit(t, input_dev->ffbit);
+                       break;
 
-                       case ABS_X:
-                       case ABS_Y:
-                       case ABS_WHEEL:
-
-                               input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
-                               set_bit(t, input_dev->ffbit);
-                               break;
-
-                       case ABS_THROTTLE:
-                       case ABS_GAS:
-                       case ABS_BRAKE:
-
-                               input_set_abs_params(input_dev, t, 0, 255, 0, 0);
-                               break;
-
-                       case ABS_RUDDER:
-
-                               input_set_abs_params(input_dev, t, -128, 127, 0, 0);
-                               break;
+               case ABS_THROTTLE:
+               case ABS_GAS:
+               case ABS_BRAKE:
+                       input_set_abs_params(input_dev, t, 0, 255, 0, 0);
+                       break;
 
-                       case ABS_HAT0X:
-                       case ABS_HAT0Y:
-                       case ABS_HAT1X:
-                       case ABS_HAT1Y:
+               case ABS_RUDDER:
+                       input_set_abs_params(input_dev, t, -128, 127, 0, 0);
+                       break;
 
-                               input_set_abs_params(input_dev, t, -1, 1, 0, 0);
-                               break;
+               case ABS_HAT0X:
+               case ABS_HAT0Y:
+               case ABS_HAT1X:
+               case ABS_HAT1Y:
+                       input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+                       break;
                }
        }
 
@@ -431,35 +398,4 @@ int iforce_init_device(struct iforce *iforce)
  fail: input_free_device(input_dev);
        return error;
 }
-
-static int __init iforce_init(void)
-{
-       int err = 0;
-
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
-       err = usb_register(&iforce_usb_driver);
-       if (err)
-               return err;
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_232
-       err = serio_register_driver(&iforce_serio_drv);
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
-       if (err)
-               usb_deregister(&iforce_usb_driver);
-#endif
-#endif
-       return err;
-}
-
-static void __exit iforce_exit(void)
-{
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
-       usb_deregister(&iforce_usb_driver);
-#endif
-#ifdef CONFIG_JOYSTICK_IFORCE_232
-       serio_unregister_driver(&iforce_serio_drv);
-#endif
-}
-
-module_init(iforce_init);
-module_exit(iforce_exit);
+EXPORT_SYMBOL(iforce_init_device);