Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
compile_commands.json
Module.symvers
modules.order
.idea
.vscode
3 changes: 2 additions & 1 deletion Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ hid-tmff-new-y := \
src/tmt300rs/hid-tmt300rs.o \
src/tmt248/hid-tmt248.o \
src/tmtx/hid-tmtx.o \
src/tmtsxw/hid-tmtsxw.o
src/tmtsxw/hid-tmtsxw.o \
src/tmt818/hid-tmt818.o
123 changes: 118 additions & 5 deletions src/hid-tmff2.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,19 @@ MODULE_PARM_DESC(alt_mode,
"Alternate mode, eg. F1 mode");

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

int mode = 3;
module_param(mode, int, 0);
MODULE_PARM_DESC(mode, "FFB Mode of the Wheel (0-3; 0: Comfort, 1: Sport, 2: Performance, 3: Extreme)");

int color = 0xff26cff;
module_param(color, int, 0);
MODULE_PARM_DESC(color, "Color of the RGB LEDs on the Wheel. Values are provided in RGBA Hex.");

static spinlock_t lock;
static unsigned long lock_flags;

Expand Down Expand Up @@ -225,6 +233,72 @@ static ssize_t alternate_modes_show(struct device *dev,
}
static DEVICE_ATTR_RW(alternate_modes);

static ssize_t mode_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;
int ret;

if (!tmff2)
return -ENODEV;

if ((ret = kstrtouint(buf, 0, &value))) {
dev_err(dev, "kstrtouint failed at mode_store: %i", ret);
return ret;
}

mode = value;
if (tmff2->set_mode) /* if we can, update mode immediately */
tmff2->set_mode(tmff2->data, mode);

return count;
}

static ssize_t mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct tmff2_device_entry *tmff2 = tmff2_from_hdev(to_hid_device(dev));

if (!tmff2)
return -ENODEV;

if (tmff2->mode_show)
return tmff2->mode_show(tmff2->data, buf);

return -ENODEV;
}
static DEVICE_ATTR_RW(mode);

static ssize_t color_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;
int ret;

if (!tmff2)
return -ENODEV;

if ((ret = kstrtouint(buf, 0, &value))) {
dev_err(dev, "kstrtouint failed at color_store: %i", ret);
return ret;
}

color = value;
if (tmff2->set_color) /* if we can, update color immediately */
tmff2->set_color(tmff2->data, color);

return count;
}

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

static ssize_t gain_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
Expand Down Expand Up @@ -541,6 +615,20 @@ static int tmff2_create_files(struct tmff2_device_entry *tmff2)
}
}

if (tmff2->params & PARAM_MODE) {
if ((ret = device_create_file(dev, &dev_attr_mode))) {
hid_warn(tmff2->hdev, "unable to create sysfs for mode\n");
goto mode_err;
}
}

if (tmff2->params & PARAM_COLOR) {
if ((ret = device_create_file(dev, &dev_attr_color))) {
hid_warn(tmff2->hdev, "unable to create sysfs for color\n");
goto color_err;
}
}

return 0;

friction_err:
Expand All @@ -553,6 +641,10 @@ static int tmff2_create_files(struct tmff2_device_entry *tmff2)
device_remove_file(dev, &dev_attr_alternate_modes);
alt_err:
device_remove_file(dev, &dev_attr_gain);
mode_err:
device_remove_file(dev, &dev_attr_mode);
color_err:
device_remove_file(dev, &dev_attr_color);
gain_err:
return ret;
}
Expand Down Expand Up @@ -618,6 +710,10 @@ static int tmff2_wheel_init(struct tmff2_device_entry *tmff2)
tmff2->set_gain(tmff2->data, (GAIN_MAX * gain) / GAIN_MAX);
}

if(tmff2->set_mode) {
tmff2->set_mode(tmff2->data, mode);
}

if (tmff2->set_autocenter)
ff->set_autocenter = tmff2_set_autocenter;

Expand All @@ -627,6 +723,9 @@ static int tmff2_wheel_init(struct tmff2_device_entry *tmff2)
if (tmff2->switch_mode)
tmff2->switch_mode(tmff2->data, alt_mode);

if (tmff2->set_color)
tmff2->set_color(tmff2->data, color);

/* create files */
if ((ret = tmff2_create_files(tmff2)))
goto file_err;
Expand Down Expand Up @@ -666,9 +765,17 @@ static int tmff2_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto wheel_err;
break;

case TMT248_PC_ID:
if ((ret = t248_populate_api(tmff2)))
goto wheel_err;
case TMAR_PC_ID:
switch (tmff2->hdev->version) {
case TMT818_VERSION:
if ((ret = t818_populate_api(tmff2)))
goto wheel_err;
break;
default:
if ((ret = t248_populate_api(tmff2)))
goto wheel_err;
break;
}
break;

case TX_ACTIVE:
Expand Down Expand Up @@ -762,6 +869,12 @@ static void tmff2_remove(struct hid_device *hdev)
if (tmff2->params & PARAM_GAIN)
device_remove_file(dev, &dev_attr_gain);

if (tmff2->params & PARAM_MODE)
device_remove_file(dev, &dev_attr_mode);

if (tmff2->params & PARAM_COLOR)
device_remove_file(dev, &dev_attr_color);

hid_hw_stop(hdev);
tmff2->wheel_destroy(tmff2->data);

Expand All @@ -775,7 +888,7 @@ static const struct hid_device_id tmff2_devices[] = {
{HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TMT300RS_PS3_ADV_ID)},
{HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TMT300RS_PS4_NORM_ID)},
/* t248 PC*/
{HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TMT248_PC_ID)},
{HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TMAR_PC_ID)},
/* tx */
{HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TX_ACTIVE)},
/* tsxw */
Expand Down
13 changes: 11 additions & 2 deletions src/hid-tmff2.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ extern int friction_level;
extern int range;
extern int gain;
extern int alt_mode;
extern int mode;
extern int color;

#define USB_VENDOR_ID_THRUSTMASTER 0x044f

Expand All @@ -36,6 +38,8 @@ extern int alt_mode;
#define PARAM_RANGE (1 << 3)
#define PARAM_ALT_MODE (1 << 4)
#define PARAM_GAIN (1 << 5)
#define PARAM_MODE (1 << 6)
#define PARAM_COLOR (1 << 7)

#undef fixp_sin16
#define fixp_sin16(v) (((v % 360) > 180) ?\
Expand Down Expand Up @@ -86,10 +90,13 @@ struct tmff2_device_entry {
int (*close)(void *data, int);
int (*set_gain)(void *data, uint16_t gain);
int (*set_range)(void *data, uint16_t range);
int (*set_mode)(void *data, uint);
int (*set_color)(void *data, uint32_t rgba);
/* switch_mode is required to not do anything if we're alredy in the
* specified mode */
int (*switch_mode)(void *data, uint16_t mode);
ssize_t (*alt_mode_show)(void *data, char *buf);
ssize_t (*alt_mode_show)(void *data, char *buf);
ssize_t (*mode_show)(void *data, char *buf);
ssize_t (*alt_mode_store)(void *data, const char *buf, size_t count);
int (*set_autocenter)(void *data, uint16_t autocenter);
__u8 *(*wheel_fixup)(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize);
Expand All @@ -103,12 +110,14 @@ int t300rs_populate_api(struct tmff2_device_entry *tmff2);
int t248_populate_api(struct tmff2_device_entry *tmff2);
int tx_populate_api(struct tmff2_device_entry *tmff2);
int tsxw_populate_api(struct tmff2_device_entry *tmff2);
int t818_populate_api(struct tmff2_device_entry *tmff2);

#define TMT300RS_PS3_NORM_ID 0xb66e
#define TMT300RS_PS3_ADV_ID 0xb66f
#define TMT300RS_PS4_NORM_ID 0xb66d

#define TMT248_PC_ID 0xb696
#define TMAR_PC_ID 0xb696
#define TMT818_VERSION 0x111

#define TX_ACTIVE 0xb669

Expand Down
Loading