drivers/input/joydev.c

Source file repositories/reference/linux-study-clean/drivers/input/joydev.c

File Facts

System
Linux kernel
Corpus path
drivers/input/joydev.c
Extension
.c
Size
27045 bytes
Lines
1098
Domain
Driver Families
Bucket
drivers/input
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations joydev_fops = {
	.owner		= THIS_MODULE,
	.read		= joydev_read,
	.poll		= joydev_poll,
	.open		= joydev_open,
	.release	= joydev_release,
	.unlocked_ioctl	= joydev_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= joydev_compat_ioctl,
#endif
	.fasync		= joydev_fasync,
};

/*
 * Mark device non-existent. This disables writes, ioctls and
 * prevents new users from opening the device. Already posted
 * blocking reads will stay, however new ones will fail.
 */
static void joydev_mark_dead(struct joydev *joydev)
{
	mutex_lock(&joydev->mutex);
	joydev->exist = false;
	mutex_unlock(&joydev->mutex);
}

static void joydev_cleanup(struct joydev *joydev)
{
	struct input_handle *handle = &joydev->handle;

	joydev_mark_dead(joydev);
	joydev_hangup(joydev);

	/* joydev is marked dead so no one else accesses joydev->open */
	if (joydev->open)
		input_close_device(handle);
}

/*
 * These codes are copied from hid-ids.h, unfortunately there is no common
 * usb_ids/bt_ids.h header.
 */
#define USB_VENDOR_ID_SONY			0x054c
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER		0x0268
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER		0x05c4
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2		0x09cc
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE	0x0ba0

#define USB_VENDOR_ID_THQ			0x20d6
#define USB_DEVICE_ID_THQ_PS3_UDRAW			0xcb17

#define USB_VENDOR_ID_NINTENDO		0x057e
#define USB_DEVICE_ID_NINTENDO_JOYCONL	0x2006
#define USB_DEVICE_ID_NINTENDO_JOYCONR	0x2007
#define USB_DEVICE_ID_NINTENDO_PROCON	0x2009
#define USB_DEVICE_ID_NINTENDO_CHRGGRIP	0x200E

#define ACCEL_DEV(vnd, prd)						\
	{								\
		.flags = INPUT_DEVICE_ID_MATCH_VENDOR |			\
				INPUT_DEVICE_ID_MATCH_PRODUCT |		\
				INPUT_DEVICE_ID_MATCH_PROPBIT,		\
		.vendor = (vnd),					\
		.product = (prd),					\
		.propbit = { BIT_MASK(INPUT_PROP_ACCELEROMETER) },	\
	}

static const struct input_device_id joydev_blacklist[] = {
	/* Avoid touchpads and touchscreens */
	{
		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
				INPUT_DEVICE_ID_MATCH_KEYBIT,
		.evbit = { BIT_MASK(EV_KEY) },
		.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
	},
	/* Avoid tablets, digitisers and similar devices */
	{
		.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
				INPUT_DEVICE_ID_MATCH_KEYBIT,
		.evbit = { BIT_MASK(EV_KEY) },
		.keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
	},
	/* Disable accelerometers on composite devices */
	ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
	ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
	ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
	ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE),
	ACCEL_DEV(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW),
	ACCEL_DEV(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_PROCON),
	ACCEL_DEV(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_CHRGGRIP),
	ACCEL_DEV(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_JOYCONL),

Annotation

Implementation Notes