Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 224ee88f authored by Anssi Hannula's avatar Anssi Hannula Committed by Dmitry Torokhov
Browse files

Input: add force feedback driver for PID devices



This replaces the older PID driver which was never completed.

Signed-off-by: default avatarAnssi Hannula <anssi.hannula@gmail.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent f6a01c85
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -60,12 +60,12 @@ config HID_FF
	  If unsure, say N.
	  If unsure, say N.


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


config LOGITECH_FF
config LOGITECH_FF
	bool "Logitech WingMan *3D support"
	bool "Logitech WingMan *3D support"
+1 −1
Original line number Original line Diff line number Diff line
@@ -14,7 +14,7 @@ ifeq ($(CONFIG_USB_HIDINPUT),y)
	usbhid-objs	+= hid-input.o
	usbhid-objs	+= hid-input.o
endif
endif
ifeq ($(CONFIG_HID_PID),y)
ifeq ($(CONFIG_HID_PID),y)
	usbhid-objs	+= pid.o
	usbhid-objs	+= hid-pidff.o
endif
endif
ifeq ($(CONFIG_LOGITECH_FF),y)
ifeq ($(CONFIG_LOGITECH_FF),y)
	usbhid-objs	+= hid-lgff.o
	usbhid-objs	+= hid-lgff.o
+17 −28
Original line number Original line Diff line number Diff line
@@ -44,45 +44,34 @@ struct hid_ff_initializer {
	int (*init)(struct hid_device*);
	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[] = {
static struct hid_ff_initializer inits[] = {
#ifdef CONFIG_LOGITECH_FF
#ifdef CONFIG_LOGITECH_FF
	{0x46d, 0xc211, hid_lgff_init}, // Logitech Cordless rumble pad
	{ 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */
	{0x46d, 0xc283, hid_lgff_init}, // Logitech Wingman Force 3d
	{ 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
	{0x46d, 0xc295, hid_lgff_init},	// Logitech MOMO force wheel
	{ 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
	{0x46d, 0xc219, hid_lgff_init}, // Logitech Cordless rumble pad 2
	{ 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
#endif
#ifdef CONFIG_HID_PID
	{0x45e, 0x001b, hid_pid_init},
#endif
#endif
#ifdef CONFIG_THRUSTMASTER_FF
#ifdef CONFIG_THRUSTMASTER_FF
	{ 0x44f, 0xb304, hid_tmff_init },
	{ 0x44f, 0xb304, hid_tmff_init },
#endif
#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)
int hid_ff_init(struct hid_device* hid)
{
{
	struct hid_ff_initializer *init;
	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),
	for (init = inits; init->idVendor; init++)
			       le16_to_cpu(hid->dev->descriptor.idProduct));
		if (init->idVendor == vendor && init->idProduct == product)
			break;


	if (!init) {
		dbg("hid_ff_init could not find initializer");
		return -ENOSYS;
	}
	return init->init(hid);
	return init->init(hid);
}
}
+1 −20
Original line number Original line Diff line number Diff line
@@ -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_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_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_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_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_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
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK


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


		case HID_UP_PID:
		case HID_UP_PID:


			set_bit(EV_FF, input->evbit);
			switch(usage->hid & HID_USAGE) {
			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;
				case 0xa4: map_key_clear(BTN_DEAD);	break;
				default: goto ignore;
				default: goto ignore;
			}
			}
@@ -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 */
	if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
		input->ff_effects_max = value;
		dbg("Maximum Effects - %d",value);
		dbg("Maximum Effects - %d",input->ff_effects_max);
		return;
		return;
	}
	}


+1330 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading