#define WAC_CMD_ICON_XFER 0x23
#define WAC_CMD_ICON_BT_XFER 0x26
#define WAC_CMD_RETRIES 10
+++++++++++ #define WAC_CMD_DELETE_PAIRING 0x20
+++++++++++ #define WAC_CMD_UNPAIR_ALL 0xFF
+++++++++++ #define WAC_REMOTE_SERIAL_MAX_STRLEN 9
#define DEV_ATTR_RW_PERM (S_IRUGO | S_IWUSR | S_IWGRP)
#define DEV_ATTR_WO_PERM (S_IWUSR | S_IWGRP)
+++++++++++ #define DEV_ATTR_RO_PERM (S_IRUSR | S_IRGRP)
static int wacom_get_report(struct hid_device *hdev, u8 type, u8 *buf,
size_t size, unsigned int retries)
if (error >= 0)
error = wacom_get_report(hdev, HID_FEATURE_REPORT,
rep_data, length, 1);
---------- } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES);
++++++++++ } while (error >= 0 && rep_data[1] != mode && limit++ < WAC_MSG_RETRIES);
kfree(rep_data);
* interface number.
*/
if (features->type == WIRELESS) {
----------- if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
+++++++++++ if (intf->cur_altsetting->desc.bInterfaceNumber == 0)
+++++++++++ features->device_type = WACOM_DEVICETYPE_WL_MONITOR;
+++++++++++ else
features->device_type = WACOM_DEVICETYPE_NONE;
----------- } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) {
----------- features->device_type |= WACOM_DEVICETYPE_TOUCH;
----------- features->pktlen = WACOM_PKGLEN_BBTOUCH3;
----------- }
+++++++++++ return;
}
wacom_parse_hid(hdev, features);
static DEVICE_ATTR(speed, DEV_ATTR_RW_PERM,
wacom_show_speed, wacom_store_speed);
+++++++++++
+++++++++++ static ssize_t wacom_show_remote_mode(struct kobject *kobj,
+++++++++++ struct kobj_attribute *kattr,
+++++++++++ char *buf, int index)
+++++++++++ {
+++++++++++ struct device *dev = container_of(kobj->parent, struct device, kobj);
+++++++++++ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+++++++++++ struct wacom *wacom = hid_get_drvdata(hdev);
+++++++++++ u8 mode;
+++++++++++
+++++++++++ mode = wacom->led.select[index];
+++++++++++ if (mode >= 0 && mode < 3)
+++++++++++ return snprintf(buf, PAGE_SIZE, "%d\n", mode);
+++++++++++ else
+++++++++++ return snprintf(buf, PAGE_SIZE, "%d\n", -1);
+++++++++++ }
+++++++++++
+++++++++++ #define DEVICE_EKR_ATTR_GROUP(SET_ID) \
+++++++++++ static ssize_t wacom_show_remote##SET_ID##_mode(struct kobject *kobj, \
+++++++++++ struct kobj_attribute *kattr, char *buf) \
+++++++++++ { \
+++++++++++ return wacom_show_remote_mode(kobj, kattr, buf, SET_ID); \
+++++++++++ } \
+++++++++++ static struct kobj_attribute remote##SET_ID##_mode_attr = { \
+++++++++++ .attr = {.name = "remote_mode", \
+++++++++++ .mode = DEV_ATTR_RO_PERM}, \
+++++++++++ .show = wacom_show_remote##SET_ID##_mode, \
+++++++++++ }; \
+++++++++++ static struct attribute *remote##SET_ID##_serial_attrs[] = { \
+++++++++++ &remote##SET_ID##_mode_attr.attr, \
+++++++++++ NULL \
+++++++++++ }; \
+++++++++++ static struct attribute_group remote##SET_ID##_serial_group = { \
+++++++++++ .name = NULL, \
+++++++++++ .attrs = remote##SET_ID##_serial_attrs, \
+++++++++++ }
+++++++++++
+++++++++++ DEVICE_EKR_ATTR_GROUP(0);
+++++++++++ DEVICE_EKR_ATTR_GROUP(1);
+++++++++++ DEVICE_EKR_ATTR_GROUP(2);
+++++++++++ DEVICE_EKR_ATTR_GROUP(3);
+++++++++++ DEVICE_EKR_ATTR_GROUP(4);
+++++++++++
+++++++++++ int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial, int index)
+++++++++++ {
+++++++++++ int error = 0;
+++++++++++ char *buf;
+++++++++++ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+++++++++++
+++++++++++ wacom_wac->serial[index] = serial;
+++++++++++
+++++++++++ buf = kzalloc(WAC_REMOTE_SERIAL_MAX_STRLEN, GFP_KERNEL);
+++++++++++ if (!buf)
+++++++++++ return -ENOMEM;
+++++++++++ snprintf(buf, WAC_REMOTE_SERIAL_MAX_STRLEN, "%d", serial);
+++++++++++ wacom->remote_group[index].name = buf;
+++++++++++
+++++++++++ error = sysfs_create_group(wacom->remote_dir,
+++++++++++ &wacom->remote_group[index]);
+++++++++++ if (error) {
+++++++++++ hid_err(wacom->hdev,
+++++++++++ "cannot create sysfs group err: %d\n", error);
+++++++++++ kobject_put(wacom->remote_dir);
+++++++++++ return error;
+++++++++++ }
+++++++++++
+++++++++++ return 0;
+++++++++++ }
+++++++++++
+++++++++++ void wacom_remote_destroy_attr_group(struct wacom *wacom, __u32 serial)
+++++++++++ {
+++++++++++ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+++++++++++ int i;
+++++++++++
+++++++++++ if (!serial)
+++++++++++ return;
+++++++++++
+++++++++++ for (i = 0; i < WACOM_MAX_REMOTES; i++) {
+++++++++++ if (wacom_wac->serial[i] == serial) {
+++++++++++ wacom_wac->serial[i] = 0;
+++++++++++ wacom->led.select[i] = WACOM_STATUS_UNKNOWN;
+++++++++++ if (wacom->remote_group[i].name) {
+++++++++++ sysfs_remove_group(wacom->remote_dir,
+++++++++++ &wacom->remote_group[i]);
+++++++++++ kfree(wacom->remote_group[i].name);
+++++++++++ wacom->remote_group[i].name = NULL;
+++++++++++ }
+++++++++++ }
+++++++++++ }
+++++++++++ }
+++++++++++
+++++++++++ static int wacom_cmd_unpair_remote(struct wacom *wacom, unsigned char selector)
+++++++++++ {
+++++++++++ const size_t buf_size = 2;
+++++++++++ unsigned char *buf;
+++++++++++ int retval;
+++++++++++
+++++++++++ buf = kzalloc(buf_size, GFP_KERNEL);
+++++++++++ if (!buf)
+++++++++++ return -ENOMEM;
+++++++++++
+++++++++++ buf[0] = WAC_CMD_DELETE_PAIRING;
+++++++++++ buf[1] = selector;
+++++++++++
+++++++++++ retval = wacom_set_report(wacom->hdev, HID_OUTPUT_REPORT, buf,
+++++++++++ buf_size, WAC_CMD_RETRIES);
+++++++++++ kfree(buf);
+++++++++++
+++++++++++ return retval;
+++++++++++ }
+++++++++++
+++++++++++ static ssize_t wacom_store_unpair_remote(struct kobject *kobj,
+++++++++++ struct kobj_attribute *attr,
+++++++++++ const char *buf, size_t count)
+++++++++++ {
+++++++++++ unsigned char selector = 0;
+++++++++++ struct device *dev = container_of(kobj->parent, struct device, kobj);
+++++++++++ struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+++++++++++ struct wacom *wacom = hid_get_drvdata(hdev);
+++++++++++ int err;
+++++++++++
+++++++++++ if (!strncmp(buf, "*\n", 2)) {
+++++++++++ selector = WAC_CMD_UNPAIR_ALL;
+++++++++++ } else {
+++++++++++ hid_info(wacom->hdev, "remote: unrecognized unpair code: %s\n",
+++++++++++ buf);
+++++++++++ return -1;
+++++++++++ }
+++++++++++
+++++++++++ mutex_lock(&wacom->lock);
+++++++++++
+++++++++++ err = wacom_cmd_unpair_remote(wacom, selector);
+++++++++++ mutex_unlock(&wacom->lock);
+++++++++++
+++++++++++ return err < 0 ? err : count;
+++++++++++ }
+++++++++++
+++++++++++ static struct kobj_attribute unpair_remote_attr = {
+++++++++++ .attr = {.name = "unpair_remote", .mode = 0200},
+++++++++++ .store = wacom_store_unpair_remote,
+++++++++++ };
+++++++++++
+++++++++++ static const struct attribute *remote_unpair_attrs[] = {
+++++++++++ &unpair_remote_attr.attr,
+++++++++++ NULL
+++++++++++ };
+++++++++++
+++++++++++ static int wacom_initialize_remote(struct wacom *wacom)
+++++++++++ {
+++++++++++ int error = 0;
+++++++++++ struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
+++++++++++ int i;
+++++++++++
+++++++++++ if (wacom->wacom_wac.features.type != REMOTE)
+++++++++++ return 0;
+++++++++++
+++++++++++ wacom->remote_group[0] = remote0_serial_group;
+++++++++++ wacom->remote_group[1] = remote1_serial_group;
+++++++++++ wacom->remote_group[2] = remote2_serial_group;
+++++++++++ wacom->remote_group[3] = remote3_serial_group;
+++++++++++ wacom->remote_group[4] = remote4_serial_group;
+++++++++++
+++++++++++ wacom->remote_dir = kobject_create_and_add("wacom_remote",
+++++++++++ &wacom->hdev->dev.kobj);
+++++++++++ if (!wacom->remote_dir)
+++++++++++ return -ENOMEM;
+++++++++++
+++++++++++ error = sysfs_create_files(wacom->remote_dir, remote_unpair_attrs);
+++++++++++
+++++++++++ if (error) {
+++++++++++ hid_err(wacom->hdev,
+++++++++++ "cannot create sysfs group err: %d\n", error);
+++++++++++ return error;
+++++++++++ }
+++++++++++
+++++++++++ for (i = 0; i < WACOM_MAX_REMOTES; i++) {
+++++++++++ wacom->led.select[i] = WACOM_STATUS_UNKNOWN;
+++++++++++ wacom_wac->serial[i] = 0;
+++++++++++ }
+++++++++++
+++++++++++ return 0;
+++++++++++ }
+++++++++++
static struct input_dev *wacom_allocate_input(struct wacom *wacom)
{
struct input_dev *input_dev;
if (!input_dev)
return NULL;
----------- input_dev->name = wacom_wac->pen_name;
+++++++++++ input_dev->name = wacom_wac->features.name;
input_dev->phys = hdev->phys;
input_dev->dev.parent = &hdev->dev;
input_dev->open = wacom_open;
return input_dev;
}
----------- static void wacom_free_inputs(struct wacom *wacom)
----------- {
----------- struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
-----------
- input_free_device(wacom_wac->pen_input);
- input_free_device(wacom_wac->touch_input);
- input_free_device(wacom_wac->pad_input);
---------- if (wacom_wac->pen_input)
---------- input_free_device(wacom_wac->pen_input);
---------- if (wacom_wac->touch_input)
---------- input_free_device(wacom_wac->touch_input);
---------- if (wacom_wac->pad_input)
---------- input_free_device(wacom_wac->pad_input);
----------- wacom_wac->pen_input = NULL;
----------- wacom_wac->touch_input = NULL;
----------- wacom_wac->pad_input = NULL;
----------- }
-----------
----------- static int wacom_allocate_inputs(struct wacom *wacom)
----------- {
----------- struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev;
----------- struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
-----------
----------- pen_input_dev = wacom_allocate_input(wacom);
----------- touch_input_dev = wacom_allocate_input(wacom);
----------- pad_input_dev = wacom_allocate_input(wacom);
----------- if (!pen_input_dev || !touch_input_dev || !pad_input_dev) {
----------- wacom_free_inputs(wacom);
----------- return -ENOMEM;
----------- }
-----------
----------- wacom_wac->pen_input = pen_input_dev;
----------- wacom_wac->touch_input = touch_input_dev;
----------- wacom_wac->touch_input->name = wacom_wac->touch_name;
----------- wacom_wac->pad_input = pad_input_dev;
----------- wacom_wac->pad_input->name = wacom_wac->pad_name;
-----------
----------- return 0;
----------- }
-----------
static void wacom_clean_inputs(struct wacom *wacom)
{
if (wacom->wacom_wac.pen_input) {
else
input_free_device(wacom->wacom_wac.pad_input);
}
+++++++++++ if (wacom->remote_dir)
+++++++++++ kobject_put(wacom->remote_dir);
wacom->wacom_wac.pen_input = NULL;
wacom->wacom_wac.touch_input = NULL;
wacom->wacom_wac.pad_input = NULL;
wacom_destroy_leds(wacom);
}
+++++++++++ static int wacom_allocate_inputs(struct wacom *wacom)
+++++++++++ {
+++++++++++ struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
+++++++++++
+++++++++++ wacom_wac->pen_input = wacom_allocate_input(wacom);
+++++++++++ wacom_wac->touch_input = wacom_allocate_input(wacom);
+++++++++++ wacom_wac->pad_input = wacom_allocate_input(wacom);
+++++++++++ if (!wacom_wac->pen_input || !wacom_wac->touch_input || !wacom_wac->pad_input) {
+++++++++++ wacom_clean_inputs(wacom);
+++++++++++ return -ENOMEM;
+++++++++++ }
+++++++++++
+++++++++++ wacom_wac->pen_input->name = wacom_wac->pen_name;
+++++++++++ wacom_wac->touch_input->name = wacom_wac->touch_name;
+++++++++++ wacom_wac->pad_input->name = wacom_wac->pad_name;
+++++++++++
+++++++++++ return 0;
+++++++++++ }
+++++++++++
static int wacom_register_inputs(struct wacom *wacom)
{
struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev;
error = wacom_initialize_leds(wacom);
if (error)
goto fail_leds;
+++++++++++
+++++++++++ error = wacom_initialize_remote(wacom);
+++++++++++ if (error)
+++++++++++ goto fail_remote;
}
return 0;
+++++++++++ fail_remote:
+++++++++++ wacom_destroy_leds(wacom);
fail_leds:
input_unregister_device(pad_input_dev);
pad_input_dev = NULL;
wacom_wac->pad_registered = false;
fail_register_pad_input:
- ------ input_unregister_device(touch_input_dev);
+ ++++++ if (touch_input_dev)
+ ++++++ input_unregister_device(touch_input_dev);
wacom_wac->touch_input = NULL;
wacom_wac->touch_registered = false;
fail_register_touch_input:
- ------ input_unregister_device(pen_input_dev);
+ ++++++ if (pen_input_dev)
+ ++++++ input_unregister_device(pen_input_dev);
wacom_wac->pen_input = NULL;
wacom_wac->pen_registered = false;
fail_register_pen_input:
return error;
}
+++ +++++++/*
+++ +++++++ * 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)
+++ +++++++{
+++ +++++++ /* set unit to "100th of a mm" for devices not reported by HID */
+++ +++++++ if (!features->unit) {
+++ +++++++ features->unit = 0x11;
+++ +++++++ features->unitExpo = -3;
+++ +++++++ }
+++ +++++++
+++ +++++++ 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 void wacom_wireless_work(struct work_struct *work)
{
struct wacom *wacom = container_of(work, struct wacom, work);
if (wacom_wac1->features.type != INTUOSHT &&
wacom_wac1->features.type != BAMBOO_PT)
wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PAD;
+++ +++++++ wacom_set_default_phy(&wacom_wac1->features);
+++ +++++++ wacom_calculate_res(&wacom_wac1->features);
snprintf(wacom_wac1->pen_name, WACOM_NAME_MAX, "%s (WL) Pen",
wacom_wac1->features.name);
snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad",
wacom_wac2->features =
*((struct wacom_features *)id->driver_data);
wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
+++ +++++++ wacom_set_default_phy(&wacom_wac2->features);
wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096;
+++ +++++++ wacom_calculate_res(&wacom_wac2->features);
snprintf(wacom_wac2->touch_name, WACOM_NAME_MAX,
"%s (WL) Finger",wacom_wac2->features.name);
snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX,
}
}
--- -------/*
--- ------- * 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)
--- -------{
--- ------- /* set unit to "100th of a mm" for devices not reported by HID */
--- ------- if (!features->unit) {
--- ------- features->unit = 0x11;
--- ------- features->unitExpo = -3;
--- ------- }
--- -------
--- ------- 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 size_t wacom_compute_pktlen(struct hid_device *hdev)
{
struct hid_report_enum *report_enum;
mutex_init(&wacom->lock);
INIT_WORK(&wacom->work, wacom_wireless_work);
----------- if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) {
----------- error = wacom_allocate_inputs(wacom);
----------- if (error)
----------- goto fail_allocate_inputs;
----------- }
+++++++++++ error = wacom_allocate_inputs(wacom);
+++++++++++ if (error)
+++++++++++ goto fail_allocate_inputs;
/*
* Bamboo Pad has a generic hid handling for the Pen, and we switch it
if (error)
goto fail_shared_data;
----------- if (!(features->quirks & WACOM_QUIRK_MONITOR) &&
+++++++++++ if (!(features->device_type & WACOM_DEVICETYPE_WL_MONITOR) &&
(features->quirks & WACOM_QUIRK_BATTERY)) {
error = wacom_initialize_battery(wacom);
if (error)
goto fail_battery;
}
----------- if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) {
----------- error = wacom_register_inputs(wacom);
----------- if (error)
----------- goto fail_register_inputs;
----------- }
+++++++++++ error = wacom_register_inputs(wacom);
+++++++++++ if (error)
+++++++++++ goto fail_register_inputs;
if (hdev->bus == BUS_BLUETOOTH) {
error = device_create_file(&hdev->dev, &dev_attr_speed);
/* Note that if query fails it is not a hard failure */
wacom_query_tablet_data(hdev, features);
----------- if (features->quirks & WACOM_QUIRK_MONITOR)
+++++++++++ if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR)
error = hid_hw_open(hdev);
if (wacom_wac->features.type == INTUOSHT &&
.id_table = wacom_ids,
.probe = wacom_probe,
.remove = wacom_remove,
----------- .event = wacom_wac_event,
.report = wacom_wac_report,
#ifdef CONFIG_PM
.resume = wacom_resume,
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->id[0]) {
+++++++++++ if ((data[0] & 0x10) || (data[4] & 0x20)) {
+++++++++++ wacom->tool[0] = BTN_TOOL_RUBBER;
+++++++++++ wacom->id[0] = ERASER_DEVICE_ID;
}
----------- if (wacom->tool[1] != BTN_TOOL_RUBBER) {
----------- /* Unknown tool selected default to pen tool */
----------- wacom->tool[1] = BTN_TOOL_PEN;
+++++++++++ else {
+++++++++++ wacom->tool[0] = 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);
+++++++++++ /* If the eraser is in prox, STYLUS2 is always set. If we
+++++++++++ * mis-detected the type and notice that STYLUS2 isn't set
+++++++++++ * then force the eraser out of prox and let the pen in.
+++++++++++ */
+++++++++++ if (wacom->tool[0] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {
+++++++++++ input_report_key(input, BTN_TOOL_RUBBER, 0);
+++++++++++ input_report_abs(input, ABS_MISC, 0);
+++++++++++ input_sync(input);
+++++++++++ wacom->tool[0] = BTN_TOOL_PEN;
+++++++++++ wacom->id[0] = STYLUS_DEVICE_ID;
}
----------- wacom->tool[0] = prox; /* Save proximity state */
+++++++++++ 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;
+++++++++++
+++++++++++ 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[0] == BTN_TOOL_PEN) && (data[4] & 0x20));
+++++++++++
+++++++++++ if (!prox)
+++++++++++ wacom->id[0] = 0;
+++++++++++ input_report_key(input, wacom->tool[0], prox);
+++++++++++ input_report_abs(input, ABS_MISC, wacom->id[0]);
return 1;
}
return 0;
}
+++++++++++ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)
+++++++++++ {
+++++++++++ unsigned char *data = wacom_wac->data;
+++++++++++ struct input_dev *input = wacom_wac->pad_input;
+++++++++++ struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
+++++++++++ struct wacom_features *features = &wacom_wac->features;
+++++++++++ int bat_charging, bat_percent, touch_ring_mode;
+++++++++++ __u32 serial;
+++++++++++ int i;
+++++++++++
+++++++++++ if (data[0] != WACOM_REPORT_REMOTE) {
+++++++++++ dev_dbg(input->dev.parent,
+++++++++++ "%s: received unknown report #%d", __func__, data[0]);
+++++++++++ return 0;
+++++++++++ }
+++++++++++
+++++++++++ serial = data[3] + (data[4] << 8) + (data[5] << 16);
+++++++++++ wacom_wac->id[0] = PAD_DEVICE_ID;
+++++++++++
+++++++++++ input_report_key(input, BTN_0, (data[9] & 0x01));
+++++++++++ input_report_key(input, BTN_1, (data[9] & 0x02));
+++++++++++ input_report_key(input, BTN_2, (data[9] & 0x04));
+++++++++++ input_report_key(input, BTN_3, (data[9] & 0x08));
+++++++++++ input_report_key(input, BTN_4, (data[9] & 0x10));
+++++++++++ input_report_key(input, BTN_5, (data[9] & 0x20));
+++++++++++ input_report_key(input, BTN_6, (data[9] & 0x40));
+++++++++++ input_report_key(input, BTN_7, (data[9] & 0x80));
+++++++++++
+++++++++++ input_report_key(input, BTN_8, (data[10] & 0x01));
+++++++++++ input_report_key(input, BTN_9, (data[10] & 0x02));
+++++++++++ input_report_key(input, BTN_A, (data[10] & 0x04));
+++++++++++ input_report_key(input, BTN_B, (data[10] & 0x08));
+++++++++++ input_report_key(input, BTN_C, (data[10] & 0x10));
+++++++++++ input_report_key(input, BTN_X, (data[10] & 0x20));
+++++++++++ input_report_key(input, BTN_Y, (data[10] & 0x40));
+++++++++++ input_report_key(input, BTN_Z, (data[10] & 0x80));
+++++++++++
+++++++++++ input_report_key(input, BTN_BASE, (data[11] & 0x01));
+++++++++++ input_report_key(input, BTN_BASE2, (data[11] & 0x02));
+++++++++++
+++++++++++ if (data[12] & 0x80)
+++++++++++ input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f));
+++++++++++ else
+++++++++++ input_report_abs(input, ABS_WHEEL, 0);
+++++++++++
+++++++++++ bat_percent = data[7] & 0x7f;
+++++++++++ bat_charging = !!(data[7] & 0x80);
+++++++++++
+++++++++++ if (data[9] | data[10] | (data[11] & 0x03) | data[12])
+++++++++++ input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
+++++++++++ else
+++++++++++ input_report_abs(input, ABS_MISC, 0);
+++++++++++
+++++++++++ input_event(input, EV_MSC, MSC_SERIAL, serial);
+++++++++++
+++++++++++ /*Which mode select (LED light) is currently on?*/
+++++++++++ touch_ring_mode = (data[11] & 0xC0) >> 6;
+++++++++++
+++++++++++ for (i = 0; i < WACOM_MAX_REMOTES; i++) {
+++++++++++ if (wacom_wac->serial[i] == serial)
+++++++++++ wacom->led.select[i] = touch_ring_mode;
+++++++++++ }
+++++++++++
+++++++++++ if (!wacom->battery &&
+++++++++++ !(features->quirks & WACOM_QUIRK_BATTERY)) {
+++++++++++ features->quirks |= WACOM_QUIRK_BATTERY;
+++++++++++ INIT_WORK(&wacom->work, wacom_battery_work);
+++++++++++ wacom_schedule_work(wacom_wac);
+++++++++++ }
+++++++++++
+++++++++++ wacom_notify_battery(wacom_wac, bat_percent, bat_charging, 1,
+++++++++++ bat_charging);
+++++++++++
+++++++++++ return 1;
+++++++++++ }
+++++++++++
+++++++++++ static int wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len)
+++++++++++ {
+++++++++++ struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
+++++++++++ unsigned char *data = wacom_wac->data;
+++++++++++ int i;
+++++++++++
+++++++++++ if (data[0] != WACOM_REPORT_DEVICE_LIST)
+++++++++++ return 0;
+++++++++++
+++++++++++ for (i = 0; i < WACOM_MAX_REMOTES; i++) {
+++++++++++ int j = i * 6;
+++++++++++ int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4];
+++++++++++ bool connected = data[j+2];
+++++++++++
+++++++++++ if (connected) {
+++++++++++ int k;
+++++++++++
+++++++++++ if (wacom_wac->serial[i] == serial)
+++++++++++ continue;
+++++++++++
+++++++++++ if (wacom_wac->serial[i]) {
+++++++++++ wacom_remote_destroy_attr_group(wacom,
+++++++++++ wacom_wac->serial[i]);
+++++++++++ }
+++++++++++
+++++++++++ /* A remote can pair more than once with an EKR,
+++++++++++ * check to make sure this serial isn't already paired.
+++++++++++ */
+++++++++++ for (k = 0; k < WACOM_MAX_REMOTES; k++) {
+++++++++++ if (wacom_wac->serial[k] == serial)
+++++++++++ break;
+++++++++++ }
+++++++++++
+++++++++++ if (k < WACOM_MAX_REMOTES) {
+++++++++++ wacom_wac->serial[i] = serial;
+++++++++++ continue;
+++++++++++ }
+++++++++++ wacom_remote_create_attr_group(wacom, serial, i);
+++++++++++
+++++++++++ } else if (wacom_wac->serial[i]) {
+++++++++++ wacom_remote_destroy_attr_group(wacom,
+++++++++++ wacom_wac->serial[i]);
+++++++++++ }
+++++++++++ }
+++++++++++
+++++++++++ return 0;
+++++++++++ }
+++++++++++
static void wacom_intuos_general(struct wacom_wac *wacom)
{
struct wacom_features *features = &wacom->features;
return 0;
}
+++++++++++ static void wacom_wac_pen_pre_report(struct hid_device *hdev,
+++++++++++ struct hid_report *report)
+++++++++++ {
+++++++++++ return;
+++++++++++ }
+++++++++++
static void wacom_wac_pen_report(struct hid_device *hdev,
struct hid_report *report)
{
wacom_map_usage(input, usage, field, EV_ABS,
ABS_MT_POSITION_Y, 4);
break;
+++++++++++ case HID_DG_WIDTH:
+++++++++++ case HID_DG_HEIGHT:
+++++++++++ features->last_slot_field = usage->hid;
+++++++++++ wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MAJOR, 0);
+++++++++++ wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MINOR, 0);
+++++++++++ input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
+++++++++++ break;
case HID_DG_CONTACTID:
features->last_slot_field = usage->hid;
break;
features->last_slot_field = usage->hid;
wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0);
break;
+++++++++++ case HID_DG_CONTACTCOUNT:
+++++++++++ wacom_wac->hid_data.cc_index = field->index;
+++++++++++ wacom_wac->hid_data.cc_value_index = usage->usage_index;
+++++++++++ break;
}
}
bool prox = hid_data->tipswitch &&
!wacom_wac->shared->stylus_in_proximity;
+++++++++++ wacom_wac->hid_data.num_received++;
+++++++++++ if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected)
+++++++++++ return;
+++++++++++
if (mt) {
int slot;
hid_data->x);
input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y,
hid_data->y);
+++++++++++
+++++++++++ if (test_bit(ABS_MT_TOUCH_MAJOR, input->absbit)) {
+++++++++++ input_report_abs(input, ABS_MT_TOUCH_MAJOR, max(hid_data->width, hid_data->height));
+++++++++++ input_report_abs(input, ABS_MT_TOUCH_MINOR, min(hid_data->width, hid_data->height));
+++++++++++ if (hid_data->width != hid_data->height)
+++++++++++ input_report_abs(input, ABS_MT_ORIENTATION, hid_data->width <= hid_data->height ? 0 : 1);
+++++++++++ }
}
}
case HID_GD_Y:
wacom_wac->hid_data.y = value;
break;
+++++++++++ case HID_DG_WIDTH:
+++++++++++ wacom_wac->hid_data.width = value;
+++++++++++ break;
+++++++++++ case HID_DG_HEIGHT:
+++++++++++ wacom_wac->hid_data.height = value;
+++++++++++ break;
case HID_DG_CONTACTID:
wacom_wac->hid_data.id = value;
break;
return 0;
}
+++++++++++ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
+++++++++++ struct hid_report *report)
+++++++++++ {
+++++++++++ struct wacom *wacom = hid_get_drvdata(hdev);
+++++++++++ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+++++++++++ struct hid_data* hid_data = &wacom_wac->hid_data;
+++++++++++
+++++++++++ if (hid_data->cc_index >= 0) {
+++++++++++ struct hid_field *field = report->field[hid_data->cc_index];
+++++++++++ int value = field->value[hid_data->cc_value_index];
+++++++++++ if (value)
+++++++++++ hid_data->num_expected = value;
+++++++++++ }
+++++++++++ else {
+++++++++++ hid_data->num_expected = wacom_wac->features.touch_max;
+++++++++++ }
+++++++++++ }
+++++++++++
static void wacom_wac_finger_report(struct hid_device *hdev,
struct hid_report *report)
{
struct input_dev *input = wacom_wac->touch_input;
unsigned touch_max = wacom_wac->features.touch_max;
+++++++++++ /* If more packets of data are expected, give us a chance to
+++++++++++ * process them rather than immediately syncing a partial
+++++++++++ * update.
+++++++++++ */
+++++++++++ if (wacom_wac->hid_data.num_received < wacom_wac->hid_data.num_expected)
+++++++++++ return;
+++++++++++
if (touch_max > 1)
input_mt_sync_frame(input);
input_sync(input);
+++++++++++ wacom_wac->hid_data.num_received = 0;
/* keep touch state for pen event */
wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);
return 0;
}
+++++++++++ static void wacom_report_events(struct hid_device *hdev, struct hid_report *report)
+++++++++++ {
+++++++++++ int r;
+++++++++++
+++++++++++ for (r = 0; r < report->maxfield; r++) {
+++++++++++ struct hid_field *field;
+++++++++++ unsigned count, n;
+++++++++++
+++++++++++ field = report->field[r];
+++++++++++ count = field->report_count;
+++++++++++
+++++++++++ if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
+++++++++++ continue;
+++++++++++
+++++++++++ for (n = 0; n < count; n++)
+++++++++++ wacom_wac_event(hdev, field, &field->usage[n], field->value[n]);
+++++++++++ }
+++++++++++ }
+++++++++++
void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
{
struct wacom *wacom = hid_get_drvdata(hdev);
if (wacom_wac->features.type != HID_GENERIC)
return;
+++++++++++ if (WACOM_PEN_FIELD(field))
+++++++++++ wacom_wac_pen_pre_report(hdev, report);
+++++++++++
+++++++++++ if (WACOM_FINGER_FIELD(field))
+++++++++++ wacom_wac_finger_pre_report(hdev, report);
+++++++++++
+++++++++++ wacom_report_events(hdev, report);
+++++++++++
if (WACOM_PEN_FIELD(field))
return wacom_wac_pen_report(hdev, report);
int y = (data[3] << 4) | (data[4] & 0x0f);
int width, height;
----------- if (features->type >= INTUOSPS && features->type <= INTUOSPL) {
+++++++++++ if (features->type >= INTUOSPS && features->type <= INTUOSHT) {
width = data[5] * 100;
height = data[6] * 100;
} else {
sync = wacom_wireless_irq(wacom_wac, len);
break;
+++++++++++ case REMOTE:
+++++++++++ if (wacom_wac->data[0] == WACOM_REPORT_DEVICE_LIST)
+++++++++++ sync = wacom_remote_status_irq(wacom_wac, len);
+++++++++++ else
+++++++++++ sync = wacom_remote_irq(wacom_wac, len);
+++++++++++ break;
+++++++++++
default:
sync = false;
break;
features->x_max = 4096;
features->y_max = 4096;
}
+ ++++++ else if (features->pktlen == WACOM_PKGLEN_BBTOUCH) {
+ ++++++ features->device_type |= WACOM_DEVICETYPE_PAD;
+ ++++++ }
}
/*
* 0, whose HID descriptor has an application usage of 0xFF0D
* (i.e., WACOM_VENDORDEFINED_PEN). We route pen packets back
* out through the HID_GENERIC device created for interface 1,
----------- * so rewrite this one to be of type BTN_TOOL_FINGER.
+++++++++++ * so rewrite this one to be of type WACOM_DEVICETYPE_TOUCH.
*/
if (features->type == BAMBOO_PAD)
----------- features->device_type |= WACOM_DEVICETYPE_TOUCH;
+++++++++++ features->device_type = WACOM_DEVICETYPE_TOUCH;
+++++++++++
+++++++++++ if (features->type == REMOTE)
+++++++++++ features->device_type = WACOM_DEVICETYPE_PAD;
if (wacom->hdev->bus == BUS_BLUETOOTH)
features->quirks |= WACOM_QUIRK_BATTERY;
}
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 == WACOM_DEVICETYPE_NONE) {
----------- features->quirks |= WACOM_QUIRK_MONITOR;
+++++++++++ if (features->device_type == WACOM_DEVICETYPE_WL_MONITOR) {
features->quirks |= WACOM_QUIRK_BATTERY;
}
}
return 0;
}
+++++++++++ static void wacom_setup_numbered_buttons(struct input_dev *input_dev,
+++++++++++ int button_count)
+++++++++++ {
+++++++++++ int i;
+++++++++++
+++++++++++ for (i = 0; i < button_count && i < 10; i++)
+++++++++++ __set_bit(BTN_0 + i, input_dev->keybit);
+++++++++++ for (i = 10; i < button_count && i < 16; i++)
+++++++++++ __set_bit(BTN_A + (i-10), input_dev->keybit);
+++++++++++ for (i = 16; i < button_count && i < 18; i++)
+++++++++++ __set_bit(BTN_BASE + (i-16), input_dev->keybit);
+++++++++++ }
+++++++++++
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;
if (!(features->device_type & WACOM_DEVICETYPE_PAD))
return -ENODEV;
/* kept for making udev and libwacom accepting the pad */
__set_bit(BTN_STYLUS, input_dev->keybit);
+++++++++++ wacom_setup_numbered_buttons(input_dev, features->numbered_buttons);
+++++++++++
switch (features->type) {
+++++++++++
+++++++++++ case CINTIQ_HYBRID:
+++++++++++ case DTK:
+++++++++++ case DTUS:
case GRAPHIRE_BT:
----------- __set_bit(BTN_0, input_dev->keybit);
----------- __set_bit(BTN_1, input_dev->keybit);
break;
case WACOM_MO:
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);
__set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit);
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);
/* 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 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:
----------- 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:
__clear_bit(ABS_MISC, input_dev->absbit);
break;
+++++++++++ case REMOTE:
+++++++++++ input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
+++++++++++ input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
+++++++++++ break;
+++++++++++
default:
/* no pad supported */
return -ENODEV;
GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
static const struct wacom_features wacom_features_0x81 =
{ "Wacom Graphire BT", 16704, 12064, 511, 32,
----------- GRAPHIRE_BT, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
+++++++++++ GRAPHIRE_BT, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES, 2 };
static const struct wacom_features wacom_features_0x11 =
{ "Wacom Graphire2 4x5", 10206, 7422, 511, 63,
GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
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 };
+++++++++++ INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 4 };
static const struct wacom_features wacom_features_0xB1 =
{ "Wacom Intuos3 6x8", 40640, 30480, 1023, 63,
----------- INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
static const struct wacom_features wacom_features_0xB2 =
{ "Wacom Intuos3 9x12", 60960, 45720, 1023, 63,
----------- INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
static const struct wacom_features wacom_features_0xB3 =
{ "Wacom Intuos3 12x12", 60960, 60960, 1023, 63,
----------- INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
static const struct wacom_features wacom_features_0xB4 =
{ "Wacom Intuos3 12x19", 97536, 60960, 1023, 63,
----------- INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
static const struct wacom_features wacom_features_0xB5 =
{ "Wacom Intuos3 6x11", 54204, 31750, 1023, 63,
----------- INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
static const struct wacom_features wacom_features_0xB7 =
{ "Wacom Intuos3 4x6", 31496, 19685, 1023, 63,
----------- INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 4 };
static const struct wacom_features wacom_features_0xB8 =
{ "Wacom Intuos4 4x6", 31496, 19685, 2047, 63,
----------- INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7 };
static const struct wacom_features wacom_features_0xB9 =
{ "Wacom Intuos4 6x9", 44704, 27940, 2047, 63,
----------- INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
static const struct wacom_features wacom_features_0xBA =
{ "Wacom Intuos4 8x13", 65024, 40640, 2047, 63,
----------- INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
static const struct wacom_features wacom_features_0xBB =
{ "Wacom Intuos4 12x19", 97536, 60960, 2047, 63,
----------- INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
static const struct wacom_features wacom_features_0xBC =
{ "Wacom Intuos4 WL", 40640, 25400, 2047, 63,
----------- INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
static const struct wacom_features wacom_features_0xBD =
{ "Wacom Intuos4 WL", 40640, 25400, 2047, 63,
----------- INTUOS4WL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS4WL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
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 };
+++++++++++ INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .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 };
+++++++++++ INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .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 };
+++++++++++ INTUOS5L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .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 };
+++++++++++ INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7 };
static const struct wacom_features wacom_features_0x2A =
{ "Wacom Intuos5 M", 44704, 27940, 2047, 63,
----------- INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
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,
+++++++++++ INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .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,
+++++++++++ INTUOSPM, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .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,
+++++++++++ INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16,
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0xF4 =
{ "Wacom Cintiq 24HD", 104080, 65200, 2047, 63,
----------- WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 16,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0xF8 =
{ "Wacom Cintiq 24HD touch", 104080, 65200, 2047, 63, /* Pen */
----------- WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 16,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
static const struct wacom_features wacom_features_0xF6 =
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0x32A =
{ "Wacom Cintiq 27QHD", 119740, 67520, 2047, 63,
----------- WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0x32B =
{ "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63,
----------- WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32C };
static const struct wacom_features wacom_features_0x32C =
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32B, .touch_max = 10 };
static const struct wacom_features wacom_features_0x3F =
{ "Wacom Cintiq 21UX", 87200, 65600, 1023, 63,
----------- CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
static const struct wacom_features wacom_features_0xC5 =
{ "Wacom Cintiq 20WSX", 86680, 54180, 1023, 63,
----------- WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 10 };
static const struct wacom_features wacom_features_0xC6 =
{ "Wacom Cintiq 12WX", 53020, 33440, 1023, 63,
----------- WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
+++++++++++ WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 10 };
static const struct wacom_features wacom_features_0x304 =
{ "Wacom Cintiq 13HD", 59152, 33448, 1023, 63,
----------- WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0x333 =
{ "Wacom Cintiq 13HD touch", 59152, 33448, 2047, 63,
----------- WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x335 };
static const struct wacom_features wacom_features_0x335 =
DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xFB =
{ "Wacom DTU1031", 21896, 13760, 511, 0,
----------- DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+++++++++++ DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,
WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
static const struct wacom_features wacom_features_0x32F =
{ "Wacom DTU1031X", 22472, 12728, 511, 0,
----------- DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+++++++++++ DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 0,
WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
static const struct wacom_features wacom_features_0x336 =
{ "Wacom DTU1141", 23472, 13203, 1023, 0,
----------- DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+++++++++++ DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };
static const struct wacom_features wacom_features_0x57 =
{ "Wacom DTK2241", 95640, 54060, 2047, 63,
----------- DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 6,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0x59 = /* Pen */
{ "Wacom DTH2242", 95640, 54060, 2047, 63,
----------- DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 6,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D };
static const struct wacom_features wacom_features_0x5D = /* Touch */
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0xCC =
{ "Wacom Cintiq 21UX2", 86800, 65200, 2047, 63,
----------- WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0xFA =
{ "Wacom Cintiq 22HD", 95440, 53860, 2047, 63,
----------- WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0x5B =
{ "Wacom Cintiq 22HDT", 95440, 53860, 2047, 63,
----------- WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
static const struct wacom_features wacom_features_0x5E =
TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x307 =
{ "Wacom ISDv5 307", 59152, 33448, 2047, 63,
----------- CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 };
static const struct wacom_features wacom_features_0x309 =
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0x30A =
{ "Wacom ISDv5 30A", 59152, 33448, 2047, 63,
----------- CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
+++++++++++ CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C };
static const struct wacom_features wacom_features_0x30C =
{ "Wacom Intuos P M", 21600, 13500, 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_0x331 =
+++++++++++ { "Wacom Express Key Remote", 0, 0, 0, 0,
+++++++++++ REMOTE, 0, 0, 18, .check_for_hid_type = true,
+++++++++++ .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_HID_ANY_ID =
{ "Wacom HID", .type = HID_GENERIC };
{ USB_DEVICE_WACOM(0x32B) },
{ USB_DEVICE_WACOM(0x32C) },
{ USB_DEVICE_WACOM(0x32F) },
+++++++++++ { USB_DEVICE_WACOM(0x331) },
{ USB_DEVICE_WACOM(0x333) },
{ USB_DEVICE_WACOM(0x335) },
{ USB_DEVICE_WACOM(0x336) },