diff mbox series

[5/6] HID: hid-sony: Add touchpad_mouse param

Message ID 20220427224526.35657-5-vi@endrift.com
State New
Headers show
Series [1/6] HID: hid-playstation: Allow removal of touchpad | expand

Commit Message

Vicki Pfau April 27, 2022, 10:45 p.m. UTC
Add parameter "touchpad_mouse" to enable disabling or re-enabling exposing the
touchpad input_dev, which can be changed while the module is loaded.

Signed-off-by: Vicki Pfau <vi@endrift.com>
---
 drivers/hid/hid-sony.c | 49 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 41 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 1c347b3ca992..c4ccad95ee9a 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -98,6 +98,8 @@  static const char ghl_ps3wiiu_magic_data[] = {
 	0x02, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
+static bool touchpad_mouse = true;
+
 /* PS/3 Motion controller */
 static u8 motion_rdesc[] = {
 	0x05, 0x01,         /*  Usage Page (Desktop),               */
@@ -525,7 +527,7 @@  struct motion_output_report_02 {
 #define SIXAXIS_INPUT_REPORT_ACC_X_OFFSET 41
 #define SIXAXIS_ACC_RES_PER_G 113
 
-static DEFINE_SPINLOCK(sony_dev_list_lock);
+static DEFINE_MUTEX(sony_dev_list_lock);
 static LIST_HEAD(sony_device_list);
 static DEFINE_IDA(sony_device_id_allocator);
 
@@ -1670,6 +1672,9 @@  static int sony_register_ds4_touchpad(struct sony_sc *sc)
 	struct input_dev *touchpad;
 	int ret;
 
+	if (!touchpad_mouse)
+		return 0;
+
 	rcu_read_lock();
 	touchpad = rcu_dereference(sc->touchpad);
 	rcu_read_unlock();
@@ -2599,10 +2604,9 @@  static inline int sony_compare_connection_type(struct sony_sc *sc0,
 static int sony_check_add_dev_list(struct sony_sc *sc)
 {
 	struct sony_sc *entry;
-	unsigned long flags;
 	int ret;
 
-	spin_lock_irqsave(&sony_dev_list_lock, flags);
+	mutex_lock(&sony_dev_list_lock);
 
 	list_for_each_entry(entry, &sony_device_list, list_node) {
 		ret = memcmp(sc->mac_address, entry->mac_address,
@@ -2624,18 +2628,16 @@  static int sony_check_add_dev_list(struct sony_sc *sc)
 	list_add(&(sc->list_node), &sony_device_list);
 
 unlock:
-	spin_unlock_irqrestore(&sony_dev_list_lock, flags);
+	mutex_unlock(&sony_dev_list_lock);
 	return ret;
 }
 
 static void sony_remove_dev_list(struct sony_sc *sc)
 {
-	unsigned long flags;
-
 	if (sc->list_node.next) {
-		spin_lock_irqsave(&sony_dev_list_lock, flags);
+		mutex_lock(&sony_dev_list_lock);
 		list_del(&(sc->list_node));
-		spin_unlock_irqrestore(&sony_dev_list_lock, flags);
+		mutex_unlock(&sony_dev_list_lock);
 	}
 }
 
@@ -3171,6 +3173,37 @@  static int sony_resume(struct hid_device *hdev)
 
 #endif
 
+static int sony_param_set_touchpad_mouse(const char *val,
+					const struct kernel_param *kp)
+{
+	struct sony_sc *sc;
+	int ret;
+
+	ret = param_set_bool(val, kp);
+	if (ret)
+		return ret;
+
+	mutex_lock(&sony_dev_list_lock);
+	list_for_each_entry(sc, &sony_device_list, list_node) {
+		mutex_lock(&sc->mutex);
+		if (touchpad_mouse)
+			sony_register_ds4_touchpad(sc);
+		else
+			sony_unregister_touchpad(sc);
+		mutex_unlock(&sc->mutex);
+	}
+	mutex_unlock(&sony_dev_list_lock);
+	return 0;
+}
+
+static const struct kernel_param_ops sony_touchpad_mouse_ops = {
+	.set	= sony_param_set_touchpad_mouse,
+	.get	= param_get_bool,
+};
+
+module_param_cb(touchpad_mouse, &sony_touchpad_mouse_ops, &touchpad_mouse, 0644);
+MODULE_PARM_DESC(touchpad_mouse, "Enable mouse emulation using the touchpad");
+
 static const struct hid_device_id sony_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
 		.driver_data = SIXAXIS_CONTROLLER_USB },