Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 36 additions & 9 deletions src/hid-tmff2.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,16 @@ MODULE_PARM_DESC(alt_mode,
"Alternate mode, eg. F1 mode");

#define GAIN_MAX 65535
int gain = 40000;
module_param(gain, int, 0);
u16 gain = 40000;
module_param(gain, ushort, 0);
MODULE_PARM_DESC(gain,
"Level of gain (0-65535)");

static u16 tmff2_scale_gain(u16 value)
{
return (u32)value * gain / GAIN_MAX;
}

static spinlock_t lock;

static struct tmff2_device_entry *tmff2_from_hdev(struct hid_device *hdev)
Expand Down Expand Up @@ -230,28 +235,29 @@ static ssize_t gain_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct tmff2_device_entry *tmff2 = tmff2_from_hdev(to_hid_device(dev));
unsigned int value;
u16 value;
int ret;

if (!tmff2)
return -ENODEV;

if ((ret = kstrtouint(buf, 0, &value))) {
dev_err(dev, "kstrtouint failed at gain_store: %i", ret);
ret = kstrtou16(buf, 0, &value);
if (ret) {
dev_err(dev, "failed to parse gain: %d\n", ret);
return ret;
}

gain = value;
if (tmff2->set_gain) /* if we can, update gain immediately */
tmff2->set_gain(tmff2->data, (GAIN_MAX * gain) / GAIN_MAX);
tmff2->set_gain(tmff2->data, gain);

return count;
}

static ssize_t gain_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%i\n", gain);
return scnprintf(buf, PAGE_SIZE, "%u\n", gain);
}
static DEVICE_ATTR_RW(gain);

Expand All @@ -267,7 +273,7 @@ static void tmff2_set_gain(struct input_dev *dev, uint16_t value)
return;
}

if (tmff2->set_gain(tmff2->data, (value * gain) / GAIN_MAX))
if (tmff2->set_gain(tmff2->data, tmff2_scale_gain(value)))
hid_warn(tmff2->hdev, "unable to set gain\n");
}

Expand Down Expand Up @@ -643,7 +649,7 @@ static int tmff2_wheel_init(struct tmff2_device_entry *tmff2)
/* set defaults wherever possible */
if (tmff2->set_gain) {
ff->set_gain = tmff2_set_gain;
tmff2->set_gain(tmff2->data, (GAIN_MAX * gain) / GAIN_MAX);
tmff2->set_gain(tmff2->data, gain);
}

if (tmff2->set_autocenter)
Expand Down Expand Up @@ -801,6 +807,26 @@ static void tmff2_remove(struct hid_device *hdev)
kfree(tmff2);
}

static int tmff2_input_configured(struct hid_device *hdev,
struct hid_input *hidinput)
{
struct input_dev *input = hidinput->input;
int axis;

if (!input->absinfo)
return 0;

for (axis = ABS_X; axis <= ABS_BRAKE; axis++) {
if (!test_bit(axis, input->absbit))
continue;

input_abs_set_fuzz(input, axis, 0);
input_abs_set_flat(input, axis, 0);
}

return 0;
}

static const struct hid_device_id tmff2_devices[] = {
/* t300rs and variations */
{HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TMT300RS_PS3_NORM_ID)},
Expand All @@ -825,6 +851,7 @@ static struct hid_driver tmff2_driver = {
.probe = tmff2_probe,
.remove = tmff2_remove,
.report_fixup = tmff2_report_fixup,
.input_configured = tmff2_input_configured,
};
module_hid_driver(tmff2_driver);

Expand Down
2 changes: 1 addition & 1 deletion src/hid-tmff2.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern int spring_level;
extern int damper_level;
extern int friction_level;
extern int range;
extern int gain;
extern u16 gain;
extern int alt_mode;

#define USB_VENDOR_ID_THRUSTMASTER 0x044f
Expand Down
32 changes: 20 additions & 12 deletions src/tmt300rs/hid-tmt300rs.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,30 +344,35 @@ static uint16_t t300rs_calculate_length(uint16_t length)
return length;
}

static s32 t300rs_scale_direction(s16 level, u16 direction)
{
return (s32)level * fixp_sin16(direction * 360 / 0x10000) / 0x7fff;
}

static int16_t t300rs_calculate_constant_level(int16_t level, uint16_t direction)
{
level = (level * fixp_sin16(direction * 360 / 0x10000)) / 0x7fff;
s32 scaled_level = t300rs_scale_direction(level, direction);

/* the Windows driver uses the range [-16385;16381] */
level = level / 2;

return level;
return scaled_level / 2;
}

static void t300rs_calculate_periodic_values(struct ff_effect *effect)
{
struct ff_periodic_effect *periodic = &effect->u.periodic;
int16_t headroom;
s32 magnitude, headroom;

periodic->magnitude = (periodic->magnitude * fixp_sin16(effect->direction * 360 / 0x10000)) / 0x7fff;
magnitude = t300rs_scale_direction(periodic->magnitude,
effect->direction);

if (periodic->magnitude < 0){
if (magnitude < 0) {
/* the wheel handles positive magnitudes only */
periodic->magnitude = -periodic->magnitude;
magnitude = -magnitude;

/* to give the expected result 180 deg is added to the phase */
periodic->phase = (periodic->phase + (0x10000 / 2)) % 0x10000;
}
periodic->magnitude = min_t(s32, magnitude, S16_MAX);

/* the interval [0; 32677[ is used by the wheel for the [0; 360[ degree phase shift */
periodic->phase = periodic->phase * 32677 / 0x10000;
Expand Down Expand Up @@ -443,13 +448,16 @@ static void t300rs_calculate_ramp_parameters(uint16_t *out_slope,
{
struct ff_ramp_effect *ramp = &effect->u.ramp;

int16_t start_level, end_level;
s32 start_level, end_level;

start_level = (ramp->start_level * fixp_sin16(effect->direction * 360 / 0x10000)) / 0x7fff;
end_level = (ramp->end_level * fixp_sin16(effect->direction * 360 / 0x10000)) / 0x7fff;
start_level = t300rs_scale_direction(ramp->start_level,
effect->direction);
end_level = t300rs_scale_direction(ramp->end_level,
effect->direction);

*out_slope = abs(start_level - end_level) / 2;
*out_center = (start_level + end_level) / 2;
*out_center = clamp_t(s32, (start_level + end_level) / 2,
S16_MIN, S16_MAX);

*out_invert = (start_level < end_level) ? 0x04 : 0x05;
}
Expand Down