summaryrefslogtreecommitdiff
path: root/SOURCES/steam-deck.patch
diff options
context:
space:
mode:
Diffstat (limited to 'SOURCES/steam-deck.patch')
-rw-r--r--SOURCES/steam-deck.patch224
1 files changed, 112 insertions, 112 deletions
diff --git a/SOURCES/steam-deck.patch b/SOURCES/steam-deck.patch
index 395cdd3..9eba750 100644
--- a/SOURCES/steam-deck.patch
+++ b/SOURCES/steam-deck.patch
@@ -24,7 +24,7 @@ index 8b93856de432..af335d9150e9 100644
@@ -2260,5 +2260,16 @@ config MFD_RSMU_SPI
Additional drivers must be enabled in order to use the functionality
of the device.
-
+
+config MFD_STEAMDECK
+ tristate "Valve Steam Deck"
+ select MFD_CORE
@@ -206,7 +206,7 @@ index 7ac3daaf59ce..d784c78417cf 100644
@@ -1900,6 +1900,17 @@ config SENSORS_SCH5636
This driver can also be built as a module. If so, the module
will be called sch5636.
-
+
+config SENSORS_STEAMDECK
+ tristate "Steam Deck EC sensors"
+ depends on MFD_STEAMDECK
@@ -486,7 +486,7 @@ index 499d0f215a8b..d1d761695cd6 100644
@@ -864,6 +864,13 @@ config LEDS_ACER_A500
This option enables support for the Power Button LED of
Acer Iconia Tab A500.
-
+
+config LEDS_STEAMDECK
+ tristate "LED support for Steam Deck"
+ depends on LEDS_CLASS && MFD_STEAMDECK
@@ -495,7 +495,7 @@ index 499d0f215a8b..d1d761695cd6 100644
+ power button) on Steam Deck
+
source "drivers/leds/blink/Kconfig"
-
+
comment "Flash and Torch LED drivers"
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 4fd2f92cd198..130a1c175dde 100644
@@ -612,7 +612,7 @@ index 290186e44e6b..4d444a9e2c1f 100644
@@ -189,4 +189,11 @@ config EXTCON_USBC_TUSB320
Say Y here to enable support for USB Type C cable detection extcon
support using a TUSB320.
-
+
+config EXTCON_STEAMDECK
+ tristate "Steam Deck extcon support"
+ depends on MFD_STEAMDECK
@@ -840,7 +840,7 @@ index fab9e9460bd4..9d0a5471b181 100644
@@ -180,6 +180,76 @@ static const struct hwmon_chip_info steamdeck_hwmon_chip_info = {
.info = steamdeck_hwmon_info,
};
-
+
+
+static ssize_t
+steamdeck_hwmon_simple_store(struct device *dev, const char *buf, size_t count,
@@ -948,7 +948,7 @@ index 0e504b3c2796..a60fa7db9141 100644
@@ -41,9 +41,29 @@ struct steamdeck {
STEAMDECK_ATTR_RO(firmware_version, "PDFW");
STEAMDECK_ATTR_RO(board_id, "BOID");
-
+
+static ssize_t controller_board_power_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
@@ -1010,13 +1010,13 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
#include <linux/sched.h>
#include <linux/usb/g_hid.h>
+#include <uapi/linux/usb/g_hid.h>
-
+
#include "u_f.h"
#include "u_hid.h"
@@ -75,6 +76,13 @@ struct f_hidg {
wait_queue_head_t write_queue;
struct usb_request *req;
-
+
+ /* get report */
+ struct usb_request *get_req;
+ struct usb_hidg_report get_report;
@@ -1030,7 +1030,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
@@ -523,6 +531,64 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
return status;
}
-
+
+
+static int f_hidg_get_report(struct file *file, struct usb_hidg_report __user *buffer)
+{
@@ -1097,13 +1097,13 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
#undef READ_COND_SSREPORT
#undef READ_COND_INTOUT
+#undef GET_REPORT_COND
-
+
static int f_hidg_release(struct inode *inode, struct file *fd)
{
@@ -640,6 +707,10 @@ static void hidg_ssreport_complete(struct usb_ep *ep, struct usb_request *req)
wake_up(&hidg->read_queue);
}
-
+
+static void hidg_get_report_complete(struct usb_ep *ep, struct usb_request *req)
+{
+}
@@ -1118,7 +1118,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
+ unsigned long flags;
+ bool do_wake = false;
__u16 value, length;
-
+
value = __le16_to_cpu(ctrl->wValue);
@@ -659,14 +732,29 @@ static int hidg_setup(struct usb_function *f,
switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
@@ -1126,7 +1126,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
| HID_REQ_GET_REPORT):
- VDBG(cdev, "get_report\n");
+ VDBG(cdev, "get_report | wLength=%d\n", ctrl->wLength);
-
+
- /* send an empty report */
- length = min_t(unsigned, length, hidg->report_length);
- memset(req->buf, 0x0, length);
@@ -1137,7 +1137,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
+ if (status < 0) {
+ ERROR(cdev, "usb_ep_queue error on get_report %d\n",
+ status);
-
+
- goto respond;
- break;
+ spin_lock_irqsave(&hidg->get_spinlock, flags);
@@ -1153,11 +1153,11 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
+ }
+
+ return status;
-
+
case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
| HID_REQ_GET_PROTOCOL):
@@ -800,6 +888,14 @@ static void hidg_disable(struct usb_function *f)
-
+
hidg->req = NULL;
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
+
@@ -1169,7 +1169,7 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
+ hidg->get_req = NULL;
+ spin_unlock_irqrestore(&hidg->get_spinlock, flags);
}
-
+
static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
@@ -908,6 +1004,7 @@ static const struct file_operations f_hidg_fops = {
.write = f_hidg_write,
@@ -1178,11 +1178,11 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
+ .unlocked_ioctl = f_hidg_ioctl,
.llseek = noop_llseek,
};
-
+
@@ -918,6 +1015,14 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_string *us;
int status;
-
+
+ hidg->get_req = usb_ep_alloc_request(c->cdev->gadget->ep0, GFP_ATOMIC);
+ if (!hidg->get_req)
+ return -ENOMEM;
@@ -1203,17 +1203,17 @@ index ea85e2c701a15..6fec92b5a0bd9 100644
init_waitqueue_head(&hidg->read_queue);
+ init_waitqueue_head(&hidg->get_queue);
INIT_LIST_HEAD(&hidg->completed_out_req);
-
+
/* create char device */
@@ -1021,6 +1128,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
if (hidg->req != NULL)
free_ep_req(hidg->in_ep, hidg->req);
-
+
+ usb_ep_free_request(c->cdev->gadget->ep0, hidg->get_req);
+
return status;
}
-
+
diff --git a/include/uapi/linux/usb/g_hid.h b/include/uapi/linux/usb/g_hid.h
new file mode 100644
index 0000000000000..c6068b4863543
@@ -1264,14 +1264,14 @@ index 835473910a498..9754822b2a409 100644
+++ b/include/uapi/linux/usb/gadgetfs.h
@@ -62,7 +62,7 @@ struct usb_gadgetfs_event {
};
-
-
+
+
-/* The 'g' code is also used by printer gadget ioctl requests.
+/* The 'g' code is also used by printer and hid gadget ioctl requests.
* Don't add any colliding codes to either driver, and keep
* them in unique ranges (size 0x20 for now).
*/
---
+--
2.41.0
@@ -1306,7 +1306,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644
@@ -76,6 +76,11 @@ struct f_hidg {
wait_queue_head_t write_queue;
struct usb_request *req;
-
+
+ /* set report */
+ struct list_head completed_set_req;
+ spinlock_t set_spinlock;
@@ -1318,7 +1318,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644
@@ -531,6 +536,54 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
return status;
}
-
+
+static int f_hidg_set_report(struct file *file, struct usb_hidg_report __user *buffer)
+{
+ struct f_hidg *hidg = file->private_data;
@@ -1367,7 +1367,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644
+ free_ep_req(hidg->func.config->cdev->gadget->ep0, req);
+ return status;
+}
-
+
static int f_hidg_get_report(struct file *file, struct usb_hidg_report __user *buffer)
{
@@ -582,6 +635,8 @@ static int f_hidg_get_report(struct file *file, struct usb_hidg_report __user *b
@@ -1380,34 +1380,34 @@ index 6fec92b5a0bd9..172cba91aded1 100644
return f_hidg_get_report(file, (struct usb_hidg_report __user *)arg);
default:
@@ -596,6 +651,7 @@ static __poll_t f_hidg_poll(struct file *file, poll_table *wait)
-
+
poll_wait(file, &hidg->read_queue, wait);
poll_wait(file, &hidg->write_queue, wait);
+ poll_wait(file, &hidg->set_queue, wait);
-
+
if (WRITE_COND)
ret |= EPOLLOUT | EPOLLWRNORM;
@@ -608,12 +664,16 @@ static __poll_t f_hidg_poll(struct file *file, poll_table *wait)
ret |= EPOLLIN | EPOLLRDNORM;
}
-
+
+ if (SET_REPORT_COND)
+ ret |= EPOLLPRI;
+
return ret;
}
-
+
#undef WRITE_COND
#undef READ_COND_SSREPORT
#undef READ_COND_INTOUT
+#undef SET_REPORT_COND
#undef GET_REPORT_COND
-
+
static int f_hidg_release(struct inode *inode, struct file *fd)
@@ -658,11 +718,19 @@ static void hidg_intout_complete(struct usb_ep *ep, struct usb_request *req)
-
+
req_list->req = req;
-
+
- spin_lock_irqsave(&hidg->read_spinlock, flags);
- list_add_tail(&req_list->list, &hidg->completed_out_req);
- spin_unlock_irqrestore(&hidg->read_spinlock, flags);
@@ -1415,7 +1415,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644
+ spin_lock_irqsave(&hidg->set_spinlock, flags);
+ list_add_tail(&req_list->list, &hidg->completed_set_req);
+ spin_unlock_irqrestore(&hidg->set_spinlock, flags);
-
+
- wake_up(&hidg->read_queue);
+ wake_up(&hidg->set_queue);
+ } else {
@@ -1457,13 +1457,13 @@ index 6fec92b5a0bd9..172cba91aded1 100644
+ }
+
+ return status;
-
+
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
| HID_REQ_SET_PROTOCOL):
@@ -880,6 +963,14 @@ static void hidg_disable(struct usb_function *f)
spin_unlock_irqrestore(&hidg->read_spinlock, flags);
}
-
+
+ spin_lock_irqsave(&hidg->set_spinlock, flags);
+ list_for_each_entry_safe(list, next, &hidg->completed_set_req, list) {
+ free_ep_req(f->config->cdev->gadget->ep0, list->req);
@@ -1487,7 +1487,7 @@ index 6fec92b5a0bd9..172cba91aded1 100644
init_waitqueue_head(&hidg->get_queue);
INIT_LIST_HEAD(&hidg->completed_out_req);
+ INIT_LIST_HEAD(&hidg->completed_set_req);
-
+
/* create char device */
cdev_init(&hidg->cdev, &f_hidg_fops);
diff --git a/include/uapi/linux/usb/g_hid.h b/include/uapi/linux/usb/g_hid.h
@@ -1515,12 +1515,12 @@ index c6068b4863543..54814c2c68d60 100644
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
+
#ifndef __UAPI_LINUX_USB_G_HID_H
#define __UAPI_LINUX_USB_G_HID_H
-
+
#include <linux/types.h>
-
+
+#define HIDG_REPORT_SIZE_MAX 64
+
struct usb_hidg_report {
@@ -1528,16 +1528,16 @@ index c6068b4863543..54814c2c68d60 100644
- __u8 data[512];
+ __u8 data[HIDG_REPORT_SIZE_MAX];
};
-
+
/* The 'g' code is also used by gadgetfs and hid gadget ioctl requests.
* Don't add any colliding codes to either driver, and keep
* them in unique ranges (size 0x20 for now).
*/
+#define GADGET_HID_READ_SET_REPORT _IOR('g', 0x41, struct usb_hidg_report)
#define GADGET_HID_WRITE_GET_REPORT _IOW('g', 0x42, struct usb_hidg_report)
-
+
#endif /* __UAPI_LINUX_USB_G_HID_H */
---
+--
2.41.0
@@ -1562,7 +1562,7 @@ index b110818fc9458..39a9bf3b7f77d 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -71,7 +71,7 @@ static LIST_HEAD(steam_devices);
-
+
/*
* Commands that can be sent in a feature report.
- * Thanks to Valve for some valuable hints.
@@ -1618,7 +1618,7 @@ index b110818fc9458..39a9bf3b7f77d 100644
+#define STEAM_CMD_DONGLE_GET_CONN_SLOTS 0xc4
+#define STEAM_CMD_HAPTIC_CMD 0xea
#define STEAM_CMD_HAPTIC_RUMBLE 0xeb
-
+
/* Some useful register ids */
-#define STEAM_REG_LPAD_MODE 0x07
-#define STEAM_REG_RPAD_MODE 0x08
@@ -1679,13 +1679,13 @@ index b110818fc9458..39a9bf3b7f77d 100644
+#define STEAM_REG_SLEEP_INACTIVITY_TIMEOUT 0x32
+#define STEAM_REG_LEFT_TRACKPAD_CLICK_PRESSURE 0x34
+#define STEAM_REG_RIGHT_TRACKPAD_CLICK_PRESSURE 0x35
-
+
/* Raw event identifiers */
#define STEAM_EV_INPUT_DATA 0x01
@@ -108,13 +179,28 @@ static LIST_HEAD(steam_devices);
#define STEAM_EV_BATTERY 0x04
#define STEAM_EV_DECK_INPUT_DATA 0x09
-
+
+/* String attribute idenitifiers */
+#define STEAM_ATTRIB_STR_BOARD_SERIAL 0x00
+#define STEAM_ATTRIB_STR_UNIT_SERIAL 0x01
@@ -1714,7 +1714,7 @@ index b110818fc9458..39a9bf3b7f77d 100644
+#define STEAM_TRACKPAD_ABSOLUTE_DPAD 0x06
+#define STEAM_TRACKPAD_NONE 0x07
+#define STEAM_TRACKPAD_GESTURE_KEYBOARD 0x08
-
+
/* Other random constants */
#define STEAM_SERIAL_LEN 10
@@ -232,7 +318,7 @@ static int steam_write_registers(struct steam_device *steam,
@@ -1725,7 +1725,7 @@ index b110818fc9458..39a9bf3b7f77d 100644
+ u8 cmd[64] = {STEAM_CMD_SET_REGISTER, 0x00};
int ret;
va_list args;
-
+
@@ -268,7 +354,7 @@ static int steam_get_serial(struct steam_device *steam)
* Recv: 0xae 0x15 0x01 serialnumber (10 chars)
*/
@@ -1733,7 +1733,7 @@ index b110818fc9458..39a9bf3b7f77d 100644
- u8 cmd[] = {STEAM_CMD_GET_SERIAL, 0x15, 0x01};
+ u8 cmd[] = {STEAM_CMD_GET_STRING_ATTRIB, 0x15, STEAM_ATTRIB_STR_UNIT_SERIAL};
u8 reply[3 + STEAM_SERIAL_LEN + 1];
-
+
ret = steam_send_report(steam, cmd, sizeof(cmd));
@@ -277,7 +363,7 @@ static int steam_get_serial(struct steam_device *steam)
ret = steam_recv_report(steam, reply, sizeof(reply));
@@ -1751,7 +1751,7 @@ index b110818fc9458..39a9bf3b7f77d 100644
- return steam_send_report_byte(steam, STEAM_CMD_REQUEST_COMM_STATUS);
+ return steam_send_report_byte(steam, STEAM_CMD_DONGLE_GET_STATE);
}
-
+
static inline int steam_haptic_rumble(struct steam_device *steam,
@@ -339,9 +425,9 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
/* enable esc, enter, cursors */
@@ -1763,10 +1763,10 @@ index b110818fc9458..39a9bf3b7f77d 100644
- STEAM_REG_RPAD_MARGIN, 0x01, /* enable margin */
+ STEAM_REG_SMOOTH_ABSOLUTE_MOUSE, 0x01, /* enable smooth */
0);
-
+
cancel_delayed_work_sync(&steam->heartbeat);
@@ -351,11 +437,11 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
-
+
if (steam->quirks & STEAM_QUIRK_DECK) {
steam_write_registers(steam,
- STEAM_REG_RPAD_MARGIN, 0x00, /* disable margin */
@@ -1804,7 +1804,7 @@ index b110818fc9458..39a9bf3b7f77d 100644
0);
schedule_delayed_work(&steam->heartbeat, 5 * HZ);
}
---
+--
2.41.0
@@ -1826,7 +1826,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644
@@ -202,6 +202,11 @@ static LIST_HEAD(steam_devices);
#define STEAM_TRACKPAD_NONE 0x07
#define STEAM_TRACKPAD_GESTURE_KEYBOARD 0x08
-
+
+/* Pad identifiers for the deck */
+#define STEAM_PAD_LEFT 0
+#define STEAM_PAD_RIGHT 1
@@ -1834,7 +1834,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644
+
/* Other random constants */
#define STEAM_SERIAL_LEN 10
-
+
@@ -221,6 +226,9 @@ struct steam_device {
u8 battery_charge;
u16 voltage;
@@ -1848,7 +1848,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644
@@ -380,6 +388,33 @@ static inline int steam_request_conn_status(struct steam_device *steam)
return steam_send_report_byte(steam, STEAM_CMD_DONGLE_GET_STATE);
}
-
+
+/*
+ * Send a haptic pulse to the trackpads
+ * Duration and interval are measured in microseconds, count is the number
@@ -1880,7 +1880,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644
u16 intensity, u16 left_speed, u16 right_speed,
u8 left_gain, u8 right_gain)
@@ -421,6 +456,9 @@ static int steam_play_effect(struct input_dev *dev, void *data,
-
+
static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
{
+ if (steam->gamepad_mode)
@@ -1892,7 +1892,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644
@@ -805,6 +843,29 @@ static void steam_work_connect_cb(struct work_struct *work)
}
}
-
+
+static void steam_mode_switch_cb(struct work_struct *work)
+{
+ struct steam_device *steam = container_of(to_delayed_work(work),
@@ -1945,7 +1945,7 @@ index 39a9bf3b7f77d..0620046b142ef 100644
}
@@ -1393,6 +1457,14 @@ static void steam_do_deck_input_event(struct steam_device *steam,
input_event(input, EV_KEY, BTN_BASE, !!(b14 & BIT(2)));
-
+
input_sync(input);
+
+ if (!(b9 & BIT(6)) && steam->did_mode_switch) {
@@ -1956,9 +1956,9 @@ index 39a9bf3b7f77d..0620046b142ef 100644
+ schedule_delayed_work(&steam->mode_switch, 45 * HZ / 100);
+ }
}
-
+
/*
---
+--
2.41.0
@@ -2000,7 +2000,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
+ int ret = 0;
u8 cmd[] = {STEAM_CMD_GET_STRING_ATTRIB, 0x15, STEAM_ATTRIB_STR_UNIT_SERIAL};
u8 reply[3 + STEAM_SERIAL_LEN + 1];
-
+
+ mutex_lock(&steam->report_mutex);
ret = steam_send_report(steam, cmd, sizeof(cmd));
if (ret < 0)
@@ -2023,7 +2023,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
+ mutex_unlock(&steam->report_mutex);
+ return ret;
}
-
+
/*
@@ -385,7 +390,11 @@ static int steam_get_serial(struct steam_device *steam)
*/
@@ -2036,7 +2036,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
+ mutex_unlock(&steam->report_mutex);
+ return ret;
}
-
+
/*
@@ -397,6 +406,7 @@ static inline int steam_request_conn_status(struct steam_device *steam)
static inline int steam_haptic_pulse(struct steam_device *steam, u8 pad,
@@ -2044,42 +2044,42 @@ index 0620046b142ef..845ca71b8bd3a 100644
{
+ int ret;
u8 report[10] = {STEAM_CMD_HAPTIC_PULSE, 8};
-
+
/* Left and right are swapped on this report for legacy reasons */
@@ -412,13 +422,17 @@ static inline int steam_haptic_pulse(struct steam_device *steam, u8 pad,
report[8] = count >> 8;
report[9] = gain;
-
+
- return steam_send_report(steam, report, sizeof(report));
+ mutex_lock(&steam->report_mutex);
+ ret = steam_send_report(steam, report, sizeof(report));
+ mutex_unlock(&steam->report_mutex);
+ return ret;
}
-
+
static inline int steam_haptic_rumble(struct steam_device *steam,
u16 intensity, u16 left_speed, u16 right_speed,
u8 left_gain, u8 right_gain)
{
+ int ret;
u8 report[11] = {STEAM_CMD_HAPTIC_RUMBLE, 9};
-
+
report[3] = intensity & 0xFF;
@@ -430,7 +444,10 @@ static inline int steam_haptic_rumble(struct steam_device *steam,
report[9] = left_gain;
report[10] = right_gain;
-
+
- return steam_send_report(steam, report, sizeof(report));
+ mutex_lock(&steam->report_mutex);
+ ret = steam_send_report(steam, report, sizeof(report));
+ mutex_unlock(&steam->report_mutex);
+ return ret;
}
-
+
static void steam_haptic_rumble_cb(struct work_struct *work)
@@ -460,6 +477,7 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
enable = false;
-
+
if (enable) {
+ mutex_lock(&steam->report_mutex);
/* enable esc, enter, cursors */
@@ -2090,13 +2090,13 @@ index 0620046b142ef..845ca71b8bd3a 100644
STEAM_REG_SMOOTH_ABSOLUTE_MOUSE, 0x01, /* enable smooth */
0);
+ mutex_unlock(&steam->report_mutex);
-
+
cancel_delayed_work_sync(&steam->heartbeat);
} else {
+ mutex_lock(&steam->report_mutex);
/* disable esc, enter, cursor */
steam_send_report_byte(steam, STEAM_CMD_CLEAR_MAPPINGS);
-
+
@@ -481,18 +501,19 @@ static void steam_set_lizard_mode(struct steam_device *steam, bool enable)
STEAM_REG_LEFT_TRACKPAD_CLICK_PRESSURE, 0xFFFF, /* disable clicky pad */
STEAM_REG_RIGHT_TRACKPAD_CLICK_PRESSURE, 0xFFFF, /* disable clicky pad */
@@ -2125,7 +2125,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
struct steam_device *steam = input_get_drvdata(dev);
+ unsigned long flags;
+ bool set_lizard_mode;
-
+
- mutex_lock(&steam->mutex);
- if (!steam->client_opened && lizard_mode)
+ spin_lock_irqsave(&steam->lock, flags);
@@ -2137,13 +2137,13 @@ index 0620046b142ef..845ca71b8bd3a 100644
+
return 0;
}
-
+
static void steam_input_close(struct input_dev *dev)
{
struct steam_device *steam = input_get_drvdata(dev);
+ unsigned long flags;
+ bool set_lizard_mode;
-
+
- mutex_lock(&steam->mutex);
- if (!steam->client_opened && lizard_mode)
+ spin_lock_irqsave(&steam->lock, flags);
@@ -2153,14 +2153,14 @@ index 0620046b142ef..845ca71b8bd3a 100644
steam_set_lizard_mode(steam, true);
- mutex_unlock(&steam->mutex);
}
-
+
static enum power_supply_property steam_battery_props[] = {
@@ -760,6 +788,7 @@ static int steam_register(struct steam_device *steam)
{
int ret;
bool client_opened;
+ unsigned long flags;
-
+
/*
* This function can be called several times in a row with the
@@ -772,11 +801,9 @@ static int steam_register(struct steam_device *steam)
@@ -2172,13 +2172,13 @@ index 0620046b142ef..845ca71b8bd3a 100644
strscpy(steam->serial_no, "XXXXXXXXXX",
sizeof(steam->serial_no));
- mutex_unlock(&steam->mutex);
-
+
hid_info(steam->hdev, "Steam Controller '%s' connected",
steam->serial_no);
@@ -791,11 +818,11 @@ static int steam_register(struct steam_device *steam)
mutex_unlock(&steam_devices_lock);
}
-
+
- mutex_lock(&steam->mutex);
+ spin_lock_irqsave(&steam->lock, flags);
client_opened = steam->client_opened;
@@ -2186,7 +2186,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
if (!client_opened)
steam_set_lizard_mode(steam, lizard_mode);
- mutex_unlock(&steam->mutex);
-
+
if (!client_opened)
ret = steam_input_register(steam);
@@ -847,16 +874,21 @@ static void steam_mode_switch_cb(struct work_struct *work)
@@ -2198,7 +2198,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
steam->gamepad_mode = !steam->gamepad_mode;
if (!lizard_mode)
return;
-
+
- mutex_lock(&steam->mutex);
if (steam->gamepad_mode)
steam_set_lizard_mode(steam, false);
@@ -2212,7 +2212,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
+ if (!client_opened)
+ steam_set_lizard_mode(steam, lizard_mode);
+ }
-
+
steam_haptic_pulse(steam, STEAM_PAD_RIGHT, 0x190, 0, 1, 0);
if (steam->gamepad_mode) {
@@ -889,16 +921,21 @@ static void steam_lizard_mode_heartbeat(struct work_struct *work)
@@ -2221,7 +2221,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
heartbeat.work);
+ bool client_opened;
+ unsigned long flags;
-
+
- mutex_lock(&steam->mutex);
- if (!steam->client_opened && steam->client_hdev) {
+ spin_lock_irqsave(&steam->lock, flags);
@@ -2238,37 +2238,37 @@ index 0620046b142ef..845ca71b8bd3a 100644
}
- mutex_unlock(&steam->mutex);
}
-
+
static int steam_client_ll_parse(struct hid_device *hdev)
@@ -921,10 +958,11 @@ static void steam_client_ll_stop(struct hid_device *hdev)
static int steam_client_ll_open(struct hid_device *hdev)
{
struct steam_device *steam = hdev->driver_data;
+ unsigned long flags;
-
+
- mutex_lock(&steam->mutex);
+ spin_lock_irqsave(&steam->lock, flags);
steam->client_opened = true;
- mutex_unlock(&steam->mutex);
+ spin_unlock_irqrestore(&steam->lock, flags);
-
+
steam_input_unregister(steam);
-
+
@@ -939,14 +977,12 @@ static void steam_client_ll_close(struct hid_device *hdev)
bool connected;
-
+
spin_lock_irqsave(&steam->lock, flags);
- connected = steam->connected;
+ steam->client_opened = false;
+ connected = steam->connected && !steam->client_opened;
spin_unlock_irqrestore(&steam->lock, flags);
-
+
- mutex_lock(&steam->mutex);
- steam->client_opened = false;
if (connected)
steam_set_lizard_mode(steam, lizard_mode);
- mutex_unlock(&steam->mutex);
-
+
if (connected)
steam_input_register(steam);
@@ -1035,7 +1071,7 @@ static int steam_probe(struct hid_device *hdev,
@@ -2283,7 +2283,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
@@ -1043,13 +1079,6 @@ static int steam_probe(struct hid_device *hdev,
INIT_DEFERRABLE_WORK(&steam->heartbeat, steam_lizard_mode_heartbeat);
INIT_WORK(&steam->rumble_work, steam_haptic_rumble_cb);
-
+
- steam->client_hdev = steam_create_client_hid(hdev);
- if (IS_ERR(steam->client_hdev)) {
- ret = PTR_ERR(steam->client_hdev);
@@ -2297,7 +2297,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
@@ -1058,10 +1087,6 @@ static int steam_probe(struct hid_device *hdev,
if (ret)
goto hid_hw_start_fail;
-
+
- ret = hid_add_device(steam->client_hdev);
- if (ret)
- goto client_hdev_add_fail;
@@ -2308,7 +2308,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
@@ -1087,15 +1112,26 @@ static int steam_probe(struct hid_device *hdev,
}
}
-
+
+ steam->client_hdev = steam_create_client_hid(hdev);
+ if (IS_ERR(steam->client_hdev)) {
+ ret = PTR_ERR(steam->client_hdev);
@@ -2321,7 +2321,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
+ goto client_hdev_add_fail;
+
return 0;
-
+
-input_register_fail:
-hid_hw_open_fail:
client_hdev_add_fail:
@@ -2339,7 +2339,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
@@ -1115,14 +1151,12 @@ static void steam_remove(struct hid_device *hdev)
return;
}
-
+
+ cancel_delayed_work_sync(&steam->heartbeat);
+ cancel_delayed_work_sync(&steam->mode_switch);
+ cancel_work_sync(&steam->work_connect);
@@ -2355,7 +2355,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
hid_info(hdev, "Steam wireless receiver disconnected");
}
@@ -1597,10 +1631,8 @@ static int steam_param_set_lizard_mode(const char *val,
-
+
mutex_lock(&steam_devices_lock);
list_for_each_entry(steam, &steam_devices, list) {
- mutex_lock(&steam->mutex);
@@ -2365,7 +2365,7 @@ index 0620046b142ef..845ca71b8bd3a 100644
}
mutex_unlock(&steam_devices_lock);
return 0;
---
+--
2.41.0
@@ -2405,26 +2405,26 @@ index 845ca71b8bd3a..0c2fe51b29bc1 100644
- bool client_opened;
+ unsigned long client_opened;
unsigned long flags;
-
+
/*
@@ -961,7 +961,7 @@ static int steam_client_ll_open(struct hid_device *hdev)
unsigned long flags;
-
+
spin_lock_irqsave(&steam->lock, flags);
- steam->client_opened = true;
+ steam->client_opened++;
spin_unlock_irqrestore(&steam->lock, flags);
-
+
steam_input_unregister(steam);
@@ -977,7 +977,7 @@ static void steam_client_ll_close(struct hid_device *hdev)
bool connected;
-
+
spin_lock_irqsave(&steam->lock, flags);
- steam->client_opened = false;
+ steam->client_opened--;
connected = steam->connected && !steam->client_opened;
spin_unlock_irqrestore(&steam->lock, flags);
-
+
@@ -1156,7 +1156,7 @@ static void steam_remove(struct hid_device *hdev)
cancel_work_sync(&steam->work_connect);
hid_destroy_device(steam->client_hdev);
@@ -2434,7 +2434,7 @@ index 845ca71b8bd3a..0c2fe51b29bc1 100644
if (steam->quirks & STEAM_QUIRK_WIRELESS) {
hid_info(hdev, "Steam wireless receiver disconnected");
}
---
+--
2.41.0
@@ -2458,11 +2458,11 @@ index 0c2fe51b29bc1..92e3e1052fa42 100644
+++ b/drivers/hid/hid-steam.c
@@ -208,7 +208,7 @@ static LIST_HEAD(steam_devices);
#define STEAM_PAD_BOTH 2
-
+
/* Other random constants */
-#define STEAM_SERIAL_LEN 10
+#define STEAM_SERIAL_LEN 0x15
-
+
struct steam_device {
struct list_head list;
@@ -359,10 +359,10 @@ static int steam_get_serial(struct steam_device *steam)
@@ -2476,7 +2476,7 @@ index 0c2fe51b29bc1..92e3e1052fa42 100644
- u8 cmd[] = {STEAM_CMD_GET_STRING_ATTRIB, 0x15, STEAM_ATTRIB_STR_UNIT_SERIAL};
+ u8 cmd[] = {STEAM_CMD_GET_STRING_ATTRIB, sizeof(steam->serial_no), STEAM_ATTRIB_STR_UNIT_SERIAL};
u8 reply[3 + STEAM_SERIAL_LEN + 1];
-
+
mutex_lock(&steam->report_mutex);
@@ -372,12 +372,12 @@ static int steam_get_serial(struct steam_device *steam)
ret = steam_recv_report(steam, reply, sizeof(reply));
@@ -2493,5 +2493,5 @@ index 0c2fe51b29bc1..92e3e1052fa42 100644
out:
mutex_unlock(&steam->report_mutex);
return ret;
---
+--
2.41.0