aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-03-24 20:43:42 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2022-03-24 20:54:28 +0200
commit2814c3eb42a0ed97d40a42aaefa1bfcd79781bdc (patch)
treefcb985d45828430dbc66d8ba60df0afd02cf01a4
parent51623455c8136f40f47ad98a0532ea70dd1c99e4 (diff)
downloadhid-tmff2-2814c3eb42a0ed97d40a42aaefa1bfcd79781bdc.tar.gz
hid-tmff2-2814c3eb42a0ed97d40a42aaefa1bfcd79781bdc.zip
add master gain
-rw-r--r--hid-tmff2.c67
-rw-r--r--hid-tmff2.h2
-rw-r--r--hid-tmt248.c1
-rw-r--r--hid-tmt300rs.c1
4 files changed, 64 insertions, 7 deletions
diff --git a/hid-tmff2.c b/hid-tmff2.c
index fe4950d..f5202ae 100644
--- a/hid-tmff2.c
+++ b/hid-tmff2.c
@@ -29,12 +29,18 @@ MODULE_PARM_DESC(friction_level,
int range = 900;
module_param(range, int, 0);
MODULE_PARM_DESC(range,
- "Range of wheel, depends on the wheel. Invalid values are ignored.");
+ "Range of wheel, depends on the wheel. Invalid values are ignored");
int alt_mode = 0;
module_param(alt_mode, int, 0);
MODULE_PARM_DESC(alt_mode,
- "Alternate mode, eg. F1 mode.");
+ "Alternate mode, eg. F1 mode");
+
+#define GAIN_MAX 65535
+int gain = 40000;
+module_param(gain, int, 0);
+MODULE_PARM_DESC(gain,
+ "Level of gain (0-65535)");
static spinlock_t lock;
static unsigned long lock_flags;
@@ -228,7 +234,36 @@ static ssize_t alt_mode_show(struct device *dev,
}
static DEVICE_ATTR_RW(alt_mode);
-static void tmff2_set_gain(struct input_dev *dev, uint16_t gain)
+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;
+ int ret;
+
+ if (!tmff2)
+ return -ENODEV;
+
+ if ((ret = kstrtouint(buf, 0, &value))) {
+ dev_err(dev, "kstrtouint failed at gain_store: %i", 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);
+
+ return count;
+}
+
+static ssize_t gain_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%i\n", gain);
+}
+static DEVICE_ATTR_RW(gain);
+
+static void tmff2_set_gain(struct input_dev *dev, uint16_t value)
{
struct tmff2_device_entry *tmff2 = tmff2_from_input(dev);
@@ -240,11 +275,11 @@ static void tmff2_set_gain(struct input_dev *dev, uint16_t gain)
return;
}
- if (tmff2->set_gain(tmff2->data, gain))
+ if (tmff2->set_gain(tmff2->data, (value * gain) / GAIN_MAX))
hid_warn(tmff2->hdev, "unable to set gain\n");
}
-static void tmff2_set_autocenter(struct input_dev *dev, uint16_t autocenter)
+static void tmff2_set_autocenter(struct input_dev *dev, uint16_t value)
{
struct tmff2_device_entry *tmff2 = tmff2_from_input(dev);
@@ -256,7 +291,7 @@ static void tmff2_set_autocenter(struct input_dev *dev, uint16_t autocenter)
return;
}
- if (tmff2->set_autocenter(tmff2->data, autocenter))
+ if (tmff2->set_autocenter(tmff2->data, value))
hid_warn(tmff2->hdev, "unable to set autocenter\n");
}
@@ -441,6 +476,13 @@ static int tmff2_create_files(struct tmff2_device_entry *tmff2)
/* could use short circuiting but this is more explicit */
+ if (tmff2->params & PARAM_GAIN) {
+ if ((ret = device_create_file(dev, &dev_attr_gain))) {
+ hid_err(tmff2->hdev, "unable to create sysfs for gain\n");
+ goto gain_err;
+ }
+ }
+
if (tmff2->params & PARAM_ALT_MODE) {
if ((ret = device_create_file(dev, &dev_attr_alt_mode))) {
hid_err(tmff2->hdev, "unable to create sysfs for alt_mode\n");
@@ -487,6 +529,8 @@ spring_err:
range_err:
device_remove_file(dev, &dev_attr_alt_mode);
alt_err:
+ device_remove_file(dev, &dev_attr_gain);
+gain_err:
return ret;
}
@@ -533,12 +577,18 @@ static int tmff2_wheel_init(struct tmff2_device_entry *tmff2)
if (tmff2->close)
tmff2->input_dev->close = tmff2_close;
- if (tmff2->set_gain)
+ /* set defaults wherever possible */
+ if (tmff2->set_gain) {
ff->set_gain = tmff2_set_gain;
+ tmff2->set_gain(tmff2->data, (GAIN_MAX * gain) / GAIN_MAX);
+ }
if (tmff2->set_autocenter)
ff->set_autocenter = tmff2_set_autocenter;
+ if (tmff2->set_range)
+ tmff2->set_range(tmff2->data, range);
+
/* create files */
if ((ret = tmff2_create_files(tmff2)))
goto err;
@@ -653,6 +703,9 @@ static void tmff2_remove(struct hid_device *hdev)
if (tmff2->params & PARAM_ALT_MODE)
device_remove_file(dev, &dev_attr_alt_mode);
+ if (tmff2->params & PARAM_GAIN)
+ device_remove_file(dev, &dev_attr_gain);
+
hid_hw_stop(hdev);
tmff2->wheel_destroy(tmff2->data);
diff --git a/hid-tmff2.h b/hid-tmff2.h
index 390bd94..765f071 100644
--- a/hid-tmff2.h
+++ b/hid-tmff2.h
@@ -11,6 +11,7 @@ extern int spring_level;
extern int damper_level;
extern int friction_level;
extern int range;
+extern int gain;
extern int alt_mode;
#define USB_VENDOR_ID_THRUSTMASTER 0x044f
@@ -34,6 +35,7 @@ extern int alt_mode;
#define PARAM_FRICTION_LEVEL (1 << 2)
#define PARAM_RANGE (1 << 3)
#define PARAM_ALT_MODE (1 << 4)
+#define PARAM_GAIN (1 << 5)
#undef fixp_sin16
#define fixp_sin16(v) (((v % 360) > 180) ?\
diff --git a/hid-tmt248.c b/hid-tmt248.c
index aef2944..e241301 100644
--- a/hid-tmt248.c
+++ b/hid-tmt248.c
@@ -29,6 +29,7 @@ static const unsigned long t248_params =
| PARAM_DAMPER_LEVEL
| PARAM_FRICTION_LEVEL
| PARAM_RANGE
+ | PARAM_GAIN
;
static const signed short t248_effects[] = {
diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c
index 167262c..5e4a848 100644
--- a/hid-tmt300rs.c
+++ b/hid-tmt300rs.c
@@ -11,6 +11,7 @@ static const unsigned long t300rs_params =
PARAM_SPRING_LEVEL
| PARAM_DAMPER_LEVEL
| PARAM_FRICTION_LEVEL
+ | PARAM_GAIN
| PARAM_RANGE
| PARAM_ALT_MODE
;