Skip to content

Commit

Permalink
Input: add force feedback driver for PID devices
Browse files Browse the repository at this point in the history
This replaces the older PID driver which was never completed.

Signed-off-by: Anssi Hannula <anssi.hannula@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
  • Loading branch information
Anssi Hannula authored and Dmitry Torokhov committed Jul 19, 2006
1 parent f6a01c8 commit 224ee88
Show file tree
Hide file tree
Showing 8 changed files with 1,364 additions and 414 deletions.
8 changes: 4 additions & 4 deletions drivers/usb/input/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ config HID_FF
If unsure, say N.

config HID_PID
bool "PID Devices (Microsoft Sidewinder Force Feedback 2)"
bool "PID device support"
depends on HID_FF
help
Say Y here if you have a PID-compliant joystick and wish to enable force
feedback for it. The Microsoft Sidewinder Force Feedback 2 is one such
device.
Say Y here if you have a PID-compliant device and wish to enable force
feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
devices.

config LOGITECH_FF
bool "Logitech WingMan *3D support"
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/input/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ ifeq ($(CONFIG_USB_HIDINPUT),y)
usbhid-objs += hid-input.o
endif
ifeq ($(CONFIG_HID_PID),y)
usbhid-objs += pid.o
usbhid-objs += hid-pidff.o
endif
ifeq ($(CONFIG_LOGITECH_FF),y)
usbhid-objs += hid-lgff.o
Expand Down
45 changes: 17 additions & 28 deletions drivers/usb/input/hid-ff.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,45 +44,34 @@ struct hid_ff_initializer {
int (*init)(struct hid_device*);
};

/*
* We try pidff when no other driver is found because PID is the
* standards compliant way of implementing force feedback in HID.
* pidff_init() will quickly abort if the device doesn't appear to
* be a PID device
*/
static struct hid_ff_initializer inits[] = {
#ifdef CONFIG_LOGITECH_FF
{0x46d, 0xc211, hid_lgff_init}, // Logitech Cordless rumble pad
{0x46d, 0xc283, hid_lgff_init}, // Logitech Wingman Force 3d
{0x46d, 0xc295, hid_lgff_init}, // Logitech MOMO force wheel
{0x46d, 0xc219, hid_lgff_init}, // Logitech Cordless rumble pad 2
#endif
#ifdef CONFIG_HID_PID
{0x45e, 0x001b, hid_pid_init},
{ 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */
{ 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
{ 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
{ 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
#endif
#ifdef CONFIG_THRUSTMASTER_FF
{0x44f, 0xb304, hid_tmff_init},
{ 0x44f, 0xb304, hid_tmff_init },
#endif
{0, 0, NULL} /* Terminating entry */
{ 0, 0, hid_pidff_init} /* Matches anything */
};

static struct hid_ff_initializer *hid_get_ff_init(__u16 idVendor,
__u16 idProduct)
{
struct hid_ff_initializer *init;
for (init = inits;
init->idVendor
&& !(init->idVendor == idVendor
&& init->idProduct == idProduct);
init++);

return init->idVendor? init : NULL;
}

int hid_ff_init(struct hid_device* hid)
{
struct hid_ff_initializer *init;
int vendor = le16_to_cpu(hid->dev->descriptor.idVendor);
int product = le16_to_cpu(hid->dev->descriptor.idProduct);

init = hid_get_ff_init(le16_to_cpu(hid->dev->descriptor.idVendor),
le16_to_cpu(hid->dev->descriptor.idProduct));
for (init = inits; init->idVendor; init++)
if (init->idVendor == vendor && init->idProduct == product)
break;

if (!init) {
dbg("hid_ff_init could not find initializer");
return -ENOSYS;
}
return init->init(hid);
}
21 changes: 1 addition & 20 deletions drivers/usb/input/hid-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,9 @@ static const struct {
#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
#define map_ff(c) do { usage->code = c; usage->type = EV_FF; bit = input->ffbit; max = FF_MAX; } while (0)

#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0)
#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
#define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0)

#ifdef CONFIG_USB_HIDINPUT_POWERBOOK

Expand Down Expand Up @@ -525,23 +523,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel

case HID_UP_PID:

set_bit(EV_FF, input->evbit);
switch(usage->hid & HID_USAGE) {
case 0x26: map_ff_effect(FF_CONSTANT); goto ignore;
case 0x27: map_ff_effect(FF_RAMP); goto ignore;
case 0x28: map_ff_effect(FF_CUSTOM); goto ignore;
case 0x30: map_ff_effect(FF_SQUARE); map_ff_effect(FF_PERIODIC); goto ignore;
case 0x31: map_ff_effect(FF_SINE); map_ff_effect(FF_PERIODIC); goto ignore;
case 0x32: map_ff_effect(FF_TRIANGLE); map_ff_effect(FF_PERIODIC); goto ignore;
case 0x33: map_ff_effect(FF_SAW_UP); map_ff_effect(FF_PERIODIC); goto ignore;
case 0x34: map_ff_effect(FF_SAW_DOWN); map_ff_effect(FF_PERIODIC); goto ignore;
case 0x40: map_ff_effect(FF_SPRING); goto ignore;
case 0x41: map_ff_effect(FF_DAMPER); goto ignore;
case 0x42: map_ff_effect(FF_INERTIA); goto ignore;
case 0x43: map_ff_effect(FF_FRICTION); goto ignore;
case 0x7e: map_ff(FF_GAIN); break;
case 0x83: input->ff_effects_max = field->value[0]; goto ignore;
case 0x98: map_ff(FF_AUTOCENTER); break;
case 0xa4: map_key_clear(BTN_DEAD); break;
default: goto ignore;
}
Expand Down Expand Up @@ -698,8 +680,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
}

if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
input->ff_effects_max = value;
dbg("Maximum Effects - %d",input->ff_effects_max);
dbg("Maximum Effects - %d",value);
return;
}

Expand Down
Loading

0 comments on commit 224ee88

Please sign in to comment.