From 81e8768fc3188409f2e0cc4f2f606554fb5ae6a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Mal=C3=BD?= Date: Thu, 4 Aug 2011 16:16:09 +0200 Subject: [PATCH] --- yaml --- r: 264723 b: refs/heads/master c: 7362cd2286d2364cca6738b583668f64254fe04b h: refs/heads/master i: 264721: eabe99e166fe01ec6bb7ed62f22ca09d75000378 264719: 8918bb8e93423e57f626f54123a2eead67a8d7d5 v: v3 --- [refs] | 2 +- trunk/drivers/hid/Kconfig | 2 +- trunk/drivers/hid/hid-axff.c | 36 ++++++------------ trunk/drivers/hid/hid-ids.h | 1 + trunk/drivers/hid/hid-lg.c | 19 ++++++---- trunk/drivers/hid/hid-lg4ff.c | 70 ++++++++++++++++++++++++----------- trunk/drivers/hid/hid-lgff.c | 13 ------- 7 files changed, 74 insertions(+), 69 deletions(-) diff --git a/[refs] b/[refs] index c4eb8193f750..874f353df89b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b55ebc27b0a54ff4cdbfdcb218a85f96e502db3c +refs/heads/master: 7362cd2286d2364cca6738b583668f64254fe04b diff --git a/trunk/drivers/hid/Kconfig b/trunk/drivers/hid/Kconfig index 342be43211d8..306b15f39c9c 100644 --- a/trunk/drivers/hid/Kconfig +++ b/trunk/drivers/hid/Kconfig @@ -69,7 +69,7 @@ config HID_ACRUX Say Y here if you want to enable support for ACRUX game controllers. config HID_ACRUX_FF - bool "ACRUX force feedback support" + tristate "ACRUX force feedback support" depends on HID_ACRUX select INPUT_FF_MEMLESS ---help--- diff --git a/trunk/drivers/hid/hid-axff.c b/trunk/drivers/hid/hid-axff.c index 3bdb4500f95e..121514149e0b 100644 --- a/trunk/drivers/hid/hid-axff.c +++ b/trunk/drivers/hid/hid-axff.c @@ -6,7 +6,7 @@ * Xbox 360 controller. * * 1a34:0802 "ACRUX USB GAMEPAD 8116" - * - tested with an EXEQ EQ-PCU-02090 game controller. + * - tested with a EXEQ EQ-PCU-02090 game controller. * * Copyright (c) 2010 Sergei Kolzun */ @@ -45,10 +45,7 @@ static int axff_play(struct input_dev *dev, void *data, struct ff_effect *effect { struct hid_device *hid = input_get_drvdata(dev); struct axff_device *axff = data; - struct hid_report *report = axff->report; - int field_count = 0; int left, right; - int i, j; left = effect->u.rumble.strong_magnitude; right = effect->u.rumble.weak_magnitude; @@ -58,14 +55,10 @@ static int axff_play(struct input_dev *dev, void *data, struct ff_effect *effect left = left * 0xff / 0xffff; right = right * 0xff / 0xffff; - for (i = 0; i < report->maxfield; i++) { - for (j = 0; j < report->field[i]->report_count; j++) { - report->field[i]->value[j] = - field_count % 2 ? right : left; - field_count++; - } - } - + axff->report->field[0]->value[0] = left; + axff->report->field[1]->value[0] = right; + axff->report->field[2]->value[0] = left; + axff->report->field[3]->value[0] = right; dbg_hid("running with 0x%02x 0x%02x", left, right); usbhid_submit_report(hid, axff->report, USB_DIR_OUT); @@ -79,8 +72,6 @@ static int axff_init(struct hid_device *hid) struct hid_input *hidinput = list_first_entry(&hid->inputs, struct hid_input, list); struct list_head *report_list =&hid->report_enum[HID_OUTPUT_REPORT].report_list; struct input_dev *dev = hidinput->input; - int field_count = 0; - int i, j; int error; if (list_empty(report_list)) { @@ -89,16 +80,9 @@ static int axff_init(struct hid_device *hid) } report = list_first_entry(report_list, struct hid_report, list); - for (i = 0; i < report->maxfield; i++) { - for (j = 0; j < report->field[i]->report_count; j++) { - report->field[i]->value[j] = 0x00; - field_count++; - } - } - if (field_count < 4) { - hid_err(hid, "not enough fields in the report: %d\n", - field_count); + if (report->maxfield < 4) { + hid_err(hid, "no fields in the report: %d\n", report->maxfield); return -ENODEV; } @@ -113,9 +97,13 @@ static int axff_init(struct hid_device *hid) goto err_free_mem; axff->report = report; + axff->report->field[0]->value[0] = 0x00; + axff->report->field[1]->value[0] = 0x00; + axff->report->field[2]->value[0] = 0x00; + axff->report->field[3]->value[0] = 0x00; usbhid_submit_report(hid, axff->report, USB_DIR_OUT); - hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun \n"); + hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun\n"); return 0; diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index db63ccf21cc8..ea2c338814fe 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -436,6 +436,7 @@ #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298 #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 +#define USB_DEVICE_ID_LOGITECH_DFGT_WHEEL 0xc29a #define USB_DEVICE_ID_LOGITECH_G27_WHEEL 0xc29b #define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a diff --git a/trunk/drivers/hid/hid-lg.c b/trunk/drivers/hid/hid-lg.c index a7f916e8fc32..e0ae4a09425d 100644 --- a/trunk/drivers/hid/hid-lg.c +++ b/trunk/drivers/hid/hid-lg.c @@ -363,7 +363,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err_free; } - if (quirks & (LG_FF | LG_FF2 | LG_FF3)) + if (quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4)) connect_mask &= ~HID_CONNECT_FF; ret = hid_hw_start(hdev, connect_mask); @@ -372,7 +372,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err_free; } - if (quirks & LG_FF4) { + /* Setup wireless link with Logitech Wii wheel */ + if(hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) { unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); @@ -431,7 +432,7 @@ static const struct hid_device_id lg_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D), .driver_data = LG_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), - .driver_data = LG_NOGET | LG_FF }, + .driver_data = LG_NOGET | LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD), .driver_data = LG_FF2 }, @@ -444,15 +445,17 @@ static const struct hid_device_id lg_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL), - .driver_data = LG_FF }, + .driver_data = LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), - .driver_data = LG_FF }, + .driver_data = LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), - .driver_data = LG_FF }, + .driver_data = LG_FF4 }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL), + .driver_data = LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL), - .driver_data = LG_FF }, + .driver_data = LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL), - .driver_data = LG_NOGET | LG_FF }, + .driver_data = LG_NOGET | LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), .driver_data = LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), diff --git a/trunk/drivers/hid/hid-lg4ff.c b/trunk/drivers/hid/hid-lg4ff.c index fa550c8e1d1b..1fcb2da32785 100644 --- a/trunk/drivers/hid/hid-lg4ff.c +++ b/trunk/drivers/hid/hid-lg4ff.c @@ -29,17 +29,32 @@ #include "usbhid/usbhid.h" #include "hid-lg.h" +#include "hid-ids.h" -struct lg4ff_device { - struct hid_report *report; -}; - -static const signed short ff4_wheel_ac[] = { +static const signed short lg4ff_wheel_effects[] = { FF_CONSTANT, FF_AUTOCENTER, -1 }; +struct lg4ff_wheel { + const __u32 product_id; + const signed short *ff_effects; + const __u16 min_range; + const __u16 max_range; +}; + +static const struct lg4ff_wheel lg4ff_devices[] = { + {USB_DEVICE_ID_LOGITECH_WHEEL, lg4ff_wheel_effects, 40, 270}, + {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL, lg4ff_wheel_effects, 40, 270}, + {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, lg4ff_wheel_effects, 40, 900}, + {USB_DEVICE_ID_LOGITECH_G25_WHEEL, lg4ff_wheel_effects, 40, 900}, + {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, lg4ff_wheel_effects, 40, 900}, + {USB_DEVICE_ID_LOGITECH_G27_WHEEL, lg4ff_wheel_effects, 40, 900}, + {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270}, + {USB_DEVICE_ID_LOGITECH_WII_WHEEL, lg4ff_wheel_effects, 40, 270} +}; + static int hid_lg4ff_play(struct input_dev *dev, void *data, struct ff_effect *effect) { @@ -55,13 +70,12 @@ static int hid_lg4ff_play(struct input_dev *dev, void *data, x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */ CLAMP(x); report->field[0]->value[0] = 0x11; /* Slot 1 */ - report->field[0]->value[1] = 0x10; + report->field[0]->value[1] = 0x08; report->field[0]->value[2] = x; - report->field[0]->value[3] = 0x00; + report->field[0]->value[3] = 0x80; report->field[0]->value[4] = 0x00; - report->field[0]->value[5] = 0x08; + report->field[0]->value[5] = 0x00; report->field[0]->value[6] = 0x00; - dbg_hid("Autocenter, x=0x%02X\n", x); usbhid_submit_report(hid, report, USB_DIR_OUT); break; @@ -74,15 +88,14 @@ static void hid_lg4ff_set_autocenter(struct input_dev *dev, u16 magnitude) struct hid_device *hid = input_get_drvdata(dev); struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; struct hid_report *report = list_entry(report_list->next, struct hid_report, list); - __s32 *value = report->field[0]->value; - *value++ = 0xfe; - *value++ = 0x0d; - *value++ = 0x07; - *value++ = 0x07; - *value++ = (magnitude >> 8) & 0xff; - *value++ = 0x00; - *value = 0x00; + report->field[0]->value[0] = 0xfe; + report->field[0]->value[1] = 0x0d; + report->field[0]->value[2] = magnitude >> 13; + report->field[0]->value[3] = magnitude >> 13; + report->field[0]->value[4] = magnitude >> 8; + report->field[0]->value[5] = 0x00; + report->field[0]->value[6] = 0x00; usbhid_submit_report(hid, report, USB_DIR_OUT); } @@ -95,9 +108,7 @@ int lg4ff_init(struct hid_device *hid) struct input_dev *dev = hidinput->input; struct hid_report *report; struct hid_field *field; - const signed short *ff_bits = ff4_wheel_ac; - int error; - int i; + int error, i, j; /* Find the report to use */ if (list_empty(report_list)) { @@ -117,9 +128,24 @@ int lg4ff_init(struct hid_device *hid) hid_err(hid, "NULL field\n"); return -1; } + + /* Check what wheel has been connected */ + for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) { + if (hid->product == lg4ff_devices[i].product_id) { + dbg_hid("Found compatible device, product ID %04X\n", lg4ff_devices[i].product_id); + break; + } + } + + if (i == ARRAY_SIZE(lg4ff_devices)) { + hid_err(hid, "Device is not supported by lg4ff driver. If you think it should be, consider reporting a bug to" + "LKML, Simon Wood or Michal Maly \n"); + return -1; + } - for (i = 0; ff_bits[i] >= 0; i++) - set_bit(ff_bits[i], dev->ffbit); + /* Set supported force feedback capabilities */ + for (j = 0; lg4ff_devices[i].ff_effects[j] >= 0; j++) + set_bit(lg4ff_devices[i].ff_effects[j], dev->ffbit); error = input_ff_create_memless(dev, NULL, hid_lg4ff_play); diff --git a/trunk/drivers/hid/hid-lgff.c b/trunk/drivers/hid/hid-lgff.c index 088f85049290..27bc54f92f44 100644 --- a/trunk/drivers/hid/hid-lgff.c +++ b/trunk/drivers/hid/hid-lgff.c @@ -58,12 +58,6 @@ static const signed short ff_joystick_ac[] = { -1 }; -static const signed short ff_wheel[] = { - FF_CONSTANT, - FF_AUTOCENTER, - -1 -}; - static const struct dev_type devices[] = { { 0x046d, 0xc211, ff_rumble }, { 0x046d, 0xc219, ff_rumble }, @@ -71,14 +65,7 @@ static const struct dev_type devices[] = { { 0x046d, 0xc286, ff_joystick_ac }, { 0x046d, 0xc287, ff_joystick_ac }, { 0x046d, 0xc293, ff_joystick }, - { 0x046d, 0xc294, ff_wheel }, - { 0x046d, 0xc298, ff_wheel }, - { 0x046d, 0xc299, ff_wheel }, - { 0x046d, 0xc29b, ff_wheel }, { 0x046d, 0xc295, ff_joystick }, - { 0x046d, 0xc298, ff_wheel }, - { 0x046d, 0xc299, ff_wheel }, - { 0x046d, 0xca03, ff_wheel }, }; static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)