diff options
Diffstat (limited to 'drivers/input/joystick/iforce/iforce-main.c')
-rw-r--r-- | drivers/input/joystick/iforce/iforce-main.c | 178 |
1 files changed, 57 insertions, 121 deletions
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 55f5b7bb4cac..9a5f90da06ec 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -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); |