drivers/hid/hid-udraw-ps3.c

Source file repositories/reference/linux-study-clean/drivers/hid/hid-udraw-ps3.c

File Facts

System
Linux kernel
Corpus path
drivers/hid/hid-udraw-ps3.c
Extension
.c
Size
11580 bytes
Lines
467
Domain
Driver Families
Bucket
drivers/hid
Inferred role
Driver Families: implementation source
Status
source 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

struct udraw {
	struct input_dev *joy_input_dev;
	struct input_dev *touch_input_dev;
	struct input_dev *pen_input_dev;
	struct input_dev *accel_input_dev;
	struct hid_device *hdev;

	/*
	 * The device's two-finger support is pretty unreliable, as
	 * the device could report a single touch when the two fingers
	 * are too close together, and the distance between fingers, even
	 * though reported is not in the same unit as the touches.
	 *
	 * We'll make do without it, and try to report the first touch
	 * as reliably as possible.
	 */
	int last_one_finger_x;
	int last_one_finger_y;
	int last_two_finger_x;
	int last_two_finger_y;
};

static int clamp_accel(int axis, int offset)
{
	axis = clamp(axis,
			accel_limits[offset].min,
			accel_limits[offset].max);
	axis = (axis - accel_limits[offset].min) /
			((accel_limits[offset].max -
			  accel_limits[offset].min) * 0xFF);
	return axis;
}

static int udraw_raw_event(struct hid_device *hdev, struct hid_report *report,
	 u8 *data, int len)
{
	struct udraw *udraw = hid_get_drvdata(hdev);
	int touch;
	int x, y, z;

	if (len != 27)
		return 0;

	if (data[11] == 0x00)
		touch = TOUCH_NONE;
	else if (data[11] == 0x40)
		touch = TOUCH_PEN;
	else if (data[11] == 0x80)
		touch = TOUCH_FINGER;
	else
		touch = TOUCH_TWOFINGER;

	/* joypad */
	input_report_key(udraw->joy_input_dev, BTN_WEST, data[0] & 1);
	input_report_key(udraw->joy_input_dev, BTN_SOUTH, !!(data[0] & 2));
	input_report_key(udraw->joy_input_dev, BTN_EAST, !!(data[0] & 4));
	input_report_key(udraw->joy_input_dev, BTN_NORTH, !!(data[0] & 8));

	input_report_key(udraw->joy_input_dev, BTN_SELECT, !!(data[1] & 1));
	input_report_key(udraw->joy_input_dev, BTN_START, !!(data[1] & 2));
	input_report_key(udraw->joy_input_dev, BTN_MODE, !!(data[1] & 16));

	x = y = 0;
	switch (data[2]) {
	case 0x0:
		y = -127;
		break;
	case 0x1:
		y = -127;
		x = 127;
		break;
	case 0x2:
		x = 127;
		break;
	case 0x3:
		y = 127;
		x = 127;
		break;
	case 0x4:
		y = 127;
		break;
	case 0x5:
		y = 127;
		x = -127;
		break;
	case 0x6:
		x = -127;
		break;
	case 0x7:
		y = -127;

Annotation

Implementation Notes