aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-lg4ff.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-lg4ff.c')
-rw-r--r--drivers/hid/hid-lg4ff.c101
1 files changed, 87 insertions, 14 deletions
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index 8782fe1aaa07..befe0e336471 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -196,6 +196,21 @@ static int hid_lg4ff_play(struct input_dev *dev, void *data, struct ff_effect *e
196 case FF_CONSTANT: 196 case FF_CONSTANT:
197 x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */ 197 x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */
198 CLAMP(x); 198 CLAMP(x);
199
200 if (x == 0x80) {
201 /* De-activate force in slot-1*/
202 value[0] = 0x13;
203 value[1] = 0x00;
204 value[2] = 0x00;
205 value[3] = 0x00;
206 value[4] = 0x00;
207 value[5] = 0x00;
208 value[6] = 0x00;
209
210 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
211 return 0;
212 }
213
199 value[0] = 0x11; /* Slot 1 */ 214 value[0] = 0x11; /* Slot 1 */
200 value[1] = 0x08; 215 value[1] = 0x08;
201 value[2] = x; 216 value[2] = x;
@@ -218,12 +233,70 @@ static void hid_lg4ff_set_autocenter_default(struct input_dev *dev, u16 magnitud
218 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; 233 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
219 struct hid_report *report = list_entry(report_list->next, struct hid_report, list); 234 struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
220 __s32 *value = report->field[0]->value; 235 __s32 *value = report->field[0]->value;
236 __u32 expand_a, expand_b;
237 struct lg4ff_device_entry *entry;
238 struct lg_drv_data *drv_data;
239
240 drv_data = hid_get_drvdata(hid);
241 if (!drv_data) {
242 hid_err(hid, "Private driver data not found!\n");
243 return;
244 }
245
246 entry = drv_data->device_props;
247 if (!entry) {
248 hid_err(hid, "Device properties not found!\n");
249 return;
250 }
251
252 /* De-activate Auto-Center */
253 if (magnitude == 0) {
254 value[0] = 0xf5;
255 value[1] = 0x00;
256 value[2] = 0x00;
257 value[3] = 0x00;
258 value[4] = 0x00;
259 value[5] = 0x00;
260 value[6] = 0x00;
261
262 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
263 return;
264 }
265
266 if (magnitude <= 0xaaaa) {
267 expand_a = 0x0c * magnitude;
268 expand_b = 0x80 * magnitude;
269 } else {
270 expand_a = (0x0c * 0xaaaa) + 0x06 * (magnitude - 0xaaaa);
271 expand_b = (0x80 * 0xaaaa) + 0xff * (magnitude - 0xaaaa);
272 }
273
274 /* Adjust for non-MOMO wheels */
275 switch (entry->product_id) {
276 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
277 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
278 break;
279 default:
280 expand_a = expand_a >> 1;
281 break;
282 }
221 283
222 value[0] = 0xfe; 284 value[0] = 0xfe;
223 value[1] = 0x0d; 285 value[1] = 0x0d;
224 value[2] = magnitude >> 13; 286 value[2] = expand_a / 0xaaaa;
225 value[3] = magnitude >> 13; 287 value[3] = expand_a / 0xaaaa;
226 value[4] = magnitude >> 8; 288 value[4] = expand_b / 0xaaaa;
289 value[5] = 0x00;
290 value[6] = 0x00;
291
292 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
293
294 /* Activate Auto-Center */
295 value[0] = 0x14;
296 value[1] = 0x00;
297 value[2] = 0x00;
298 value[3] = 0x00;
299 value[4] = 0x00;
227 value[5] = 0x00; 300 value[5] = 0x00;
228 value[6] = 0x00; 301 value[6] = 0x00;
229 302
@@ -540,17 +613,6 @@ int lg4ff_init(struct hid_device *hid)
540 if (error) 613 if (error)
541 return error; 614 return error;
542 615
543 /* Check if autocentering is available and
544 * set the centering force to zero by default */
545 if (test_bit(FF_AUTOCENTER, dev->ffbit)) {
546 if (rev_maj == FFEX_REV_MAJ && rev_min == FFEX_REV_MIN) /* Formula Force EX expects different autocentering command */
547 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_ffex;
548 else
549 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_default;
550
551 dev->ff->set_autocenter(dev, 0);
552 }
553
554 /* Get private driver data */ 616 /* Get private driver data */
555 drv_data = hid_get_drvdata(hid); 617 drv_data = hid_get_drvdata(hid);
556 if (!drv_data) { 618 if (!drv_data) {
@@ -571,6 +633,17 @@ int lg4ff_init(struct hid_device *hid)
571 entry->max_range = lg4ff_devices[i].max_range; 633 entry->max_range = lg4ff_devices[i].max_range;
572 entry->set_range = lg4ff_devices[i].set_range; 634 entry->set_range = lg4ff_devices[i].set_range;
573 635
636 /* Check if autocentering is available and
637 * set the centering force to zero by default */
638 if (test_bit(FF_AUTOCENTER, dev->ffbit)) {
639 if (rev_maj == FFEX_REV_MAJ && rev_min == FFEX_REV_MIN) /* Formula Force EX expects different autocentering command */
640 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_ffex;
641 else
642 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_default;
643
644 dev->ff->set_autocenter(dev, 0);
645 }
646
574 /* Create sysfs interface */ 647 /* Create sysfs interface */
575 error = device_create_file(&hid->dev, &dev_attr_range); 648 error = device_create_file(&hid->dev, &dev_attr_range);
576 if (error) 649 if (error)