// SPDX-License-Identifier: GPL-2.0-or-later /* * Wacom protocol 4 serial tablet driver * * Copyright 2014 Hans de Goede <hdegoede@redhat.com> * Copyright 2011-2012 Julian Squires <julian@cipht.net> * * 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 <vojtech@ucw.cz>; * - wacom_w8001 driver by Jaya Kumar <jayakumar.lkml@gmail.com>; * - 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. <Lepied@XFree86.org> and * Ping Cheng, Wacom. <pingc@wacom.com>; * - and xf86wacom.c (a presumably ancient version of the linuxwacom code), * by Frederic Lepied and Raph Levien <raph@gtk.org>. * * 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
*/
MODULE_AUTHOR("Julian Squires , Hans de Goede ");
MODULE_DESCRIPTION("Wacom protocol 4 serial tablet driver");
MODULE_LICENSE("GPL");
#define REQUEST_MODEL_AND_ROM_VERSION "~#" #define REQUEST_MAX_COORDINATES "~C\r" #define REQUEST_CONFIGURATION_STRING "~R\r" #define REQUEST_RESET_TO_PROTOCOL_IV "\r#" /* * Note: sending "\r$\r" causes at least the Digitizer II to send * packets in ASCII instead of binary. "\r#" seems to undo that.
*/
dev_info(&wacom->dev->dev, "%s tablet, version %u.%u\n",
wacom->dev->name, major_v, minor_v);
}
staticvoid wacom_handle_configuration_response(struct wacom *wacom)
{ int r, skip;
dev_dbg(&wacom->dev->dev, "Configuration string: %s\n", wacom->data);
r = sscanf(wacom->data, "~R%x,%u,%u,%u,%u", &skip, &skip, &skip,
&wacom->res_x, &wacom->res_y); if (r != 5)
dev_warn(&wacom->dev->dev, "could not get resolution\n");
}
staticvoid wacom_handle_coordinates_response(struct wacom *wacom)
{ int r;
dev_dbg(&wacom->dev->dev, "Coordinates string: %s\n", wacom->data);
r = sscanf(wacom->data, "~C%u,%u", &wacom->max_x, &wacom->max_y); if (r != 2)
dev_warn(&wacom->dev->dev, "could not get max coordinates\n");
}
if (in_proximity_p && stylus_p) {
z = wacom->data[6] & 0x7f; if (wacom->extra_z_bits >= 1)
z = z << 1 | (wacom->data[3] & 0x4) >> 2; if (wacom->extra_z_bits > 1)
z = z << 1 | (wacom->data[0] & 0x4) >> 2;
z = z ^ (0x40 << wacom->extra_z_bits);
} else {
z = -1;
}
/* * We're either expecting a carriage return-terminated ASCII * response string, or a seven-byte packet with the MSB set on * the first byte. * * Note however that some tablets (the PenPartner, for * example) don't send a carriage return at the end of a * command. We handle these by waiting for timeout.
*/ if (data == '\r' && !(wacom->data[0] & 0x80)) {
wacom_handle_response(wacom);
wacom_clear_data_buf(wacom); return IRQ_HANDLED;
}
/* Leave place for 0 termination */ if (wacom->idx > (DATA_SIZE - 2)) {
dev_dbg(&wacom->dev->dev, "throwing away %d bytes of garbage\n", wacom->idx);
wacom_clear_data_buf(wacom);
}
wacom->data[wacom->idx++] = data;
err = wacom_send(serio, cmd); if (err) return err;
u = wait_for_completion_timeout(&wacom->cmd_done, HZ); if (u == 0) { /* Timeout, process what we've received. */
wacom_handle_response(wacom);
}
wacom->expect = 0; return wacom->result;
}
staticint wacom_setup(struct wacom *wacom, struct serio *serio)
{ int err;
/* Note that setting the link speed is the job of inputattach. * We assume that reset negotiation has already happened,
* here. */
err = wacom_send_and_wait(wacom, serio, REQUEST_MODEL_AND_ROM_VERSION, "model and version"); if (err) return err;
if (!(wacom->res_x && wacom->res_y)) {
err = wacom_send_and_wait(wacom, serio,
REQUEST_CONFIGURATION_STRING, "configuration string"); if (err) return err;
}
if (!(wacom->max_x && wacom->max_y)) {
err = wacom_send_and_wait(wacom, serio,
REQUEST_MAX_COORDINATES, "coordinates string"); if (err) return err;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.