Commit 24dd3b58 authored by Xing Wei's avatar Xing Wei Committed by Dmitry Torokhov
Browse files

Input: hanwang - make compatible with xf86-input-wacom driver



Add necessary events so that Hanwang Art Master III tablet can be handled
by the stock xf86-input-wacom driver.

Signed-off-by: default avatarXing Wei <weixing@hanwang.com.cn>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 33d5f713
Loading
Loading
Loading
Loading
+33 −4
Original line number Diff line number Diff line
@@ -44,6 +44,13 @@ MODULE_LICENSE(DRIVER_LICENSE);

#define ART_MASTERIII_PKGLEN_MAX	10

/* device IDs */
#define STYLUS_DEVICE_ID	0x02
#define TOUCH_DEVICE_ID		0x03
#define CURSOR_DEVICE_ID	0x06
#define ERASER_DEVICE_ID	0x0A
#define PAD_DEVICE_ID		0x0F

/* match vendor and interface info  */
#define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \
	.match_flags = USB_DEVICE_ID_MATCH_VENDOR \
@@ -61,6 +68,7 @@ struct hanwang {
	struct urb *irq;
	const struct hanwang_features *features;
	unsigned int current_tool;
	unsigned int current_id;
	char name[64];
	char phys[32];
};
@@ -86,16 +94,22 @@ static const struct hanwang_features features_array[] = {
};

static const int hw_eventtypes[] = {
	EV_KEY, EV_ABS,
	EV_KEY, EV_ABS, EV_MSC,
};

static const int hw_absevents[] = {
	ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL, ABS_PRESSURE,
	ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL,
	ABS_PRESSURE, ABS_MISC,
};

static const int hw_btnevents[] = {
	BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_MOUSE,
	BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8
	BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER,
	BTN_TOOL_MOUSE, BTN_TOOL_FINGER,
	BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8,
};

static const int hw_mscevents[] = {
	MSC_SERIAL,
};

static void hanwang_parse_packet(struct hanwang *hanwang)
@@ -109,20 +123,24 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
	case 0x02:	/* data packet */
		switch (data[1]) {
		case 0x80:	/* tool prox out */
			hanwang->current_id = 0;
			input_report_key(input_dev, hanwang->current_tool, 0);
			break;

		case 0xc2:	/* first time tool prox in */
			switch (data[3] & 0xf0) {
			case 0x20:
				hanwang->current_id = STYLUS_DEVICE_ID;
				hanwang->current_tool = BTN_TOOL_PEN;
				input_report_key(input_dev, BTN_TOOL_PEN, 1);
				break;
			case 0xa0:
				hanwang->current_id = ERASER_DEVICE_ID;
				hanwang->current_tool = BTN_TOOL_RUBBER;
				input_report_key(input_dev, BTN_TOOL_RUBBER, 1);
				break;
			default:
				hanwang->current_id = 0;
				dev_dbg(&dev->dev,
					"unknown tablet tool %02x ", data[0]);
				break;
@@ -144,15 +162,23 @@ static void hanwang_parse_packet(struct hanwang *hanwang)
			input_report_key(input_dev, BTN_STYLUS2, data[1] & 0x04);
			break;
		}
		input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
		input_event(input_dev, EV_MSC, MSC_SERIAL,
				hanwang->features->pid);
		break;

	case 0x0c:
		/* roll wheel */
		hanwang->current_id = PAD_DEVICE_ID;
		input_report_key(input_dev, BTN_TOOL_FINGER, data[1] ||
						data[2] || data[3]);
		input_report_abs(input_dev, ABS_WHEEL, data[1]);
		input_report_key(input_dev, BTN_0, data[2]);
		for (i = 0; i < 8; i++)
			input_report_key(input_dev,
					 BTN_1 + i, data[3] & (1 << i));
		input_report_abs(input_dev, ABS_MISC, hanwang->current_id);
		input_event(input_dev, EV_MSC, MSC_SERIAL, 0xffffffff);
		break;

	default:
@@ -287,6 +313,9 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id
	for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i)
		__set_bit(hw_btnevents[i], input_dev->keybit);

	for (i = 0; i < ARRAY_SIZE(hw_mscevents); ++i)
		__set_bit(hw_mscevents[i], input_dev->mscbit);

	input_set_abs_params(input_dev, ABS_X,
			     0, hanwang->features->max_x, 4, 0);
	input_set_abs_params(input_dev, ABS_Y,