distribution/packages/kernel/linux/patches/X86_64/004-steam-deck-controller.patch

543 lines
19 KiB
Diff
Raw Normal View History

diff -rupN hid.orig/hid-ids.h hid/hid-ids.h
--- linux/drivers/hid.orig/hid-ids.h 2022-11-10 18:46:50.091977625 -0800
+++ linux/drivers/hid/hid-ids.h 2022-11-10 18:51:51.442399828 -0800
@@ -1175,6 +1175,7 @@
#define USB_VENDOR_ID_VALVE 0x28de
#define USB_DEVICE_ID_STEAM_CONTROLLER 0x1102
+#define USB_DEVICE_ID_STEAM_DECK_CONTROLLER 0x1205
#define USB_DEVICE_ID_STEAM_CONTROLLER_WIRELESS 0x1142
#define USB_VENDOR_ID_STEELSERIES 0x1038
diff -rupN hid.orig/hid-steam.c hid/hid-steam.c
--- linux/drivers/hid.orig/hid-steam.c 2022-11-10 18:46:50.095977727 -0800
+++ linux/drivers/hid/hid-steam.c 2022-11-10 18:50:19.152673800 -0800
@@ -42,6 +42,9 @@
#include <linux/rcupdate.h>
#include <linux/delay.h>
#include <linux/power_supply.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
#include "hid-ids.h"
MODULE_LICENSE("GPL");
@@ -54,6 +57,7 @@ static LIST_HEAD(steam_devices);
#define STEAM_QUIRK_WIRELESS BIT(0)
+int lizard_reset_fn (void *data);
/* Touch pads are 40 mm in diameter and 65535 units */
#define STEAM_PAD_RESOLUTION 1638
/* Trigger runs are about 5 mm and 256 units */
@@ -82,9 +86,10 @@ static LIST_HEAD(steam_devices);
#define STEAM_CMD_GET_REGISTER_DEFAULT 0x8c
#define STEAM_CMD_SET_MODE 0x8d
#define STEAM_CMD_DEFAULT_MOUSE 0x8e
-#define STEAM_CMD_FORCEFEEDBAK 0x8f
+#define STEAM_CMD_TOUCHPAD_HAPTIC 0x8f
#define STEAM_CMD_REQUEST_COMM_STATUS 0xb4
#define STEAM_CMD_GET_SERIAL 0xae
+#define STEAM_CMD_RUMBLE 0xeb
/* Some useful register ids */
#define STEAM_REG_LPAD_MODE 0x07
@@ -97,6 +102,7 @@ static LIST_HEAD(steam_devices);
#define STEAM_EV_INPUT_DATA 0x01
#define STEAM_EV_CONNECT 0x03
#define STEAM_EV_BATTERY 0x04
+#define STEAM_DECK_EV_INPUT_DATA 0x09
/* Values for GYRO_MODE (bitmask) */
#define STEAM_GYRO_MODE_OFF 0x0000
@@ -118,12 +124,18 @@ struct steam_device {
struct input_dev __rcu *input;
unsigned long quirks;
struct work_struct work_connect;
+ struct work_struct work_effect;
bool connected;
char serial_no[STEAM_SERIAL_LEN + 1];
struct power_supply_desc battery_desc;
struct power_supply __rcu *battery;
u8 battery_charge;
u16 voltage;
+ bool steamdeck;
+ bool device_open;
+ struct task_struct *lizard_reset;
+ uint32_t rumble_weak;
+ uint32_t rumble_strong;
};
static int steam_recv_report(struct steam_device *steam,
@@ -165,6 +177,7 @@ static int steam_send_report(struct stea
u8 *cmd, int size)
{
struct hid_report *r;
+ u32 len;
u8 *buf;
unsigned int retries = 50;
int ret;
@@ -175,13 +188,15 @@ static int steam_send_report(struct stea
return -EINVAL;
}
- if (hid_report_len(r) < 64)
+ len = hid_report_len(r);
+ if (len < 64)
return -EINVAL;
buf = hid_alloc_report_buf(r, GFP_KERNEL);
if (!buf)
return -ENOMEM;
+ memset(buf, 0, len);
/* The report ID is always 0 */
memcpy(buf + 1, cmd, size);
@@ -193,7 +208,7 @@ static int steam_send_report(struct stea
*/
do {
ret = hid_hw_raw_request(steam->hdev, 0,
- buf, size + 1,
+ buf, len,
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
if (ret != -EPIPE)
break;
@@ -273,6 +288,10 @@ static inline int steam_request_conn_sta
static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
{
if (enable) {
+ if (steam->lizard_reset) {
+ kthread_stop(steam->lizard_reset);
+ steam->lizard_reset = NULL;
+ }
/* enable esc, enter, cursors */
steam_send_report_byte(steam, STEAM_CMD_DEFAULT_MAPPINGS);
/* enable mouse */
@@ -287,17 +306,39 @@ static void steam_set_lizard_mode(struct
STEAM_REG_RPAD_MODE, 0x07, /* disable mouse */
STEAM_REG_RPAD_MARGIN, 0x00, /* disable margin */
0);
+
+ if (steam->lizard_reset)
+ return;
+ steam->lizard_reset = kthread_create(lizard_reset_fn, (void*)steam, "lizard_reset");
+ if (IS_ERR(steam->lizard_reset)) {
+ steam->lizard_reset = NULL;
+ return;
+ }
+
+ wake_up_process(steam->lizard_reset);
+ }
+}
+
+int lizard_reset_fn (void *data) {
+ struct steam_device *steam = (struct steam_device*)data;
+ while (steam->device_open) {
+ mutex_lock(&steam->mutex);
+ steam_set_lizard_mode(steam, false);
+ mutex_unlock(&steam->mutex);
+ msleep(1000);
}
+ return 0;
}
static int steam_input_open(struct input_dev *dev)
{
struct steam_device *steam = input_get_drvdata(dev);
-
+ steam->device_open = 1;
mutex_lock(&steam->mutex);
if (!steam->client_opened && lizard_mode)
steam_set_lizard_mode(steam, false);
mutex_unlock(&steam->mutex);
+
return 0;
}
@@ -305,6 +346,7 @@ static void steam_input_close(struct inp
{
struct steam_device *steam = input_get_drvdata(dev);
+ steam->device_open = 0;
mutex_lock(&steam->mutex);
if (!steam->client_opened && lizard_mode)
steam_set_lizard_mode(steam, true);
@@ -390,6 +432,62 @@ static int steam_battery_register(struct
return 0;
}
+static int steam_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
+{
+ struct steam_device *steam = input_get_drvdata(dev);
+ unsigned long flags;
+ u32 strong, weak;
+
+ if (effect->u.rumble.strong_magnitude == 0 && effect->u.rumble.weak_magnitude == 0)
+ return 0;
+
+ /* Steam uses a factor of 1.33 to the values. */
+ strong = (effect->u.rumble.strong_magnitude * 100ul) / 75;
+ weak = (effect->u.rumble.weak_magnitude * 100ul) / 75;
+
+ /* Clamp values to 16 bit */
+ if (strong > 0xffff)
+ strong = 0xffff;
+
+ if (weak > 0xffff)
+ weak = 0xffff;
+
+ spin_lock_irqsave(&steam->lock, flags);
+ steam->rumble_strong = strong;
+ steam->rumble_weak = weak;
+ spin_unlock_irqrestore(&steam->lock, flags);
+
+ schedule_work(&steam->work_effect);
+ return 0;
+}
+/**
+ * Prepares the command buffer for the rumble command.
+ * It is reverse-engineered from captured traces when using Steam's
+ * controller support.
+ */
+static void prepare_effect_buffer(u8 *buf,uint16_t strong, uint16_t weak)
+{
+ buf[0] = STEAM_CMD_RUMBLE;
+ buf[1] = 9;
+ buf[2] = 1;
+ buf[3] = 0x40;
+ buf[4] = 0x1f;
+ buf[5] = strong & 0xff;
+ buf[6] = strong >> 8;
+ buf[7] = weak & 0xff;
+ buf[8] = weak >> 8;
+}
+
+static void steam_play_effect_cb(struct work_struct *work)
+{
+ struct steam_device *steam = container_of(work, struct steam_device, work_effect);
+ u8 cmd_buf[9];
+ prepare_effect_buffer(cmd_buf, steam->rumble_strong, steam->rumble_weak);
+ mutex_lock(&steam->mutex);
+ steam_send_report(steam, cmd_buf, sizeof(cmd_buf));
+ mutex_unlock(&steam->mutex);
+}
+
static int steam_input_register(struct steam_device *steam)
{
struct hid_device *hdev = steam->hdev;
@@ -423,48 +521,107 @@ static int steam_input_register(struct s
input->id.product = hdev->product;
input->id.version = hdev->version;
- input_set_capability(input, EV_KEY, BTN_TR2);
- input_set_capability(input, EV_KEY, BTN_TL2);
- input_set_capability(input, EV_KEY, BTN_TR);
- input_set_capability(input, EV_KEY, BTN_TL);
- input_set_capability(input, EV_KEY, BTN_Y);
- input_set_capability(input, EV_KEY, BTN_B);
- input_set_capability(input, EV_KEY, BTN_X);
- input_set_capability(input, EV_KEY, BTN_A);
- input_set_capability(input, EV_KEY, BTN_DPAD_UP);
- input_set_capability(input, EV_KEY, BTN_DPAD_RIGHT);
- input_set_capability(input, EV_KEY, BTN_DPAD_LEFT);
- input_set_capability(input, EV_KEY, BTN_DPAD_DOWN);
- input_set_capability(input, EV_KEY, BTN_SELECT);
- input_set_capability(input, EV_KEY, BTN_MODE);
- input_set_capability(input, EV_KEY, BTN_START);
- input_set_capability(input, EV_KEY, BTN_GEAR_DOWN);
- input_set_capability(input, EV_KEY, BTN_GEAR_UP);
- input_set_capability(input, EV_KEY, BTN_THUMBR);
- input_set_capability(input, EV_KEY, BTN_THUMBL);
- input_set_capability(input, EV_KEY, BTN_THUMB);
- input_set_capability(input, EV_KEY, BTN_THUMB2);
-
- input_set_abs_params(input, ABS_HAT2Y, 0, 255, 0, 0);
- input_set_abs_params(input, ABS_HAT2X, 0, 255, 0, 0);
- input_set_abs_params(input, ABS_X, -32767, 32767, 0, 0);
- input_set_abs_params(input, ABS_Y, -32767, 32767, 0, 0);
- input_set_abs_params(input, ABS_RX, -32767, 32767,
- STEAM_PAD_FUZZ, 0);
- input_set_abs_params(input, ABS_RY, -32767, 32767,
- STEAM_PAD_FUZZ, 0);
- input_set_abs_params(input, ABS_HAT0X, -32767, 32767,
- STEAM_PAD_FUZZ, 0);
- input_set_abs_params(input, ABS_HAT0Y, -32767, 32767,
- STEAM_PAD_FUZZ, 0);
- input_abs_set_res(input, ABS_X, STEAM_JOYSTICK_RESOLUTION);
- input_abs_set_res(input, ABS_Y, STEAM_JOYSTICK_RESOLUTION);
- input_abs_set_res(input, ABS_RX, STEAM_PAD_RESOLUTION);
- input_abs_set_res(input, ABS_RY, STEAM_PAD_RESOLUTION);
- input_abs_set_res(input, ABS_HAT0X, STEAM_PAD_RESOLUTION);
- input_abs_set_res(input, ABS_HAT0Y, STEAM_PAD_RESOLUTION);
- input_abs_set_res(input, ABS_HAT2Y, STEAM_TRIGGER_RESOLUTION);
- input_abs_set_res(input, ABS_HAT2X, STEAM_TRIGGER_RESOLUTION);
+ if (!steam->steamdeck) {
+ input_set_capability(input, EV_KEY, BTN_TR2);
+ input_set_capability(input, EV_KEY, BTN_TL2);
+ input_set_capability(input, EV_KEY, BTN_TR);
+ input_set_capability(input, EV_KEY, BTN_TL);
+ input_set_capability(input, EV_KEY, BTN_Y);
+ input_set_capability(input, EV_KEY, BTN_B);
+ input_set_capability(input, EV_KEY, BTN_X);
+ input_set_capability(input, EV_KEY, BTN_A);
+ input_set_capability(input, EV_KEY, BTN_DPAD_UP);
+ input_set_capability(input, EV_KEY, BTN_DPAD_RIGHT);
+ input_set_capability(input, EV_KEY, BTN_DPAD_LEFT);
+ input_set_capability(input, EV_KEY, BTN_DPAD_DOWN);
+ input_set_capability(input, EV_KEY, BTN_SELECT);
+ input_set_capability(input, EV_KEY, BTN_MODE);
+ input_set_capability(input, EV_KEY, BTN_START);
+ input_set_capability(input, EV_KEY, BTN_GEAR_DOWN);
+ input_set_capability(input, EV_KEY, BTN_GEAR_UP);
+ input_set_capability(input, EV_KEY, BTN_THUMBR);
+ input_set_capability(input, EV_KEY, BTN_THUMBL);
+ input_set_capability(input, EV_KEY, BTN_THUMB);
+ input_set_capability(input, EV_KEY, BTN_THUMB2);
+
+ input_set_abs_params(input, ABS_HAT2Y, 0, 255, 0, 0);
+ input_set_abs_params(input, ABS_HAT2X, 0, 255, 0, 0);
+ input_set_abs_params(input, ABS_X, -32767, 32767, 0, 0);
+ input_set_abs_params(input, ABS_Y, -32767, 32767, 0, 0);
+ input_set_abs_params(input, ABS_RX, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_RY, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT0X, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT0Y, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_abs_set_res(input, ABS_X, STEAM_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_Y, STEAM_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_RX, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_RY, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT0X, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT0Y, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT2Y, STEAM_TRIGGER_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT2X, STEAM_TRIGGER_RESOLUTION);
+ } else {
+ input_set_capability(input, EV_KEY, BTN_TR2);
+ input_set_capability(input, EV_KEY, BTN_TL2);
+ input_set_capability(input, EV_KEY, BTN_TR);
+ input_set_capability(input, EV_KEY, BTN_TL);
+ input_set_capability(input, EV_KEY, BTN_Y);
+ input_set_capability(input, EV_KEY, BTN_B);
+ input_set_capability(input, EV_KEY, BTN_X);
+ input_set_capability(input, EV_KEY, BTN_A);
+ input_set_capability(input, EV_KEY, BTN_DPAD_UP);
+ input_set_capability(input, EV_KEY, BTN_DPAD_RIGHT);
+ input_set_capability(input, EV_KEY, BTN_DPAD_LEFT);
+ input_set_capability(input, EV_KEY, BTN_DPAD_DOWN);
+ input_set_capability(input, EV_KEY, BTN_SELECT);
+ input_set_capability(input, EV_KEY, BTN_MODE);
+ input_set_capability(input, EV_KEY, BTN_START);
+ input_set_capability(input, EV_KEY, BTN_GEAR_DOWN);
+ input_set_capability(input, EV_KEY, BTN_GEAR_UP);
+ input_set_capability(input, EV_KEY, BTN_THUMBR);
+ input_set_capability(input, EV_KEY, BTN_THUMBL);
+ input_set_capability(input, EV_KEY, BTN_THUMB);
+ input_set_capability(input, EV_KEY, BTN_THUMB2);
+ input_set_capability(input, EV_KEY, BTN_BASE);
+ input_set_capability(input, EV_KEY, BTN_BASE2);
+ input_set_capability(input, EV_KEY, BTN_MISC);
+
+ input_set_abs_params(input, ABS_Z, 0, 32767, 0, 0);
+ input_set_abs_params(input, ABS_RZ, 0, 32767, 0, 0);
+ input_set_abs_params(input, ABS_X, -32767, 32767, 0, 0);
+ input_set_abs_params(input, ABS_Y, -32767, 32767, 0, 0);
+ input_set_abs_params(input, ABS_RX, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_RY, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT0X, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT0Y, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT1X, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_set_abs_params(input, ABS_HAT1Y, -32767, 32767,
+ STEAM_PAD_FUZZ, 0);
+ input_abs_set_res(input, ABS_HAT0X, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT0Y, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT1X, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_HAT1Y, STEAM_PAD_RESOLUTION);
+ input_abs_set_res(input, ABS_X, STEAM_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_Y, STEAM_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_RX, STEAM_JOYSTICK_RESOLUTION);
+ input_abs_set_res(input, ABS_RY, STEAM_JOYSTICK_RESOLUTION);
+
+ input_abs_set_res(input, ABS_Z, STEAM_TRIGGER_RESOLUTION);
+ input_abs_set_res(input, ABS_RZ, STEAM_TRIGGER_RESOLUTION);
+
+
+ input_set_capability(input, EV_FF, FF_RUMBLE);
+ input_ff_create_memless(input, NULL, steam_play_effect);
+ }
ret = input_register_device(input);
if (ret)
@@ -670,6 +827,14 @@ static int steam_client_ll_raw_request(s
{
struct steam_device *steam = hdev->driver_data;
+ /*if (buf[1] != STEAM_CMD_CLEAR_MAPPINGS ) {
+ pr_info("Steam cmd=%x count=%x\n", buf[1], count);
+ for (size_t i = 0; i < count; i++) {
+ pr_cont("%x,",buf[i]);
+ if ((i+1) % 8 == 0)
+ pr_cont("\n");
+ }
+ }*/
return hid_hw_raw_request(steam->hdev, reportnum, buf, count,
report_type, reqtype);
}
@@ -743,12 +908,19 @@ static int steam_probe(struct hid_device
ret = -ENOMEM;
goto steam_alloc_fail;
}
+
+ if (id->product == USB_DEVICE_ID_STEAM_DECK_CONTROLLER) {
+ hid_info(hdev, "Steam Deck Controller connected\n");
+ steam->steamdeck = 1;
+ }
+
steam->hdev = hdev;
hid_set_drvdata(hdev, steam);
spin_lock_init(&steam->lock);
mutex_init(&steam->mutex);
steam->quirks = id->driver_data;
INIT_WORK(&steam->work_connect, steam_work_connect_cb);
+ INIT_WORK(&steam->work_effect, steam_play_effect_cb);
INIT_LIST_HEAD(&steam->list);
steam->client_hdev = steam_create_client_hid(hdev);
@@ -805,6 +977,7 @@ hid_hw_start_fail:
hid_destroy_device(steam->client_hdev);
client_hdev_fail:
cancel_work_sync(&steam->work_connect);
+ cancel_work_sync(&steam->work_effect);
steam_alloc_fail:
hid_err(hdev, "%s: failed with error %d\n",
__func__, ret);
@@ -823,6 +996,7 @@ static void steam_remove(struct hid_devi
hid_destroy_device(steam->client_hdev);
steam->client_opened = false;
cancel_work_sync(&steam->work_connect);
+ cancel_work_sync(&steam->work_effect);
if (steam->quirks & STEAM_QUIRK_WIRELESS) {
hid_info(hdev, "Steam wireless receiver disconnected");
}
@@ -993,6 +1167,78 @@ static void steam_do_input_event(struct
input_sync(input);
}
+static void steam_deck_do_input_event(struct steam_device *steam,
+ struct input_dev *input, u8 *data)
+{
+ /* 24 bits of buttons */
+ u8 b8, b9, b10, b11, b12, b13, b14;
+
+ b8 = data[8];
+ b9 = data[9];
+ b10 = data[10];
+ b11 = data[11];
+ b12 = data[12];
+ b13 = data[13];
+ b14 = data[14];
+
+ /* Left analog joystick */
+ input_report_abs(input, ABS_X, steam_le16(data + 48));
+ input_report_abs(input, ABS_Y, -steam_le16(data + 50));
+
+ /* Right analog joystick */
+ input_report_abs(input, ABS_RX, steam_le16(data + 52));
+ input_report_abs(input, ABS_RY, -steam_le16(data + 54));
+
+ /* Left touchpad */
+ input_report_abs(input, ABS_HAT0X, steam_le16(data + 16));
+ input_report_abs(input, ABS_HAT0Y, -steam_le16(data + 18));
+
+ /* Right touchpad */
+ input_report_abs(input, ABS_HAT1X, steam_le16(data + 20));
+ input_report_abs(input, ABS_HAT1Y, -steam_le16(data + 22));
+
+ /* Trigger */
+ input_report_abs(input, ABS_Z, steam_le16(data + 44));
+ input_report_abs(input, ABS_RZ, steam_le16(data + 46));
+
+ input_event(input, EV_KEY, BTN_TR2, !!(b8 & BIT(0)));
+ input_event(input, EV_KEY, BTN_TL2, !!(b8 & BIT(1)));
+ input_event(input, EV_KEY, BTN_TR, !!(b8 & BIT(2)));
+ input_event(input, EV_KEY, BTN_TL, !!(b8 & BIT(3)));
+ input_event(input, EV_KEY, BTN_SELECT, !!(b9 & BIT(4)));
+ input_event(input, EV_KEY, BTN_MODE, !!(b9 & BIT(5)));
+ input_event(input, EV_KEY, BTN_START, !!(b9 & BIT(6)));
+ input_event(input, EV_KEY, BTN_THUMBR, !!(b11 & BIT(2)));
+ input_event(input, EV_KEY, BTN_THUMBL, !!(b10 & BIT(6)));
+ input_event(input, EV_KEY, BTN_THUMB, !!(b10 & BIT(1)));
+ input_event(input, EV_KEY, BTN_THUMB2, !!(b10 & BIT(2)));
+
+ input_event(input, EV_KEY, BTN_SELECT, !!(b9 & BIT(4)));
+ input_event(input, EV_KEY, BTN_MODE, !!(b9 & BIT(5)));
+ input_event(input, EV_KEY, BTN_START, !!(b9 & BIT(6)));
+ input_event(input, EV_KEY, BTN_Y, !!(b8 & BIT(4)));
+ input_event(input, EV_KEY, BTN_B, !!(b8 & BIT(5)));
+ input_event(input, EV_KEY, BTN_X, !!(b8 & BIT(6)));
+ input_event(input, EV_KEY, BTN_A, !!(b8 & BIT(7)));
+ input_event(input, EV_KEY, BTN_DPAD_UP, !!(b9 & BIT(0)));
+ input_event(input, EV_KEY, BTN_DPAD_RIGHT, !!(b9 & BIT(1)));
+ input_event(input, EV_KEY, BTN_DPAD_LEFT, !!(b9 & BIT(2)));
+ input_event(input, EV_KEY, BTN_DPAD_DOWN, !!(b9 & BIT(3)));
+
+ /* Back button lower left L5 */
+ input_event(input, EV_KEY, BTN_GEAR_DOWN, !!(b9 & BIT(7)));
+ /* Back button lower right R5 */
+ input_event(input, EV_KEY, BTN_GEAR_UP, !!(b10 & BIT(0)));
+ /* Back button upper left L4 */
+ input_event(input, EV_KEY, BTN_BASE, !!(b13 & BIT(1)));
+ /* Back button upper right R4 */
+ input_event(input, EV_KEY, BTN_BASE2, !!(b13 & BIT(2)));
+
+ /* Menu botton right (3 dots) */
+ input_event(input, EV_KEY, BTN_MISC, !!(b14 & BIT(2)));
+ input_sync(input);
+}
+
/*
* The size for this message payload is 11.
* The known values are:
@@ -1054,10 +1300,21 @@ static int steam_raw_event(struct hid_de
* 0x04: battery status (11 bytes)
*/
- if (size != 64 || data[0] != 1 || data[1] != 0)
+ if (size != 64 || data[0] != 1 || data[1] != 0) {
+ hid_info(hdev, "Can_t use it\n");
return 0;
+ }
switch (data[2]) {
+ case STEAM_DECK_EV_INPUT_DATA:
+ if (steam->client_opened)
+ return 0;
+ rcu_read_lock();
+ input = rcu_dereference(steam->input);
+ if (likely(input))
+ steam_deck_do_input_event(steam, input, data);
+ rcu_read_unlock();
+ break;
case STEAM_EV_INPUT_DATA:
if (steam->client_opened)
return 0;
@@ -1136,6 +1393,10 @@ static const struct hid_device_id steam_
HID_USB_DEVICE(USB_VENDOR_ID_VALVE,
USB_DEVICE_ID_STEAM_CONTROLLER)
},
+ { /* Wired Steam Deck Controller */
+ HID_USB_DEVICE(USB_VENDOR_ID_VALVE,
+ USB_DEVICE_ID_STEAM_DECK_CONTROLLER)
+ },
{ /* Wireless Steam Controller */
HID_USB_DEVICE(USB_VENDOR_ID_VALVE,
USB_DEVICE_ID_STEAM_CONTROLLER_WIRELESS),