diff options
Diffstat (limited to 'drivers/hid/hid-pl.c')
-rw-r--r-- | drivers/hid/hid-pl.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index 46941f979b9d..9ad76bf71186 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c | |||
@@ -9,9 +9,12 @@ | |||
9 | * - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT) | 9 | * - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT) |
10 | * | 10 | * |
11 | * 0e8f:0003 "GreenAsia Inc. USB Joystick " | 11 | * 0e8f:0003 "GreenAsia Inc. USB Joystick " |
12 | * - tested with K??ng Gaming gamepad | 12 | * - tested with König Gaming gamepad |
13 | * | 13 | * |
14 | * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com> | 14 | * 0e8f:0003 "GASIA USB Gamepad" |
15 | * - another version of the König gamepad | ||
16 | * | ||
17 | * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com> | ||
15 | */ | 18 | */ |
16 | 19 | ||
17 | /* | 20 | /* |
@@ -46,6 +49,8 @@ | |||
46 | 49 | ||
47 | struct plff_device { | 50 | struct plff_device { |
48 | struct hid_report *report; | 51 | struct hid_report *report; |
52 | s32 *strong; | ||
53 | s32 *weak; | ||
49 | }; | 54 | }; |
50 | 55 | ||
51 | static int hid_plff_play(struct input_dev *dev, void *data, | 56 | static int hid_plff_play(struct input_dev *dev, void *data, |
@@ -62,8 +67,8 @@ static int hid_plff_play(struct input_dev *dev, void *data, | |||
62 | left = left * 0x7f / 0xffff; | 67 | left = left * 0x7f / 0xffff; |
63 | right = right * 0x7f / 0xffff; | 68 | right = right * 0x7f / 0xffff; |
64 | 69 | ||
65 | plff->report->field[0]->value[2] = left; | 70 | *plff->strong = left; |
66 | plff->report->field[0]->value[3] = right; | 71 | *plff->weak = right; |
67 | debug("running with 0x%02x 0x%02x", left, right); | 72 | debug("running with 0x%02x 0x%02x", left, right); |
68 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); | 73 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); |
69 | 74 | ||
@@ -80,6 +85,8 @@ static int plff_init(struct hid_device *hid) | |||
80 | struct list_head *report_ptr = report_list; | 85 | struct list_head *report_ptr = report_list; |
81 | struct input_dev *dev; | 86 | struct input_dev *dev; |
82 | int error; | 87 | int error; |
88 | s32 *strong; | ||
89 | s32 *weak; | ||
83 | 90 | ||
84 | /* The device contains one output report per physical device, all | 91 | /* The device contains one output report per physical device, all |
85 | containing 1 field, which contains 4 ff00.0002 usages and 4 16bit | 92 | containing 1 field, which contains 4 ff00.0002 usages and 4 16bit |
@@ -87,7 +94,12 @@ static int plff_init(struct hid_device *hid) | |||
87 | 94 | ||
88 | The input reports also contain a field which contains | 95 | The input reports also contain a field which contains |
89 | 8 ff00.0001 usages and 8 boolean values. Their meaning is | 96 | 8 ff00.0001 usages and 8 boolean values. Their meaning is |
90 | currently unknown. */ | 97 | currently unknown. |
98 | |||
99 | A version of the 0e8f:0003 exists that has all the values in | ||
100 | separate fields and misses the extra input field, thus resembling | ||
101 | Zeroplus (hid-zpff) devices. | ||
102 | */ | ||
91 | 103 | ||
92 | if (list_empty(report_list)) { | 104 | if (list_empty(report_list)) { |
93 | dev_err(&hid->dev, "no output reports found\n"); | 105 | dev_err(&hid->dev, "no output reports found\n"); |
@@ -110,8 +122,21 @@ static int plff_init(struct hid_device *hid) | |||
110 | return -ENODEV; | 122 | return -ENODEV; |
111 | } | 123 | } |
112 | 124 | ||
113 | if (report->field[0]->report_count < 4) { | 125 | if (report->field[0]->report_count >= 4) { |
114 | dev_err(&hid->dev, "not enough values in the field\n"); | 126 | report->field[0]->value[0] = 0x00; |
127 | report->field[0]->value[1] = 0x00; | ||
128 | strong = &report->field[0]->value[2]; | ||
129 | weak = &report->field[0]->value[3]; | ||
130 | debug("detected single-field device"); | ||
131 | } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 && | ||
132 | report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) { | ||
133 | report->field[0]->value[0] = 0x00; | ||
134 | report->field[1]->value[0] = 0x00; | ||
135 | strong = &report->field[2]->value[0]; | ||
136 | weak = &report->field[3]->value[0]; | ||
137 | debug("detected 4-field device"); | ||
138 | } else { | ||
139 | dev_err(&hid->dev, "not enough fields or values\n"); | ||
115 | return -ENODEV; | 140 | return -ENODEV; |
116 | } | 141 | } |
117 | 142 | ||
@@ -130,10 +155,11 @@ static int plff_init(struct hid_device *hid) | |||
130 | } | 155 | } |
131 | 156 | ||
132 | plff->report = report; | 157 | plff->report = report; |
133 | plff->report->field[0]->value[0] = 0x00; | 158 | plff->strong = strong; |
134 | plff->report->field[0]->value[1] = 0x00; | 159 | plff->weak = weak; |
135 | plff->report->field[0]->value[2] = 0x00; | 160 | |
136 | plff->report->field[0]->value[3] = 0x00; | 161 | *strong = 0x00; |
162 | *weak = 0x00; | ||
137 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); | 163 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); |
138 | } | 164 | } |
139 | 165 | ||
@@ -180,7 +206,7 @@ static const struct hid_device_id pl_devices[] = { | |||
180 | .driver_data = 1 }, /* Twin USB Joystick */ | 206 | .driver_data = 1 }, /* Twin USB Joystick */ |
181 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR), | 207 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR), |
182 | .driver_data = 1 }, /* Twin USB Joystick */ | 208 | .driver_data = 1 }, /* Twin USB Joystick */ |
183 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */ | 209 | { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, |
184 | { } | 210 | { } |
185 | }; | 211 | }; |
186 | MODULE_DEVICE_TABLE(hid, pl_devices); | 212 | MODULE_DEVICE_TABLE(hid, pl_devices); |