Compare commits
34 Commits
docs-updat
...
0.0.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3afa74502e | ||
|
|
99b4ebb4ce | ||
|
|
823a950f07 | ||
|
|
4326430856 | ||
|
|
3932a51126 | ||
|
|
561a50299b | ||
|
|
164ad09ad8 | ||
|
|
baf35a36f0 | ||
|
|
51982fd1e2 | ||
|
|
d7633c82fd | ||
|
|
56fdaa11f8 | ||
|
|
c6649f3349 | ||
|
|
092bdbd661 | ||
|
|
9e27df12cb | ||
|
|
985182baf2 | ||
|
|
55d456c9e1 | ||
|
|
3b0f38483f | ||
|
|
3d19599175 | ||
|
|
6d0ac791b1 | ||
|
|
bc87313267 | ||
|
|
8f42ca6774 | ||
|
|
2ee89cb9a4 | ||
|
|
f8e9545f39 | ||
|
|
241a25cee9 | ||
|
|
8220bbbfb0 | ||
|
|
96e036acda | ||
|
|
bfbdb9620e | ||
|
|
38c629829f | ||
|
|
b58aee4403 | ||
|
|
34d6d6b294 | ||
|
|
3ff83db322 | ||
|
|
d2585bcf17 | ||
|
|
c092780bf3 | ||
|
|
dcdd8c1e6a |
17
README.md
17
README.md
@@ -16,7 +16,7 @@ And that's basically it
|
|||||||
## What devices are supported?
|
## What devices are supported?
|
||||||
### Bases:
|
### Bases:
|
||||||
1. MOZA R3, R5, R9, R12, R16, R21
|
1. MOZA R3, R5, R9, R12, R16, R21
|
||||||
2. Cammus C5
|
2. Cammus C5, C12
|
||||||
3. ...
|
3. ...
|
||||||
|
|
||||||
## What works?
|
## What works?
|
||||||
@@ -25,15 +25,17 @@ And that's basically it
|
|||||||
|
|
||||||
|
|
||||||
## What does not work?
|
## What does not work?
|
||||||
1. Telemetry functions (Shift lights, displays, SimHub, etc), mostly because telemetry works only with proprietary soft, which can't get access to shared memory chunks from games.
|
1. Telemetry functions. They are handeled by [Monocoque](https://github.com/Spacefreak18/monocoque)
|
||||||
2. `Firmware Update` function. Use Windows PC or Windows VM at the moment.
|
2. `Firmware Update` function. Use Windows PC or Windows VM at the moment.
|
||||||
3. Setup through proprietary software. May require [some tweaking](#how-to-set-up-a-base-parameters))
|
3. Setup through proprietary software. May require [some tweaking](#how-to-set-up-a-base-parameters)
|
||||||
|
|
||||||
## How to use this driver?
|
## How to install this driver?
|
||||||
You can install it through AUR package, through DKMS or manually.
|
You can install it through AUR package, through DKMS or manually.
|
||||||
|
|
||||||
|
On SecureBoot enabled systems you will need additional steps for load this driver into the system. See [Signing](docs/SIGNING.md#signing) section.
|
||||||
|
|
||||||
### AUR package
|
### AUR package
|
||||||
There's an [AUR package](https://aur.archlinux.org/packages/universal-ff-dkms-git) for Arch Linux maintained by [@Lawstorant](https://github.com/Lawstorant).
|
There's an [AUR package](https://aur.archlinux.org/packages/universal-pidff-dkms-git) for Arch Linux maintained by [@Lawstorant](https://github.com/Lawstorant).
|
||||||
|
|
||||||
### DKMS
|
### DKMS
|
||||||
DKMS will install module into system, and will update it every time you update your kernel. Module will persist after reboots. It's the preferrable way to install it on the most distros.
|
DKMS will install module into system, and will update it every time you update your kernel. Module will persist after reboots. It's the preferrable way to install it on the most distros.
|
||||||
@@ -59,6 +61,9 @@ Best for debugging purposes, where you need frequently change codebase/branches
|
|||||||
To unload module:
|
To unload module:
|
||||||
`sudo rmmod hid_universal_pidff`
|
`sudo rmmod hid_universal_pidff`
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
To test the supported effects, use ffbplay from [ffbtools](https://github.com/berarma/ffbtools) and play the included [effect-test.ffb](./effect-test.ffb) file
|
||||||
|
|
||||||
## How to set up a base parameters?
|
## How to set up a base parameters?
|
||||||
### MOZA
|
### MOZA
|
||||||
**[Boxflat](https://github.com/Lawstorant/boxflat)** is a Linux Pit House alternative made by [@Lawstorant](https://github.com/Lawstorant)
|
**[Boxflat](https://github.com/Lawstorant/boxflat)** is a Linux Pit House alternative made by [@Lawstorant](https://github.com/Lawstorant)
|
||||||
@@ -69,7 +74,7 @@ To unload module:
|
|||||||
**[Android App](https://play.google.com/store/apps/details?id=com.cammus.simulator)**
|
**[Android App](https://play.google.com/store/apps/details?id=com.cammus.simulator)**
|
||||||
|
|
||||||
## Known issues with the driver
|
## Known issues with the driver
|
||||||
- Buttons above 80 simply don't show up. This is a Linux limitation and we're trying to fix that in the upstream
|
- Current limit of usable buttons is 160 (up from the Linux default of 80). Create an issue if you want this increased further.
|
||||||
|
|
||||||
## Known issues with the firmware
|
## Known issues with the firmware
|
||||||
You tell me please
|
You tell me please
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
PACKAGE_NAME="universal-pidff"
|
PACKAGE_NAME="universal-pidff"
|
||||||
PACKAGE_VERSION="0.0.3"
|
PACKAGE_VERSION="0.0.7"
|
||||||
MAKE[0]="make KVERSION=$kernelver"
|
MAKE[0]="make KVERSION=$kernelver"
|
||||||
CLEAN="make clean"
|
CLEAN="make clean"
|
||||||
BUILT_MODULE_NAME[0]="hid-universal-pidff"
|
BUILT_MODULE_NAME[0]="hid-universal-pidff"
|
||||||
|
|||||||
59
docs/SIGNING.md
Normal file
59
docs/SIGNING.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
# Signing
|
||||||
|
|
||||||
|
## Signing module for SecureBoot
|
||||||
|
Latest kernels forbid loading unsigned custom kernel modules into the system with SecureBoot enabled.
|
||||||
|
|
||||||
|
For SecureBoot enabled system you have a choice:
|
||||||
|
1. Disable SecureBoot in your UEFI/BIOS
|
||||||
|
2. Use generated Machine Owner Key from DKMS (supports automatic signing)
|
||||||
|
3. Create Machine Owner Key and load it into your UEFI/BIOS, and sign kernel module with it.
|
||||||
|
|
||||||
|
### Using DKMS MOK key
|
||||||
|
MOK private key and certificates are generated the first time DKMS is run. You just need to import it to your system.
|
||||||
|
|
||||||
|
The location as well can be changed by setting the appropriate variables in /etc/dkms/framework.conf. For example, to allow usage of the system default Ubuntu update-secureboot-policy set the configuration file as follows:
|
||||||
|
```
|
||||||
|
mok_signing_key="/var/lib/shim-signed/mok/MOK.priv"
|
||||||
|
mok_certificate="/var/lib/shim-signed/mok/MOK.der"
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
# Find where keys are on your distro
|
||||||
|
ls -al /var/lib/dkms/mok*
|
||||||
|
# OR (on Ubuntu)
|
||||||
|
ls -al /var/lib/shim-signed/mok/MOK*
|
||||||
|
|
||||||
|
# Enroll keys into system
|
||||||
|
sudo mokutil --import /var/lib/dkms/mok.pub
|
||||||
|
# OR (on Ubuntu)
|
||||||
|
sudo mokutil --import /var/lib/shim-signed/mok/MOK.der
|
||||||
|
```
|
||||||
|
You need to reboot your PC after that, you will be greeted with blue screen dialog.
|
||||||
|
Choose "Enroll MOK", then "Continue" and "Yes". After that choose "Reboot system".
|
||||||
|
|
||||||
|
Now DKMS should sign updated modules automatically as they updated.
|
||||||
|
|
||||||
|
[Reference](https://github.com/dell/dkms/blob/master/README.md#module-signing)
|
||||||
|
|
||||||
|
### Manually create MOK key and manually sign kernel module
|
||||||
|
```
|
||||||
|
# This creates Machine Owner Key
|
||||||
|
openssl req -new -x509 -newkey rsa:2048 -keyout mok.key -outform DER -out mok.pub -nodes -days 36500 -subj "/CN=$hostname kernel module signing key/"
|
||||||
|
|
||||||
|
# This loads it into UEFI
|
||||||
|
sudo mokutil --import mok.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
You need to reboot your PC after that, you will be greeted with blue screen dialog
|
||||||
|
Choose "Enroll MOK", enter your MOK password if exists, then "Continue", "Yes", and then reboot your system.
|
||||||
|
|
||||||
|
After that you can manually sign your built kernel module like so (feel free to adjust paths to keys/certificate/modules):
|
||||||
|
```
|
||||||
|
sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 mok.key mok.pub hid-universal-pidff.ko
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you should be able to load driver like so:
|
||||||
|
```
|
||||||
|
sudo insmod hid-universal-pidff.ko
|
||||||
|
```
|
||||||
67
effect-test.ffb
Normal file
67
effect-test.ffb
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
00000000 # Constant force left
|
||||||
|
00000000 > UPLOAD id:-1 dir:16384 type:CONSTANT level:9000
|
||||||
|
00000000 < 0 id:0
|
||||||
|
00000000 > PLAY 0 1
|
||||||
|
03000000 # Constant force right
|
||||||
|
03000000 > UPLOAD id:0 dir:16384 type:CONSTANT level:-9000
|
||||||
|
06000000 # Spring
|
||||||
|
06000000 > REMOVE 0
|
||||||
|
06000000 > UPLOAD id:-1 dir:16384 type:SPRING left_coeff:32767 right_coeff:32767
|
||||||
|
06000000 < 0 id:0
|
||||||
|
06000000 > PLAY 0 1
|
||||||
|
07000000 # Move the wheel yourself to test these next 3 effects
|
||||||
|
09000000 > STOP 0
|
||||||
|
09000000 # Damper
|
||||||
|
09000000 > REMOVE 0
|
||||||
|
09000000 > UPLOAD id:-1 dir:16384 type:DAMPER left_coeff:32767 right_coeff:32767
|
||||||
|
09000000 < 0 id:0
|
||||||
|
09000000 > PLAY 0 1
|
||||||
|
12000000 # Friction
|
||||||
|
12000000 > STOP 0
|
||||||
|
12000000 > REMOVE 0
|
||||||
|
12000000 > UPLOAD id:-1 dir:16384 type:FRICTION left_coeff:32767 right_coeff:32767
|
||||||
|
12000000 < 0 id:0
|
||||||
|
12000000 > PLAY 0 1
|
||||||
|
15000000 # Inertia
|
||||||
|
15000000 > STOP 0
|
||||||
|
15000000 > REMOVE 0
|
||||||
|
15000000 > UPLOAD id:-1 dir:16384 type:INERTIA left_coeff:32767 right_coeff:32767
|
||||||
|
15000000 < 0 id:0
|
||||||
|
15000000 > PLAY 0 1
|
||||||
|
18000000 # Periodic sine
|
||||||
|
18000000 > REMOVE 0
|
||||||
|
18000000 > UPLOAD id:-1 dir:16384 type:PERIODIC waveform:SINE period:100 magnitude:9000
|
||||||
|
18000000 < 0 id:0
|
||||||
|
18000000 > PLAY 0 1
|
||||||
|
21000000 # Periodic square
|
||||||
|
21000000 > REMOVE 0
|
||||||
|
21000000 > UPLOAD id:-1 dir:16384 type:PERIODIC waveform:SQUARE period:100 magnitude:9000
|
||||||
|
21000000 < 0 id:0
|
||||||
|
21000000 > PLAY 0 1
|
||||||
|
24000000 # Periodic triangle
|
||||||
|
24000000 > REMOVE 0
|
||||||
|
24000000 > UPLOAD id:-1 dir:16384 type:PERIODIC waveform:TRIANGLE period:100 magnitude:9000
|
||||||
|
24000000 < 0 id:0
|
||||||
|
24000000 > PLAY 0 1
|
||||||
|
27000000 # Periodic saw up
|
||||||
|
27000000 > REMOVE 0
|
||||||
|
27000000 > UPLOAD id:-1 dir:16384 type:PERIODIC waveform:SAW_UP period:100 magnitude:9000
|
||||||
|
27000000 < 0 id:0
|
||||||
|
27000000 > PLAY 0 1
|
||||||
|
30000000 # Periodic saw down
|
||||||
|
30000000 > REMOVE 0
|
||||||
|
30000000 > UPLOAD id:-1 dir:16384 type:PERIODIC waveform:SAW_DOWN period:100 magnitude:9000
|
||||||
|
30000000 < 0 id:0
|
||||||
|
30000000 > PLAY 0 1
|
||||||
|
33000000 # Sine constant force emulation left
|
||||||
|
33000000 > REMOVE 0
|
||||||
|
33000000 > UPLOAD id:-1 dir:16384 type:PERIODIC waveform:SINE period:1000 magnitude:0 offset:12000
|
||||||
|
33000000 < 0 id:0
|
||||||
|
33000000 > PLAY 0 1
|
||||||
|
36000000 # Sine constant force emulation right
|
||||||
|
36000000 > UPLOAD id:0 dir:16384 type:PERIODIC waveform:SINE period:1000 magnitude:0 offset:-12000
|
||||||
|
39000000 > REMOVE 0
|
||||||
|
39000000 # Sine constant force emulation right
|
||||||
|
39000000 > UPLOAD id:0 dir:16384 type:PERIODIC waveform:SINE period:1000 magnitude:0 offset:-12000
|
||||||
|
42000000 > STOP 0
|
||||||
|
42000000 > REMOVE 0
|
||||||
@@ -11,5 +11,6 @@
|
|||||||
|
|
||||||
#define USB_VENDOR_ID_CAMMUS 0x3416
|
#define USB_VENDOR_ID_CAMMUS 0x3416
|
||||||
#define USB_DEVICE_ID_CAMMUS_C5 0x0301
|
#define USB_DEVICE_ID_CAMMUS_C5 0x0301
|
||||||
|
#define USB_DEVICE_ID_CAMMUS_C12 0x0302
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,27 +4,33 @@
|
|||||||
* First of all targeting steering wheels and wheelbases
|
* First of all targeting steering wheels and wheelbases
|
||||||
*
|
*
|
||||||
* Copyright (c) 2024 Makarenko Oleg
|
* Copyright (c) 2024 Makarenko Oleg
|
||||||
|
* Copyright (c) 2024 Tomasz Pakuła
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/hid.h>
|
#include <linux/hid.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
#include "hid-ids.h"
|
#include "hid-ids.h"
|
||||||
#include "hid-pidff.h"
|
#include "hid-pidff.h"
|
||||||
|
|
||||||
|
#define JOY_RANGE (BTN_DEAD - BTN_JOYSTICK + 1)
|
||||||
|
|
||||||
static const struct hid_device_id pidff_wheel_devices[] = {
|
static const struct hid_device_id pidff_wheel_devices[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R3),
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R3),
|
||||||
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE },
|
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R5),
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R5),
|
||||||
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE },
|
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R9),
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R9),
|
||||||
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE },
|
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R12),
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R12),
|
||||||
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE },
|
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R16_R21),
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R16_R21),
|
||||||
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE },
|
.driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_CAMMUS, USB_DEVICE_ID_CAMMUS_C5),
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CAMMUS, USB_DEVICE_ID_CAMMUS_C5),
|
||||||
.driver_data = PIDFF_QUIRK_NO_DELAY_EFFECT },
|
.driver_data = PIDFF_QUIRK_NO_DELAY_EFFECT },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_CAMMUS, USB_DEVICE_ID_CAMMUS_C12),
|
||||||
|
.driver_data = PIDFF_QUIRK_NO_DELAY_EFFECT },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(hid, pidff_wheel_devices);
|
MODULE_DEVICE_TABLE(hid, pidff_wheel_devices);
|
||||||
@@ -50,6 +56,36 @@ static u8 *universal_pidff_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
|||||||
return rdesc;
|
return rdesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map buttons manually to extend the default joystick buttn limit
|
||||||
|
*/
|
||||||
|
static int universal_pidff_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
||||||
|
struct hid_field *field, struct hid_usage *usage,
|
||||||
|
unsigned long **bit, int *max)
|
||||||
|
{
|
||||||
|
// Let the default behavior handle mapping if usage is not a button
|
||||||
|
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int button = ((usage->hid - 1) & HID_USAGE);
|
||||||
|
int code = button + BTN_JOYSTICK;
|
||||||
|
|
||||||
|
// Detect the end of JOYSTICK buttons range
|
||||||
|
// KEY_AUDIO_DESC = 0x270
|
||||||
|
if (code > BTN_DEAD)
|
||||||
|
code = button + KEY_NEXT_FAVORITE - JOY_RANGE;
|
||||||
|
|
||||||
|
// Map overflowing buttons to KEY_RESERVED for the upcoming new input event
|
||||||
|
// It will handle button presses differently and won't depend on defined
|
||||||
|
// ranges. KEY_RESERVED usage is needed for the button to not be ignored.
|
||||||
|
if (code > KEY_MAX)
|
||||||
|
code = KEY_RESERVED;
|
||||||
|
|
||||||
|
hid_map_usage(hi, usage, bit, max, EV_KEY, code);
|
||||||
|
hid_dbg(hdev, "Button %d: usage %d", button, code);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the device is PID and initialize it
|
* Check if the device is PID and initialize it
|
||||||
@@ -85,17 +121,30 @@ err:
|
|||||||
static int universal_pidff_input_configured(struct hid_device *hdev,
|
static int universal_pidff_input_configured(struct hid_device *hdev,
|
||||||
struct hid_input *hidinput)
|
struct hid_input *hidinput)
|
||||||
{
|
{
|
||||||
// Remove fuzz and deadzone
|
// Remove fuzz and deadzone from the wheel axis
|
||||||
struct input_dev *input = hidinput->input;
|
struct input_dev *input = hidinput->input;
|
||||||
input_set_abs_params(input, ABS_X,
|
input_set_abs_params(input, ABS_X,
|
||||||
input->absinfo[ABS_X].minimum, input->absinfo[ABS_X].maximum, 0, 0);
|
input->absinfo[ABS_X].minimum, input->absinfo[ABS_X].maximum, 0, 0);
|
||||||
|
|
||||||
|
// Decrease fuzz and deadzone on additional axes
|
||||||
|
// Default Linux values are 255 for fuzz and 4096 for flat (deadzone)
|
||||||
|
int axis;
|
||||||
|
for (axis = ABS_Y; axis <= ABS_BRAKE; axis++) {
|
||||||
|
if (!test_bit(axis, input->absbit))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
input_set_abs_params(input, axis,
|
||||||
|
input->absinfo[axis].minimum,
|
||||||
|
input->absinfo[axis].maximum, 8, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hid_driver universal_pidff = {
|
static struct hid_driver universal_pidff = {
|
||||||
.name = "hid-universal-pidff",
|
.name = "hid-universal-pidff",
|
||||||
.id_table = pidff_wheel_devices,
|
.id_table = pidff_wheel_devices,
|
||||||
|
.input_mapping = universal_pidff_input_mapping,
|
||||||
.probe = universal_pidff_probe,
|
.probe = universal_pidff_probe,
|
||||||
.input_configured = universal_pidff_input_configured,
|
.input_configured = universal_pidff_input_configured,
|
||||||
.report_fixup = universal_pidff_report_fixup
|
.report_fixup = universal_pidff_report_fixup
|
||||||
@@ -103,5 +152,6 @@ static struct hid_driver universal_pidff = {
|
|||||||
module_hid_driver(universal_pidff);
|
module_hid_driver(universal_pidff);
|
||||||
|
|
||||||
MODULE_AUTHOR("Oleg Makarenko <oleg@makarenk.ooo>");
|
MODULE_AUTHOR("Oleg Makarenko <oleg@makarenk.ooo>");
|
||||||
|
MODULE_AUTHOR("Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>");
|
||||||
MODULE_DESCRIPTION("Universal HID PIDFF Driver");
|
MODULE_DESCRIPTION("Universal HID PIDFF Driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|||||||
34
hid-pidff.c
34
hid-pidff.c
@@ -311,6 +311,14 @@ static void pidff_set_envelope_report(struct pidff_device *pidff,
|
|||||||
static int pidff_needs_set_envelope(struct ff_envelope *envelope,
|
static int pidff_needs_set_envelope(struct ff_envelope *envelope,
|
||||||
struct ff_envelope *old)
|
struct ff_envelope *old)
|
||||||
{
|
{
|
||||||
|
if (!old) {
|
||||||
|
return envelope->attack_level != 0 ||
|
||||||
|
envelope->fade_level != 0 ||
|
||||||
|
envelope->attack_length != 0 ||
|
||||||
|
envelope->fade_length != 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return envelope->attack_level != old->attack_level ||
|
return envelope->attack_level != old->attack_level ||
|
||||||
envelope->fade_level != old->fade_level ||
|
envelope->fade_level != old->fade_level ||
|
||||||
envelope->attack_length != old->attack_length ||
|
envelope->attack_length != old->attack_length ||
|
||||||
@@ -643,9 +651,8 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
|
|||||||
pidff_set_effect_report(pidff, effect);
|
pidff_set_effect_report(pidff, effect);
|
||||||
if (!old || pidff_needs_set_constant(effect, old))
|
if (!old || pidff_needs_set_constant(effect, old))
|
||||||
pidff_set_constant_force_report(pidff, effect);
|
pidff_set_constant_force_report(pidff, effect);
|
||||||
if (!old ||
|
if (pidff_needs_set_envelope(&effect->u.constant.envelope,
|
||||||
pidff_needs_set_envelope(&effect->u.constant.envelope,
|
old ? &old->u.periodic.envelope : NULL))
|
||||||
&old->u.constant.envelope))
|
|
||||||
pidff_set_envelope_report(pidff,
|
pidff_set_envelope_report(pidff,
|
||||||
&effect->u.constant.envelope);
|
&effect->u.constant.envelope);
|
||||||
break;
|
break;
|
||||||
@@ -683,19 +690,8 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
|
|||||||
if (!old || pidff_needs_set_periodic(effect, old))
|
if (!old || pidff_needs_set_periodic(effect, old))
|
||||||
pidff_set_periodic_report(pidff, effect);
|
pidff_set_periodic_report(pidff, effect);
|
||||||
|
|
||||||
if (pidff->quirks & PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE)
|
if (pidff_needs_set_envelope(&effect->u.periodic.envelope,
|
||||||
{
|
old ? &old->u.periodic.envelope : NULL))
|
||||||
effect->u.periodic.envelope.attack_level =
|
|
||||||
effect->u.periodic.envelope.attack_level == 0
|
|
||||||
? 0x7fff : effect->u.periodic.envelope.attack_level;
|
|
||||||
|
|
||||||
effect->u.periodic.envelope.fade_level =
|
|
||||||
effect->u.periodic.envelope.fade_level == 0
|
|
||||||
? 0x7fff : effect->u.periodic.envelope.fade_level;
|
|
||||||
}
|
|
||||||
if (!old ||
|
|
||||||
pidff_needs_set_envelope(&effect->u.periodic.envelope,
|
|
||||||
&old->u.periodic.envelope))
|
|
||||||
pidff_set_envelope_report(pidff,
|
pidff_set_envelope_report(pidff,
|
||||||
&effect->u.periodic.envelope);
|
&effect->u.periodic.envelope);
|
||||||
break;
|
break;
|
||||||
@@ -711,9 +707,9 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
|
|||||||
pidff_set_effect_report(pidff, effect);
|
pidff_set_effect_report(pidff, effect);
|
||||||
if (!old || pidff_needs_set_ramp(effect, old))
|
if (!old || pidff_needs_set_ramp(effect, old))
|
||||||
pidff_set_ramp_force_report(pidff, effect);
|
pidff_set_ramp_force_report(pidff, effect);
|
||||||
if (!old ||
|
|
||||||
pidff_needs_set_envelope(&effect->u.ramp.envelope,
|
if (pidff_needs_set_envelope(&effect->u.ramp.envelope,
|
||||||
&old->u.ramp.envelope))
|
old ? &old->u.periodic.envelope : NULL))
|
||||||
pidff_set_envelope_report(pidff,
|
pidff_set_envelope_report(pidff,
|
||||||
&effect->u.ramp.envelope);
|
&effect->u.ramp.envelope);
|
||||||
break;
|
break;
|
||||||
|
|||||||
10
hid-pidff.h
10
hid-pidff.h
@@ -4,21 +4,15 @@
|
|||||||
|
|
||||||
/* PIDFF Quirks to solve issues with certain devices */
|
/* PIDFF Quirks to solve issues with certain devices */
|
||||||
|
|
||||||
/*
|
|
||||||
* Always set a value > 0 for PERIODIC envelope attack and fade level
|
|
||||||
*/
|
|
||||||
#define PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE BIT(0)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ignore direction and always set 16384 (0x4000)
|
* Ignore direction and always set 16384 (0x4000)
|
||||||
*/
|
*/
|
||||||
#define PIDFF_QUIRK_FIX_WHEEL_DIRECTION BIT(1)
|
#define PIDFF_QUIRK_FIX_WHEEL_DIRECTION BIT(0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip initialization of 0xA7 descriptor (Delay effect)
|
* Skip initialization of 0xA7 descriptor (Delay effect)
|
||||||
*/
|
*/
|
||||||
#define PIDFF_QUIRK_NO_DELAY_EFFECT BIT(2)
|
#define PIDFF_QUIRK_NO_DELAY_EFFECT BIT(1)
|
||||||
|
|
||||||
|
|
||||||
int hid_pidff_init_quirks(struct hid_device *hid, const struct hid_device_id *id);
|
int hid_pidff_init_quirks(struct hid_device *hid, const struct hid_device_id *id);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user