// SPDX-License-Identifier: GPL-2.0-or-later /* * Force feedback support for various HID compliant devices by ThrustMaster: * ThrustMaster FireStorm Dual Power 2 * and possibly others whose device ids haven't been added. * * Modified to support ThrustMaster devices by Zinx Verituse * on 2003-01-25 from the Logitech force feedback driver, * which is by Johann Deneux. * * Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org> * Copyright (c) 2002 Johann Deneux
*/
/* Changes values from 0 to 0xffff into values from minimum to maximum */ staticinlineint tmff_scale_u16(unsignedint in, int minimum, int maximum)
{ int ret;
ret = (in * (maximum - minimum) / 0xffff) + minimum; if (ret < minimum) return minimum; if (ret > maximum) return maximum; return ret;
}
/* Changes values from -0x80 to 0x7f into values from minimum to maximum */ staticinlineint tmff_scale_s8(int in, int minimum, int maximum)
{ int ret;
ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum; if (ret < minimum) return minimum; if (ret > maximum) return maximum; return ret;
}
switch (effect->type) { case FF_CONSTANT:
x = tmff_scale_s8(effect->u.ramp.start_level,
ff_field->logical_minimum,
ff_field->logical_maximum);
y = tmff_scale_s8(effect->u.ramp.end_level,
ff_field->logical_minimum,
ff_field->logical_maximum);
case FF_RUMBLE:
left = tmff_scale_u16(effect->u.rumble.weak_magnitude,
ff_field->logical_minimum,
ff_field->logical_maximum);
right = tmff_scale_u16(effect->u.rumble.strong_magnitude,
ff_field->logical_minimum,
ff_field->logical_maximum);
/* 2-in-1 strong motor is left */ if (hid->product == THRUSTMASTER_DEVICE_ID_2_IN_1_DT)
swap(left, right);
if (list_empty(&hid->inputs)) {
hid_err(hid, "no inputs found\n"); return -ENODEV;
}
hidinput = list_entry(hid->inputs.next, struct hid_input, list);
input_dev = hidinput->input;
tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); if (!tmff) return -ENOMEM;
/* Find the report to use */
report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
list_for_each_entry(report, report_list, list) { int fieldnum;
switch (field->usage[0].hid) { case THRUSTMASTER_USAGE_FF: if (field->report_count < 2) {
hid_warn(hid, "ignoring FF field with report_count < 2\n"); continue;
}
if (field->logical_maximum ==
field->logical_minimum) {
hid_warn(hid, "ignoring FF field with logical_maximum == logical_minimum\n"); continue;
}
if (tmff->report && tmff->report != report) {
hid_warn(hid, "ignoring FF field in other report\n"); continue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.