aboutsummaryrefslogtreecommitdiff
path: root/hid-tmt300rs.c
diff options
context:
space:
mode:
Diffstat (limited to 'hid-tmt300rs.c')
-rw-r--r--hid-tmt300rs.c77
1 files changed, 74 insertions, 3 deletions
diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c
index 5e4a848..687832f 100644
--- a/hid-tmt300rs.c
+++ b/hid-tmt300rs.c
@@ -1167,25 +1167,94 @@ static int t300rs_switch_mode(void *data, uint16_t mode)
if (!t300rs)
return -ENODEV;
- if(alt_mode == mode) /* already in specified mode */
+ if(t300rs->mode == mode) /* already in specified mode */
return 0;
if (mode == 0)
+ /* go to normal mode */
usb_control_msg(t300rs->usbdev,
usb_sndctrlpipe(t300rs->usbdev, 0),
83, 0x41, 5, 0, 0, 0,
USB_CTRL_SET_TIMEOUT
);
- else
+ else if (mode == 1)
+ /* go to advanced mode */
usb_control_msg(t300rs->usbdev,
usb_sndctrlpipe(t300rs->usbdev, 0),
83, 0x41, 3, 0, 0, 0,
USB_CTRL_SET_TIMEOUT
);
+ else
+ hid_warn(t300rs->hdev, "mode %i not supported\n", mode);
+
return 0;
}
+static struct t300rs_alt_modes {
+ char *id;
+ char *label;
+ uint16_t mode;
+} t300rs_modes[] = {
+ {"native", "T300RS base", 0},
+ {"F1", "T300RS with F1 wheel attachment", 1}
+};
+
+static ssize_t t300rs_alt_mode_show(void *data, char *buf)
+{
+ struct t300rs_device_entry *t300rs = data;
+ ssize_t count = 0;
+ int i;
+ if (!t300rs)
+ return -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(t300rs_modes); ++i) {
+ count += scnprintf(buf + count, PAGE_SIZE - count, "%s: %s",
+ t300rs_modes[i].id, t300rs_modes[i].label);
+
+ if (count >= PAGE_SIZE - 1)
+ return count;
+
+ if (t300rs_modes[i].mode == t300rs->mode)
+ count += scnprintf(buf + count, PAGE_SIZE - count, " *\n");
+ else
+ count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
+
+ if (count >= PAGE_SIZE - 1)
+ return count;
+ }
+
+ return count;
+}
+
+static ssize_t t300rs_alt_mode_store(void *data, const char *buf, size_t count)
+{
+ struct tmff2_device_entry *t300rs = data;
+ int i, len, mode_len;
+ char *lbuf;
+ if (!t300rs)
+ return -ENODEV;
+
+ lbuf = kasprintf(GFP_KERNEL, "%s", buf);
+ if (!lbuf)
+ return -ENOMEM;
+
+ len = strlen(buf);
+ for (i = 0; i < ARRAY_SIZE(t300rs_modes); ++i) {
+ mode_len = strlen(t300rs_modes[i].id);
+ if (mode_len > len)
+ continue;
+
+ if (strncmp(lbuf, t300rs_modes[i].id, mode_len) == 0) {
+ t300rs_switch_mode(data, t300rs_modes[i].mode);
+ break;
+ }
+ }
+
+ kfree(lbuf);
+ return count;
+}
+
int t300rs_set_autocenter(void *data, uint16_t value)
{
struct t300rs_device_entry *t300rs = data;
@@ -1413,7 +1482,7 @@ static int t300rs_wheel_init(struct tmff2_device_entry *tmff2)
t300rs->close = t300rs->input_dev->close;
/* TODO: PS4 advanced mode? */
- alt_mode = (t300rs->hdev->product == TMT300RS_PS3_ADV_ID);
+ t300rs->mode = (t300rs->hdev->product == TMT300RS_PS3_ADV_ID);
/* everythin went OK */
tmff2->data = t300rs;
@@ -1486,6 +1555,8 @@ int t300rs_populate_api(struct tmff2_device_entry *tmff2)
tmff2->set_gain = t300rs_set_gain;
tmff2->set_range = t300rs_set_range;
tmff2->switch_mode = t300rs_switch_mode;
+ tmff2->alt_mode_show = t300rs_alt_mode_show;
+ tmff2->alt_mode_store = t300rs_alt_mode_store;
tmff2->set_autocenter = t300rs_set_autocenter;
tmff2->wheel_fixup = t300rs_wheel_fixup;