// SPDX-License-Identifier: GPL-2.0-or-later /* * Wacom protocol 4 serial tablet driver * * Copyright 2014 Hans de Goede <[email protected]> * Copyright 2011-2012 Julian Squires <[email protected]> * * Many thanks to Bill Seremetis, without whom PenPartner support * would not have been possible. Thanks to Patrick Mahoney. * * This driver was developed with reference to much code written by others, * particularly: * - elo, gunze drivers by Vojtech Pavlik <[email protected]>; * - wacom_w8001 driver by Jaya Kumar <[email protected]>; * - the USB wacom input driver, credited to many people * (see drivers/input/tablet/wacom.h); * - new and old versions of linuxwacom / xf86-input-wacom credited to * Frederic Lepied, France. <[email protected]> and * Ping Cheng, Wacom. <[email protected]>; * - and xf86wacom.c (a presumably ancient version of the linuxwacom code), * by Frederic Lepied and Raph Levien <[email protected]>. * * To do: * - support pad buttons; (requires access to a model with pad buttons) * - support (protocol 4-style) tilt (requires access to a > 1.4 rom model) */ /* * Wacom serial protocol 4 documentation taken from linuxwacom-0.9.9 code, * protocol 4 uses 7 or 9 byte of data in the following format: * * Byte 1 * bit 7 Sync bit always 1 * bit 6 Pointing device detected * bit 5 Cursor = 0 / Stylus = 1 * bit 4 Reserved * bit 3 1 if a button on the pointing device has been pressed * bit 2 P0 (optional) * bit 1 X15 * bit 0 X14 * * Byte 2 * bit 7 Always 0 * bits 6-0 = X13 - X7 * * Byte 3 * bit 7 Always 0 * bits 6-0 = X6 - X0 * * Byte 4 * bit 7 Always 0 * bit 6 B3 * bit 5 B2 * bit 4 B1 * bit 3 B0 * bit 2 P1 (optional) * bit 1 Y15 * bit 0 Y14 * * Byte 5 * bit 7 Always 0 * bits 6-0 = Y13 - Y7 * * Byte 6 * bit 7 Always 0 * bits 6-0 = Y6 - Y0 * * Byte 7 * bit 7 Always 0 * bit 6 Sign of pressure data; or wheel-rel for cursor tool * bit 5 P7; or REL1 for cursor tool * bit 4 P6; or REL0 for cursor tool * bit 3 P5 * bit 2 P4 * bit 1 P3 * bit 0 P2 * * byte 8 and 9 are optional and present only * in tilt mode. * * Byte 8 * bit 7 Always 0 * bit 6 Sign of tilt X * bit 5 Xt6 * bit 4 Xt5 * bit 3 Xt4 * bit 2 Xt3 * bit 1 Xt2 * bit 0 Xt1 * * Byte 9 * bit 7 Always 0 * bit 6 Sign of tilt Y * bit 5 Yt6 * bit 4 Yt5 * bit 3 Yt4 * bit 2 Yt3 * bit 1 Yt2 * bit 0 Yt1 */ #include <linux/completion.h> #include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/serio.h> #include <linux/slab.h> #include <linux/string.h> MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; #define REQUEST_MODEL_AND_ROM_VERSION … #define REQUEST_MAX_COORDINATES … #define REQUEST_CONFIGURATION_STRING … #define REQUEST_RESET_TO_PROTOCOL_IV … /* * Note: sending "\r$\r" causes at least the Digitizer II to send * packets in ASCII instead of binary. "\r#" seems to undo that. */ #define COMMAND_START_SENDING_PACKETS … #define COMMAND_STOP_SENDING_PACKETS … #define COMMAND_MULTI_MODE_INPUT … #define COMMAND_ORIGIN_IN_UPPER_LEFT … #define COMMAND_ENABLE_ALL_MACRO_BUTTONS … #define COMMAND_DISABLE_GROUP_1_MACRO_BUTTONS … #define COMMAND_TRANSMIT_AT_MAX_RATE … #define COMMAND_DISABLE_INCREMENTAL_MODE … #define COMMAND_ENABLE_CONTINUOUS_MODE … #define COMMAND_ENABLE_PRESSURE_MODE … #define COMMAND_Z_FILTER … /* Note that this is a protocol 4 packet without tilt information. */ #define PACKET_LENGTH … #define DATA_SIZE … /* flags */ #define F_COVERS_SCREEN … #define F_HAS_STYLUS2 … #define F_HAS_SCROLLWHEEL … /* device IDs */ #define STYLUS_DEVICE_ID … #define CURSOR_DEVICE_ID … #define ERASER_DEVICE_ID … enum { … }; static const struct { … } tools[] = …; struct wacom { … }; enum { … }; static void wacom_handle_model_response(struct wacom *wacom) { … } static void wacom_handle_configuration_response(struct wacom *wacom) { … } static void wacom_handle_coordinates_response(struct wacom *wacom) { … } static void wacom_handle_response(struct wacom *wacom) { … } static void wacom_handle_packet(struct wacom *wacom) { … } static void wacom_clear_data_buf(struct wacom *wacom) { … } static irqreturn_t wacom_interrupt(struct serio *serio, unsigned char data, unsigned int flags) { … } static void wacom_disconnect(struct serio *serio) { … } static int wacom_send(struct serio *serio, const u8 *command) { … } static int wacom_send_setup_string(struct wacom *wacom, struct serio *serio) { … } static int wacom_send_and_wait(struct wacom *wacom, struct serio *serio, const u8 *cmd, const char *desc) { … } static int wacom_setup(struct wacom *wacom, struct serio *serio) { … } static int wacom_connect(struct serio *serio, struct serio_driver *drv) { … } static const struct serio_device_id wacom_serio_ids[] = …; MODULE_DEVICE_TABLE(serio, wacom_serio_ids); static struct serio_driver wacom_drv = …; module_serio_driver(…) …;