Skip to content

Commit 55b0425

Browse files
author
Jiri Kosina
committed
Merge branch 'for-6.10/steam' into for-linus
- support for Deck IMU in hid-steam (Max Maisel)
2 parents 4784694 + 3347e16 commit 55b0425

File tree

1 file changed

+147
-8
lines changed

1 file changed

+147
-8
lines changed

drivers/hid/hid-steam.c

Lines changed: 147 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ static LIST_HEAD(steam_devices);
6666
#define STEAM_DECK_TRIGGER_RESOLUTION 5461
6767
/* Joystick runs are about 5 mm and 32768 units */
6868
#define STEAM_DECK_JOYSTICK_RESOLUTION 6553
69+
/* Accelerometer has 16 bit resolution and a range of +/- 2g */
70+
#define STEAM_DECK_ACCEL_RES_PER_G 16384
71+
#define STEAM_DECK_ACCEL_RANGE 32768
72+
#define STEAM_DECK_ACCEL_FUZZ 32
73+
/* Gyroscope has 16 bit resolution and a range of +/- 2000 dps */
74+
#define STEAM_DECK_GYRO_RES_PER_DPS 16
75+
#define STEAM_DECK_GYRO_RANGE 32768
76+
#define STEAM_DECK_GYRO_FUZZ 1
6977

7078
#define STEAM_PAD_FUZZ 256
7179

@@ -288,6 +296,7 @@ struct steam_device {
288296
struct mutex report_mutex;
289297
unsigned long client_opened;
290298
struct input_dev __rcu *input;
299+
struct input_dev __rcu *sensors;
291300
unsigned long quirks;
292301
struct work_struct work_connect;
293302
bool connected;
@@ -302,6 +311,7 @@ struct steam_device {
302311
struct work_struct rumble_work;
303312
u16 rumble_left;
304313
u16 rumble_right;
314+
unsigned int sensor_timestamp_us;
305315
};
306316

307317
static int steam_recv_report(struct steam_device *steam,
@@ -825,6 +835,74 @@ static int steam_input_register(struct steam_device *steam)
825835
return ret;
826836
}
827837

838+
static int steam_sensors_register(struct steam_device *steam)
839+
{
840+
struct hid_device *hdev = steam->hdev;
841+
struct input_dev *sensors;
842+
int ret;
843+
844+
if (!(steam->quirks & STEAM_QUIRK_DECK))
845+
return 0;
846+
847+
rcu_read_lock();
848+
sensors = rcu_dereference(steam->sensors);
849+
rcu_read_unlock();
850+
if (sensors) {
851+
dbg_hid("%s: already connected\n", __func__);
852+
return 0;
853+
}
854+
855+
sensors = input_allocate_device();
856+
if (!sensors)
857+
return -ENOMEM;
858+
859+
input_set_drvdata(sensors, steam);
860+
sensors->dev.parent = &hdev->dev;
861+
862+
sensors->name = "Steam Deck Motion Sensors";
863+
sensors->phys = hdev->phys;
864+
sensors->uniq = steam->serial_no;
865+
sensors->id.bustype = hdev->bus;
866+
sensors->id.vendor = hdev->vendor;
867+
sensors->id.product = hdev->product;
868+
sensors->id.version = hdev->version;
869+
870+
__set_bit(INPUT_PROP_ACCELEROMETER, sensors->propbit);
871+
__set_bit(EV_MSC, sensors->evbit);
872+
__set_bit(MSC_TIMESTAMP, sensors->mscbit);
873+
874+
input_set_abs_params(sensors, ABS_X, -STEAM_DECK_ACCEL_RANGE,
875+
STEAM_DECK_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0);
876+
input_set_abs_params(sensors, ABS_Y, -STEAM_DECK_ACCEL_RANGE,
877+
STEAM_DECK_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0);
878+
input_set_abs_params(sensors, ABS_Z, -STEAM_DECK_ACCEL_RANGE,
879+
STEAM_DECK_ACCEL_RANGE, STEAM_DECK_ACCEL_FUZZ, 0);
880+
input_abs_set_res(sensors, ABS_X, STEAM_DECK_ACCEL_RES_PER_G);
881+
input_abs_set_res(sensors, ABS_Y, STEAM_DECK_ACCEL_RES_PER_G);
882+
input_abs_set_res(sensors, ABS_Z, STEAM_DECK_ACCEL_RES_PER_G);
883+
884+
input_set_abs_params(sensors, ABS_RX, -STEAM_DECK_GYRO_RANGE,
885+
STEAM_DECK_GYRO_RANGE, STEAM_DECK_GYRO_FUZZ, 0);
886+
input_set_abs_params(sensors, ABS_RY, -STEAM_DECK_GYRO_RANGE,
887+
STEAM_DECK_GYRO_RANGE, STEAM_DECK_GYRO_FUZZ, 0);
888+
input_set_abs_params(sensors, ABS_RZ, -STEAM_DECK_GYRO_RANGE,
889+
STEAM_DECK_GYRO_RANGE, STEAM_DECK_GYRO_FUZZ, 0);
890+
input_abs_set_res(sensors, ABS_RX, STEAM_DECK_GYRO_RES_PER_DPS);
891+
input_abs_set_res(sensors, ABS_RY, STEAM_DECK_GYRO_RES_PER_DPS);
892+
input_abs_set_res(sensors, ABS_RZ, STEAM_DECK_GYRO_RES_PER_DPS);
893+
894+
ret = input_register_device(sensors);
895+
if (ret)
896+
goto sensors_register_fail;
897+
898+
rcu_assign_pointer(steam->sensors, sensors);
899+
return 0;
900+
901+
sensors_register_fail:
902+
input_free_device(sensors);
903+
return ret;
904+
}
905+
828906
static void steam_input_unregister(struct steam_device *steam)
829907
{
830908
struct input_dev *input;
@@ -838,6 +916,24 @@ static void steam_input_unregister(struct steam_device *steam)
838916
input_unregister_device(input);
839917
}
840918

919+
static void steam_sensors_unregister(struct steam_device *steam)
920+
{
921+
struct input_dev *sensors;
922+
923+
if (!(steam->quirks & STEAM_QUIRK_DECK))
924+
return;
925+
926+
rcu_read_lock();
927+
sensors = rcu_dereference(steam->sensors);
928+
rcu_read_unlock();
929+
930+
if (!sensors)
931+
return;
932+
RCU_INIT_POINTER(steam->sensors, NULL);
933+
synchronize_rcu();
934+
input_unregister_device(sensors);
935+
}
936+
841937
static void steam_battery_unregister(struct steam_device *steam)
842938
{
843939
struct power_supply *battery;
@@ -890,18 +986,28 @@ static int steam_register(struct steam_device *steam)
890986
spin_lock_irqsave(&steam->lock, flags);
891987
client_opened = steam->client_opened;
892988
spin_unlock_irqrestore(&steam->lock, flags);
989+
893990
if (!client_opened) {
894991
steam_set_lizard_mode(steam, lizard_mode);
895992
ret = steam_input_register(steam);
896-
} else
897-
ret = 0;
993+
if (ret != 0)
994+
goto steam_register_input_fail;
995+
ret = steam_sensors_register(steam);
996+
if (ret != 0)
997+
goto steam_register_sensors_fail;
998+
}
999+
return 0;
8981000

1001+
steam_register_sensors_fail:
1002+
steam_input_unregister(steam);
1003+
steam_register_input_fail:
8991004
return ret;
9001005
}
9011006

9021007
static void steam_unregister(struct steam_device *steam)
9031008
{
9041009
steam_battery_unregister(steam);
1010+
steam_sensors_unregister(steam);
9051011
steam_input_unregister(steam);
9061012
if (steam->serial_no[0]) {
9071013
hid_info(steam->hdev, "Steam Controller '%s' disconnected",
@@ -1010,6 +1116,7 @@ static int steam_client_ll_open(struct hid_device *hdev)
10101116
steam->client_opened++;
10111117
spin_unlock_irqrestore(&steam->lock, flags);
10121118

1119+
steam_sensors_unregister(steam);
10131120
steam_input_unregister(steam);
10141121

10151122
return 0;
@@ -1030,6 +1137,7 @@ static void steam_client_ll_close(struct hid_device *hdev)
10301137
if (connected) {
10311138
steam_set_lizard_mode(steam, lizard_mode);
10321139
steam_input_register(steam);
1140+
steam_sensors_register(steam);
10331141
}
10341142
}
10351143

@@ -1121,6 +1229,7 @@ static int steam_probe(struct hid_device *hdev,
11211229
INIT_DELAYED_WORK(&steam->mode_switch, steam_mode_switch_cb);
11221230
INIT_LIST_HEAD(&steam->list);
11231231
INIT_WORK(&steam->rumble_work, steam_haptic_rumble_cb);
1232+
steam->sensor_timestamp_us = 0;
11241233

11251234
/*
11261235
* With the real steam controller interface, do not connect hidraw.
@@ -1380,12 +1489,12 @@ static void steam_do_input_event(struct steam_device *steam,
13801489
* 18-19 | s16 | ABS_HAT0Y | left-pad Y value
13811490
* 20-21 | s16 | ABS_HAT1X | right-pad X value
13821491
* 22-23 | s16 | ABS_HAT1Y | right-pad Y value
1383-
* 24-25 | s16 | -- | accelerometer X value
1384-
* 26-27 | s16 | -- | accelerometer Y value
1385-
* 28-29 | s16 | -- | accelerometer Z value
1386-
* 30-31 | s16 | -- | gyro X value
1387-
* 32-33 | s16 | -- | gyro Y value
1388-
* 34-35 | s16 | -- | gyro Z value
1492+
* 24-25 | s16 | IMU ABS_X | accelerometer X value
1493+
* 26-27 | s16 | IMU ABS_Z | accelerometer Y value
1494+
* 28-29 | s16 | IMU ABS_Y | accelerometer Z value
1495+
* 30-31 | s16 | IMU ABS_RX | gyro X value
1496+
* 32-33 | s16 | IMU ABS_RZ | gyro Y value
1497+
* 34-35 | s16 | IMU ABS_RY | gyro Z value
13891498
* 36-37 | s16 | -- | quaternion W value
13901499
* 38-39 | s16 | -- | quaternion X value
13911500
* 40-41 | s16 | -- | quaternion Y value
@@ -1546,6 +1655,32 @@ static void steam_do_deck_input_event(struct steam_device *steam,
15461655
input_sync(input);
15471656
}
15481657

1658+
static void steam_do_deck_sensors_event(struct steam_device *steam,
1659+
struct input_dev *sensors, u8 *data)
1660+
{
1661+
/*
1662+
* The deck input report is received every 4 ms on average,
1663+
* with a jitter of +/- 4 ms even though the USB descriptor claims
1664+
* that it uses 1 kHz.
1665+
* Since the HID report does not include a sensor timestamp,
1666+
* use a fixed increment here.
1667+
*/
1668+
steam->sensor_timestamp_us += 4000;
1669+
1670+
if (!steam->gamepad_mode)
1671+
return;
1672+
1673+
input_event(sensors, EV_MSC, MSC_TIMESTAMP, steam->sensor_timestamp_us);
1674+
input_report_abs(sensors, ABS_X, steam_le16(data + 24));
1675+
input_report_abs(sensors, ABS_Z, -steam_le16(data + 26));
1676+
input_report_abs(sensors, ABS_Y, steam_le16(data + 28));
1677+
input_report_abs(sensors, ABS_RX, steam_le16(data + 30));
1678+
input_report_abs(sensors, ABS_RZ, -steam_le16(data + 32));
1679+
input_report_abs(sensors, ABS_RY, steam_le16(data + 34));
1680+
1681+
input_sync(sensors);
1682+
}
1683+
15491684
/*
15501685
* The size for this message payload is 11.
15511686
* The known values are:
@@ -1583,6 +1718,7 @@ static int steam_raw_event(struct hid_device *hdev,
15831718
{
15841719
struct steam_device *steam = hid_get_drvdata(hdev);
15851720
struct input_dev *input;
1721+
struct input_dev *sensors;
15861722
struct power_supply *battery;
15871723

15881724
if (!steam)
@@ -1628,6 +1764,9 @@ static int steam_raw_event(struct hid_device *hdev,
16281764
input = rcu_dereference(steam->input);
16291765
if (likely(input))
16301766
steam_do_deck_input_event(steam, input, data);
1767+
sensors = rcu_dereference(steam->sensors);
1768+
if (likely(sensors))
1769+
steam_do_deck_sensors_event(steam, sensors, data);
16311770
rcu_read_unlock();
16321771
break;
16331772
case ID_CONTROLLER_WIRELESS:

0 commit comments

Comments
 (0)