Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b41f79e7 authored by Roderick Colenbrander's avatar Roderick Colenbrander Committed by Kishor Krishna Bhat
Browse files

TREAM: HID: playstation: Track devices in list



Track devices in a list, so we can detect when a device is connected
twice when using Bluetooth and USB.

Bug: 167947264
CRs-fixed: 2971837
Change-Id: Ibfa0e5b3821891240545f484f1ceb59b211cb6fb
Signed-off-by: default avatarRoderick Colenbrander <roderick.colenbrander@sony.com>
Reviewed-by: default avatarBarnabás Pőcze <pobrn@protonmail.com>
Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarFarid Chahla <farid.chahla@sony.com>
Signed-off-by: default avatarSiarhei Vishniakou <svv@google.com>
Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git


Git-commit: 53f04e83577c5e146eeee1a671efeb58db14afd1
Signed-off-by: default avatarKishor Krishna Bhat <kishkris@codeaurora.org>
parent 871a7a9a
Loading
Loading
Loading
Loading
+46 −0
Original line number Original line Diff line number Diff line
@@ -15,10 +15,15 @@


#include "hid-ids.h"
#include "hid-ids.h"


/* List of connected playstation devices. */
static DEFINE_MUTEX(ps_devices_lock);
static LIST_HEAD(ps_devices_list);

#define HID_PLAYSTATION_VERSION_PATCH 0x8000
#define HID_PLAYSTATION_VERSION_PATCH 0x8000


/* Base class for playstation devices. */
/* Base class for playstation devices. */
struct ps_device {
struct ps_device {
	struct list_head list;
	struct hid_device *hdev;
	struct hid_device *hdev;
	spinlock_t lock;
	spinlock_t lock;


@@ -137,6 +142,38 @@ static const struct {int x; int y; } ps_gamepad_hat_mapping[] = {
	{0, 0},
	{0, 0},
};
};


/*
 * Add a new ps_device to ps_devices if it doesn't exist.
 * Return error on duplicate device, which can happen if the same
 * device is connected using both Bluetooth and USB.
 */
static int ps_devices_list_add(struct ps_device *dev)
{
	struct ps_device *entry;

	mutex_lock(&ps_devices_lock);
	list_for_each_entry(entry, &ps_devices_list, list) {
		if (!memcmp(entry->mac_address, dev->mac_address, sizeof(dev->mac_address))) {
			hid_err(dev->hdev, "Duplicate device found for MAC address %pMR.\n",
					dev->mac_address);
			mutex_unlock(&ps_devices_lock);
			return -EEXIST;
		}
	}

	list_add_tail(&dev->list, &ps_devices_list);
	mutex_unlock(&ps_devices_lock);
	return 0;
}

static int ps_devices_list_remove(struct ps_device *dev)
{
	mutex_lock(&ps_devices_lock);
	list_del(&dev->list);
	mutex_unlock(&ps_devices_lock);
	return 0;
}

static struct input_dev *ps_allocate_input_dev(struct hid_device *hdev, const char *name_suffix)
static struct input_dev *ps_allocate_input_dev(struct hid_device *hdev, const char *name_suffix)
{
{
	struct input_dev *input_dev;
	struct input_dev *input_dev;
@@ -519,6 +556,10 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
	}
	}
	snprintf(hdev->uniq, sizeof(hdev->uniq), "%pMR", ds->base.mac_address);
	snprintf(hdev->uniq, sizeof(hdev->uniq), "%pMR", ds->base.mac_address);


	ret = ps_devices_list_add(ps_dev);
	if (ret)
		return ERR_PTR(ret);

	ds->gamepad = ps_gamepad_create(hdev);
	ds->gamepad = ps_gamepad_create(hdev);
	if (IS_ERR(ds->gamepad)) {
	if (IS_ERR(ds->gamepad)) {
		ret = PTR_ERR(ds->gamepad);
		ret = PTR_ERR(ds->gamepad);
@@ -538,6 +579,7 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
	return &ds->base;
	return &ds->base;


err:
err:
	ps_devices_list_remove(ps_dev);
	return ERR_PTR(ret);
	return ERR_PTR(ret);
}
}


@@ -595,6 +637,10 @@ static int ps_probe(struct hid_device *hdev, const struct hid_device_id *id)


static void ps_remove(struct hid_device *hdev)
static void ps_remove(struct hid_device *hdev)
{
{
	struct ps_device *dev = hid_get_drvdata(hdev);

	ps_devices_list_remove(dev);

	hid_hw_close(hdev);
	hid_hw_close(hdev);
	hid_hw_stop(hdev);
	hid_hw_stop(hdev);
}
}