diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2014-07-24 22:10:09 +0200 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-07-26 03:55:38 +0200 |
commit | 471d17148c8b4174ac5f5283a73316d12c4379bc (patch) | |
tree | 07e8fc37b04e07479404806977f1c75cd0d09765 /drivers/input/tablet | |
parent | Input: wacom - keep wacom_ids ordered (diff) | |
download | linux-471d17148c8b4174ac5f5283a73316d12c4379bc.tar.xz linux-471d17148c8b4174ac5f5283a73316d12c4379bc.zip |
Input: wacom - move the USB (now hid) Wacom driver in drivers/hid
wacom.ko is now a full HID driver, we have to move it into the proper
subdirectory: drivers/hid.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/tablet')
-rw-r--r-- | drivers/input/tablet/Kconfig | 16 | ||||
-rw-r--r-- | drivers/input/tablet/Makefile | 3 | ||||
-rw-r--r-- | drivers/input/tablet/wacom.h | 138 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_sys.c | 1257 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 2548 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.h | 169 |
6 files changed, 0 insertions, 4131 deletions
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index bed7cbf84cfd..cd9c79e0a11b 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig @@ -73,20 +73,4 @@ config TABLET_USB_KBTAB To compile this driver as a module, choose M here: the module will be called kbtab. -config TABLET_USB_WACOM - tristate "Wacom Intuos/Graphire tablet support (USB)" - depends on USB_ARCH_HAS_HCD - select POWER_SUPPLY - select USB - select NEW_LEDS - select LEDS_CLASS - help - Say Y here if you want to use the USB version of the Wacom Intuos - or Graphire tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" - (CONFIG_INPUT_EVDEV) as well. - - To compile this driver as a module, choose M here: the - module will be called wacom. - endif diff --git a/drivers/input/tablet/Makefile b/drivers/input/tablet/Makefile index 3f6c25220638..cc3bc17d5b08 100644 --- a/drivers/input/tablet/Makefile +++ b/drivers/input/tablet/Makefile @@ -2,12 +2,9 @@ # Makefile for the tablet drivers # -# Multipart objects. -wacom-objs := wacom_wac.o wacom_sys.o obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o obj-$(CONFIG_TABLET_USB_HANWANG) += hanwang.o obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o -obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h deleted file mode 100644 index dd67b7da8a97..000000000000 --- a/drivers/input/tablet/wacom.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * drivers/input/tablet/wacom.h - * - * USB Wacom tablet support - * - * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> - * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> - * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at> - * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org> - * Copyright (c) 2000 James E. Blair <corvus@gnu.org> - * Copyright (c) 2000 Daniel Egger <egger@suse.de> - * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> - * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> - * Copyright (c) 2002-2011 Ping Cheng <pingc@wacom.com> - * - * ChangeLog: - * v0.1 (vp) - Initial release - * v0.2 (aba) - Support for all buttons / combinations - * v0.3 (vp) - Support for Intuos added - * v0.4 (sm) - Support for more Intuos models, menustrip - * relative mode, proximity. - * v0.5 (vp) - Big cleanup, nifty features removed, - * they belong in userspace - * v1.8 (vp) - Submit URB only when operating, moved to CVS, - * use input_report_key instead of report_btn and - * other cleanups - * v1.11 (vp) - Add URB ->dev setting for new kernels - * v1.11 (jb) - Add support for the 4D Mouse & Lens - * v1.12 (de) - Add support for two more inking pen IDs - * v1.14 (vp) - Use new USB device id probing scheme. - * Fix Wacom Graphire mouse wheel - * v1.18 (vp) - Fix mouse wheel direction - * Make mouse relative - * v1.20 (fl) - Report tool id for Intuos devices - * - Multi tools support - * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...) - * - Add PL models support - * - Fix Wacom Graphire mouse wheel again - * v1.21 (vp) - Removed protocol descriptions - * - Added MISC_SERIAL for tool serial numbers - * (gb) - Identify version on module load. - * v1.21.1 (fl) - added Graphire2 support - * v1.21.2 (fl) - added Intuos2 support - * - added all the PL ids - * v1.21.3 (fl) - added another eraser id from Neil Okamoto - * - added smooth filter for Graphire from Peri Hankey - * - added PenPartner support from Olaf van Es - * - new tool ids from Ole Martin Bjoerndalen - * v1.29 (pc) - Add support for more tablets - * - Fix pressure reporting - * v1.30 (vp) - Merge 2.4 and 2.5 drivers - * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse - * - Cleanups here and there - * v1.30.1 (pi) - Added Graphire3 support - * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ... - * v1.43 (pc) - Added support for Cintiq 21UX - * - Fixed a Graphire bug - * - Merged wacom_intuos3_irq into wacom_intuos_irq - * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc. - * - Report Device IDs - * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19 - * - Minor data report fix - * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c, - * - where wacom_sys.c deals with system specific code, - * - and wacom_wac.c deals with Wacom specific code - * - Support Intuos3 4x6 - * v1.47 (pc) - Added support for Bamboo - * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX - * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) - * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 - * v1.51 (pc) - Added support for Intuos4 - * v1.52 (pc) - Query Wacom data upon system resume - * - add defines for features->type - * - add new devices (0x9F, 0xE2, and 0XE3) - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ -#ifndef WACOM_H -#define WACOM_H -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/mod_devicetable.h> -#include <linux/usb/input.h> -#include <linux/power_supply.h> -#include <asm/unaligned.h> - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.53" -#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" -#define DRIVER_DESC "USB Wacom tablet driver" -#define DRIVER_LICENSE "GPL" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE(DRIVER_LICENSE); - -#define USB_VENDOR_ID_WACOM 0x056a -#define USB_VENDOR_ID_LENOVO 0x17ef - -struct wacom { - struct usb_device *usbdev; - struct usb_interface *intf; - struct wacom_wac wacom_wac; - struct hid_device *hdev; - struct mutex lock; - struct work_struct work; - struct wacom_led { - u8 select[2]; /* status led selector (0..3) */ - u8 llv; /* status led brightness no button (1..127) */ - u8 hlv; /* status led brightness button pressed (1..127) */ - u8 img_lum; /* OLED matrix display brightness */ - } led; - struct power_supply battery; -}; - -static inline void wacom_schedule_work(struct wacom_wac *wacom_wac) -{ - struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); - schedule_work(&wacom->work); -} - -extern const struct hid_device_id wacom_ids[]; - -void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len); -void wacom_setup_device_quirks(struct wacom_features *features); -int wacom_setup_input_capabilities(struct input_dev *input_dev, - struct wacom_wac *wacom_wac); -int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, - struct wacom_wac *wacom_wac); -#endif diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c deleted file mode 100644 index 06e304b3bbfd..000000000000 --- a/drivers/input/tablet/wacom_sys.c +++ /dev/null @@ -1,1257 +0,0 @@ -/* - * drivers/input/tablet/wacom_sys.c - * - * USB Wacom tablet support - system specific code - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include "wacom_wac.h" -#include "wacom.h" -#include <linux/hid.h> - -#define WAC_MSG_RETRIES 5 - -#define WAC_CMD_LED_CONTROL 0x20 -#define WAC_CMD_ICON_START 0x21 -#define WAC_CMD_ICON_XFER 0x23 -#define WAC_CMD_RETRIES 10 - -static int wacom_get_report(struct hid_device *hdev, u8 type, u8 id, - void *buf, size_t size, unsigned int retries) -{ - int retval; - - do { - retval = hid_hw_raw_request(hdev, id, buf, size, type, - HID_REQ_GET_REPORT); - } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); - - return retval; -} - -static int wacom_set_report(struct hid_device *hdev, u8 type, u8 id, - void *buf, size_t size, unsigned int retries) -{ - int retval; - - do { - retval = hid_hw_raw_request(hdev, id, buf, size, type, - HID_REQ_SET_REPORT); - } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); - - return retval; -} - -static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, - u8 *raw_data, int size) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - - if (size > WACOM_PKGLEN_MAX) - return 1; - - memcpy(wacom->wacom_wac.data, raw_data, size); - - wacom_wac_irq(&wacom->wacom_wac, size); - - return 0; -} - -static int wacom_open(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - int retval; - - mutex_lock(&wacom->lock); - retval = hid_hw_open(wacom->hdev); - mutex_unlock(&wacom->lock); - - return retval; -} - -static void wacom_close(struct input_dev *dev) -{ - struct wacom *wacom = input_get_drvdata(dev); - - mutex_lock(&wacom->lock); - hid_hw_close(wacom->hdev); - mutex_unlock(&wacom->lock); -} - -/* - * Calculate the resolution of the X or Y axis using hidinput_calc_abs_res. - */ -static int wacom_calc_hid_res(int logical_extents, int physical_extents, - unsigned unit, int exponent) -{ - struct hid_field field = { - .logical_maximum = logical_extents, - .physical_maximum = physical_extents, - .unit = unit, - .unit_exponent = exponent, - }; - - return hidinput_calc_abs_res(&field, ABS_X); -} - -static void wacom_feature_mapping(struct hid_device *hdev, - struct hid_field *field, struct hid_usage *usage) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_features *features = &wacom->wacom_wac.features; - - switch (usage->hid) { - case HID_DG_CONTACTMAX: - /* leave touch_max as is if predefined */ - if (!features->touch_max) - features->touch_max = field->value[0]; - break; - } -} - -/* - * Interface Descriptor of wacom devices can be incomplete and - * inconsistent so wacom_features table is used to store stylus - * device's packet lengths, various maximum values, and tablet - * resolution based on product ID's. - * - * For devices that contain 2 interfaces, wacom_features table is - * inaccurate for the touch interface. Since the Interface Descriptor - * for touch interfaces has pretty complete data, this function exists - * to query tablet for this missing information instead of hard coding in - * an additional table. - * - * A typical Interface Descriptor for a stylus will contain a - * boot mouse application collection that is not of interest and this - * function will ignore it. - * - * It also contains a digitizer application collection that also is not - * of interest since any information it contains would be duplicate - * of what is in wacom_features. Usually it defines a report of an array - * of bytes that could be used as max length of the stylus packet returned. - * If it happens to define a Digitizer-Stylus Physical Collection then - * the X and Y logical values contain valid data but it is ignored. - * - * A typical Interface Descriptor for a touch interface will contain a - * Digitizer-Finger Physical Collection which will define both logical - * X/Y maximum as well as the physical size of tablet. Since touch - * interfaces haven't supported pressure or distance, this is enough - * information to override invalid values in the wacom_features table. - * - * Intuos5 touch interface and 3rd gen Bamboo Touch do not contain useful - * data. We deal with them after returning from this function. - */ -static void wacom_usage_mapping(struct hid_device *hdev, - struct hid_field *field, struct hid_usage *usage) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_features *features = &wacom->wacom_wac.features; - bool finger = (field->logical == HID_DG_FINGER) || - (field->physical == HID_DG_FINGER); - bool pen = (field->logical == HID_DG_STYLUS) || - (field->physical == HID_DG_STYLUS); - - /* - * Requiring Stylus Usage will ignore boot mouse - * X/Y values and some cases of invalid Digitizer X/Y - * values commonly reported. - */ - if (!pen && !finger) - return; - - if (finger && !features->touch_max) - /* touch device at least supports one touch point */ - features->touch_max = 1; - - switch (usage->hid) { - case HID_GD_X: - features->x_max = field->logical_maximum; - if (finger) { - features->device_type = BTN_TOOL_FINGER; - features->x_phy = field->physical_maximum; - if (features->type != BAMBOO_PT) { - features->unit = field->unit; - features->unitExpo = field->unit_exponent; - } - } else { - features->device_type = BTN_TOOL_PEN; - } - break; - case HID_GD_Y: - features->y_max = field->logical_maximum; - if (finger) { - features->y_phy = field->physical_maximum; - if (features->type != BAMBOO_PT) { - features->unit = field->unit; - features->unitExpo = field->unit_exponent; - } - } - break; - case HID_DG_TIPPRESSURE: - if (pen) - features->pressure_max = field->logical_maximum; - break; - } -} - -static void wacom_parse_hid(struct hid_device *hdev, - struct wacom_features *features) -{ - struct hid_report_enum *rep_enum; - struct hid_report *hreport; - int i, j; - - /* check features first */ - rep_enum = &hdev->report_enum[HID_FEATURE_REPORT]; - list_for_each_entry(hreport, &rep_enum->report_list, list) { - for (i = 0; i < hreport->maxfield; i++) { - /* Ignore if report count is out of bounds. */ - if (hreport->field[i]->report_count < 1) - continue; - - for (j = 0; j < hreport->field[i]->maxusage; j++) { - wacom_feature_mapping(hdev, hreport->field[i], - hreport->field[i]->usage + j); - } - } - } - - /* now check the input usages */ - rep_enum = &hdev->report_enum[HID_INPUT_REPORT]; - list_for_each_entry(hreport, &rep_enum->report_list, list) { - - if (!hreport->maxfield) - continue; - - for (i = 0; i < hreport->maxfield; i++) - for (j = 0; j < hreport->field[i]->maxusage; j++) - wacom_usage_mapping(hdev, hreport->field[i], - hreport->field[i]->usage + j); - } -} - -static int wacom_set_device_mode(struct hid_device *hdev, int report_id, - int length, int mode) -{ - unsigned char *rep_data; - int error = -ENOMEM, limit = 0; - - rep_data = kzalloc(length, GFP_KERNEL); - if (!rep_data) - return error; - - do { - rep_data[0] = report_id; - rep_data[1] = mode; - - error = wacom_set_report(hdev, HID_FEATURE_REPORT, - report_id, rep_data, length, 1); - if (error >= 0) - error = wacom_get_report(hdev, HID_FEATURE_REPORT, - report_id, rep_data, length, 1); - } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES); - - kfree(rep_data); - - return error < 0 ? error : 0; -} - -/* - * Switch the tablet into its most-capable mode. Wacom tablets are - * typically configured to power-up in a mode which sends mouse-like - * reports to the OS. To get absolute position, pressure data, etc. - * from the tablet, it is necessary to switch the tablet out of this - * mode and into one which sends the full range of tablet data. - */ -static int wacom_query_tablet_data(struct hid_device *hdev, - struct wacom_features *features) -{ - if (features->device_type == BTN_TOOL_FINGER) { - if (features->type > TABLETPC) { - /* MT Tablet PC touch */ - return wacom_set_device_mode(hdev, 3, 4, 4); - } - else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { - return wacom_set_device_mode(hdev, 18, 3, 2); - } - } else if (features->device_type == BTN_TOOL_PEN) { - if (features->type <= BAMBOO_PT && features->type != WIRELESS) { - return wacom_set_device_mode(hdev, 2, 2, 2); - } - } - - return 0; -} - -static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, - struct wacom_features *features) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - struct usb_interface *intf = wacom->intf; - - /* default features */ - features->device_type = BTN_TOOL_PEN; - features->x_fuzz = 4; - features->y_fuzz = 4; - features->pressure_fuzz = 0; - features->distance_fuzz = 0; - - /* - * The wireless device HID is basic and layout conflicts with - * other tablets (monitor and touch interface can look like pen). - * Skip the query for this type and modify defaults based on - * interface number. - */ - if (features->type == WIRELESS) { - if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { - features->device_type = 0; - } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) { - features->device_type = BTN_TOOL_FINGER; - features->pktlen = WACOM_PKGLEN_BBTOUCH3; - } - } - - /* only devices that support touch need to retrieve the info */ - if (features->type < BAMBOO_PT) - return; - - wacom_parse_hid(hdev, features); -} - -struct wacom_hdev_data { - struct list_head list; - struct kref kref; - struct hid_device *dev; - struct wacom_shared shared; -}; - -static LIST_HEAD(wacom_udev_list); -static DEFINE_MUTEX(wacom_udev_list_lock); - -static bool wacom_are_sibling(struct hid_device *hdev, - struct hid_device *sibling) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_features *features = &wacom->wacom_wac.features; - int vid = features->oVid; - int pid = features->oPid; - int n1,n2; - - if (vid == 0 && pid == 0) { - vid = hdev->vendor; - pid = hdev->product; - } - - if (vid != sibling->vendor || pid != sibling->product) - return false; - - /* Compare the physical path. */ - n1 = strrchr(hdev->phys, '.') - hdev->phys; - n2 = strrchr(sibling->phys, '.') - sibling->phys; - if (n1 != n2 || n1 <= 0 || n2 <= 0) - return false; - - return !strncmp(hdev->phys, sibling->phys, n1); -} - -static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev) -{ - struct wacom_hdev_data *data; - - list_for_each_entry(data, &wacom_udev_list, list) { - if (wacom_are_sibling(hdev, data->dev)) { - kref_get(&data->kref); - return data; - } - } - - return NULL; -} - -static int wacom_add_shared_data(struct hid_device *hdev) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct wacom_hdev_data *data; - int retval = 0; - - mutex_lock(&wacom_udev_list_lock); - - data = wacom_get_hdev_data(hdev); - if (!data) { - data = kzalloc(sizeof(struct wacom_hdev_data), GFP_KERNEL); - if (!data) { - retval = -ENOMEM; - goto out; - } - - kref_init(&data->kref); - data->dev = hdev; - list_add_tail(&data->list, &wacom_udev_list); - } - - wacom_wac->shared = &data->shared; - -out: - mutex_unlock(&wacom_udev_list_lock); - return retval; -} - -static void wacom_release_shared_data(struct kref *kref) -{ - struct wacom_hdev_data *data = - container_of(kref, struct wacom_hdev_data, kref); - - mutex_lock(&wacom_udev_list_lock); - list_del(&data->list); - mutex_unlock(&wacom_udev_list_lock); - - kfree(data); -} - -static void wacom_remove_shared_data(struct wacom_wac *wacom) -{ - struct wacom_hdev_data *data; - - if (wacom->shared) { - data = container_of(wacom->shared, struct wacom_hdev_data, shared); - kref_put(&data->kref, wacom_release_shared_data); - wacom->shared = NULL; - } -} - -static int wacom_led_control(struct wacom *wacom) -{ - unsigned char *buf; - int retval; - - buf = kzalloc(9, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - if (wacom->wacom_wac.features.type >= INTUOS5S && - wacom->wacom_wac.features.type <= INTUOSPL) { - /* - * Touch Ring and crop mark LED luminance may take on - * one of four values: - * 0 = Low; 1 = Medium; 2 = High; 3 = Off - */ - int ring_led = wacom->led.select[0] & 0x03; - int ring_lum = (((wacom->led.llv & 0x60) >> 5) - 1) & 0x03; - int crop_lum = 0; - - buf[0] = WAC_CMD_LED_CONTROL; - buf[1] = (crop_lum << 4) | (ring_lum << 2) | (ring_led); - } - else { - int led = wacom->led.select[0] | 0x4; - - if (wacom->wacom_wac.features.type == WACOM_21UX2 || - wacom->wacom_wac.features.type == WACOM_24HD) - led |= (wacom->led.select[1] << 4) | 0x40; - - buf[0] = WAC_CMD_LED_CONTROL; - buf[1] = led; - buf[2] = wacom->led.llv; - buf[3] = wacom->led.hlv; - buf[4] = wacom->led.img_lum; - } - - retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, - WAC_CMD_LED_CONTROL, buf, 9, WAC_CMD_RETRIES); - kfree(buf); - - return retval; -} - -static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *img) -{ - unsigned char *buf; - int i, retval; - - buf = kzalloc(259, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - /* Send 'start' command */ - buf[0] = WAC_CMD_ICON_START; - buf[1] = 1; - retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, - WAC_CMD_ICON_START, buf, 2, WAC_CMD_RETRIES); - if (retval < 0) - goto out; - - buf[0] = WAC_CMD_ICON_XFER; - buf[1] = button_id & 0x07; - for (i = 0; i < 4; i++) { - buf[2] = i; - memcpy(buf + 3, img + i * 256, 256); - - retval = wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, - WAC_CMD_ICON_XFER, - buf, 259, WAC_CMD_RETRIES); - if (retval < 0) - break; - } - - /* Send 'stop' */ - buf[0] = WAC_CMD_ICON_START; - buf[1] = 0; - wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, WAC_CMD_ICON_START, - buf, 2, WAC_CMD_RETRIES); - -out: - kfree(buf); - return retval; -} - -static ssize_t wacom_led_select_store(struct device *dev, int set_id, - const char *buf, size_t count) -{ - struct hid_device *hdev = container_of(dev, struct hid_device, dev); - struct wacom *wacom = hid_get_drvdata(hdev); - unsigned int id; - int err; - - err = kstrtouint(buf, 10, &id); - if (err) - return err; - - mutex_lock(&wacom->lock); - - wacom->led.select[set_id] = id & 0x3; - err = wacom_led_control(wacom); - - mutex_unlock(&wacom->lock); - - return err < 0 ? err : count; -} - -#define DEVICE_LED_SELECT_ATTR(SET_ID) \ -static ssize_t wacom_led##SET_ID##_select_store(struct device *dev, \ - struct device_attribute *attr, const char *buf, size_t count) \ -{ \ - return wacom_led_select_store(dev, SET_ID, buf, count); \ -} \ -static ssize_t wacom_led##SET_ID##_select_show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct hid_device *hdev = container_of(dev, struct hid_device, dev);\ - struct wacom *wacom = hid_get_drvdata(hdev); \ - return snprintf(buf, 2, "%d\n", wacom->led.select[SET_ID]); \ -} \ -static DEVICE_ATTR(status_led##SET_ID##_select, S_IWUSR | S_IRUSR, \ - wacom_led##SET_ID##_select_show, \ - wacom_led##SET_ID##_select_store) - -DEVICE_LED_SELECT_ATTR(0); -DEVICE_LED_SELECT_ATTR(1); - -static ssize_t wacom_luminance_store(struct wacom *wacom, u8 *dest, - const char *buf, size_t count) -{ - unsigned int value; - int err; - - err = kstrtouint(buf, 10, &value); - if (err) - return err; - - mutex_lock(&wacom->lock); - - *dest = value & 0x7f; - err = wacom_led_control(wacom); - - mutex_unlock(&wacom->lock); - - return err < 0 ? err : count; -} - -#define DEVICE_LUMINANCE_ATTR(name, field) \ -static ssize_t wacom_##name##_luminance_store(struct device *dev, \ - struct device_attribute *attr, const char *buf, size_t count) \ -{ \ - struct hid_device *hdev = container_of(dev, struct hid_device, dev);\ - struct wacom *wacom = hid_get_drvdata(hdev); \ - \ - return wacom_luminance_store(wacom, &wacom->led.field, \ - buf, count); \ -} \ -static DEVICE_ATTR(name##_luminance, S_IWUSR, \ - NULL, wacom_##name##_luminance_store) - -DEVICE_LUMINANCE_ATTR(status0, llv); -DEVICE_LUMINANCE_ATTR(status1, hlv); -DEVICE_LUMINANCE_ATTR(buttons, img_lum); - -static ssize_t wacom_button_image_store(struct device *dev, int button_id, - const char *buf, size_t count) -{ - struct hid_device *hdev = container_of(dev, struct hid_device, dev); - struct wacom *wacom = hid_get_drvdata(hdev); - int err; - - if (count != 1024) - return -EINVAL; - - mutex_lock(&wacom->lock); - - err = wacom_led_putimage(wacom, button_id, buf); - - mutex_unlock(&wacom->lock); - - return err < 0 ? err : count; -} - -#define DEVICE_BTNIMG_ATTR(BUTTON_ID) \ -static ssize_t wacom_btnimg##BUTTON_ID##_store(struct device *dev, \ - struct device_attribute *attr, const char *buf, size_t count) \ -{ \ - return wacom_button_image_store(dev, BUTTON_ID, buf, count); \ -} \ -static DEVICE_ATTR(button##BUTTON_ID##_rawimg, S_IWUSR, \ - NULL, wacom_btnimg##BUTTON_ID##_store) - -DEVICE_BTNIMG_ATTR(0); -DEVICE_BTNIMG_ATTR(1); -DEVICE_BTNIMG_ATTR(2); -DEVICE_BTNIMG_ATTR(3); -DEVICE_BTNIMG_ATTR(4); -DEVICE_BTNIMG_ATTR(5); -DEVICE_BTNIMG_ATTR(6); -DEVICE_BTNIMG_ATTR(7); - -static struct attribute *cintiq_led_attrs[] = { - &dev_attr_status_led0_select.attr, - &dev_attr_status_led1_select.attr, - NULL -}; - -static struct attribute_group cintiq_led_attr_group = { - .name = "wacom_led", - .attrs = cintiq_led_attrs, -}; - -static struct attribute *intuos4_led_attrs[] = { - &dev_attr_status0_luminance.attr, - &dev_attr_status1_luminance.attr, - &dev_attr_status_led0_select.attr, - &dev_attr_buttons_luminance.attr, - &dev_attr_button0_rawimg.attr, - &dev_attr_button1_rawimg.attr, - &dev_attr_button2_rawimg.attr, - &dev_attr_button3_rawimg.attr, - &dev_attr_button4_rawimg.attr, - &dev_attr_button5_rawimg.attr, - &dev_attr_button6_rawimg.attr, - &dev_attr_button7_rawimg.attr, - NULL -}; - -static struct attribute_group intuos4_led_attr_group = { - .name = "wacom_led", - .attrs = intuos4_led_attrs, -}; - -static struct attribute *intuos5_led_attrs[] = { - &dev_attr_status0_luminance.attr, - &dev_attr_status_led0_select.attr, - NULL -}; - -static struct attribute_group intuos5_led_attr_group = { - .name = "wacom_led", - .attrs = intuos5_led_attrs, -}; - -static int wacom_initialize_leds(struct wacom *wacom) -{ - int error; - - /* Initialize default values */ - switch (wacom->wacom_wac.features.type) { - case INTUOS4S: - case INTUOS4: - case INTUOS4L: - wacom->led.select[0] = 0; - wacom->led.select[1] = 0; - wacom->led.llv = 10; - wacom->led.hlv = 20; - wacom->led.img_lum = 10; - error = sysfs_create_group(&wacom->hdev->dev.kobj, - &intuos4_led_attr_group); - break; - - case WACOM_24HD: - case WACOM_21UX2: - wacom->led.select[0] = 0; - wacom->led.select[1] = 0; - wacom->led.llv = 0; - wacom->led.hlv = 0; - wacom->led.img_lum = 0; - - error = sysfs_create_group(&wacom->hdev->dev.kobj, - &cintiq_led_attr_group); - break; - - case INTUOS5S: - case INTUOS5: - case INTUOS5L: - case INTUOSPS: - case INTUOSPM: - case INTUOSPL: - if (wacom->wacom_wac.features.device_type == BTN_TOOL_PEN) { - wacom->led.select[0] = 0; - wacom->led.select[1] = 0; - wacom->led.llv = 32; - wacom->led.hlv = 0; - wacom->led.img_lum = 0; - - error = sysfs_create_group(&wacom->hdev->dev.kobj, - &intuos5_led_attr_group); - } else - return 0; - break; - - default: - return 0; - } - - if (error) { - hid_err(wacom->hdev, - "cannot create sysfs group err: %d\n", error); - return error; - } - wacom_led_control(wacom); - - return 0; -} - -static void wacom_destroy_leds(struct wacom *wacom) -{ - switch (wacom->wacom_wac.features.type) { - case INTUOS4S: - case INTUOS4: - case INTUOS4L: - sysfs_remove_group(&wacom->hdev->dev.kobj, - &intuos4_led_attr_group); - break; - - case WACOM_24HD: - case WACOM_21UX2: - sysfs_remove_group(&wacom->hdev->dev.kobj, - &cintiq_led_attr_group); - break; - - case INTUOS5S: - case INTUOS5: - case INTUOS5L: - case INTUOSPS: - case INTUOSPM: - case INTUOSPL: - if (wacom->wacom_wac.features.device_type == BTN_TOOL_PEN) - sysfs_remove_group(&wacom->hdev->dev.kobj, - &intuos5_led_attr_group); - break; - } -} - -static enum power_supply_property wacom_battery_props[] = { - POWER_SUPPLY_PROP_SCOPE, - POWER_SUPPLY_PROP_CAPACITY -}; - -static int wacom_battery_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct wacom *wacom = container_of(psy, struct wacom, battery); - int ret = 0; - - switch (psp) { - case POWER_SUPPLY_PROP_SCOPE: - val->intval = POWER_SUPPLY_SCOPE_DEVICE; - break; - case POWER_SUPPLY_PROP_CAPACITY: - val->intval = - wacom->wacom_wac.battery_capacity * 100 / 31; - break; - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static int wacom_initialize_battery(struct wacom *wacom) -{ - int error = 0; - - if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR) { - wacom->battery.properties = wacom_battery_props; - wacom->battery.num_properties = ARRAY_SIZE(wacom_battery_props); - wacom->battery.get_property = wacom_battery_get_property; - wacom->battery.name = "wacom_battery"; - wacom->battery.type = POWER_SUPPLY_TYPE_BATTERY; - wacom->battery.use_for_apm = 0; - - error = power_supply_register(&wacom->hdev->dev, - &wacom->battery); - - if (!error) - power_supply_powers(&wacom->battery, - &wacom->hdev->dev); - } - - return error; -} - -static void wacom_destroy_battery(struct wacom *wacom) -{ - if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR && - wacom->battery.dev) { - power_supply_unregister(&wacom->battery); - wacom->battery.dev = NULL; - } -} - -static struct input_dev *wacom_allocate_input(struct wacom *wacom) -{ - struct input_dev *input_dev; - struct hid_device *hdev = wacom->hdev; - struct wacom_wac *wacom_wac = &(wacom->wacom_wac); - - input_dev = input_allocate_device(); - if (!input_dev) - return NULL; - - input_dev->name = wacom_wac->name; - input_dev->phys = hdev->phys; - input_dev->dev.parent = &hdev->dev; - input_dev->open = wacom_open; - input_dev->close = wacom_close; - input_dev->uniq = hdev->uniq; - input_dev->id.bustype = hdev->bus; - input_dev->id.vendor = hdev->vendor; - input_dev->id.product = hdev->product; - input_dev->id.version = hdev->version; - input_set_drvdata(input_dev, wacom); - - return input_dev; -} - -static void wacom_unregister_inputs(struct wacom *wacom) -{ - if (wacom->wacom_wac.input) - input_unregister_device(wacom->wacom_wac.input); - if (wacom->wacom_wac.pad_input) - input_unregister_device(wacom->wacom_wac.pad_input); - wacom->wacom_wac.input = NULL; - wacom->wacom_wac.pad_input = NULL; -} - -static int wacom_register_inputs(struct wacom *wacom) -{ - struct input_dev *input_dev, *pad_input_dev; - struct wacom_wac *wacom_wac = &(wacom->wacom_wac); - int error; - - input_dev = wacom_allocate_input(wacom); - pad_input_dev = wacom_allocate_input(wacom); - if (!input_dev || !pad_input_dev) { - error = -ENOMEM; - goto fail1; - } - - wacom_wac->input = input_dev; - wacom_wac->pad_input = pad_input_dev; - wacom_wac->pad_input->name = wacom_wac->pad_name; - - error = wacom_setup_input_capabilities(input_dev, wacom_wac); - if (error) - goto fail2; - - error = input_register_device(input_dev); - if (error) - goto fail2; - - error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); - if (error) { - /* no pad in use on this interface */ - input_free_device(pad_input_dev); - wacom_wac->pad_input = NULL; - pad_input_dev = NULL; - } else { - error = input_register_device(pad_input_dev); - if (error) - goto fail3; - } - - return 0; - -fail3: - input_unregister_device(input_dev); - input_dev = NULL; -fail2: - wacom_wac->input = NULL; - wacom_wac->pad_input = NULL; -fail1: - if (input_dev) - input_free_device(input_dev); - if (pad_input_dev) - input_free_device(pad_input_dev); - return error; -} - -static void wacom_wireless_work(struct work_struct *work) -{ - struct wacom *wacom = container_of(work, struct wacom, work); - struct usb_device *usbdev = wacom->usbdev; - struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct hid_device *hdev1, *hdev2; - struct wacom *wacom1, *wacom2; - struct wacom_wac *wacom_wac1, *wacom_wac2; - int error; - - /* - * Regardless if this is a disconnect or a new tablet, - * remove any existing input and battery devices. - */ - - wacom_destroy_battery(wacom); - - /* Stylus interface */ - hdev1 = usb_get_intfdata(usbdev->config->interface[1]); - wacom1 = hid_get_drvdata(hdev1); - wacom_wac1 = &(wacom1->wacom_wac); - wacom_unregister_inputs(wacom1); - - /* Touch interface */ - hdev2 = usb_get_intfdata(usbdev->config->interface[2]); - wacom2 = hid_get_drvdata(hdev2); - wacom_wac2 = &(wacom2->wacom_wac); - wacom_unregister_inputs(wacom2); - - if (wacom_wac->pid == 0) { - hid_info(wacom->hdev, "wireless tablet disconnected\n"); - } else { - const struct hid_device_id *id = wacom_ids; - - hid_info(wacom->hdev, "wireless tablet connected with PID %x\n", - wacom_wac->pid); - - while (id->bus) { - if (id->vendor == USB_VENDOR_ID_WACOM && - id->product == wacom_wac->pid) - break; - id++; - } - - if (!id->bus) { - hid_info(wacom->hdev, "ignoring unknown PID.\n"); - return; - } - - /* Stylus interface */ - wacom_wac1->features = - *((struct wacom_features *)id->driver_data); - wacom_wac1->features.device_type = BTN_TOOL_PEN; - snprintf(wacom_wac1->name, WACOM_NAME_MAX, "%s (WL) Pen", - wacom_wac1->features.name); - snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad", - wacom_wac1->features.name); - wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max; - wacom_wac1->shared->type = wacom_wac1->features.type; - error = wacom_register_inputs(wacom1); - if (error) - goto fail; - - /* Touch interface */ - if (wacom_wac1->features.touch_max || - wacom_wac1->features.type == INTUOSHT) { - wacom_wac2->features = - *((struct wacom_features *)id->driver_data); - wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; - wacom_wac2->features.device_type = BTN_TOOL_FINGER; - wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; - if (wacom_wac2->features.touch_max) - snprintf(wacom_wac2->name, WACOM_NAME_MAX, - "%s (WL) Finger",wacom_wac2->features.name); - else - snprintf(wacom_wac2->name, WACOM_NAME_MAX, - "%s (WL) Pad",wacom_wac2->features.name); - snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX, - "%s (WL) Pad", wacom_wac2->features.name); - error = wacom_register_inputs(wacom2); - if (error) - goto fail; - - if (wacom_wac1->features.type == INTUOSHT && - wacom_wac1->features.touch_max) - wacom_wac->shared->touch_input = wacom_wac2->input; - } - - error = wacom_initialize_battery(wacom); - if (error) - goto fail; - } - - return; - -fail: - wacom_unregister_inputs(wacom1); - wacom_unregister_inputs(wacom2); - return; -} - -/* - * Not all devices report physical dimensions from HID. - * Compute the default from hardcoded logical dimension - * and resolution before driver overwrites them. - */ -static void wacom_set_default_phy(struct wacom_features *features) -{ - if (features->x_resolution) { - features->x_phy = (features->x_max * 100) / - features->x_resolution; - features->y_phy = (features->y_max * 100) / - features->y_resolution; - } -} - -static void wacom_calculate_res(struct wacom_features *features) -{ - features->x_resolution = wacom_calc_hid_res(features->x_max, - features->x_phy, - features->unit, - features->unitExpo); - features->y_resolution = wacom_calc_hid_res(features->y_max, - features->y_phy, - features->unit, - features->unitExpo); -} - -static int wacom_hid_report_len(struct hid_report *report) -{ - /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ - return ((report->size - 1) >> 3) + 1 + (report->id > 0); -} - -static size_t wacom_compute_pktlen(struct hid_device *hdev) -{ - struct hid_report_enum *report_enum; - struct hid_report *report; - size_t size = 0; - - report_enum = hdev->report_enum + HID_INPUT_REPORT; - - list_for_each_entry(report, &report_enum->report_list, list) { - size_t report_size = wacom_hid_report_len(report); - if (report_size > size) - size = report_size; - } - - return size; -} - -static int wacom_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - struct usb_device *dev = interface_to_usbdev(intf); - struct wacom *wacom; - struct wacom_wac *wacom_wac; - struct wacom_features *features; - int error; - - if (!id->driver_data) - return -EINVAL; - - wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); - if (!wacom) - return -ENOMEM; - - hid_set_drvdata(hdev, wacom); - wacom->hdev = hdev; - - /* ask for the report descriptor to be loaded by HID */ - error = hid_parse(hdev); - if (error) { - hid_err(hdev, "parse failed\n"); - goto fail1; - } - - wacom_wac = &wacom->wacom_wac; - wacom_wac->features = *((struct wacom_features *)id->driver_data); - features = &wacom_wac->features; - features->pktlen = wacom_compute_pktlen(hdev); - if (features->pktlen > WACOM_PKGLEN_MAX) { - error = -EINVAL; - goto fail1; - } - - if (features->check_for_hid_type && features->hid_type != hdev->type) { - error = -ENODEV; - goto fail1; - } - - wacom->usbdev = dev; - wacom->intf = intf; - mutex_init(&wacom->lock); - INIT_WORK(&wacom->work, wacom_wireless_work); - - /* set the default size in case we do not get them from hid */ - wacom_set_default_phy(features); - - /* Retrieve the physical and logical size for touch devices */ - wacom_retrieve_hid_descriptor(hdev, features); - - /* - * Intuos5 has no useful data about its touch interface in its - * HID descriptor. If this is the touch interface (PacketSize - * of WACOM_PKGLEN_BBTOUCH3), override the table values. - */ - if (features->type >= INTUOS5S && features->type <= INTUOSHT) { - if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { - features->device_type = BTN_TOOL_FINGER; - - features->x_max = 4096; - features->y_max = 4096; - } else { - features->device_type = BTN_TOOL_PEN; - } - } - - /* - * Same thing for Bamboo 3rd gen. - */ - if ((features->type == BAMBOO_PT) && - (features->pktlen == WACOM_PKGLEN_BBTOUCH3) && - (features->device_type == BTN_TOOL_PEN)) { - features->device_type = BTN_TOOL_FINGER; - - features->x_max = 4096; - features->y_max = 4096; - } - - wacom_setup_device_quirks(features); - - /* set unit to "100th of a mm" for devices not reported by HID */ - if (!features->unit) { - features->unit = 0x11; - features->unitExpo = -3; - } - wacom_calculate_res(features); - - strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); - snprintf(wacom_wac->pad_name, sizeof(wacom_wac->pad_name), - "%s Pad", features->name); - - if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { - /* Append the device type to the name */ - if (features->device_type != BTN_TOOL_FINGER) - strlcat(wacom_wac->name, " Pen", WACOM_NAME_MAX); - else if (features->touch_max) - strlcat(wacom_wac->name, " Finger", WACOM_NAME_MAX); - else - strlcat(wacom_wac->name, " Pad", WACOM_NAME_MAX); - - error = wacom_add_shared_data(hdev); - if (error) - goto fail1; - } - - error = wacom_initialize_leds(wacom); - if (error) - goto fail2; - - if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) { - error = wacom_register_inputs(wacom); - if (error) - goto fail3; - } - - /* Note that if query fails it is not a hard failure */ - wacom_query_tablet_data(hdev, features); - - /* Regular HID work starts now */ - error = hid_hw_start(hdev, HID_CONNECT_HIDRAW); - if (error) { - hid_err(hdev, "hw start failed\n"); - goto fail4; - } - - if (features->quirks & WACOM_QUIRK_MONITOR) - error = hid_hw_open(hdev); - - if (wacom_wac->features.type == INTUOSHT && wacom_wac->features.touch_max) { - if (wacom_wac->features.device_type == BTN_TOOL_FINGER) - wacom_wac->shared->touch_input = wacom_wac->input; - } - - return 0; - - fail4: wacom_unregister_inputs(wacom); - fail3: wacom_destroy_leds(wacom); - fail2: wacom_remove_shared_data(wacom_wac); - fail1: kfree(wacom); - hid_set_drvdata(hdev, NULL); - return error; -} - -static void wacom_remove(struct hid_device *hdev) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - - hid_hw_stop(hdev); - - cancel_work_sync(&wacom->work); - wacom_unregister_inputs(wacom); - wacom_destroy_battery(wacom); - wacom_destroy_leds(wacom); - wacom_remove_shared_data(&wacom->wacom_wac); - - hid_set_drvdata(hdev, NULL); - kfree(wacom); -} - -static int wacom_resume(struct hid_device *hdev) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_features *features = &wacom->wacom_wac.features; - - mutex_lock(&wacom->lock); - - /* switch to wacom mode first */ - wacom_query_tablet_data(hdev, features); - wacom_led_control(wacom); - - mutex_unlock(&wacom->lock); - - return 0; -} - -static int wacom_reset_resume(struct hid_device *hdev) -{ - return wacom_resume(hdev); -} - -static struct hid_driver wacom_driver = { - .name = "wacom", - .id_table = wacom_ids, - .probe = wacom_probe, - .remove = wacom_remove, -#ifdef CONFIG_PM - .resume = wacom_resume, - .reset_resume = wacom_reset_resume, -#endif - .raw_event = wacom_raw_event, -}; -module_hid_driver(wacom_driver); diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c deleted file mode 100644 index cd915211fcca..000000000000 --- a/drivers/input/tablet/wacom_wac.c +++ /dev/null @@ -1,2548 +0,0 @@ -/* - * drivers/input/tablet/wacom_wac.c - * - * USB Wacom tablet support - Wacom specific code - * - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include "wacom_wac.h" -#include "wacom.h" -#include <linux/input/mt.h> -#include <linux/hid.h> - -/* resolution for penabled devices */ -#define WACOM_PL_RES 20 -#define WACOM_PENPRTN_RES 40 -#define WACOM_VOLITO_RES 50 -#define WACOM_GRAPHIRE_RES 80 -#define WACOM_INTUOS_RES 100 -#define WACOM_INTUOS3_RES 200 - -/* Scale factor relating reported contact size to logical contact area. - * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo - */ -#define WACOM_CONTACT_AREA_SCALE 2607 - -static int wacom_penpartner_irq(struct wacom_wac *wacom) -{ - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - - switch (data[0]) { - case 1: - if (data[5] & 0x80) { - wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID; - input_report_key(input, wacom->tool[0], 1); - input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_abs(input, ABS_X, get_unaligned_le16(&data[1])); - input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3])); - input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127); - input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -127)); - input_report_key(input, BTN_STYLUS, (data[5] & 0x40)); - } else { - input_report_key(input, wacom->tool[0], 0); - input_report_abs(input, ABS_MISC, 0); /* report tool id */ - input_report_abs(input, ABS_PRESSURE, -1); - input_report_key(input, BTN_TOUCH, 0); - } - break; - - case 2: - input_report_key(input, BTN_TOOL_PEN, 1); - input_report_abs(input, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */ - input_report_abs(input, ABS_X, get_unaligned_le16(&data[1])); - input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3])); - input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127); - input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20)); - input_report_key(input, BTN_STYLUS, (data[5] & 0x40)); - break; - - default: - dev_dbg(input->dev.parent, - "%s: received unknown report #%d\n", __func__, data[0]); - return 0; - } - - return 1; -} - -static int wacom_pl_irq(struct wacom_wac *wacom) -{ - struct wacom_features *features = &wacom->features; - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - int prox, pressure; - - if (data[0] != WACOM_REPORT_PENABLED) { - dev_dbg(input->dev.parent, - "%s: received unknown report #%d\n", __func__, data[0]); - return 0; - } - - prox = data[1] & 0x40; - - if (prox) { - wacom->id[0] = ERASER_DEVICE_ID; - pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); - if (features->pressure_max > 255) - pressure = (pressure << 1) | ((data[4] >> 6) & 1); - pressure += (features->pressure_max + 1) / 2; - - /* - * if going from out of proximity into proximity select between the eraser - * and the pen based on the state of the stylus2 button, choose eraser if - * pressed else choose pen. if not a proximity change from out to in, send - * an out of proximity for previous tool then a in for new tool. - */ - if (!wacom->tool[0]) { - /* Eraser bit set for DTF */ - if (data[1] & 0x10) - wacom->tool[1] = BTN_TOOL_RUBBER; - else - /* Going into proximity select tool */ - wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - } else { - /* was entered with stylus2 pressed */ - if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) { - /* report out proximity for previous tool */ - input_report_key(input, wacom->tool[1], 0); - input_sync(input); - wacom->tool[1] = BTN_TOOL_PEN; - return 0; - } - } - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - input_report_key(input, wacom->tool[1], prox); /* report in proximity for tool */ - input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14)); - input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14)); - input_report_abs(input, ABS_PRESSURE, pressure); - - input_report_key(input, BTN_TOUCH, data[4] & 0x08); - input_report_key(input, BTN_STYLUS, data[4] & 0x10); - /* Only allow the stylus2 button to be reported for the pen tool. */ - input_report_key(input, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20)); - } else { - /* report proximity-out of a (valid) tool */ - if (wacom->tool[1] != BTN_TOOL_RUBBER) { - /* Unknown tool selected default to pen tool */ - wacom->tool[1] = BTN_TOOL_PEN; - } - input_report_key(input, wacom->tool[1], prox); - } - - wacom->tool[0] = prox; /* Save proximity state */ - return 1; -} - -static int wacom_ptu_irq(struct wacom_wac *wacom) -{ - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - - if (data[0] != WACOM_REPORT_PENABLED) { - dev_dbg(input->dev.parent, - "%s: received unknown report #%d\n", __func__, data[0]); - return 0; - } - - if (data[1] & 0x04) { - input_report_key(input, BTN_TOOL_RUBBER, data[1] & 0x20); - input_report_key(input, BTN_TOUCH, data[1] & 0x08); - wacom->id[0] = ERASER_DEVICE_ID; - } else { - input_report_key(input, BTN_TOOL_PEN, data[1] & 0x20); - input_report_key(input, BTN_TOUCH, data[1] & 0x01); - wacom->id[0] = STYLUS_DEVICE_ID; - } - input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); - input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); - input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6])); - input_report_key(input, BTN_STYLUS, data[1] & 0x02); - input_report_key(input, BTN_STYLUS2, data[1] & 0x10); - return 1; -} - -static int wacom_dtu_irq(struct wacom_wac *wacom) -{ - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - int prox = data[1] & 0x20; - - dev_dbg(input->dev.parent, - "%s: received report #%d", __func__, data[0]); - - if (prox) { - /* Going into proximity select tool */ - wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - if (wacom->tool[0] == BTN_TOOL_PEN) - wacom->id[0] = STYLUS_DEVICE_ID; - else - wacom->id[0] = ERASER_DEVICE_ID; - } - input_report_key(input, BTN_STYLUS, data[1] & 0x02); - input_report_key(input, BTN_STYLUS2, data[1] & 0x10); - input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); - input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); - input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x01) << 8) | data[6]); - input_report_key(input, BTN_TOUCH, data[1] & 0x05); - if (!prox) /* out-prox */ - wacom->id[0] = 0; - input_report_key(input, wacom->tool[0], prox); - input_report_abs(input, ABS_MISC, wacom->id[0]); - return 1; -} - -static int wacom_dtus_irq(struct wacom_wac *wacom) -{ - char *data = wacom->data; - struct input_dev *input = wacom->input; - unsigned short prox, pressure = 0; - - if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) { - dev_dbg(input->dev.parent, - "%s: received unknown report #%d", __func__, data[0]); - return 0; - } else if (data[0] == WACOM_REPORT_DTUSPAD) { - input = wacom->pad_input; - input_report_key(input, BTN_0, (data[1] & 0x01)); - input_report_key(input, BTN_1, (data[1] & 0x02)); - input_report_key(input, BTN_2, (data[1] & 0x04)); - input_report_key(input, BTN_3, (data[1] & 0x08)); - input_report_abs(input, ABS_MISC, - data[1] & 0x0f ? PAD_DEVICE_ID : 0); - return 1; - } else { - prox = data[1] & 0x80; - if (prox) { - switch ((data[1] >> 3) & 3) { - case 1: /* Rubber */ - wacom->tool[0] = BTN_TOOL_RUBBER; - wacom->id[0] = ERASER_DEVICE_ID; - break; - - case 2: /* Pen */ - wacom->tool[0] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - break; - } - } - - input_report_key(input, BTN_STYLUS, data[1] & 0x20); - input_report_key(input, BTN_STYLUS2, data[1] & 0x40); - input_report_abs(input, ABS_X, get_unaligned_be16(&data[3])); - input_report_abs(input, ABS_Y, get_unaligned_be16(&data[5])); - pressure = ((data[1] & 0x03) << 8) | (data[2] & 0xff); - input_report_abs(input, ABS_PRESSURE, pressure); - input_report_key(input, BTN_TOUCH, pressure > 10); - - if (!prox) /* out-prox */ - wacom->id[0] = 0; - input_report_key(input, wacom->tool[0], prox); - input_report_abs(input, ABS_MISC, wacom->id[0]); - return 1; - } -} - -static int wacom_graphire_irq(struct wacom_wac *wacom) -{ - struct wacom_features *features = &wacom->features; - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - struct input_dev *pad_input = wacom->pad_input; - int prox; - int rw = 0; - int retval = 0; - - if (data[0] != WACOM_REPORT_PENABLED) { - dev_dbg(input->dev.parent, - "%s: received unknown report #%d\n", __func__, data[0]); - goto exit; - } - - prox = data[1] & 0x80; - if (prox || wacom->id[0]) { - if (prox) { - switch ((data[1] >> 5) & 3) { - - case 0: /* Pen */ - wacom->tool[0] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - break; - - case 1: /* Rubber */ - wacom->tool[0] = BTN_TOOL_RUBBER; - wacom->id[0] = ERASER_DEVICE_ID; - break; - - case 2: /* Mouse with wheel */ - input_report_key(input, BTN_MIDDLE, data[1] & 0x04); - /* fall through */ - - case 3: /* Mouse without wheel */ - wacom->tool[0] = BTN_TOOL_MOUSE; - wacom->id[0] = CURSOR_DEVICE_ID; - break; - } - } - input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); - input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); - if (wacom->tool[0] != BTN_TOOL_MOUSE) { - input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x03) << 8)); - input_report_key(input, BTN_TOUCH, data[1] & 0x01); - input_report_key(input, BTN_STYLUS, data[1] & 0x02); - input_report_key(input, BTN_STYLUS2, data[1] & 0x04); - } else { - input_report_key(input, BTN_LEFT, data[1] & 0x01); - input_report_key(input, BTN_RIGHT, data[1] & 0x02); - if (features->type == WACOM_G4 || - features->type == WACOM_MO) { - input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f); - rw = (data[7] & 0x04) - (data[7] & 0x03); - } else { - input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f); - rw = -(signed char)data[6]; - } - input_report_rel(input, REL_WHEEL, rw); - } - - if (!prox) - wacom->id[0] = 0; - input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */ - input_report_key(input, wacom->tool[0], prox); - input_sync(input); /* sync last event */ - } - - /* send pad data */ - switch (features->type) { - case WACOM_G4: - prox = data[7] & 0xf8; - if (prox || wacom->id[1]) { - wacom->id[1] = PAD_DEVICE_ID; - input_report_key(pad_input, BTN_BACK, (data[7] & 0x40)); - input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x80)); - rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3); - input_report_rel(pad_input, REL_WHEEL, rw); - if (!prox) - wacom->id[1] = 0; - input_report_abs(pad_input, ABS_MISC, wacom->id[1]); - retval = 1; - } - break; - - case WACOM_MO: - prox = (data[7] & 0xf8) || data[8]; - if (prox || wacom->id[1]) { - wacom->id[1] = PAD_DEVICE_ID; - input_report_key(pad_input, BTN_BACK, (data[7] & 0x08)); - input_report_key(pad_input, BTN_LEFT, (data[7] & 0x20)); - input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x10)); - input_report_key(pad_input, BTN_RIGHT, (data[7] & 0x40)); - input_report_abs(pad_input, ABS_WHEEL, (data[8] & 0x7f)); - if (!prox) - wacom->id[1] = 0; - input_report_abs(pad_input, ABS_MISC, wacom->id[1]); - retval = 1; - } - break; - } -exit: - return retval; -} - -static int wacom_intuos_inout(struct wacom_wac *wacom) -{ - struct wacom_features *features = &wacom->features; - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - int idx = 0; - - /* tool number */ - if (features->type == INTUOS) - idx = data[1] & 0x01; - - /* Enter report */ - if ((data[1] & 0xfc) == 0xc0) { - if (features->quirks & WACOM_QUIRK_MULTI_INPUT) - wacom->shared->stylus_in_proximity = true; - - /* serial number of the tool */ - wacom->serial[idx] = ((data[3] & 0x0f) << 28) + - (data[4] << 20) + (data[5] << 12) + - (data[6] << 4) + (data[7] >> 4); - - wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) | - ((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12); - - switch (wacom->id[idx]) { - case 0x812: /* Inking pen */ - case 0x801: /* Intuos3 Inking pen */ - case 0x120802: /* Intuos4/5 Inking Pen */ - case 0x012: - wacom->tool[idx] = BTN_TOOL_PENCIL; - break; - - case 0x822: /* Pen */ - case 0x842: - case 0x852: - case 0x823: /* Intuos3 Grip Pen */ - case 0x813: /* Intuos3 Classic Pen */ - case 0x885: /* Intuos3 Marker Pen */ - case 0x802: /* Intuos4/5 13HD/24HD General Pen */ - case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */ - case 0x022: - case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */ - case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */ - case 0x160802: /* Cintiq 13HD Pro Pen */ - case 0x180802: /* DTH2242 Pen */ - case 0x100802: /* Intuos4/5 13HD/24HD General Pen */ - wacom->tool[idx] = BTN_TOOL_PEN; - break; - - case 0x832: /* Stroke pen */ - case 0x032: - wacom->tool[idx] = BTN_TOOL_BRUSH; - break; - - case 0x007: /* Mouse 4D and 2D */ - case 0x09c: - case 0x094: - case 0x017: /* Intuos3 2D Mouse */ - case 0x806: /* Intuos4 Mouse */ - wacom->tool[idx] = BTN_TOOL_MOUSE; - break; - - case 0x096: /* Lens cursor */ - case 0x097: /* Intuos3 Lens cursor */ - case 0x006: /* Intuos4 Lens cursor */ - wacom->tool[idx] = BTN_TOOL_LENS; - break; - - case 0x82a: /* Eraser */ - case 0x85a: - case 0x91a: - case 0xd1a: - case 0x0fa: - case 0x82b: /* Intuos3 Grip Pen Eraser */ - case 0x81b: /* Intuos3 Classic Pen Eraser */ - case 0x91b: /* Intuos3 Airbrush Eraser */ - case 0x80c: /* Intuos4/5 13HD/24HD Marker Pen Eraser */ - case 0x80a: /* Intuos4/5 13HD/24HD General Pen Eraser */ - case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */ - case 0x14080a: /* Intuos4/5 13HD/24HD Classic Pen Eraser */ - case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */ - case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */ - case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */ - case 0x18080a: /* DTH2242 Eraser */ - case 0x10080a: /* Intuos4/5 13HD/24HD General Pen Eraser */ - wacom->tool[idx] = BTN_TOOL_RUBBER; - break; - - case 0xd12: - case 0x912: - case 0x112: - case 0x913: /* Intuos3 Airbrush */ - case 0x902: /* Intuos4/5 13HD/24HD Airbrush */ - case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */ - wacom->tool[idx] = BTN_TOOL_AIRBRUSH; - break; - - default: /* Unknown tool */ - wacom->tool[idx] = BTN_TOOL_PEN; - break; - } - return 1; - } - - /* older I4 styli don't work with new Cintiqs */ - if (!((wacom->id[idx] >> 20) & 0x01) && - (features->type == WACOM_21UX2)) - return 1; - - /* Range Report */ - if ((data[1] & 0xfe) == 0x20) { - input_report_key(input, BTN_TOUCH, 0); - input_report_abs(input, ABS_PRESSURE, 0); - input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max); - if (features->quirks & WACOM_QUIRK_MULTI_INPUT) - wacom->shared->stylus_in_proximity = true; - } - - /* Exit report */ - if ((data[1] & 0xfe) == 0x80) { - if (features->quirks & WACOM_QUIRK_MULTI_INPUT) - wacom->shared->stylus_in_proximity = false; - - /* - * Reset all states otherwise we lose the initial states - * when in-prox next time - */ - input_report_abs(input, ABS_X, 0); - input_report_abs(input, ABS_Y, 0); - input_report_abs(input, ABS_DISTANCE, 0); - input_report_abs(input, ABS_TILT_X, 0); - input_report_abs(input, ABS_TILT_Y, 0); - if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { - input_report_key(input, BTN_LEFT, 0); - input_report_key(input, BTN_MIDDLE, 0); - input_report_key(input, BTN_RIGHT, 0); - input_report_key(input, BTN_SIDE, 0); - input_report_key(input, BTN_EXTRA, 0); - input_report_abs(input, ABS_THROTTLE, 0); - input_report_abs(input, ABS_RZ, 0); - } else { - input_report_abs(input, ABS_PRESSURE, 0); - input_report_key(input, BTN_STYLUS, 0); - input_report_key(input, BTN_STYLUS2, 0); - input_report_key(input, BTN_TOUCH, 0); - input_report_abs(input, ABS_WHEEL, 0); - if (features->type >= INTUOS3S) - input_report_abs(input, ABS_Z, 0); - } - input_report_key(input, wacom->tool[idx], 0); - input_report_abs(input, ABS_MISC, 0); /* reset tool id */ - input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - wacom->id[idx] = 0; - return 2; - } - return 0; -} - -static void wacom_intuos_general(struct wacom_wac *wacom) -{ - struct wacom_features *features = &wacom->features; - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - unsigned int t; - - /* general pen packet */ - if ((data[1] & 0xb8) == 0xa0) { - t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (features->type >= INTUOS4S && features->type <= CINTIQ_HYBRID) { - t = (t << 1) | (data[1] & 1); - } - input_report_abs(input, ABS_PRESSURE, t); - input_report_abs(input, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); - input_report_key(input, BTN_STYLUS, data[1] & 2); - input_report_key(input, BTN_STYLUS2, data[1] & 4); - input_report_key(input, BTN_TOUCH, t > 10); - } - - /* airbrush second packet */ - if ((data[1] & 0xbc) == 0xb4) { - input_report_abs(input, ABS_WHEEL, - (data[6] << 2) | ((data[7] >> 6) & 3)); - input_report_abs(input, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); - } -} - -static int wacom_intuos_irq(struct wacom_wac *wacom) -{ - struct wacom_features *features = &wacom->features; - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - unsigned int t; - int idx = 0, result; - - if (data[0] != WACOM_REPORT_PENABLED && - data[0] != WACOM_REPORT_INTUOSREAD && - data[0] != WACOM_REPORT_INTUOSWRITE && - data[0] != WACOM_REPORT_INTUOSPAD && - data[0] != WACOM_REPORT_INTUOS5PAD) { - dev_dbg(input->dev.parent, - "%s: received unknown report #%d\n", __func__, data[0]); - return 0; - } - - /* tool number */ - if (features->type == INTUOS) - idx = data[1] & 0x01; - - /* pad packets. Works as a second tool and is always in prox */ - if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD) { - input = wacom->pad_input; - if (features->type >= INTUOS4S && features->type <= INTUOS4L) { - input_report_key(input, BTN_0, (data[2] & 0x01)); - input_report_key(input, BTN_1, (data[3] & 0x01)); - input_report_key(input, BTN_2, (data[3] & 0x02)); - input_report_key(input, BTN_3, (data[3] & 0x04)); - input_report_key(input, BTN_4, (data[3] & 0x08)); - input_report_key(input, BTN_5, (data[3] & 0x10)); - input_report_key(input, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - if (features->type != INTUOS4S) { - input_report_key(input, BTN_7, (data[3] & 0x40)); - input_report_key(input, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == DTK) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] & 0x04)); - input_report_key(input, BTN_3, (data[6] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x10)); - input_report_key(input, BTN_5, (data[6] & 0x20)); - if (data[6] & 0x3f) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == WACOM_13HD) { - input_report_key(input, BTN_0, (data[3] & 0x01)); - input_report_key(input, BTN_1, (data[4] & 0x01)); - input_report_key(input, BTN_2, (data[4] & 0x02)); - input_report_key(input, BTN_3, (data[4] & 0x04)); - input_report_key(input, BTN_4, (data[4] & 0x08)); - input_report_key(input, BTN_5, (data[4] & 0x10)); - input_report_key(input, BTN_6, (data[4] & 0x20)); - input_report_key(input, BTN_7, (data[4] & 0x40)); - input_report_key(input, BTN_8, (data[4] & 0x80)); - if ((data[3] & 0x01) | data[4]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == WACOM_24HD) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] & 0x04)); - input_report_key(input, BTN_3, (data[6] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x10)); - input_report_key(input, BTN_5, (data[6] & 0x20)); - input_report_key(input, BTN_6, (data[6] & 0x40)); - input_report_key(input, BTN_7, (data[6] & 0x80)); - input_report_key(input, BTN_8, (data[8] & 0x01)); - input_report_key(input, BTN_9, (data[8] & 0x02)); - input_report_key(input, BTN_A, (data[8] & 0x04)); - input_report_key(input, BTN_B, (data[8] & 0x08)); - input_report_key(input, BTN_C, (data[8] & 0x10)); - input_report_key(input, BTN_X, (data[8] & 0x20)); - input_report_key(input, BTN_Y, (data[8] & 0x40)); - input_report_key(input, BTN_Z, (data[8] & 0x80)); - - /* - * Three "buttons" are available on the 24HD which are - * physically implemented as a touchstrip. Each button - * is approximately 3 bits wide with a 2 bit spacing. - * The raw touchstrip bits are stored at: - * ((data[3] & 0x1f) << 8) | data[4]) - */ - input_report_key(input, KEY_PROG1, data[4] & 0x07); - input_report_key(input, KEY_PROG2, data[4] & 0xE0); - input_report_key(input, KEY_PROG3, data[3] & 0x1C); - - if (data[1] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - - if (data[2] & 0x80) { - input_report_abs(input, ABS_THROTTLE, (data[2] & 0x7f)); - } else { - /* Out of proximity, clear second wheel value. */ - input_report_abs(input, ABS_THROTTLE, 0); - } - - if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == CINTIQ_HYBRID) { - /* - * Do not send hardware buttons under Android. They - * are already sent to the system through GPIO (and - * have different meaning). - */ - input_report_key(input, BTN_1, (data[4] & 0x01)); - input_report_key(input, BTN_2, (data[4] & 0x02)); - input_report_key(input, BTN_3, (data[4] & 0x04)); - input_report_key(input, BTN_4, (data[4] & 0x08)); - - input_report_key(input, BTN_5, (data[4] & 0x10)); /* Right */ - input_report_key(input, BTN_6, (data[4] & 0x20)); /* Up */ - input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */ - input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */ - input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */ - } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { - int i; - - /* Touch ring mode switch has no capacitive sensor */ - input_report_key(input, BTN_0, (data[3] & 0x01)); - - /* - * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in - * addition to the mechanical switch. Switch data is - * stored in data[4], capacitive data in data[5]. - */ - for (i = 0; i < 8; i++) - input_report_key(input, BTN_1 + i, data[4] & (1 << i)); - - if (data[2] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - - if (data[2] | (data[3] & 0x01) | data[4] | data[5]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else { - if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) { - input_report_key(input, BTN_0, (data[5] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x01)); - input_report_key(input, BTN_2, (data[6] & 0x02)); - input_report_key(input, BTN_3, (data[6] & 0x04)); - input_report_key(input, BTN_4, (data[6] & 0x08)); - input_report_key(input, BTN_5, (data[6] & 0x10)); - input_report_key(input, BTN_6, (data[6] & 0x20)); - input_report_key(input, BTN_7, (data[6] & 0x40)); - input_report_key(input, BTN_8, (data[6] & 0x80)); - input_report_key(input, BTN_9, (data[7] & 0x01)); - input_report_key(input, BTN_A, (data[8] & 0x01)); - input_report_key(input, BTN_B, (data[8] & 0x02)); - input_report_key(input, BTN_C, (data[8] & 0x04)); - input_report_key(input, BTN_X, (data[8] & 0x08)); - input_report_key(input, BTN_Y, (data[8] & 0x10)); - input_report_key(input, BTN_Z, (data[8] & 0x20)); - input_report_key(input, BTN_BASE, (data[8] & 0x40)); - input_report_key(input, BTN_BASE2, (data[8] & 0x80)); - - if (features->type == WACOM_22HD) { - input_report_key(input, KEY_PROG1, data[9] & 0x01); - input_report_key(input, KEY_PROG2, data[9] & 0x02); - input_report_key(input, KEY_PROG3, data[9] & 0x04); - } - } else { - input_report_key(input, BTN_0, (data[5] & 0x01)); - input_report_key(input, BTN_1, (data[5] & 0x02)); - input_report_key(input, BTN_2, (data[5] & 0x04)); - input_report_key(input, BTN_3, (data[5] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x01)); - input_report_key(input, BTN_5, (data[6] & 0x02)); - input_report_key(input, BTN_6, (data[6] & 0x04)); - input_report_key(input, BTN_7, (data[6] & 0x08)); - input_report_key(input, BTN_8, (data[5] & 0x10)); - input_report_key(input, BTN_9, (data[6] & 0x10)); - } - input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); - input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - - if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4] | data[8] | - (data[7] & 0x01)) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } - return 1; - } - - /* process in/out prox events */ - result = wacom_intuos_inout(wacom); - if (result) - return result - 1; - - /* don't proceed if we don't know the ID */ - if (!wacom->id[idx]) - return 0; - - /* Only large Intuos support Lense Cursor */ - if (wacom->tool[idx] == BTN_TOOL_LENS && - (features->type == INTUOS3 || - features->type == INTUOS3S || - features->type == INTUOS4 || - features->type == INTUOS4S || - features->type == INTUOS5 || - features->type == INTUOS5S || - features->type == INTUOSPM || - features->type == INTUOSPS)) { - - return 0; - } - - /* Cintiq doesn't send data when RDY bit isn't set */ - if (features->type == CINTIQ && !(data[1] & 0x40)) - return 0; - - if (features->type >= INTUOS3S) { - input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[2])); - input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[4])); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); - } - - /* process general packets */ - wacom_intuos_general(wacom); - - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { - - if (data[1] & 0x02) { - /* Rotation packet */ - if (features->type >= INTUOS3S) { - /* I3 marker pen rotation */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : - ((t-1) / 2 + 450)) : (450 - t / 2) ; - input_report_abs(input, ABS_Z, t); - } else { - /* 4D mouse rotation packet */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? - ((t - 1) / 2) : -t / 2); - } - - } else if (!(data[1] & 0x10) && features->type < INTUOS3S) { - /* 4D mouse packet */ - input_report_key(input, BTN_LEFT, data[8] & 0x01); - input_report_key(input, BTN_MIDDLE, data[8] & 0x02); - input_report_key(input, BTN_RIGHT, data[8] & 0x04); - - input_report_key(input, BTN_SIDE, data[8] & 0x20); - input_report_key(input, BTN_EXTRA, data[8] & 0x10); - t = (data[6] << 2) | ((data[7] >> 6) & 3); - input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - - } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { - /* I4 mouse */ - if (features->type >= INTUOS4S && features->type <= INTUOSPL) { - input_report_key(input, BTN_LEFT, data[6] & 0x01); - input_report_key(input, BTN_MIDDLE, data[6] & 0x02); - input_report_key(input, BTN_RIGHT, data[6] & 0x04); - input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7) - - ((data[7] & 0x40) >> 6)); - input_report_key(input, BTN_SIDE, data[6] & 0x08); - input_report_key(input, BTN_EXTRA, data[6] & 0x10); - - input_report_abs(input, ABS_TILT_X, - ((data[7] << 1) & 0x7e) | (data[8] >> 7)); - input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f); - } else { - /* 2D mouse packet */ - input_report_key(input, BTN_LEFT, data[8] & 0x04); - input_report_key(input, BTN_MIDDLE, data[8] & 0x08); - input_report_key(input, BTN_RIGHT, data[8] & 0x10); - input_report_rel(input, REL_WHEEL, (data[8] & 0x01) - - ((data[8] & 0x02) >> 1)); - - /* I3 2D mouse side buttons */ - if (features->type >= INTUOS3S && features->type <= INTUOS3L) { - input_report_key(input, BTN_SIDE, data[8] & 0x40); - input_report_key(input, BTN_EXTRA, data[8] & 0x20); - } - } - } else if ((features->type < INTUOS3S || features->type == INTUOS3L || - features->type == INTUOS4L || features->type == INTUOS5L || - features->type == INTUOSPL) && - wacom->tool[idx] == BTN_TOOL_LENS) { - /* Lens cursor packets */ - input_report_key(input, BTN_LEFT, data[8] & 0x01); - input_report_key(input, BTN_MIDDLE, data[8] & 0x02); - input_report_key(input, BTN_RIGHT, data[8] & 0x04); - input_report_key(input, BTN_SIDE, data[8] & 0x10); - input_report_key(input, BTN_EXTRA, data[8] & 0x08); - } - } - - input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */ - input_report_key(input, wacom->tool[idx], 1); - input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); - return 1; -} - -static int int_dist(int x1, int y1, int x2, int y2) -{ - int x = x2 - x1; - int y = y2 - y1; - - return int_sqrt(x*x + y*y); -} - -static int wacom_24hdt_irq(struct wacom_wac *wacom) -{ - struct input_dev *input = wacom->input; - unsigned char *data = wacom->data; - int i; - int current_num_contacts = data[61]; - int contacts_to_send = 0; - - /* - * First packet resets the counter since only the first - * packet in series will have non-zero current_num_contacts. - */ - if (current_num_contacts) - wacom->num_contacts_left = current_num_contacts; - - /* There are at most 4 contacts per packet */ - contacts_to_send = min(4, wacom->num_contacts_left); - - for (i = 0; i < contacts_to_send; i++) { - int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1; - bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity; - int slot = input_mt_get_slot_by_key(input, data[offset + 1]); - - if (slot < 0) - continue; - input_mt_slot(input, slot); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - - if (touch) { - int t_x = get_unaligned_le16(&data[offset + 2]); - int c_x = get_unaligned_le16(&data[offset + 4]); - int t_y = get_unaligned_le16(&data[offset + 6]); - int c_y = get_unaligned_le16(&data[offset + 8]); - int w = get_unaligned_le16(&data[offset + 10]); - int h = get_unaligned_le16(&data[offset + 12]); - - input_report_abs(input, ABS_MT_POSITION_X, t_x); - input_report_abs(input, ABS_MT_POSITION_Y, t_y); - input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h)); - input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y)); - input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); - input_report_abs(input, ABS_MT_ORIENTATION, w > h); - } - } - input_mt_report_pointer_emulation(input, true); - - wacom->num_contacts_left -= contacts_to_send; - if (wacom->num_contacts_left <= 0) - wacom->num_contacts_left = 0; - - return 1; -} - -static int wacom_mt_touch(struct wacom_wac *wacom) -{ - struct input_dev *input = wacom->input; - unsigned char *data = wacom->data; - int i; - int current_num_contacts = data[2]; - int contacts_to_send = 0; - int x_offset = 0; - - /* MTTPC does not support Height and Width */ - if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B) - x_offset = -4; - - /* - * First packet resets the counter since only the first - * packet in series will have non-zero current_num_contacts. - */ - if (current_num_contacts) - wacom->num_contacts_left = current_num_contacts; - - /* There are at most 5 contacts per packet */ - contacts_to_send = min(5, wacom->num_contacts_left); - - for (i = 0; i < contacts_to_send; i++) { - int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; - bool touch = data[offset] & 0x1; - int id = get_unaligned_le16(&data[offset + 1]); - int slot = input_mt_get_slot_by_key(input, id); - - if (slot < 0) - continue; - - input_mt_slot(input, slot); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - if (touch) { - int x = get_unaligned_le16(&data[offset + x_offset + 7]); - int y = get_unaligned_le16(&data[offset + x_offset + 9]); - input_report_abs(input, ABS_MT_POSITION_X, x); - input_report_abs(input, ABS_MT_POSITION_Y, y); - } - } - input_mt_report_pointer_emulation(input, true); - - wacom->num_contacts_left -= contacts_to_send; - if (wacom->num_contacts_left < 0) - wacom->num_contacts_left = 0; - - return 1; -} - -static int wacom_tpc_mt_touch(struct wacom_wac *wacom) -{ - struct input_dev *input = wacom->input; - unsigned char *data = wacom->data; - int contact_with_no_pen_down_count = 0; - int i; - - for (i = 0; i < 2; i++) { - int p = data[1] & (1 << i); - bool touch = p && !wacom->shared->stylus_in_proximity; - - input_mt_slot(input, i); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - if (touch) { - int x = le16_to_cpup((__le16 *)&data[i * 2 + 2]) & 0x7fff; - int y = le16_to_cpup((__le16 *)&data[i * 2 + 6]) & 0x7fff; - - input_report_abs(input, ABS_MT_POSITION_X, x); - input_report_abs(input, ABS_MT_POSITION_Y, y); - contact_with_no_pen_down_count++; - } - } - input_mt_report_pointer_emulation(input, true); - - /* keep touch state for pen event */ - wacom->shared->touch_down = (contact_with_no_pen_down_count > 0); - - return 1; -} - -static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) -{ - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - bool prox; - int x = 0, y = 0; - - if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG) - return 0; - - if (!wacom->shared->stylus_in_proximity) { - if (len == WACOM_PKGLEN_TPC1FG) { - prox = data[0] & 0x01; - x = get_unaligned_le16(&data[1]); - y = get_unaligned_le16(&data[3]); - } else if (len == WACOM_PKGLEN_TPC1FG_B) { - prox = data[2] & 0x01; - x = get_unaligned_le16(&data[3]); - y = get_unaligned_le16(&data[5]); - } else { - prox = data[1] & 0x01; - x = le16_to_cpup((__le16 *)&data[2]); - y = le16_to_cpup((__le16 *)&data[4]); - } - } else - /* force touch out when pen is in prox */ - prox = 0; - - if (prox) { - input_report_abs(input, ABS_X, x); - input_report_abs(input, ABS_Y, y); - } - input_report_key(input, BTN_TOUCH, prox); - - /* keep touch state for pen events */ - wacom->shared->touch_down = prox; - - return 1; -} - -static int wacom_tpc_pen(struct wacom_wac *wacom) -{ - unsigned char *data = wacom->data; - struct input_dev *input = wacom->input; - bool prox = data[1] & 0x20; - - if (!wacom->shared->stylus_in_proximity) /* first in prox */ - /* Going into proximity select tool */ - wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - - /* keep pen state for touch events */ - wacom->shared->stylus_in_proximity = prox; - - /* send pen events only when touch is up or forced out */ - if (!wacom->shared->touch_down) { - input_report_key(input, BTN_STYLUS, data[1] & 0x02); - input_report_key(input, BTN_STYLUS2, data[1] & 0x10); - input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); - input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); - input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x03) << 8) | data[6]); - input_report_key(input, BTN_TOUCH, data[1] & 0x05); - input_report_key(input, wacom->tool[0], prox); - return 1; - } - - return 0; -} - -static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) -{ - unsigned char *data = wacom->data; - - dev_dbg(wacom->input->dev.parent, - "%s: received report #%d\n", __func__, data[0]); - - switch (len) { - case WACOM_PKGLEN_TPC1FG: - return wacom_tpc_single_touch(wacom, len); - - case WACOM_PKGLEN_TPC2FG: - return wacom_tpc_mt_touch(wacom); - - case WACOM_PKGLEN_PENABLED: - return wacom_tpc_pen(wacom); - - default: - switch (data[0]) { - case WACOM_REPORT_TPC1FG: - case WACOM_REPORT_TPCHID: - case WACOM_REPORT_TPCST: - case WACOM_REPORT_TPC1FGE: - return wacom_tpc_single_touch(wacom, len); - - case WACOM_REPORT_TPCMT: - case WACOM_REPORT_TPCMT2: - return wacom_mt_touch(wacom); - - case WACOM_REPORT_PENABLED: - return wacom_tpc_pen(wacom); - } - } - - return 0; -} - -static int wacom_bpt_touch(struct wacom_wac *wacom) -{ - struct wacom_features *features = &wacom->features; - struct input_dev *input = wacom->input; - struct input_dev *pad_input = wacom->pad_input; - unsigned char *data = wacom->data; - int i; - - if (data[0] != 0x02) - return 0; - - for (i = 0; i < 2; i++) { - int offset = (data[1] & 0x80) ? (8 * i) : (9 * i); - bool touch = data[offset + 3] & 0x80; - - /* - * Touch events need to be disabled while stylus is - * in proximity because user's hand is resting on touchpad - * and sending unwanted events. User expects tablet buttons - * to continue working though. - */ - touch = touch && !wacom->shared->stylus_in_proximity; - - input_mt_slot(input, i); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - if (touch) { - int x = get_unaligned_be16(&data[offset + 3]) & 0x7ff; - int y = get_unaligned_be16(&data[offset + 5]) & 0x7ff; - if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) { - x <<= 5; - y <<= 5; - } - input_report_abs(input, ABS_MT_POSITION_X, x); - input_report_abs(input, ABS_MT_POSITION_Y, y); - } - } - - input_mt_report_pointer_emulation(input, true); - - input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0); - input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0); - input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0); - input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0); - - return 1; -} - -static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) -{ - struct wacom_features *features = &wacom->features; - struct input_dev *input = wacom->input; - bool touch = data[1] & 0x80; - int slot = input_mt_get_slot_by_key(input, data[0]); - - if (slot < 0) - return; - - touch = touch && !wacom->shared->stylus_in_proximity; - - input_mt_slot(input, slot); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - - if (touch) { - int x = (data[2] << 4) | (data[4] >> 4); - int y = (data[3] << 4) | (data[4] & 0x0f); - int width, height; - - if (features->type >= INTUOSPS && features->type <= INTUOSPL) { - width = data[5] * 100; - height = data[6] * 100; - } else { - /* - * "a" is a scaled-down area which we assume is - * roughly circular and which can be described as: - * a=(pi*r^2)/C. - */ - int a = data[5]; - int x_res = input_abs_get_res(input, ABS_X); - int y_res = input_abs_get_res(input, ABS_Y); - width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE); - height = width * y_res / x_res; - } - - input_report_abs(input, ABS_MT_POSITION_X, x); - input_report_abs(input, ABS_MT_POSITION_Y, y); - input_report_abs(input, ABS_MT_TOUCH_MAJOR, width); - input_report_abs(input, ABS_MT_TOUCH_MINOR, height); - } -} - -static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data) -{ - struct input_dev *input = wacom->pad_input; - struct wacom_features *features = &wacom->features; - - if (features->type == INTUOSHT) { - input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0); - input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0); - } else { - input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0); - input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); - } - input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); - input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0); -} - -static int wacom_bpt3_touch(struct wacom_wac *wacom) -{ - struct input_dev *input = wacom->input; - unsigned char *data = wacom->data; - int count = data[1] & 0x07; - int i; - - if (data[0] != 0x02) - return 0; - - /* data has up to 7 fixed sized 8-byte messages starting at data[2] */ - for (i = 0; i < count; i++) { - int offset = (8 * i) + 2; - int msg_id = data[offset]; - - if (msg_id >= 2 && msg_id <= 17) - wacom_bpt3_touch_msg(wacom, data + offset); - else if (msg_id == 128) - wacom_bpt3_button_msg(wacom, data + offset); - - } - input_mt_report_pointer_emulation(input, true); - - return 1; -} - -static int wacom_bpt_pen(struct wacom_wac *wacom) -{ - struct wacom_features *features = &wacom->features; - struct input_dev *input = wacom->input; - unsigned char *data = wacom->data; - int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; - - if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_USB) - return 0; - - if (data[0] == WACOM_REPORT_USB) { - if (features->type == INTUOSHT && features->touch_max) { - input_report_switch(wacom->shared->touch_input, - SW_MUTE_DEVICE, data[8] & 0x40); - input_sync(wacom->shared->touch_input); - } - return 0; - } - - prox = (data[1] & 0x20) == 0x20; - - /* - * All reports shared between PEN and RUBBER tool must be - * forced to a known starting value (zero) when transitioning to - * out-of-prox. - * - * If not reset then, to userspace, it will look like lost events - * if new tool comes in-prox with same values as previous tool sent. - * - * Hardware does report zero in most out-of-prox cases but not all. - */ - if (prox) { - if (!wacom->shared->stylus_in_proximity) { - if (data[1] & 0x08) { - wacom->tool[0] = BTN_TOOL_RUBBER; - wacom->id[0] = ERASER_DEVICE_ID; - } else { - wacom->tool[0] = BTN_TOOL_PEN; - wacom->id[0] = STYLUS_DEVICE_ID; - } - wacom->shared->stylus_in_proximity = true; - } - x = le16_to_cpup((__le16 *)&data[2]); - y = le16_to_cpup((__le16 *)&data[4]); - p = le16_to_cpup((__le16 *)&data[6]); - /* - * Convert distance from out prox to distance from tablet. - * distance will be greater than distance_max once - * touching and applying pressure; do not report negative - * distance. - */ - if (data[8] <= features->distance_max) - d = features->distance_max - data[8]; - - pen = data[1] & 0x01; - btn1 = data[1] & 0x02; - btn2 = data[1] & 0x04; - } - - input_report_key(input, BTN_TOUCH, pen); - input_report_key(input, BTN_STYLUS, btn1); - input_report_key(input, BTN_STYLUS2, btn2); - - input_report_abs(input, ABS_X, x); - input_report_abs(input, ABS_Y, y); - input_report_abs(input, ABS_PRESSURE, p); - input_report_abs(input, ABS_DISTANCE, d); - - if (!prox) { - wacom->id[0] = 0; - wacom->shared->stylus_in_proximity = false; - } - - input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */ - input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */ - - return 1; -} - -static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) -{ - if (len == WACOM_PKGLEN_BBTOUCH) - return wacom_bpt_touch(wacom); - else if (len == WACOM_PKGLEN_BBTOUCH3) - return wacom_bpt3_touch(wacom); - else if (len == WACOM_PKGLEN_BBFUN || len == WACOM_PKGLEN_BBPEN) - return wacom_bpt_pen(wacom); - - return 0; -} - -static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) -{ - unsigned char *data = wacom->data; - int connected; - - if (len != WACOM_PKGLEN_WIRELESS || data[0] != WACOM_REPORT_WL) - return 0; - - connected = data[1] & 0x01; - if (connected) { - int pid, battery; - - if ((wacom->shared->type == INTUOSHT) && - wacom->shared->touch_max) { - input_report_switch(wacom->shared->touch_input, - SW_MUTE_DEVICE, data[5] & 0x40); - input_sync(wacom->shared->touch_input); - } - - pid = get_unaligned_be16(&data[6]); - battery = data[5] & 0x3f; - if (wacom->pid != pid) { - wacom->pid = pid; - wacom_schedule_work(wacom); - } - wacom->battery_capacity = battery; - } else if (wacom->pid != 0) { - /* disconnected while previously connected */ - wacom->pid = 0; - wacom_schedule_work(wacom); - wacom->battery_capacity = 0; - } - - return 0; -} - -void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) -{ - bool sync; - - switch (wacom_wac->features.type) { - case PENPARTNER: - sync = wacom_penpartner_irq(wacom_wac); - break; - - case PL: - sync = wacom_pl_irq(wacom_wac); - break; - - case WACOM_G4: - case GRAPHIRE: - case WACOM_MO: - sync = wacom_graphire_irq(wacom_wac); - break; - - case PTU: - sync = wacom_ptu_irq(wacom_wac); - break; - - case DTU: - sync = wacom_dtu_irq(wacom_wac); - break; - - case DTUS: - sync = wacom_dtus_irq(wacom_wac); - break; - - case INTUOS: - case INTUOS3S: - case INTUOS3: - case INTUOS3L: - case INTUOS4S: - case INTUOS4: - case INTUOS4L: - case CINTIQ: - case WACOM_BEE: - case WACOM_13HD: - case WACOM_21UX2: - case WACOM_22HD: - case WACOM_24HD: - case DTK: - case CINTIQ_HYBRID: - sync = wacom_intuos_irq(wacom_wac); - break; - - case WACOM_24HDT: - sync = wacom_24hdt_irq(wacom_wac); - break; - - case INTUOS5S: - case INTUOS5: - case INTUOS5L: - case INTUOSPS: - case INTUOSPM: - case INTUOSPL: - if (len == WACOM_PKGLEN_BBTOUCH3) - sync = wacom_bpt3_touch(wacom_wac); - else - sync = wacom_intuos_irq(wacom_wac); - break; - - case TABLETPC: - case TABLETPCE: - case TABLETPC2FG: - case MTSCREEN: - case MTTPC: - case MTTPC_B: - sync = wacom_tpc_irq(wacom_wac, len); - break; - - case BAMBOO_PT: - case INTUOSHT: - sync = wacom_bpt_irq(wacom_wac, len); - break; - - case WIRELESS: - sync = wacom_wireless_irq(wacom_wac, len); - break; - - default: - sync = false; - break; - } - - if (sync) { - input_sync(wacom_wac->input); - if (wacom_wac->pad_input) - input_sync(wacom_wac->pad_input); - } -} - -static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) -{ - struct input_dev *input_dev = wacom_wac->input; - - input_set_capability(input_dev, EV_MSC, MSC_SERIAL); - - __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); - __set_bit(BTN_TOOL_PEN, input_dev->keybit); - __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); - __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); - __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); - __set_bit(BTN_STYLUS, input_dev->keybit); - __set_bit(BTN_STYLUS2, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_DISTANCE, - 0, wacom_wac->features.distance_max, 0, 0); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); - input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); -} - -static void wacom_setup_intuos(struct wacom_wac *wacom_wac) -{ - struct input_dev *input_dev = wacom_wac->input; - - input_set_capability(input_dev, EV_REL, REL_WHEEL); - - wacom_setup_cintiq(wacom_wac); - - __set_bit(BTN_LEFT, input_dev->keybit); - __set_bit(BTN_RIGHT, input_dev->keybit); - __set_bit(BTN_MIDDLE, input_dev->keybit); - __set_bit(BTN_SIDE, input_dev->keybit); - __set_bit(BTN_EXTRA, input_dev->keybit); - __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); - __set_bit(BTN_TOOL_LENS, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); -} - -void wacom_setup_device_quirks(struct wacom_features *features) -{ - - /* touch device found but size is not defined. use default */ - if (features->device_type == BTN_TOOL_FINGER && !features->x_max) { - features->x_max = 1023; - features->y_max = 1023; - } - - /* these device have multiple inputs */ - if (features->type >= WIRELESS || - (features->type >= INTUOS5S && features->type <= INTUOSHT) || - (features->oVid && features->oPid)) - features->quirks |= WACOM_QUIRK_MULTI_INPUT; - - /* quirk for bamboo touch with 2 low res touches */ - if (features->type == BAMBOO_PT && - features->pktlen == WACOM_PKGLEN_BBTOUCH) { - features->x_max <<= 5; - features->y_max <<= 5; - features->x_fuzz <<= 5; - features->y_fuzz <<= 5; - features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES; - } - - if (features->type == WIRELESS) { - - /* monitor never has input and pen/touch have delayed create */ - features->quirks |= WACOM_QUIRK_NO_INPUT; - - /* must be monitor interface if no device_type set */ - if (!features->device_type) - features->quirks |= WACOM_QUIRK_MONITOR; - } -} - -static void wacom_abs_set_axis(struct input_dev *input_dev, - struct wacom_wac *wacom_wac) -{ - struct wacom_features *features = &wacom_wac->features; - - if (features->device_type == BTN_TOOL_PEN) { - input_set_abs_params(input_dev, ABS_X, features->x_min, - features->x_max, features->x_fuzz, 0); - input_set_abs_params(input_dev, ABS_Y, features->y_min, - features->y_max, features->y_fuzz, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, - features->pressure_max, features->pressure_fuzz, 0); - - /* penabled devices have fixed resolution for each model */ - input_abs_set_res(input_dev, ABS_X, features->x_resolution); - input_abs_set_res(input_dev, ABS_Y, features->y_resolution); - } else { - if (features->touch_max <= 2) { - input_set_abs_params(input_dev, ABS_X, 0, - features->x_max, features->x_fuzz, 0); - input_set_abs_params(input_dev, ABS_Y, 0, - features->y_max, features->y_fuzz, 0); - input_abs_set_res(input_dev, ABS_X, - features->x_resolution); - input_abs_set_res(input_dev, ABS_Y, - features->y_resolution); - } - - if (features->touch_max > 1) { - input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, - features->x_max, features->x_fuzz, 0); - input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, - features->y_max, features->y_fuzz, 0); - input_abs_set_res(input_dev, ABS_MT_POSITION_X, - features->x_resolution); - input_abs_set_res(input_dev, ABS_MT_POSITION_Y, - features->y_resolution); - } - } -} - -int wacom_setup_input_capabilities(struct input_dev *input_dev, - struct wacom_wac *wacom_wac) -{ - struct wacom_features *features = &wacom_wac->features; - - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - - __set_bit(BTN_TOUCH, input_dev->keybit); - __set_bit(ABS_MISC, input_dev->absbit); - - wacom_abs_set_axis(input_dev, wacom_wac); - - switch (features->type) { - case WACOM_MO: - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); - /* fall through */ - - case WACOM_G4: - /* fall through */ - - case GRAPHIRE: - input_set_capability(input_dev, EV_REL, REL_WHEEL); - - __set_bit(BTN_LEFT, input_dev->keybit); - __set_bit(BTN_RIGHT, input_dev->keybit); - __set_bit(BTN_MIDDLE, input_dev->keybit); - - __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); - __set_bit(BTN_TOOL_PEN, input_dev->keybit); - __set_bit(BTN_TOOL_MOUSE, input_dev->keybit); - __set_bit(BTN_STYLUS, input_dev->keybit); - __set_bit(BTN_STYLUS2, input_dev->keybit); - - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - break; - - case WACOM_24HD: - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); - /* fall through */ - - case DTK: - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - - wacom_setup_cintiq(wacom_wac); - break; - - case WACOM_22HD: - case WACOM_21UX2: - case WACOM_BEE: - case CINTIQ: - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - - wacom_setup_cintiq(wacom_wac); - break; - - case WACOM_13HD: - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - wacom_setup_cintiq(wacom_wac); - break; - - case INTUOS3: - case INTUOS3L: - case INTUOS3S: - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - /* fall through */ - - case INTUOS: - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - - wacom_setup_intuos(wacom_wac); - break; - - case INTUOS5: - case INTUOS5L: - case INTUOSPM: - case INTUOSPL: - case INTUOS5S: - case INTUOSPS: - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - - if (features->device_type == BTN_TOOL_PEN) { - input_set_abs_params(input_dev, ABS_DISTANCE, 0, - features->distance_max, - 0, 0); - - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - - wacom_setup_intuos(wacom_wac); - } else if (features->device_type == BTN_TOOL_FINGER) { - __clear_bit(ABS_MISC, input_dev->absbit); - - input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, - 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, - 0, features->y_max, 0, 0); - input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER); - } - break; - - case INTUOS4: - case INTUOS4L: - case INTUOS4S: - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - wacom_setup_intuos(wacom_wac); - - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - break; - - case WACOM_24HDT: - if (features->device_type == BTN_TOOL_FINGER) { - input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0); - input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); - } - /* fall through */ - - case MTSCREEN: - case MTTPC: - case MTTPC_B: - case TABLETPC2FG: - if (features->device_type == BTN_TOOL_FINGER) { - unsigned int flags = INPUT_MT_DIRECT; - - if (wacom_wac->features.type == TABLETPC2FG) - flags = 0; - - input_mt_init_slots(input_dev, features->touch_max, flags); - } - /* fall through */ - - case TABLETPC: - case TABLETPCE: - __clear_bit(ABS_MISC, input_dev->absbit); - - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - - if (features->device_type != BTN_TOOL_PEN) - break; /* no need to process stylus stuff */ - - /* fall through */ - - case DTUS: - case PL: - case DTU: - __set_bit(BTN_TOOL_PEN, input_dev->keybit); - __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); - __set_bit(BTN_STYLUS, input_dev->keybit); - __set_bit(BTN_STYLUS2, input_dev->keybit); - - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - break; - - case PTU: - __set_bit(BTN_STYLUS2, input_dev->keybit); - /* fall through */ - - case PENPARTNER: - __set_bit(BTN_TOOL_PEN, input_dev->keybit); - __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); - __set_bit(BTN_STYLUS, input_dev->keybit); - - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - break; - - case INTUOSHT: - if (features->touch_max && - features->device_type == BTN_TOOL_FINGER) { - input_dev->evbit[0] |= BIT_MASK(EV_SW); - __set_bit(SW_MUTE_DEVICE, input_dev->swbit); - } - /* fall through */ - - case BAMBOO_PT: - __clear_bit(ABS_MISC, input_dev->absbit); - - if (features->device_type == BTN_TOOL_FINGER) { - - if (features->touch_max) { - /* touch interface */ - unsigned int flags = INPUT_MT_POINTER; - - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { - input_set_abs_params(input_dev, - ABS_MT_TOUCH_MAJOR, - 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, - ABS_MT_TOUCH_MINOR, - 0, features->y_max, 0, 0); - } else { - __set_bit(BTN_TOOL_FINGER, input_dev->keybit); - __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); - flags = 0; - } - input_mt_init_slots(input_dev, features->touch_max, flags); - } else { - /* buttons/keys only interface */ - __clear_bit(ABS_X, input_dev->absbit); - __clear_bit(ABS_Y, input_dev->absbit); - __clear_bit(BTN_TOUCH, input_dev->keybit); - } - } else if (features->device_type == BTN_TOOL_PEN) { - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); - __set_bit(BTN_TOOL_PEN, input_dev->keybit); - __set_bit(BTN_STYLUS, input_dev->keybit); - __set_bit(BTN_STYLUS2, input_dev->keybit); - input_set_abs_params(input_dev, ABS_DISTANCE, 0, - features->distance_max, - 0, 0); - } - break; - - case CINTIQ_HYBRID: - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - - wacom_setup_cintiq(wacom_wac); - break; - } - return 0; -} - -int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, - struct wacom_wac *wacom_wac) -{ - struct wacom_features *features = &wacom_wac->features; - int i; - - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - - /* kept for making legacy xf86-input-wacom working with the wheels */ - __set_bit(ABS_MISC, input_dev->absbit); - - /* kept for making legacy xf86-input-wacom accepting the pad */ - input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0); - - switch (features->type) { - case WACOM_MO: - __set_bit(BTN_BACK, input_dev->keybit); - __set_bit(BTN_LEFT, input_dev->keybit); - __set_bit(BTN_FORWARD, input_dev->keybit); - __set_bit(BTN_RIGHT, input_dev->keybit); - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); - break; - - case WACOM_G4: - __set_bit(BTN_BACK, input_dev->keybit); - __set_bit(BTN_LEFT, input_dev->keybit); - __set_bit(BTN_FORWARD, input_dev->keybit); - __set_bit(BTN_RIGHT, input_dev->keybit); - input_set_capability(input_dev, EV_REL, REL_WHEEL); - break; - - case WACOM_24HD: - __set_bit(BTN_A, input_dev->keybit); - __set_bit(BTN_B, input_dev->keybit); - __set_bit(BTN_C, input_dev->keybit); - __set_bit(BTN_X, input_dev->keybit); - __set_bit(BTN_Y, input_dev->keybit); - __set_bit(BTN_Z, input_dev->keybit); - - for (i = 0; i < 10; i++) - __set_bit(BTN_0 + i, input_dev->keybit); - - __set_bit(KEY_PROG1, input_dev->keybit); - __set_bit(KEY_PROG2, input_dev->keybit); - __set_bit(KEY_PROG3, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); - break; - - case DTK: - for (i = 0; i < 6; i++) - __set_bit(BTN_0 + i, input_dev->keybit); - - break; - - case WACOM_22HD: - __set_bit(KEY_PROG1, input_dev->keybit); - __set_bit(KEY_PROG2, input_dev->keybit); - __set_bit(KEY_PROG3, input_dev->keybit); - /* fall through */ - - case WACOM_21UX2: - __set_bit(BTN_A, input_dev->keybit); - __set_bit(BTN_B, input_dev->keybit); - __set_bit(BTN_C, input_dev->keybit); - __set_bit(BTN_X, input_dev->keybit); - __set_bit(BTN_Y, input_dev->keybit); - __set_bit(BTN_Z, input_dev->keybit); - __set_bit(BTN_BASE, input_dev->keybit); - __set_bit(BTN_BASE2, input_dev->keybit); - /* fall through */ - - case WACOM_BEE: - __set_bit(BTN_8, input_dev->keybit); - __set_bit(BTN_9, input_dev->keybit); - /* fall through */ - - case CINTIQ: - for (i = 0; i < 8; i++) - __set_bit(BTN_0 + i, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); - break; - - case WACOM_13HD: - for (i = 0; i < 9; i++) - __set_bit(BTN_0 + i, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); - break; - - case INTUOS3: - case INTUOS3L: - __set_bit(BTN_4, input_dev->keybit); - __set_bit(BTN_5, input_dev->keybit); - __set_bit(BTN_6, input_dev->keybit); - __set_bit(BTN_7, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); - /* fall through */ - - case INTUOS3S: - __set_bit(BTN_0, input_dev->keybit); - __set_bit(BTN_1, input_dev->keybit); - __set_bit(BTN_2, input_dev->keybit); - __set_bit(BTN_3, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); - break; - - case INTUOS5: - case INTUOS5L: - case INTUOSPM: - case INTUOSPL: - __set_bit(BTN_7, input_dev->keybit); - __set_bit(BTN_8, input_dev->keybit); - /* fall through */ - - case INTUOS5S: - case INTUOSPS: - /* touch interface does not have the pad device */ - if (features->device_type != BTN_TOOL_PEN) - return 1; - - for (i = 0; i < 7; i++) - __set_bit(BTN_0 + i, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); - break; - - case INTUOS4: - case INTUOS4L: - __set_bit(BTN_7, input_dev->keybit); - __set_bit(BTN_8, input_dev->keybit); - /* fall through */ - - case INTUOS4S: - for (i = 0; i < 7; i++) - __set_bit(BTN_0 + i, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); - break; - - case CINTIQ_HYBRID: - for (i = 0; i < 9; i++) - __set_bit(BTN_0 + i, input_dev->keybit); - - break; - - case DTUS: - for (i = 0; i < 4; i++) - __set_bit(BTN_0 + i, input_dev->keybit); - break; - - case INTUOSHT: - case BAMBOO_PT: - /* pad device is on the touch interface */ - if (features->device_type != BTN_TOOL_FINGER) - return 1; - - __clear_bit(ABS_MISC, input_dev->absbit); - - __set_bit(BTN_LEFT, input_dev->keybit); - __set_bit(BTN_FORWARD, input_dev->keybit); - __set_bit(BTN_BACK, input_dev->keybit); - __set_bit(BTN_RIGHT, input_dev->keybit); - - break; - - default: - /* no pad supported */ - return 1; - } - return 0; -} - -static const struct wacom_features wacom_features_0x00 = - { "Wacom Penpartner", 5040, 3780, 255, 0, - PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; -static const struct wacom_features wacom_features_0x10 = - { "Wacom Graphire", 10206, 7422, 511, 63, - GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; -static const struct wacom_features wacom_features_0x11 = - { "Wacom Graphire2 4x5", 10206, 7422, 511, 63, - GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; -static const struct wacom_features wacom_features_0x12 = - { "Wacom Graphire2 5x7", 13918, 10206, 511, 63, - GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; -static const struct wacom_features wacom_features_0x13 = - { "Wacom Graphire3", 10208, 7424, 511, 63, - GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; -static const struct wacom_features wacom_features_0x14 = - { "Wacom Graphire3 6x8", 16704, 12064, 511, 63, - GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; -static const struct wacom_features wacom_features_0x15 = - { "Wacom Graphire4 4x5", 10208, 7424, 511, 63, - WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; -static const struct wacom_features wacom_features_0x16 = - { "Wacom Graphire4 6x8", 16704, 12064, 511, 63, - WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; -static const struct wacom_features wacom_features_0x17 = - { "Wacom BambooFun 4x5", 14760, 9225, 511, 63, - WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x18 = - { "Wacom BambooFun 6x8", 21648, 13530, 511, 63, - WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x19 = - { "Wacom Bamboo1 Medium", 16704, 12064, 511, 63, - GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; -static const struct wacom_features wacom_features_0x60 = - { "Wacom Volito", 5104, 3712, 511, 63, - GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; -static const struct wacom_features wacom_features_0x61 = - { "Wacom PenStation2", 3250, 2320, 255, 63, - GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; -static const struct wacom_features wacom_features_0x62 = - { "Wacom Volito2 4x5", 5104, 3712, 511, 63, - GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; -static const struct wacom_features wacom_features_0x63 = - { "Wacom Volito2 2x3", 3248, 2320, 511, 63, - GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; -static const struct wacom_features wacom_features_0x64 = - { "Wacom PenPartner2", 3250, 2320, 511, 63, - GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; -static const struct wacom_features wacom_features_0x65 = - { "Wacom Bamboo", 14760, 9225, 511, 63, - WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x69 = - { "Wacom Bamboo1", 5104, 3712, 511, 63, - GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; -static const struct wacom_features wacom_features_0x6A = - { "Wacom Bamboo1 4x6", 14760, 9225, 1023, 63, - GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x6B = - { "Wacom Bamboo1 5x8", 21648, 13530, 1023, 63, - GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x20 = - { "Wacom Intuos 4x5", 12700, 10600, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x21 = - { "Wacom Intuos 6x8", 20320, 16240, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x22 = - { "Wacom Intuos 9x12", 30480, 24060, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x23 = - { "Wacom Intuos 12x12", 30480, 31680, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x24 = - { "Wacom Intuos 12x18", 45720, 31680, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x30 = - { "Wacom PL400", 5408, 4056, 255, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x31 = - { "Wacom PL500", 6144, 4608, 255, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x32 = - { "Wacom PL600", 6126, 4604, 255, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x33 = - { "Wacom PL600SX", 6260, 5016, 255, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x34 = - { "Wacom PL550", 6144, 4608, 511, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x35 = - { "Wacom PL800", 7220, 5780, 511, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x37 = - { "Wacom PL700", 6758, 5406, 511, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x38 = - { "Wacom PL510", 6282, 4762, 511, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x39 = - { "Wacom DTU710", 34080, 27660, 511, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0xC4 = - { "Wacom DTF521", 6282, 4762, 511, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0xC0 = - { "Wacom DTF720", 6858, 5506, 511, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0xC2 = - { "Wacom DTF720a", 6858, 5506, 511, 0, - PL, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x03 = - { "Wacom Cintiq Partner", 20480, 15360, 511, 0, - PTU, WACOM_PL_RES, WACOM_PL_RES }; -static const struct wacom_features wacom_features_0x41 = - { "Wacom Intuos2 4x5", 12700, 10600, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x42 = - { "Wacom Intuos2 6x8", 20320, 16240, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x43 = - { "Wacom Intuos2 9x12", 30480, 24060, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x44 = - { "Wacom Intuos2 12x12", 30480, 31680, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x45 = - { "Wacom Intuos2 12x18", 45720, 31680, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xB0 = - { "Wacom Intuos3 4x5", 25400, 20320, 1023, 63, - INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xB1 = - { "Wacom Intuos3 6x8", 40640, 30480, 1023, 63, - INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xB2 = - { "Wacom Intuos3 9x12", 60960, 45720, 1023, 63, - INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xB3 = - { "Wacom Intuos3 12x12", 60960, 60960, 1023, 63, - INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xB4 = - { "Wacom Intuos3 12x19", 97536, 60960, 1023, 63, - INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xB5 = - { "Wacom Intuos3 6x11", 54204, 31750, 1023, 63, - INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xB7 = - { "Wacom Intuos3 4x6", 31496, 19685, 1023, 63, - INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xB8 = - { "Wacom Intuos4 4x6", 31496, 19685, 2047, 63, - INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xB9 = - { "Wacom Intuos4 6x9", 44704, 27940, 2047, 63, - INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xBA = - { "Wacom Intuos4 8x13", 65024, 40640, 2047, 63, - INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xBB = - { "Wacom Intuos4 12x19", 97536, 60960, 2047, 63, - INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xBC = - { "Wacom Intuos4 WL", 40640, 25400, 2047, 63, - INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0x26 = - { "Wacom Intuos5 touch S", 31496, 19685, 2047, 63, - INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 }; -static const struct wacom_features wacom_features_0x27 = - { "Wacom Intuos5 touch M", 44704, 27940, 2047, 63, - INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 }; -static const struct wacom_features wacom_features_0x28 = - { "Wacom Intuos5 touch L", 65024, 40640, 2047, 63, - INTUOS5L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16 }; -static const struct wacom_features wacom_features_0x29 = - { "Wacom Intuos5 S", 31496, 19685, 2047, 63, - INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0x2A = - { "Wacom Intuos5 M", 44704, 27940, 2047, 63, - INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0x314 = - { "Wacom Intuos Pro S", 31496, 19685, 2047, 63, - INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; -static const struct wacom_features wacom_features_0x315 = - { "Wacom Intuos Pro M", 44704, 27940, 2047, 63, - INTUOSPM, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; -static const struct wacom_features wacom_features_0x317 = - { "Wacom Intuos Pro L", 65024, 40640, 2047, 63, - INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; -static const struct wacom_features wacom_features_0xF4 = - { "Wacom Cintiq 24HD", 104280, 65400, 2047, 63, - WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; -static const struct wacom_features wacom_features_0xF8 = - { "Wacom Cintiq 24HD touch", 104280, 65400, 2047, 63, /* Pen */ - WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; -static const struct wacom_features wacom_features_0xF6 = - { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; -static const struct wacom_features wacom_features_0x3F = - { "Wacom Cintiq 21UX", 87200, 65600, 1023, 63, - CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xC5 = - { "Wacom Cintiq 20WSX", 86680, 54180, 1023, 63, - WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0xC6 = - { "Wacom Cintiq 12WX", 53020, 33440, 1023, 63, - WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0x304 = - { "Wacom Cintiq 13HD", 59352, 33648, 1023, 63, - WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; -static const struct wacom_features wacom_features_0xC7 = - { "Wacom DTU1931", 37832, 30305, 511, 0, - PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xCE = - { "Wacom DTU2231", 47864, 27011, 511, 0, - DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBMOUSE }; -static const struct wacom_features wacom_features_0xF0 = - { "Wacom DTU1631", 34623, 19553, 511, 0, - DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xFB = - { "Wacom DTU1031", 22096, 13960, 511, 0, - DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x57 = - { "Wacom DTK2241", 95640, 54060, 2047, 63, - DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; -static const struct wacom_features wacom_features_0x59 = /* Pen */ - { "Wacom DTH2242", 95640, 54060, 2047, 63, - DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D }; -static const struct wacom_features wacom_features_0x5D = /* Touch */ - { "Wacom DTH2242", .type = WACOM_24HDT, - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; -static const struct wacom_features wacom_features_0xCC = - { "Wacom Cintiq 21UX2", 87000, 65400, 2047, 63, - WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; -static const struct wacom_features wacom_features_0xFA = - { "Wacom Cintiq 22HD", 95640, 54060, 2047, 63, - WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200 }; -static const struct wacom_features wacom_features_0x5B = - { "Wacom Cintiq 22HDT", 95640, 54060, 2047, 63, - WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; -static const struct wacom_features wacom_features_0x5E = - { "Wacom Cintiq 22HDT", .type = WACOM_24HDT, - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; -static const struct wacom_features wacom_features_0x90 = - { "Wacom ISDv4 90", 26202, 16325, 255, 0, - TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x93 = - { "Wacom ISDv4 93", 26202, 16325, 255, 0, - TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x97 = - { "Wacom ISDv4 97", 26202, 16325, 511, 0, - TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x9A = - { "Wacom ISDv4 9A", 26202, 16325, 255, 0, - TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x9F = - { "Wacom ISDv4 9F", 26202, 16325, 255, 0, - TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xE2 = - { "Wacom ISDv4 E2", 26202, 16325, 255, 0, - TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xE3 = - { "Wacom ISDv4 E3", 26202, 16325, 255, 0, - TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xE5 = - { "Wacom ISDv4 E5", 26202, 16325, 255, 0, - MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xE6 = - { "Wacom ISDv4 E6", 27760, 15694, 255, 0, - TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xEC = - { "Wacom ISDv4 EC", 25710, 14500, 255, 0, - TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xED = - { "Wacom ISDv4 ED", 26202, 16325, 255, 0, - TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xEF = - { "Wacom ISDv4 EF", 26202, 16325, 255, 0, - TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x100 = - { "Wacom ISDv4 100", 26202, 16325, 255, 0, - MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x101 = - { "Wacom ISDv4 101", 26202, 16325, 255, 0, - MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x10D = - { "Wacom ISDv4 10D", 26202, 16325, 255, 0, - MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x10E = - { "Wacom ISDv4 10E", 27760, 15694, 255, 0, - MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x10F = - { "Wacom ISDv4 10F", 27760, 15694, 255, 0, - MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x116 = - { "Wacom ISDv4 116", 26202, 16325, 255, 0, - TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x4001 = - { "Wacom ISDv4 4001", 26202, 16325, 255, 0, - MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x4004 = - { "Wacom ISDv4 4004", 11060, 6220, 255, 0, - MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x5000 = - { "Wacom ISDv4 5000", 27848, 15752, 1023, 0, - MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x5002 = - { "Wacom ISDv4 5002", 29576, 16724, 1023, 0, - MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x47 = - { "Wacom Intuos2 6x8", 20320, 16240, 1023, 31, - INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x84 = - { "Wacom Wireless Receiver", 0, 0, 0, 0, - WIRELESS, 0, 0, .touch_max = 16 }; -static const struct wacom_features wacom_features_0xD0 = - { "Wacom Bamboo 2FG", 14720, 9200, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xD1 = - { "Wacom Bamboo 2FG 4x5", 14720, 9200, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xD2 = - { "Wacom Bamboo Craft", 14720, 9200, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xD3 = - { "Wacom Bamboo 2FG 6x8", 21648, 13700, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xD4 = - { "Wacom Bamboo Pen", 14720, 9200, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xD5 = - { "Wacom Bamboo Pen 6x8", 21648, 13700, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xD6 = - { "Wacom BambooPT 2FG 4x5", 14720, 9200, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xD7 = - { "Wacom BambooPT 2FG Small", 14720, 9200, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xD8 = - { "Wacom Bamboo Comic 2FG", 21648, 13700, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xDA = - { "Wacom Bamboo 2FG 4x5 SE", 14720, 9200, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xDB = - { "Wacom Bamboo 2FG 6x8 SE", 21648, 13700, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; -static const struct wacom_features wacom_features_0xDD = - { "Wacom Bamboo Connect", 14720, 9200, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0xDE = - { "Wacom Bamboo 16FG 4x5", 14720, 9200, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16 }; -static const struct wacom_features wacom_features_0xDF = - { "Wacom Bamboo 16FG 6x8", 21648, 13700, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16 }; -static const struct wacom_features wacom_features_0x300 = - { "Wacom Bamboo One S", 14720, 9225, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x301 = - { "Wacom Bamboo One M", 21648, 13530, 1023, 31, - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x302 = - { "Wacom Intuos PT S", 15200, 9500, 1023, 31, - INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; -static const struct wacom_features wacom_features_0x303 = - { "Wacom Intuos PT M", 21600, 13500, 1023, 31, - INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; -static const struct wacom_features wacom_features_0x30E = - { "Wacom Intuos S", 15200, 9500, 1023, 31, - INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; -static const struct wacom_features wacom_features_0x6004 = - { "ISD-V4", 12800, 8000, 255, 0, - TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x307 = - { "Wacom ISDv5 307", 59352, 33648, 2047, 63, - CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 200, 200, - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 }; -static const struct wacom_features wacom_features_0x309 = - { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */ - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10, - .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; - -#define USB_DEVICE_WACOM(prod) \ - HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ - .driver_data = (kernel_ulong_t)&wacom_features_##prod - -#define USB_DEVICE_LENOVO(prod) \ - HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ - .driver_data = (kernel_ulong_t)&wacom_features_##prod - -const struct hid_device_id wacom_ids[] = { - { USB_DEVICE_WACOM(0x00) }, - { USB_DEVICE_WACOM(0x03) }, - { USB_DEVICE_WACOM(0x10) }, - { USB_DEVICE_WACOM(0x11) }, - { USB_DEVICE_WACOM(0x12) }, - { USB_DEVICE_WACOM(0x13) }, - { USB_DEVICE_WACOM(0x14) }, - { USB_DEVICE_WACOM(0x15) }, - { USB_DEVICE_WACOM(0x16) }, - { USB_DEVICE_WACOM(0x17) }, - { USB_DEVICE_WACOM(0x18) }, - { USB_DEVICE_WACOM(0x19) }, - { USB_DEVICE_WACOM(0x20) }, - { USB_DEVICE_WACOM(0x21) }, - { USB_DEVICE_WACOM(0x22) }, - { USB_DEVICE_WACOM(0x23) }, - { USB_DEVICE_WACOM(0x24) }, - { USB_DEVICE_WACOM(0x26) }, - { USB_DEVICE_WACOM(0x27) }, - { USB_DEVICE_WACOM(0x28) }, - { USB_DEVICE_WACOM(0x29) }, - { USB_DEVICE_WACOM(0x2A) }, - { USB_DEVICE_WACOM(0x30) }, - { USB_DEVICE_WACOM(0x31) }, - { USB_DEVICE_WACOM(0x32) }, - { USB_DEVICE_WACOM(0x33) }, - { USB_DEVICE_WACOM(0x34) }, - { USB_DEVICE_WACOM(0x35) }, - { USB_DEVICE_WACOM(0x37) }, - { USB_DEVICE_WACOM(0x38) }, - { USB_DEVICE_WACOM(0x39) }, - { USB_DEVICE_WACOM(0x3F) }, - { USB_DEVICE_WACOM(0x41) }, - { USB_DEVICE_WACOM(0x42) }, - { USB_DEVICE_WACOM(0x43) }, - { USB_DEVICE_WACOM(0x44) }, - { USB_DEVICE_WACOM(0x45) }, - { USB_DEVICE_WACOM(0x47) }, - { USB_DEVICE_WACOM(0x57) }, - { USB_DEVICE_WACOM(0x59) }, - { USB_DEVICE_WACOM(0x5B) }, - { USB_DEVICE_WACOM(0x5D) }, - { USB_DEVICE_WACOM(0x5E) }, - { USB_DEVICE_WACOM(0x60) }, - { USB_DEVICE_WACOM(0x61) }, - { USB_DEVICE_WACOM(0x62) }, - { USB_DEVICE_WACOM(0x63) }, - { USB_DEVICE_WACOM(0x64) }, - { USB_DEVICE_WACOM(0x65) }, - { USB_DEVICE_WACOM(0x69) }, - { USB_DEVICE_WACOM(0x6A) }, - { USB_DEVICE_WACOM(0x6B) }, - { USB_DEVICE_WACOM(0x84) }, - { USB_DEVICE_WACOM(0x90) }, - { USB_DEVICE_WACOM(0x93) }, - { USB_DEVICE_WACOM(0x97) }, - { USB_DEVICE_WACOM(0x9A) }, - { USB_DEVICE_WACOM(0x9F) }, - { USB_DEVICE_WACOM(0xB0) }, - { USB_DEVICE_WACOM(0xB1) }, - { USB_DEVICE_WACOM(0xB2) }, - { USB_DEVICE_WACOM(0xB3) }, - { USB_DEVICE_WACOM(0xB4) }, - { USB_DEVICE_WACOM(0xB5) }, - { USB_DEVICE_WACOM(0xB7) }, - { USB_DEVICE_WACOM(0xB8) }, - { USB_DEVICE_WACOM(0xB9) }, - { USB_DEVICE_WACOM(0xBA) }, - { USB_DEVICE_WACOM(0xBB) }, - { USB_DEVICE_WACOM(0xBC) }, - { USB_DEVICE_WACOM(0xC0) }, - { USB_DEVICE_WACOM(0xC2) }, - { USB_DEVICE_WACOM(0xC4) }, - { USB_DEVICE_WACOM(0xC5) }, - { USB_DEVICE_WACOM(0xC6) }, - { USB_DEVICE_WACOM(0xC7) }, - { USB_DEVICE_WACOM(0xCC) }, - { USB_DEVICE_WACOM(0xCE) }, - { USB_DEVICE_WACOM(0xD0) }, - { USB_DEVICE_WACOM(0xD1) }, - { USB_DEVICE_WACOM(0xD2) }, - { USB_DEVICE_WACOM(0xD3) }, - { USB_DEVICE_WACOM(0xD4) }, - { USB_DEVICE_WACOM(0xD5) }, - { USB_DEVICE_WACOM(0xD6) }, - { USB_DEVICE_WACOM(0xD7) }, - { USB_DEVICE_WACOM(0xD8) }, - { USB_DEVICE_WACOM(0xDA) }, - { USB_DEVICE_WACOM(0xDB) }, - { USB_DEVICE_WACOM(0xDD) }, - { USB_DEVICE_WACOM(0xDE) }, - { USB_DEVICE_WACOM(0xDF) }, - { USB_DEVICE_WACOM(0xE2) }, - { USB_DEVICE_WACOM(0xE3) }, - { USB_DEVICE_WACOM(0xE5) }, - { USB_DEVICE_WACOM(0xE6) }, - { USB_DEVICE_WACOM(0xEC) }, - { USB_DEVICE_WACOM(0xED) }, - { USB_DEVICE_WACOM(0xEF) }, - { USB_DEVICE_WACOM(0xF0) }, - { USB_DEVICE_WACOM(0xF4) }, - { USB_DEVICE_WACOM(0xF6) }, - { USB_DEVICE_WACOM(0xF8) }, - { USB_DEVICE_WACOM(0xFA) }, - { USB_DEVICE_WACOM(0xFB) }, - { USB_DEVICE_WACOM(0x100) }, - { USB_DEVICE_WACOM(0x101) }, - { USB_DEVICE_WACOM(0x10D) }, - { USB_DEVICE_WACOM(0x10E) }, - { USB_DEVICE_WACOM(0x10F) }, - { USB_DEVICE_WACOM(0x116) }, - { USB_DEVICE_WACOM(0x300) }, - { USB_DEVICE_WACOM(0x301) }, - { USB_DEVICE_WACOM(0x302) }, - { USB_DEVICE_WACOM(0x303) }, - { USB_DEVICE_WACOM(0x304) }, - { USB_DEVICE_WACOM(0x307) }, - { USB_DEVICE_WACOM(0x309) }, - { USB_DEVICE_WACOM(0x30E) }, - { USB_DEVICE_WACOM(0x314) }, - { USB_DEVICE_WACOM(0x315) }, - { USB_DEVICE_WACOM(0x317) }, - { USB_DEVICE_WACOM(0x4001) }, - { USB_DEVICE_WACOM(0x4004) }, - { USB_DEVICE_WACOM(0x5000) }, - { USB_DEVICE_WACOM(0x5002) }, - { } -}; -MODULE_DEVICE_TABLE(hid, wacom_ids); diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h deleted file mode 100644 index 4c592475b237..000000000000 --- a/drivers/input/tablet/wacom_wac.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * drivers/input/tablet/wacom_wac.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ -#ifndef WACOM_WAC_H -#define WACOM_WAC_H - -#include <linux/types.h> - -/* maximum packet length for USB devices */ -#define WACOM_PKGLEN_MAX 68 - -#define WACOM_NAME_MAX 64 - -/* packet length for individual models */ -#define WACOM_PKGLEN_PENPRTN 7 -#define WACOM_PKGLEN_GRAPHIRE 8 -#define WACOM_PKGLEN_BBFUN 9 -#define WACOM_PKGLEN_INTUOS 10 -#define WACOM_PKGLEN_TPC1FG 5 -#define WACOM_PKGLEN_TPC1FG_B 10 -#define WACOM_PKGLEN_TPC2FG 14 -#define WACOM_PKGLEN_BBTOUCH 20 -#define WACOM_PKGLEN_BBTOUCH3 64 -#define WACOM_PKGLEN_BBPEN 10 -#define WACOM_PKGLEN_WIRELESS 32 -#define WACOM_PKGLEN_MTOUCH 62 -#define WACOM_PKGLEN_MTTPC 40 -#define WACOM_PKGLEN_DTUS 68 -#define WACOM_PKGLEN_PENABLED 8 - -/* wacom data size per MT contact */ -#define WACOM_BYTES_PER_MT_PACKET 11 -#define WACOM_BYTES_PER_24HDT_PACKET 14 - -/* 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 - -/* wacom data packet report IDs */ -#define WACOM_REPORT_PENABLED 2 -#define WACOM_REPORT_INTUOSREAD 5 -#define WACOM_REPORT_INTUOSWRITE 6 -#define WACOM_REPORT_INTUOSPAD 12 -#define WACOM_REPORT_INTUOS5PAD 3 -#define WACOM_REPORT_DTUSPAD 21 -#define WACOM_REPORT_TPC1FG 6 -#define WACOM_REPORT_TPC2FG 13 -#define WACOM_REPORT_TPCMT 13 -#define WACOM_REPORT_TPCMT2 3 -#define WACOM_REPORT_TPCHID 15 -#define WACOM_REPORT_TPCST 16 -#define WACOM_REPORT_DTUS 17 -#define WACOM_REPORT_TPC1FGE 18 -#define WACOM_REPORT_24HDT 1 -#define WACOM_REPORT_WL 128 -#define WACOM_REPORT_USB 192 - -/* device quirks */ -#define WACOM_QUIRK_MULTI_INPUT 0x0001 -#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002 -#define WACOM_QUIRK_NO_INPUT 0x0004 -#define WACOM_QUIRK_MONITOR 0x0008 - -enum { - PENPARTNER = 0, - GRAPHIRE, - WACOM_G4, - PTU, - PL, - DTU, - DTUS, - INTUOS, - INTUOS3S, - INTUOS3, - INTUOS3L, - INTUOS4S, - INTUOS4, - INTUOS4L, - INTUOS5S, - INTUOS5, - INTUOS5L, - INTUOSPS, - INTUOSPM, - INTUOSPL, - INTUOSHT, - WACOM_21UX2, - WACOM_22HD, - DTK, - WACOM_24HD, - CINTIQ_HYBRID, - CINTIQ, - WACOM_BEE, - WACOM_13HD, - WACOM_MO, - WIRELESS, - BAMBOO_PT, - WACOM_24HDT, - TABLETPC, /* add new TPC below */ - TABLETPCE, - TABLETPC2FG, - MTSCREEN, - MTTPC, - MTTPC_B, - MAX_TYPE -}; - -struct wacom_features { - const char *name; - int x_max; - int y_max; - int pressure_max; - int distance_max; - int type; - int x_resolution; - int y_resolution; - int x_min; - int y_min; - int device_type; - int x_phy; - int y_phy; - unsigned unit; - int unitExpo; - int x_fuzz; - int y_fuzz; - int pressure_fuzz; - int distance_fuzz; - unsigned quirks; - unsigned touch_max; - int oVid; - int oPid; - int pktlen; - bool check_for_hid_type; - int hid_type; -}; - -struct wacom_shared { - bool stylus_in_proximity; - bool touch_down; - /* for wireless device to access USB interfaces */ - unsigned touch_max; - int type; - struct input_dev *touch_input; -}; - -struct wacom_wac { - char name[WACOM_NAME_MAX]; - char pad_name[WACOM_NAME_MAX]; - unsigned char data[WACOM_PKGLEN_MAX]; - int tool[2]; - int id[2]; - __u32 serial[2]; - struct wacom_features features; - struct wacom_shared *shared; - struct input_dev *input; - struct input_dev *pad_input; - int pid; - int battery_capacity; - int num_contacts_left; -}; - -#endif |