aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hid-tmff2.c24
-rw-r--r--hid-tmff2.h4
-rw-r--r--hid-tmt300rs.c78
3 files changed, 52 insertions, 54 deletions
diff --git a/hid-tmff2.c b/hid-tmff2.c
index f1d1f84..6a112fa 100644
--- a/hid-tmff2.c
+++ b/hid-tmff2.c
@@ -52,15 +52,15 @@ static struct tmff2_device_entry *tmff2_from_hdev(struct hid_device *hdev)
static struct tmff2_device_entry *tmff2_from_input(struct input_dev *input_dev)
{
- struct tmff2_device_entry *tmff2;
+ struct hid_device *hdev;
spin_lock_irqsave(&lock, lock_flags);
- if (!(tmff2 = input_get_drvdata(input_dev))) {
+ if (!(hdev = input_get_drvdata(input_dev))) {
dev_err(&input_dev->dev, "input_dev private data not found\n");
return NULL;
}
spin_unlock_irqrestore(&lock, lock_flags);
- return tmff2;
+ return tmff2_from_hdev(hdev);
}
static ssize_t spring_level_store(struct device *dev,
@@ -301,7 +301,7 @@ static void tmff2_work_handler(struct work_struct *w)
}
if (test_bit(FF_EFFECT_QUEUE_START, &state->flags)) {
- if (tmff2->play_effect(tmff2, state)) {
+ if (tmff2->play_effect(tmff2->data, state)) {
hid_warn(tmff2->hdev, "failed starting effect\n");
} else {
__clear_bit(FF_EFFECT_QUEUE_START, &state->flags);
@@ -311,7 +311,7 @@ static void tmff2_work_handler(struct work_struct *w)
}
if (test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)) {
- if (tmff2->stop_effect(tmff2, state)) {
+ if (tmff2->stop_effect(tmff2->data, state)) {
hid_warn(tmff2->hdev, "failed stopping effect\n");
} else {
__clear_bit(FF_EFFECT_PLAYING, &state->flags);
@@ -420,9 +420,15 @@ static int tmff2_wheel_init(struct tmff2_device_entry *tmff2)
{
int ret, i;
struct ff_device *ff;
+ spin_lock_init(&lock);
spin_lock_init(&tmff2->lock);
INIT_DELAYED_WORK(&tmff2->work, tmff2_work_handler);
+ /* get parameters etc from backend */
+ if ((ret = tmff2->wheel_init(tmff2)))
+ goto err;
+
+
tmff2->states = kzalloc(sizeof(struct tmff2_effect_state) * tmff2->max_effects,
GFP_KERNEL);
@@ -431,10 +437,6 @@ static int tmff2_wheel_init(struct tmff2_device_entry *tmff2)
goto err;
}
- /* is this required or should it be done in t300rs_populate_api? */
- if ((ret = tmff2->wheel_init(tmff2->data)))
- goto err;
-
/* set supported effects into input_dev->ffbit */
for (i = 0; tmff2->supported_effects[i] >= 0; ++i)
__set_bit(tmff2->supported_effects[i], tmff2->input_dev->ffbit);
@@ -482,8 +484,6 @@ static int tmff2_probe(struct hid_device *hdev, const struct hid_device_id *id)
tmff2->hdev = hdev;
hid_set_drvdata(tmff2->hdev, tmff2);
- tmff2->input_dev = list_entry(hdev->inputs.next, struct hid_input, list)->input;
- input_set_drvdata(tmff2->input_dev, tmff2);
switch (tmff2->hdev->product) {
/* t300rs */
@@ -508,6 +508,8 @@ static int tmff2_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto hid_err;
}
+ tmff2->input_dev = list_entry(hdev->inputs.next, struct hid_input, list)->input;
+
if ((ret = tmff2_wheel_init(tmff2))) {
hid_err(hdev, "init failed\n");
goto init_err;
diff --git a/hid-tmff2.h b/hid-tmff2.h
index bdde1a7..b2a46c9 100644
--- a/hid-tmff2.h
+++ b/hid-tmff2.h
@@ -60,7 +60,7 @@ struct tmff2_device_entry {
int (*update_effect)(void *data, struct tmff2_effect_state *state);
int (*stop_effect)(void *data, struct tmff2_effect_state *state);
- int (*wheel_init)(void *data);
+ int (*wheel_init)(struct tmff2_device_entry *tmff2);
int (*wheel_destroy)(void *data);
/* optional callbacks */
@@ -71,6 +71,8 @@ struct tmff2_device_entry {
int (*switch_mode)(void *data, uint16_t mode);
int (*set_autocenter)(void *data, uint16_t autocenter);
__u8 *(*wheel_fixup)(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize);
+
+ /* void pointers are dangerous, I know, but in this case likely the best option... */
};
#endif /* _HID_TMFF2 */
diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c
index ee0e817..8171578 100644
--- a/hid-tmt300rs.c
+++ b/hid-tmt300rs.c
@@ -1329,31 +1329,31 @@ static int t300rs_close(void *data)
return ret;
}
-static int t300rs_create_files(struct hid_device *hdev)
+static int t300rs_create_files(struct t300rs_device_entry *t300rs)
{
int ret;
- if ((ret = device_create_file(&hdev->dev, &dev_attr_alt_mode))) {
- hid_err(hdev, "unable to create sysfs interface for alt_mode\n");
+ if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_alt_mode))) {
+ hid_err(t300rs->hdev, "unable to create sysfs interface for alt_mode\n");
goto alt_err;
}
- if ((ret = device_create_file(&hdev->dev, &dev_attr_range))) {
- hid_warn(hdev, "unable to create sysfs interface for range\n");
+ if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_range))) {
+ hid_warn(t300rs->hdev, "unable to create sysfs interface for range\n");
goto range_err;
}
- if ((ret = device_create_file(&hdev->dev, &dev_attr_spring_level))) {
- hid_warn(hdev, "unable to create sysfs interface for spring_level\n");
+ if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_spring_level))) {
+ hid_warn(t300rs->hdev, "unable to create sysfs interface for spring_level\n");
goto spring_err;
}
- if ((ret = device_create_file(&hdev->dev, &dev_attr_damper_level))) {
- hid_warn(hdev, "unable to create sysfs interface for damper_level\n");
+ if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_damper_level))) {
+ hid_warn(t300rs->hdev, "unable to create sysfs interface for damper_level\n");
goto damper_err;
}
- if ((ret = device_create_file(&hdev->dev, &dev_attr_friction_level))) {
- hid_warn(hdev, "unable to create sysfs interface for friction_level\n");
+ if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_friction_level))) {
+ hid_warn(t300rs->hdev, "unable to create sysfs interface for friction_level\n");
goto friction_err;
}
@@ -1362,13 +1362,13 @@ static int t300rs_create_files(struct hid_device *hdev)
/* if the creation of dev_attr_friction fails, we don't need to remove it */
/* device_remove_file(&hdev->dev, &dev_attr_friction_level); */
friction_err:
- device_remove_file(&hdev->dev, &dev_attr_damper_level);
+ device_remove_file(&t300rs->hdev->dev, &dev_attr_damper_level);
damper_err:
- device_remove_file(&hdev->dev, &dev_attr_spring_level);
+ device_remove_file(&t300rs->hdev->dev, &dev_attr_spring_level);
spring_err:
- device_remove_file(&hdev->dev, &dev_attr_range);
+ device_remove_file(&t300rs->hdev->dev, &dev_attr_range);
range_err:
- device_remove_file(&hdev->dev, &dev_attr_alt_mode);
+ device_remove_file(&t300rs->hdev->dev, &dev_attr_alt_mode);
alt_err:
return ret;
}
@@ -1397,7 +1397,7 @@ static int t300rs_check_firmware(struct t300rs_device_entry *t300rs)
);
if (ret < 0) {
- hid_err(t300rs->hdev, "could not fetch firmware version\n");
+ hid_err(t300rs->hdev, "could not fetch firmware version: %i\n", ret);
goto out;
}
@@ -1422,12 +1422,21 @@ out:
return ret;
}
-static int t300rs_wheel_init(void *data)
+static int t300rs_wheel_init(struct tmff2_device_entry *tmff2)
{
- struct t300rs_device_entry *t300rs = data;
+ struct t300rs_device_entry *t300rs = kzalloc(sizeof(struct t300rs_device_entry), GFP_KERNEL);
struct list_head *report_list;
int ret;
+ if (!t300rs) {
+ ret = -ENOMEM;
+ goto t300rs_err;
+ }
+
+ t300rs->hdev = tmff2->hdev;
+ t300rs->input_dev = tmff2->input_dev;
+ t300rs->usbdev = to_usb_device(tmff2->hdev->dev.parent->parent);
+
if(t300rs->hdev->product == 0xb66d)
t300rs->buffer_length = T300RS_PS4_BUFFER_LENGTH;
else
@@ -1451,19 +1460,21 @@ static int t300rs_wheel_init(void *data)
t300rs->open = t300rs->input_dev->open;
t300rs->close = t300rs->input_dev->close;
- if ((ret = t300rs_create_files(t300rs->hdev))) {
+ if ((ret = t300rs_create_files(t300rs))) {
/* probably not a massive issue, but could affect programs like
* Oversteer, best play it safe */
hid_err(t300rs->hdev, "could not create sysfs files\n");
goto sysfs_err;
}
- t300rs_set_range(t300rs, range);
- t300rs_set_gain(t300rs, 0xffff);
-
/* TODO: PS4 advanced mode? */
alt_mode = (t300rs->hdev->product == 0xb66f);
+ /* everythin went OK */
+ tmff2->data = t300rs;
+ tmff2->max_effects = T300RS_MAX_EFFECTS;
+ memcpy(tmff2->supported_effects, t300rs_effects, sizeof(t300rs_effects));
+
hid_info(t300rs->hdev, "force feedback for T300RS\n");
return 0;
@@ -1471,8 +1482,10 @@ sysfs_err:
firmware_err:
kfree(t300rs->send_buffer);
+t300rs_err:
+ kfree(t300rs);
send_err:
- hid_err(t300rs->hdev, "failed creating force feedback device\n");
+ hid_err(tmff2->hdev, "failed creating force feedback device\n");
return ret;
}
@@ -1523,17 +1536,6 @@ static __u8 *t300rs_wheel_fixup(struct hid_device *hdev, __u8 *rdesc,
static int t300rs_populate_api(struct tmff2_device_entry *tmff2)
{
- struct t300rs_device_entry *t300rs =
- kzalloc(sizeof(struct t300rs_device_entry), GFP_KERNEL);
-
- /* we must populate wheel_destroy at the least, even if t300rs didn't
- * get allocated */
- tmff2->data = t300rs;
- tmff2->max_effects = T300RS_MAX_EFFECTS;
-
- /* copy over supported effects */
- memcpy(tmff2->supported_effects, t300rs_effects, ARRAY_SIZE(t300rs_effects));
-
/* set callbacks */
tmff2->play_effect = t300rs_play_effect;
tmff2->upload_effect = t300rs_upload_effect;
@@ -1551,13 +1553,5 @@ static int t300rs_populate_api(struct tmff2_device_entry *tmff2)
tmff2->set_autocenter = t300rs_set_autocenter;
tmff2->wheel_fixup = t300rs_wheel_fixup;
- if (!t300rs)
- return -ENOMEM;
-
- /* copy over stuff we need */
- t300rs->hdev = tmff2->hdev;
- t300rs->input_dev = tmff2->input_dev;
- t300rs->usbdev = to_usb_device(&tmff2->hdev->dev);
-
return 0;
}