Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Wacom protocol 4 serial tablet driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright 2014      Hans de Goede <hdegoede@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright 2011-2012 Julian Squires <julian@cipht.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Many thanks to Bill Seremetis, without whom PenPartner support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * would not have been possible. Thanks to Patrick Mahoney.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * This driver was developed with reference to much code written by others,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * particularly:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *  - elo, gunze drivers by Vojtech Pavlik <vojtech@ucw.cz>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *  - wacom_w8001 driver by Jaya Kumar <jayakumar.lkml@gmail.com>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *  - the USB wacom input driver, credited to many people
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *    (see drivers/input/tablet/wacom.h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *  - new and old versions of linuxwacom / xf86-input-wacom credited to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *    Frederic Lepied, France. <Lepied@XFree86.org> and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *    Ping Cheng, Wacom. <pingc@wacom.com>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *  - and xf86wacom.c (a presumably ancient version of the linuxwacom code),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *    by Frederic Lepied and Raph Levien <raph@gtk.org>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * To do:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *  - support pad buttons; (requires access to a model with pad buttons)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *  - support (protocol 4-style) tilt (requires access to a > 1.4 rom model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * Wacom serial protocol 4 documentation taken from linuxwacom-0.9.9 code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * protocol 4 uses 7 or 9 byte of data in the following format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *	Byte 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *	bit 7  Sync bit always 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *	bit 6  Pointing device detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *	bit 5  Cursor = 0 / Stylus = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *	bit 4  Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *	bit 3  1 if a button on the pointing device has been pressed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *	bit 2  P0 (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *	bit 1  X15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *	bit 0  X14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *	Byte 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  *	bit 7  Always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  *	bits 6-0 = X13 - X7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  *	Byte 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  *	bit 7  Always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  *	bits 6-0 = X6 - X0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  *	Byte 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  *	bit 7  Always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *	bit 6  B3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  *	bit 5  B2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *	bit 4  B1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *	bit 3  B0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *	bit 2  P1 (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *	bit 1  Y15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *	bit 0  Y14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  *	Byte 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  *	bit 7  Always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  *	bits 6-0 = Y13 - Y7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  *	Byte 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  *	bit 7  Always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  *	bits 6-0 = Y6 - Y0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *	Byte 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  *	bit 7 Always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  *	bit 6  Sign of pressure data; or wheel-rel for cursor tool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *	bit 5  P7; or REL1 for cursor tool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  *	bit 4  P6; or REL0 for cursor tool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *	bit 3  P5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  *	bit 2  P4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  *	bit 1  P3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  *	bit 0  P2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  *	byte 8 and 9 are optional and present only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  *	in tilt mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  *	Byte 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  *	bit 7 Always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  *	bit 6 Sign of tilt X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *	bit 5  Xt6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *	bit 4  Xt5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  *	bit 3  Xt4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *	bit 2  Xt3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *	bit 1  Xt2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  *	bit 0  Xt1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  *	Byte 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  *	bit 7 Always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  *	bit 6 Sign of tilt Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  *	bit 5  Yt6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  *	bit 4  Yt5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  *	bit 3  Yt4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  *	bit 2  Yt3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  *	bit 1  Yt2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  *	bit 0  Yt1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #include <linux/serio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) MODULE_AUTHOR("Julian Squires <julian@cipht.net>, Hans de Goede <hdegoede@redhat.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) MODULE_DESCRIPTION("Wacom protocol 4 serial tablet driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define REQUEST_MODEL_AND_ROM_VERSION	"~#"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define REQUEST_MAX_COORDINATES		"~C\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define REQUEST_CONFIGURATION_STRING	"~R\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define REQUEST_RESET_TO_PROTOCOL_IV	"\r#"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * Note: sending "\r$\r" causes at least the Digitizer II to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * packets in ASCII instead of binary.  "\r#" seems to undo that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define COMMAND_START_SENDING_PACKETS		"ST\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define COMMAND_STOP_SENDING_PACKETS		"SP\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define COMMAND_MULTI_MODE_INPUT		"MU1\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define COMMAND_ORIGIN_IN_UPPER_LEFT		"OC1\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define COMMAND_ENABLE_ALL_MACRO_BUTTONS	"~M0\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define COMMAND_DISABLE_GROUP_1_MACRO_BUTTONS	"~M1\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define COMMAND_TRANSMIT_AT_MAX_RATE		"IT0\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define COMMAND_DISABLE_INCREMENTAL_MODE	"IN0\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define COMMAND_ENABLE_CONTINUOUS_MODE		"SR\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define COMMAND_ENABLE_PRESSURE_MODE		"PH1\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define COMMAND_Z_FILTER			"ZF1\r"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* Note that this is a protocol 4 packet without tilt information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define PACKET_LENGTH		7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define DATA_SIZE		32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define F_COVERS_SCREEN		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define F_HAS_STYLUS2		0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define F_HAS_SCROLLWHEEL	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* device IDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define STYLUS_DEVICE_ID	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define CURSOR_DEVICE_ID	0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define ERASER_DEVICE_ID	0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) enum { STYLUS = 1, ERASER, CURSOR };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	int device_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	int input_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) } tools[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	{ 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	{ STYLUS_DEVICE_ID, BTN_TOOL_PEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	{ ERASER_DEVICE_ID, BTN_TOOL_RUBBER },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	{ CURSOR_DEVICE_ID, BTN_TOOL_MOUSE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct wacom {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct input_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	struct completion cmd_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	u8 expect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	u8 eraser_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	unsigned int extra_z_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	unsigned int res_x, res_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	unsigned int max_x, max_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	unsigned int tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	u8 data[DATA_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	char phys[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	MODEL_CINTIQ		= 0x504C, /* PL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	MODEL_CINTIQ2		= 0x4454, /* DT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	MODEL_DIGITIZER_II	= 0x5544, /* UD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	MODEL_GRAPHIRE		= 0x4554, /* ET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	MODEL_PENPARTNER	= 0x4354, /* CT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	MODEL_ARTPAD_II		= 0x4B54, /* KT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static void wacom_handle_model_response(struct wacom *wacom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	int major_v, minor_v, r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	p = strrchr(wacom->data, 'V');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		r = sscanf(p + 1, "%u.%u", &major_v, &minor_v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	if (r != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		major_v = minor_v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	switch (wacom->data[2] << 8 | wacom->data[3]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	case MODEL_CINTIQ:	/* UNTESTED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	case MODEL_CINTIQ2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		if ((wacom->data[2] << 8 | wacom->data[3]) == MODEL_CINTIQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			wacom->dev->name = "Wacom Cintiq";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			wacom->dev->id.version = MODEL_CINTIQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			wacom->dev->name = "Wacom Cintiq II";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			wacom->dev->id.version = MODEL_CINTIQ2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		wacom->res_x = 508;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		wacom->res_y = 508;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		switch (wacom->data[5] << 8 | wacom->data[6]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		case 0x3731: /* PL-710 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			wacom->res_x = 2540;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			wacom->res_y = 2540;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		case 0x3535: /* PL-550 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		case 0x3830: /* PL-800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			wacom->extra_z_bits = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		wacom->flags = F_COVERS_SCREEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	case MODEL_PENPARTNER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		wacom->dev->name = "Wacom Penpartner";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		wacom->dev->id.version = MODEL_PENPARTNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		wacom->res_x = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		wacom->res_y = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	case MODEL_GRAPHIRE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		wacom->dev->name = "Wacom Graphire";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		wacom->dev->id.version = MODEL_GRAPHIRE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		wacom->res_x = 1016;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		wacom->res_y = 1016;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		wacom->max_x = 5103;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		wacom->max_y = 3711;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		wacom->extra_z_bits = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		wacom->eraser_mask = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		wacom->flags = F_HAS_STYLUS2 | F_HAS_SCROLLWHEEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	case MODEL_ARTPAD_II:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	case MODEL_DIGITIZER_II:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		wacom->dev->name = "Wacom Digitizer II";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		wacom->dev->id.version = MODEL_DIGITIZER_II;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		if (major_v == 1 && minor_v <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			wacom->extra_z_bits = 0; /* UNTESTED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		dev_err(&wacom->dev->dev, "Unsupported Wacom model %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			wacom->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		wacom->result = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	dev_info(&wacom->dev->dev, "%s tablet, version %u.%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		 wacom->dev->name, major_v, minor_v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void wacom_handle_configuration_response(struct wacom *wacom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	int r, skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	dev_dbg(&wacom->dev->dev, "Configuration string: %s\n", wacom->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	r = sscanf(wacom->data, "~R%x,%u,%u,%u,%u", &skip, &skip, &skip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		   &wacom->res_x, &wacom->res_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	if (r != 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		dev_warn(&wacom->dev->dev, "could not get resolution\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static void wacom_handle_coordinates_response(struct wacom *wacom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	dev_dbg(&wacom->dev->dev, "Coordinates string: %s\n", wacom->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	r = sscanf(wacom->data, "~C%u,%u", &wacom->max_x, &wacom->max_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (r != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		dev_warn(&wacom->dev->dev, "could not get max coordinates\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static void wacom_handle_response(struct wacom *wacom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	if (wacom->data[0] != '~' || wacom->data[1] != wacom->expect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		dev_err(&wacom->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			"Wacom got an unexpected response: %s\n", wacom->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		wacom->result = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		wacom->result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		switch (wacom->data[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		case '#':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 			wacom_handle_model_response(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		case 'R':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 			wacom_handle_configuration_response(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		case 'C':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			wacom_handle_coordinates_response(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	complete(&wacom->cmd_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void wacom_handle_packet(struct wacom *wacom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	u8 in_proximity_p, stylus_p, button;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	unsigned int tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	int x, y, z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	in_proximity_p = wacom->data[0] & 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	stylus_p = wacom->data[0] & 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	button = (wacom->data[3] & 0x78) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	x = (wacom->data[0] & 3) << 14 | wacom->data[1]<<7 | wacom->data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	y = (wacom->data[3] & 3) << 14 | wacom->data[4]<<7 | wacom->data[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	if (in_proximity_p && stylus_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		z = wacom->data[6] & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		if (wacom->extra_z_bits >= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			z = z << 1 | (wacom->data[3] & 0x4) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		if (wacom->extra_z_bits > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			z = z << 1 | (wacom->data[0] & 0x4) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		z = z ^ (0x40 << wacom->extra_z_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		z = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	if (stylus_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		tool = (button & wacom->eraser_mask) ? ERASER : STYLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		tool = CURSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (tool != wacom->tool && wacom->tool != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		input_report_key(wacom->dev, tools[wacom->tool].input_id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		input_sync(wacom->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	wacom->tool = tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	input_report_key(wacom->dev, tools[tool].input_id, in_proximity_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	input_report_abs(wacom->dev, ABS_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			 in_proximity_p ? tools[tool].device_id : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	input_report_abs(wacom->dev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	input_report_abs(wacom->dev, ABS_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	input_report_abs(wacom->dev, ABS_PRESSURE, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	if (stylus_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		input_report_key(wacom->dev, BTN_TOUCH, button & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		input_report_key(wacom->dev, BTN_STYLUS, button & 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		input_report_key(wacom->dev, BTN_STYLUS2, button & 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		input_report_key(wacom->dev, BTN_LEFT, button & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		input_report_key(wacom->dev, BTN_RIGHT, button & 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		input_report_key(wacom->dev, BTN_MIDDLE, button & 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		/* handle relative wheel for non-stylus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		z = (wacom->data[6] & 0x30) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		if (wacom->data[6] & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			z = -z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		input_report_rel(wacom->dev, REL_WHEEL, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	input_sync(wacom->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static void wacom_clear_data_buf(struct wacom *wacom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	memset(wacom->data, 0, DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	wacom->idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static irqreturn_t wacom_interrupt(struct serio *serio, unsigned char data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 				   unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	struct wacom *wacom = serio_get_drvdata(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	if (data & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		wacom->idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	 * We're either expecting a carriage return-terminated ASCII
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	 * response string, or a seven-byte packet with the MSB set on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	 * the first byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	 * Note however that some tablets (the PenPartner, for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	 * example) don't send a carriage return at the end of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	 * command.  We handle these by waiting for timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	if (data == '\r' && !(wacom->data[0] & 0x80)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		wacom_handle_response(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		wacom_clear_data_buf(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	/* Leave place for 0 termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	if (wacom->idx > (DATA_SIZE - 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		dev_dbg(&wacom->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			"throwing away %d bytes of garbage\n", wacom->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		wacom_clear_data_buf(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	wacom->data[wacom->idx++] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (wacom->idx == PACKET_LENGTH && (wacom->data[0] & 0x80)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		wacom_handle_packet(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		wacom_clear_data_buf(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static void wacom_disconnect(struct serio *serio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	struct wacom *wacom = serio_get_drvdata(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	serio_close(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	serio_set_drvdata(serio, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	input_unregister_device(wacom->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	kfree(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static int wacom_send(struct serio *serio, const u8 *command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	for (; !err && *command; command++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		err = serio_write(serio, *command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static int wacom_send_setup_string(struct wacom *wacom, struct serio *serio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	const u8 *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	switch (wacom->dev->id.version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	case MODEL_CINTIQ:	/* UNTESTED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		cmd = COMMAND_ORIGIN_IN_UPPER_LEFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			COMMAND_TRANSMIT_AT_MAX_RATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			COMMAND_ENABLE_CONTINUOUS_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			COMMAND_START_SENDING_PACKETS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	case MODEL_PENPARTNER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		cmd = COMMAND_ENABLE_PRESSURE_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 			COMMAND_START_SENDING_PACKETS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		cmd = COMMAND_MULTI_MODE_INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 			COMMAND_ORIGIN_IN_UPPER_LEFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			COMMAND_ENABLE_ALL_MACRO_BUTTONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			COMMAND_DISABLE_GROUP_1_MACRO_BUTTONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			COMMAND_TRANSMIT_AT_MAX_RATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			COMMAND_DISABLE_INCREMENTAL_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			COMMAND_ENABLE_CONTINUOUS_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			COMMAND_Z_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			COMMAND_START_SENDING_PACKETS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	return wacom_send(serio, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static int wacom_send_and_wait(struct wacom *wacom, struct serio *serio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			       const u8 *cmd, const char *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	unsigned long u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	wacom->expect = cmd[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	init_completion(&wacom->cmd_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	err = wacom_send(serio, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	u = wait_for_completion_timeout(&wacom->cmd_done, HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	if (u == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		/* Timeout, process what we've received. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		wacom_handle_response(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	wacom->expect = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	return wacom->result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static int wacom_setup(struct wacom *wacom, struct serio *serio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	/* Note that setting the link speed is the job of inputattach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	 * We assume that reset negotiation has already happened,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	 * here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	err = wacom_send_and_wait(wacom, serio, REQUEST_MODEL_AND_ROM_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 				  "model and version");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	if (!(wacom->res_x && wacom->res_y)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		err = wacom_send_and_wait(wacom, serio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 					  REQUEST_CONFIGURATION_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 					  "configuration string");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	if (!(wacom->max_x && wacom->max_y)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		err = wacom_send_and_wait(wacom, serio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 					  REQUEST_MAX_COORDINATES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 					  "coordinates string");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	return wacom_send_setup_string(wacom, serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static int wacom_connect(struct serio *serio, struct serio_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	struct wacom *wacom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	input_dev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	if (!wacom || !input_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		goto free_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	wacom->dev = input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	wacom->extra_z_bits = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	wacom->eraser_mask = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	wacom->tool = wacom->idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	snprintf(wacom->phys, sizeof(wacom->phys), "%s/input0", serio->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	input_dev->phys = wacom->phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	input_dev->id.bustype = BUS_RS232;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	input_dev->id.vendor  = SERIO_WACOM_IV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	input_dev->id.product = serio->id.extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	input_dev->dev.parent = &serio->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	input_dev->evbit[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | BIT_MASK(EV_REL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	set_bit(ABS_MISC, input_dev->absbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	set_bit(BTN_TOOL_PEN, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	set_bit(BTN_TOUCH, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	set_bit(BTN_STYLUS, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	set_bit(BTN_LEFT, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	set_bit(BTN_RIGHT, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	set_bit(BTN_MIDDLE, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	serio_set_drvdata(serio, wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	err = serio_open(serio, drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		goto free_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	err = wacom_setup(wacom, serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		goto close_serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	if (!(wacom->flags & F_COVERS_SCREEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	if (wacom->flags & F_HAS_STYLUS2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		__set_bit(BTN_STYLUS2, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	if (wacom->flags & F_HAS_SCROLLWHEEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		__set_bit(REL_WHEEL, input_dev->relbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	input_abs_set_res(wacom->dev, ABS_X, wacom->res_x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	input_abs_set_res(wacom->dev, ABS_Y, wacom->res_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	input_set_abs_params(wacom->dev, ABS_X, 0, wacom->max_x, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	input_set_abs_params(wacom->dev, ABS_Y, 0, wacom->max_y, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	input_set_abs_params(wacom->dev, ABS_PRESSURE, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 			     (1 << (7 + wacom->extra_z_bits)) - 1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	err = input_register_device(wacom->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		goto close_serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) close_serio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	serio_close(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) free_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	serio_set_drvdata(serio, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	input_free_device(input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	kfree(wacom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static const struct serio_device_id wacom_serio_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		.type	= SERIO_RS232,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		.proto	= SERIO_WACOM_IV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		.id	= SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		.extra	= SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	{ 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) MODULE_DEVICE_TABLE(serio, wacom_serio_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static struct serio_driver wacom_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		.name	= "wacom_serial4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	.description	= "Wacom protocol 4 serial tablet driver",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	.id_table	= wacom_serio_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	.interrupt	= wacom_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	.connect	= wacom_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	.disconnect	= wacom_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) module_serio_driver(wacom_drv);