hid-lgff.c (da733563be5a9da26fe81d9f007262d00b846e22) hid-lgff.c (d881427253da011495f4193663d809d0e9dfa215)
1/*
2 * Force feedback support for hid-compliant for some of the devices from
3 * Logitech, namely:
4 * - WingMan Cordless RumblePad
5 * - WingMan Force 3D
6 *
7 * Copyright (c) 2002-2004 Johann Deneux
8 * Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>

--- 16 unchanged lines hidden (view full) ---

25 *
26 * Should you need to contact me, the author, you can do so by
27 * e-mail - mail your message to <johann.deneux@it.uu.se>
28 */
29
30#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31
32#include <linux/input.h>
1/*
2 * Force feedback support for hid-compliant for some of the devices from
3 * Logitech, namely:
4 * - WingMan Cordless RumblePad
5 * - WingMan Force 3D
6 *
7 * Copyright (c) 2002-2004 Johann Deneux
8 * Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>

--- 16 unchanged lines hidden (view full) ---

25 *
26 * Should you need to contact me, the author, you can do so by
27 * e-mail - mail your message to <johann.deneux@it.uu.se>
28 */
29
30#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31
32#include <linux/input.h>
33#include <linux/usb.h>
34#include <linux/hid.h>
35
33#include <linux/hid.h>
34
36#include "usbhid/usbhid.h"
37#include "hid-lg.h"
38
39struct dev_type {
40 u16 idVendor;
41 u16 idProduct;
42 const signed short *ff;
43};
44

--- 39 unchanged lines hidden (view full) ---

84 y = effect->u.ramp.end_level + 0x7f;
85 CLAMP(x);
86 CLAMP(y);
87 report->field[0]->value[0] = 0x51;
88 report->field[0]->value[1] = 0x08;
89 report->field[0]->value[2] = x;
90 report->field[0]->value[3] = y;
91 dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
35#include "hid-lg.h"
36
37struct dev_type {
38 u16 idVendor;
39 u16 idProduct;
40 const signed short *ff;
41};
42

--- 39 unchanged lines hidden (view full) ---

82 y = effect->u.ramp.end_level + 0x7f;
83 CLAMP(x);
84 CLAMP(y);
85 report->field[0]->value[0] = 0x51;
86 report->field[0]->value[1] = 0x08;
87 report->field[0]->value[2] = x;
88 report->field[0]->value[3] = y;
89 dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
92 usbhid_submit_report(hid, report, USB_DIR_OUT);
90 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
93 break;
94
95 case FF_RUMBLE:
96 right = effect->u.rumble.strong_magnitude;
97 left = effect->u.rumble.weak_magnitude;
98 right = right * 0xff / 0xffff;
99 left = left * 0xff / 0xffff;
100 CLAMP(left);
101 CLAMP(right);
102 report->field[0]->value[0] = 0x42;
103 report->field[0]->value[1] = 0x00;
104 report->field[0]->value[2] = left;
105 report->field[0]->value[3] = right;
106 dbg_hid("(left, right)=(%04x, %04x)\n", left, right);
91 break;
92
93 case FF_RUMBLE:
94 right = effect->u.rumble.strong_magnitude;
95 left = effect->u.rumble.weak_magnitude;
96 right = right * 0xff / 0xffff;
97 left = left * 0xff / 0xffff;
98 CLAMP(left);
99 CLAMP(right);
100 report->field[0]->value[0] = 0x42;
101 report->field[0]->value[1] = 0x00;
102 report->field[0]->value[2] = left;
103 report->field[0]->value[3] = right;
104 dbg_hid("(left, right)=(%04x, %04x)\n", left, right);
107 usbhid_submit_report(hid, report, USB_DIR_OUT);
105 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
108 break;
109 }
110 return 0;
111}
112
113static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude)
114{
115 struct hid_device *hid = input_get_drvdata(dev);
116 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
117 struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
118 __s32 *value = report->field[0]->value;
119 magnitude = (magnitude >> 12) & 0xf;
120 *value++ = 0xfe;
121 *value++ = 0x0d;
122 *value++ = magnitude; /* clockwise strength */
123 *value++ = magnitude; /* counter-clockwise strength */
124 *value++ = 0x80;
125 *value++ = 0x00;
126 *value = 0x00;
106 break;
107 }
108 return 0;
109}
110
111static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude)
112{
113 struct hid_device *hid = input_get_drvdata(dev);
114 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
115 struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
116 __s32 *value = report->field[0]->value;
117 magnitude = (magnitude >> 12) & 0xf;
118 *value++ = 0xfe;
119 *value++ = 0x0d;
120 *value++ = magnitude; /* clockwise strength */
121 *value++ = magnitude; /* counter-clockwise strength */
122 *value++ = 0x80;
123 *value++ = 0x00;
124 *value = 0x00;
127 usbhid_submit_report(hid, report, USB_DIR_OUT);
125 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
128}
129
130int lgff_init(struct hid_device* hid)
131{
132 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
133 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
134 struct input_dev *dev = hidinput->input;
135 struct hid_report *report;

--- 41 unchanged lines hidden ---
126}
127
128int lgff_init(struct hid_device* hid)
129{
130 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
131 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
132 struct input_dev *dev = hidinput->input;
133 struct hid_report *report;

--- 41 unchanged lines hidden ---