Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff -Naur linux-2.6.36/drivers/input/tablet//wacom.h linux-2.6.36-rc/drivers/input/tablet//wacom.h
- --- linux-2.6.36/drivers/input/tablet//wacom.h 2010-08-02 00:11:14.000000000 +0200
- +++ linux-2.6.36-rc/drivers/input/tablet//wacom.h 2010-10-11 00:12:48.000000000 +0200
- @@ -11,7 +11,7 @@
- * 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-2009 Ping Cheng <pingc@wacom.com>
- + * Copyright (c) 2002-2010 Ping Cheng <pingc@wacom.com>
- *
- * ChangeLog:
- * v0.1 (vp) - Initial release
- @@ -93,7 +93,7 @@
- /*
- * Version Information
- */
- -#define DRIVER_VERSION "v1.52"
- +#define DRIVER_VERSION "v1.52-pc-0.3"
- #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
- #define DRIVER_DESC "USB Wacom tablet driver"
- #define DRIVER_LICENSE "GPL"
- @@ -104,6 +104,11 @@
- #define USB_VENDOR_ID_WACOM 0x056a
- +/* defines to get/set USB message */
- +#define USB_REQ_GET_REPORT 0x01
- +#define USB_REQ_SET_REPORT 0x09
- +#define WAC_HID_FEATURE_REPORT 0x03
- +
- struct wacom {
- dma_addr_t data_dma;
- struct usb_device *usbdev;
- @@ -117,6 +122,12 @@
- extern const struct usb_device_id wacom_ids[];
- +int usb_get_report(struct usb_interface *intf, unsigned char type,
- + unsigned char id, void *buf, int size);
- +int usb_set_report(struct usb_interface *intf, unsigned char type,
- + unsigned char id, void *buf, int size);
- +int wacom_ioctl(struct usb_interface *intf, unsigned int code, void *buf);
- +
- void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
- void wacom_setup_input_capabilities(struct input_dev *input_dev,
- struct wacom_wac *wacom_wac);
- diff -Naur linux-2.6.36/drivers/input/tablet//wacom_sys.c linux-2.6.36-rc/drivers/input/tablet//wacom_sys.c
- --- linux-2.6.36/drivers/input/tablet//wacom_sys.c 2010-08-02 00:11:14.000000000 +0200
- +++ linux-2.6.36-rc/drivers/input/tablet//wacom_sys.c 2010-10-11 00:12:32.000000000 +0200
- @@ -45,12 +45,7 @@
- __le16 wDescriptorLength;
- } __attribute__ ((packed));
- -/* defines to get/set USB message */
- -#define USB_REQ_GET_REPORT 0x01
- -#define USB_REQ_SET_REPORT 0x09
- -#define WAC_HID_FEATURE_REPORT 0x03
- -
- -static int usb_get_report(struct usb_interface *intf, unsigned char type,
- +int usb_get_report(struct usb_interface *intf, unsigned char type,
- unsigned char id, void *buf, int size)
- {
- return usb_control_msg(interface_to_usbdev(intf),
- @@ -60,7 +55,7 @@
- buf, size, 100);
- }
- -static int usb_set_report(struct usb_interface *intf, unsigned char type,
- +int usb_set_report(struct usb_interface *intf, unsigned char type,
- unsigned char id, void *buf, int size)
- {
- return usb_control_msg(interface_to_usbdev(intf),
- @@ -195,17 +190,30 @@
- features->pktlen = WACOM_PKGLEN_TPC2FG;
- features->device_type = BTN_TOOL_TRIPLETAP;
- }
- - features->x_max =
- - get_unaligned_le16(&report[i + 3]);
- - features->x_phy =
- - get_unaligned_le16(&report[i + 6]);
- - features->unit = report[i + 9];
- - features->unitExpo = report[i + 11];
- - i += 12;
- + if (features->type == BAMBOO_PT) {
- + /* need to reset back */
- + features->pktlen = WACOM_PKGLEN_BBTOUCH;
- + features->device_type = BTN_TOOL_TRIPLETAP;
- + features->x_phy =
- + get_unaligned_le16(&report[i + 5]);
- + features->x_max =
- + get_unaligned_le16(&report[i + 8]);
- + i += 15;
- + } else {
- + features->x_max =
- + get_unaligned_le16(&report[i + 3]);
- + features->x_phy =
- + get_unaligned_le16(&report[i + 6]);
- + features->unit = report[i + 9];
- + features->unitExpo = report[i + 11];
- + i += 12;
- + }
- } else if (pen) {
- /* penabled only accepts exact bytes of data */
- if (features->type == TABLETPC2FG)
- features->pktlen = WACOM_PKGLEN_GRAPHIRE;
- + if (features->type == BAMBOO_PT)
- + features->pktlen = WACOM_PKGLEN_BBFUN;
- features->device_type = BTN_TOOL_PEN;
- features->x_max =
- get_unaligned_le16(&report[i + 3]);
- @@ -234,6 +242,15 @@
- features->y_phy =
- get_unaligned_le16(&report[i + 6]);
- i += 7;
- + } else if (features->type == BAMBOO_PT) {
- + /* need to reset back */
- + features->pktlen = WACOM_PKGLEN_BBTOUCH;
- + features->device_type = BTN_TOOL_TRIPLETAP;
- + features->y_phy =
- + get_unaligned_le16(&report[i + 3]);
- + features->y_max =
- + get_unaligned_le16(&report[i + 6]);
- + i += 12;
- } else {
- features->y_max =
- features->x_max;
- @@ -245,6 +262,8 @@
- /* penabled only accepts exact bytes of data */
- if (features->type == TABLETPC2FG)
- features->pktlen = WACOM_PKGLEN_GRAPHIRE;
- + if (features->type == BAMBOO_PT)
- + features->pktlen = WACOM_PKGLEN_BBFUN;
- features->device_type = BTN_TOOL_PEN;
- features->y_max =
- get_unaligned_le16(&report[i + 3]);
- @@ -295,8 +314,10 @@
- if (!rep_data)
- return error;
- - /* ask to report tablet data if it is 2FGT or not a Tablet PC */
- - if (features->device_type == BTN_TOOL_TRIPLETAP) {
- + /* ask to report tablet data if it is 2FGT Tablet PC
- + * OR not a Tablet PC */
- + if (features->device_type == BTN_TOOL_TRIPLETAP &&
- + (features->type == TABLETPC2FG)) {
- do {
- rep_data[0] = 3;
- rep_data[1] = 4;
- @@ -336,8 +357,9 @@
- /* default device to penabled */
- features->device_type = BTN_TOOL_PEN;
- - /* only Tablet PCs need to retrieve the info */
- - if ((features->type != TABLETPC) && (features->type != TABLETPC2FG))
- + /* only Tablet PCs and 2FGT devices need to retrieve the info */
- + if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)
- + && (features->type != BAMBOO_PT))
- goto out;
- if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
- @@ -495,7 +517,8 @@
- strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
- - if (features->type == TABLETPC || features->type == TABLETPC2FG) {
- + if (features->type == TABLETPC || features->type == TABLETPC2FG ||
- + features->type == BAMBOO_PT) {
- /* Append the device type to the name */
- strlcat(wacom_wac->name,
- features->device_type == BTN_TOOL_PEN ?
- @@ -577,12 +600,10 @@
- /* switch to wacom mode first */
- wacom_query_tablet_data(intf, features);
- -
- if (wacom->open)
- rv = usb_submit_urb(wacom->irq, GFP_NOIO);
- else
- rv = 0;
- -
- mutex_unlock(&wacom->lock);
- return rv;
- diff -Naur linux-2.6.36/drivers/input/tablet//wacom_wac.c linux-2.6.36-rc/drivers/input/tablet//wacom_wac.c
- --- linux-2.6.36/drivers/input/tablet//wacom_wac.c 2010-10-11 00:50:55.417221949 +0200
- +++ linux-2.6.36-rc/drivers/input/tablet//wacom_wac.c 2010-10-11 00:07:39.605526080 +0200
- @@ -57,6 +57,40 @@
- return 1;
- }
- +static int wacom_dtu_irq(struct wacom_wac *wacom)
- +{
- + struct wacom_features *features = &wacom->features;
- + char *data = wacom->data;
- + struct input_dev *input = wacom->input;
- + int prox = data[1] & 0x20, pressure;
- +
- + dbg("wacom_dtu_irq: received report #%d", 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);
- + pressure = ((data[7] & 0x01) << 8) | data[6];
- + if (pressure < 0)
- + pressure = features->pressure_max + pressure + 1;
- + input_report_abs(input, ABS_PRESSURE, pressure);
- + input_report_key(input, BTN_TOUCH, data[1] & 0x05);
- + if (!prox) /* out-prox */
- + wacom->id[0] = 0;
- + else {
- + 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_key(input, wacom->tool[0], prox);
- + input_report_abs(input, ABS_MISC, wacom->id[0]);
- + return 1;
- +}
- static int wacom_pl_irq(struct wacom_wac *wacom)
- {
- @@ -158,37 +192,166 @@
- return 1;
- }
- -static int wacom_dtu_irq(struct wacom_wac *wacom)
- +static void wacom_bpt_finger_in(struct wacom_wac *wacom, char *data, int idx)
- {
- - struct wacom_features *features = &wacom->features;
- - char *data = wacom->data;
- + int x = 0, y = 0;
- + int finger = idx + 1;
- struct input_dev *input = wacom->input;
- - int prox = data[1] & 0x20, pressure;
- - dbg("wacom_dtu_irq: received report #%d", data[0]);
- + x = get_unaligned_be16(&data[3 + (idx * 9)]) & 0x7ff;
- + y = get_unaligned_be16(&data[5 + (idx * 9)]) & 0x7ff;
- - 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;
- + if (wacom->last_finger != finger) {
- + if (x == input_abs_get_val(input, ABS_X))
- + x++;
- +
- + if (y == input_abs_get_val(input, ABS_Y))
- + y++;
- }
- - 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]));
- - pressure = ((data[7] & 0x01) << 8) | data[6];
- - if (pressure < 0)
- - pressure = features->pressure_max + pressure + 1;
- - input_report_abs(input, ABS_PRESSURE, pressure);
- - 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_X, x);
- + input_report_abs(input, ABS_Y, y);
- input_report_abs(input, ABS_MISC, wacom->id[0]);
- - return 1;
- + input_report_key(input, wacom->tool[finger], 1);
- +
- + if (!idx)
- + input_report_key(input, BTN_TOUCH, 1);
- + input_event(input, EV_MSC, MSC_SERIAL, finger);
- + input_sync(input);
- +
- + wacom->last_finger = finger;
- +}
- +
- +static void wacom_bpt_touch_out(struct wacom_wac *wacom, int idx)
- +{
- + int finger = idx + 1;
- + struct input_dev *input = wacom->input;
- +
- + input_report_abs(input, ABS_PRESSURE, 0);
- + input_report_abs(input, ABS_MISC, 0);
- + input_report_key(input, wacom->tool[finger], 0);
- +
- + if (!idx)
- + input_report_key(input, BTN_TOUCH, 0);
- + input_event(input, EV_MSC, MSC_SERIAL, finger);
- + input_sync(input);
- +}
- +
- +static void wacom_bpt_touch_in(struct wacom_wac *wacom)
- +{
- + char *data = wacom->data;
- +
- + /* First finger down */
- + if (data[3] & 0x80) {
- + wacom->tool[1] = BTN_TOOL_DOUBLETAP;
- + wacom->id[0] = TOUCH_DEVICE_ID;
- + wacom_bpt_finger_in(wacom, data, 0);
- + } else if (wacom->id[2] & 0x01)
- + wacom_bpt_touch_out(wacom, 0);
- +
- + /* Second finger down */
- + if (data[12] & 0x80) {
- + wacom->tool[2] = BTN_TOOL_TRIPLETAP;
- + wacom_bpt_finger_in(wacom, data, 1);
- + } else if (wacom->id[2] & 0x02)
- + wacom_bpt_touch_out(wacom, 1);
- +}
- +
- +static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
- +{
- + char *data = wacom->data;
- + int prox = 0, retval = 0;
- + struct input_dev *input = wacom->input;
- +
- + if (data[0] != WACOM_REPORT_PENABLED) {
- + dbg("wacom_bpt_irq: received unknown report #%d", data[0]);
- + goto exit;
- + }
- +
- + /* Touch packet */
- + if (len == WACOM_PKGLEN_BBTOUCH) {
- +
- + /* Send pad data if there are any
- + * don't repeat all zeros
- + */
- + prox = data[1] & 0x0f;
- + if (prox || wacom->id[1]) {
- + if (!wacom->id[1]) /* in-prox */
- + wacom->id[1] = PAD_DEVICE_ID;
- +
- + if (!prox) /* out-prox */
- + wacom->id[1] = 0;
- +
- + input_report_key(input, BTN_0, data[1] & 0x1);
- + input_report_key(input, BTN_1, data[1] & 0x2);
- + input_report_key(input, BTN_2, data[1] & 0x4);
- + input_report_key(input, BTN_3, data[1] & 0x8);
- + input_report_key(input, BTN_TOOL_FINGER, prox);
- + input_report_abs(input, ABS_MISC, wacom->id[1]);
- + input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
- + input_sync(input);
- + }
- +
- + if (wacom->shared->stylus_in_proximity) {
- + if (wacom->id[2] & 0x01)
- + wacom_bpt_touch_out(wacom, 0);
- +
- + if (wacom->id[2] & 0x02)
- + wacom_bpt_touch_out(wacom, 1);
- + wacom->id[2] = 0;
- + return 0;
- + }
- +
- + prox = (data[17] & 0x30 >> 4);
- + if (prox) {
- + /* initialize last touched finger */
- + if (!wacom->id[1])
- + wacom->last_finger = 1;
- +
- + wacom_bpt_touch_in(wacom);
- + } else {
- + if (wacom->id[2] & 0x01)
- + wacom_bpt_touch_out(wacom, 0);
- +
- + if (wacom->id[2] & 0x02)
- + wacom_bpt_touch_out(wacom, 1);
- +
- + wacom->id[0] = 0;
- + }
- + wacom->id[2] = (((data[3] & 0x80) >> 7) & 0x1) |
- + (((data[12] & 0x80) >> 6) & 0x2);
- +
- + } else if (len == WACOM_PKGLEN_BBFUN) { /* Penabled */
- + prox = (data[1] & 0x10) && (data[1] & 0x20);
- +
- + if (!wacom->shared->stylus_in_proximity) { /* in-prox */
- + 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;
- + }
- + input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6]));
- + input_report_abs(input, ABS_DISTANCE, data[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);
- + if (!prox) {
- + wacom->id[0] = 0;
- + wacom->shared->stylus_in_proximity = false;
- + } else {
- + 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_key(input, wacom->tool[0], prox);
- + input_report_abs(input, ABS_MISC, wacom->id[0]);
- + retval = 1;
- + }
- +exit:
- + return retval;
- }
- static int wacom_graphire_irq(struct wacom_wac *wacom)
- @@ -253,6 +416,10 @@
- if (!prox)
- wacom->id[0] = 0;
- + else {
- + 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_MISC, wacom->id[0]); /* report tool id */
- input_report_key(input, wacom->tool[0], prox);
- input_sync(input); /* sync last event */
- @@ -779,7 +946,7 @@
- if (len == WACOM_PKGLEN_TPC1FG || /* single touch */
- data[0] == WACOM_REPORT_TPC1FG || /* single touch */
- data[0] == WACOM_REPORT_TPC2FG) { /* 2FG touch */
- -
- +
- if (wacom->shared->stylus_in_proximity) {
- if (wacom->id[1] & 0x01)
- wacom_tpc_touch_out(wacom, 0);
- @@ -803,8 +970,10 @@
- }
- if (prox) {
- + /* initialize last touched finger */
- if (!wacom->id[1])
- wacom->last_finger = 1;
- +
- wacom_tpc_touch_in(wacom, len);
- } else {
- if (data[0] == WACOM_REPORT_TPC2FG) {
- @@ -837,8 +1006,6 @@
- }
- 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]));
- pressure = ((data[7] & 0x01) << 8) | data[6];
- if (pressure < 0)
- pressure = features->pressure_max + pressure + 1;
- @@ -847,6 +1014,9 @@
- if (!prox) { /* out-prox */
- wacom->id[0] = 0;
- wacom->shared->stylus_in_proximity = false;
- + } else {
- + 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_key(input, wacom->tool[0], prox);
- input_report_abs(input, ABS_MISC, wacom->id[0]);
- @@ -868,6 +1038,10 @@
- sync = wacom_pl_irq(wacom_wac);
- break;
- + case BAMBOO_PT:
- + sync = wacom_bpt_irq(wacom_wac, len);
- + break;
- +
- case WACOM_G4:
- case GRAPHIRE:
- case WACOM_MO:
- @@ -909,12 +1083,11 @@
- input_sync(wacom_wac->input);
- }
- -static void wacom_setup_intuos(struct wacom_wac *wacom_wac)
- +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);
- - input_set_capability(input_dev, EV_REL, REL_WHEEL);
- __set_bit(BTN_LEFT, input_dev->keybit);
- __set_bit(BTN_RIGHT, input_dev->keybit);
- @@ -924,11 +1097,9 @@
- __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_TOOL_BRUSH, input_dev->keybit);
- __set_bit(BTN_TOOL_PENCIL, input_dev->keybit);
- __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit);
- - __set_bit(BTN_TOOL_LENS, input_dev->keybit);
- __set_bit(BTN_STYLUS, input_dev->keybit);
- __set_bit(BTN_STYLUS2, input_dev->keybit);
- @@ -937,6 +1108,18 @@
- 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_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);
- }
- @@ -958,6 +1141,26 @@
- __set_bit(ABS_MISC, input_dev->absbit);
- switch (wacom_wac->features.type) {
- + case BAMBOO_PT:
- + if (features->device_type == BTN_TOOL_TRIPLETAP) {
- + __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
- + __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
- + __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);
- + __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
- + input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
- + input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0);
- + input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0);
- + }
- + if (features->device_type == BTN_TOOL_PEN) {
- + __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);
- + }
- + break;
- case WACOM_MO:
- __set_bit(BTN_1, input_dev->keybit);
- __set_bit(BTN_5, input_dev->keybit);
- @@ -1003,9 +1206,19 @@
- __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);
- + __set_bit(BTN_TOOL_FINGER, 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);
- + input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
- + wacom_setup_cintiq(wacom_wac);
- + break;
- +
- case INTUOS3:
- case INTUOS3L:
- - case CINTIQ:
- __set_bit(BTN_4, input_dev->keybit);
- __set_bit(BTN_5, input_dev->keybit);
- __set_bit(BTN_6, input_dev->keybit);
- @@ -1115,6 +1328,16 @@
- { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO };
- static const struct wacom_features wacom_features_0x69 =
- { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE };
- +static struct wacom_features wacom_features_0xD1 =
- + { "Wacom BambooFun 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
- +static struct wacom_features wacom_features_0xD4 =
- + { "Wacom Bamboo 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
- +static struct wacom_features wacom_features_0xD2 =
- + { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
- +static struct wacom_features wacom_features_0xD3 =
- + { "Wacom BambooFun 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT };
- +static struct wacom_features wacom_features_0xD0 =
- + { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT };
- static const struct wacom_features wacom_features_0x20 =
- { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS };
- static const struct wacom_features wacom_features_0x21 =
- @@ -1255,6 +1478,11 @@
- { USB_DEVICE_WACOM(0xC0) },
- { USB_DEVICE_WACOM(0xC2) },
- { USB_DEVICE_WACOM(0x03) },
- + { USB_DEVICE_WACOM(0xD1) },
- + { USB_DEVICE_WACOM(0xD4) },
- + { USB_DEVICE_WACOM(0xD2) },
- + { USB_DEVICE_WACOM(0xD3) },
- + { USB_DEVICE_WACOM(0xD0) },
- { USB_DEVICE_WACOM(0x41) },
- { USB_DEVICE_WACOM(0x42) },
- { USB_DEVICE_WACOM(0x43) },
- @@ -1289,3 +1517,256 @@
- { }
- };
- MODULE_DEVICE_TABLE(usb, wacom_ids);
- +
- +#define WAC_LED_RETRIES 10
- +#define ICON_TRANSFER_STOP 0
- +#define ICON_TRANSFER_START 1
- +static int icon_transfer_mode(struct usb_interface *intf, int start)
- +{
- + int ret;
- + char buf[2];
- + int c = 0;
- +
- + buf[0] = 0x21;
- + buf[1] = start;
- + do {
- + ret = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
- + 0x21, buf, 2);
- + c++;
- + } while ((ret == -ETIMEDOUT || ret == -EPIPE) && c < WAC_LED_RETRIES);
- +
- + return 0;
- +}
- +
- +static int set_led_mode(struct usb_interface *intf, int led_sel, int led_llv,
- + int led_hlv, int oled_lum)
- +{
- + int ret;
- + char buf[9];
- + int c;
- +
- + c = 0;
- + ret = -1;
- +
- + /* send LED config data */
- + buf[0] = (char)0x20;
- + buf[1] = (char)(led_sel);
- + buf[2] = (char)(led_llv);
- + buf[3] = (char)(led_hlv);
- + buf[4] = (char)(oled_lum);
- + buf[5] = (char)0;
- + buf[6] = (char)0;
- + buf[7] = (char)0;
- + buf[8] = (char)0;
- + do {
- + ret = usb_set_report(intf, WAC_HID_FEATURE_REPORT,0x20, buf, 9);
- + } while ((ret == -ETIMEDOUT || ret == -EPIPE) && c++ < WAC_LED_RETRIES);
- +
- + return ret;
- +}
- +
- +/* Call this when recognizing a button 0 button press to change the ring LED
- + */
- +int set_scroll_wheel_led(struct usb_interface *intf, int num)
- +{
- + return set_led_mode(intf, 0x04+num, 0x7f, 0x7f, 0x00);
- +}
- +
- +static int wacom_set_i4_led(struct usb_interface *intf, char *img, int btn)
- +{
- + char *temp_buf;
- + int ret;
- + int i;
- + int c;
- +
- + if (icon_transfer_mode(intf, ICON_TRANSFER_START) < 0)
- + return -1;
- +
- + /* send img in chunks */
- + temp_buf = kzalloc(259, GFP_KERNEL);
- + if (!temp_buf)
- + return -ENOMEM;
- + temp_buf[0] = 0x23;
- + temp_buf[1] = btn;
- + for (i=0; i<4; ++i) {
- + temp_buf[2] = i;
- + memcpy(&temp_buf[3], &img[256*i], 256);
- + c = 0;
- + do {
- + ret = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
- + 0x23, temp_buf, 259);
- + c++;
- + } while ((ret == -ETIMEDOUT || ret == -EPIPE) &&
- + c < WAC_LED_RETRIES);
- + if (ret < 0) {
- + /* starting and stopping the transfer mode doesn't
- + * seem to have an effect on the successfull transfer
- + * of icon data. If it did, we would want to try to stop
- + * the transfer here after failure.
- + */
- + kfree(temp_buf);
- + return ret;
- + }
- + }
- + kfree(temp_buf);
- +
- + if (icon_transfer_mode(intf, ICON_TRANSFER_STOP) < 0)
- + return -1;
- +
- + return 0;
- +}
- +
- +static void wacom_led_compress(char *buf, int rows, int cols)
- +{
- + int row1, row2;
- + int i,j;
- + char compressed;
- + for (i=0; i<rows/2; ++i) {
- + row1 = i*2;
- + row2 = i*2 + 1;
- + for (j=0; j<cols; ++j) {
- + compressed = buf[row2*cols + j];
- + compressed <<= 4;
- + compressed |= buf[row1*cols + j];
- + buf[i*cols + j] = compressed;
- + }
- + }
- +}
- +
- +static void wacom_led_flip_horizontally(char *buf, int rows, int cols)
- +{
- + char temp;
- + int i,j;
- + for (i=0; i<rows; ++i) {
- + for (j=0; j<cols/2; ++j) {
- + temp = buf[i*cols + j];
- + buf[i*cols + j] = buf[((i+1)*cols - 1) - j];
- + buf[((i+1)*cols - 1) - j] = temp;
- + }
- + }
- +}
- +
- +static void wacom_led_flip_vertically(char *buf, int rows, int cols)
- +{
- + char temp;
- + int i,j;
- + for (i=0; i<cols; ++i) {
- + for (j=0; j<rows/2; ++j) {
- + temp = buf[j*cols + i];
- + buf[j*cols + i] = buf[(rows-j-1)*cols + i];
- + buf[(rows-j-1)*cols + i] = temp;
- +
- + /* also flip the first 4 bits with the last 4 bits */
- + temp = buf[j*cols + i] & 0xf0;
- + buf[j*cols + i] <<= 4;
- + buf[j*cols + i] |= (temp >> 4) & 0x0f;
- +
- + temp = buf[(rows-j-1)*cols + i] & 0xf0;
- + buf[(rows-j-1)*cols + i] <<= 4;
- + buf[(rows-j-1)*cols + i] |= (temp >> 4) & 0x0f;
- + }
- + }
- +
- +}
- +
- +static int wacom_ioctl_set_led(struct usb_interface *intf, char *img, int btn)
- +{
- + int r;
- + struct wacom *wacom = usb_get_intfdata(intf);
- +
- + /* check interface for LED support */
- + if (!(wacom->wacom_wac.features.type >= INTUOS4S &&
- + wacom->wacom_wac.features.type <= INTUOS4L)) {
- + r = -1;
- + goto out;
- + }
- + if ((wacom->wacom_wac.features.type == INTUOS4S && btn >= 6) ||
- + btn >= 8) {
- + r = -1;
- + goto out;
- + }
- +
- + /* flip image as necessary */
- + switch (wacom->wacom_wac.features.type) {
- + case INTUOS4S:
- + printk(KERN_DEBUG "INTUOS4S: set_led not supported!\n");
- + /* to support this, I need to know the dimensions */
- + r = -1;
- + goto out;
- + case INTUOS4:
- + case INTUOS4L:
- + /* Compress buffer from 32*64 byte buffer into a 16*64
- + * byte buffer.
- + */
- + wacom_led_compress(img, 32, 64);
- + if (wacom->wacom_wac.config & (1<<WACOM_CONFIG_HANDEDNESS)) {
- + /* left handed */
- + wacom_led_flip_vertically(img, 16, 64);
- + btn = 7 - btn;
- + } else {
- + /* right handed */
- + wacom_led_flip_horizontally(img, 16, 64);
- + }
- + break;
- + default:
- + r = -1;
- + goto out;
- + }
- +
- + /* set LED img */
- + r = wacom_set_i4_led(intf, img, btn);
- +
- +out:
- + return r;
- +}
- +
- +static int wacom_ioctl_set_handedness(struct usb_interface *intf, int left_hand)
- +{
- + int r;
- + struct wacom *wacom = usb_get_intfdata(intf);
- +
- + /* check interface for LED support */
- + if (!(wacom->wacom_wac.features.type >= INTUOS4S &&
- + wacom->wacom_wac.features.type <= INTUOS4L)) {
- + r = -1;
- + goto out;
- + }
- +
- + /* set handedness */
- + r = 0;
- + if (left_hand) {
- + __set_bit(WACOM_CONFIG_HANDEDNESS,
- + (void *)&wacom->wacom_wac.config);
- + } else {
- + __clear_bit(WACOM_CONFIG_HANDEDNESS,
- + (void *)&wacom->wacom_wac.config);
- + }
- +
- +out:
- + return r;
- +}
- +
- +int wacom_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
- +{
- + int ret = 0;
- + struct wacom_led_mode *mode = (struct wacom_led_mode *)buf;
- + switch (code) {
- + case WACOM_SET_LED_IMG:
- + ret = wacom_ioctl_set_led(intf,
- + ((struct wacom_led_img *)buf)->buf,
- + ((struct wacom_led_img *)buf)->btn);
- + break;
- + case WACOM_SET_LEFT_HANDED:
- + ret = wacom_ioctl_set_handedness(intf,
- + ((struct wacom_handedness *)buf)->left_handed);
- + break;
- + case WACOM_SET_LED_MODE:
- + ret = set_led_mode(intf, mode->led_sel, mode->led_llv,
- + mode->led_hlv, mode->oled_lum);
- + break;
- + default:
- + ret = -1;
- + }
- +
- + return ret;
- +}
- diff -Naur linux-2.6.36/drivers/input/tablet//wacom_wac.h linux-2.6.36-rc/drivers/input/tablet//wacom_wac.h
- --- linux-2.6.36/drivers/input/tablet//wacom_wac.h 2010-10-11 00:50:55.417221949 +0200
- +++ linux-2.6.36-rc/drivers/input/tablet//wacom_wac.h 2010-10-10 23:25:11.000000000 +0200
- @@ -21,6 +21,7 @@
- #define WACOM_PKGLEN_INTUOS 10
- #define WACOM_PKGLEN_TPC1FG 5
- #define WACOM_PKGLEN_TPC2FG 14
- +#define WACOM_PKGLEN_BBTOUCH 20
- /* device IDs */
- #define STYLUS_DEVICE_ID 0x02
- @@ -37,6 +38,11 @@
- #define WACOM_REPORT_TPC1FG 6
- #define WACOM_REPORT_TPC2FG 13
- +/* wacom_wac->config bits */
- +#define WACOM_CONFIG_HANDEDNESS 0
- +#define WACOM_CONFIG_SCROLL_LED_L 1
- +#define WACOM_CONFIG_SCROLL_LED_H 2
- +
- enum {
- PENPARTNER = 0,
- GRAPHIRE,
- @@ -44,6 +50,7 @@
- PTU,
- PL,
- DTU,
- + BAMBOO_PT,
- INTUOS,
- INTUOS3S,
- INTUOS3,
- @@ -89,6 +96,36 @@
- struct wacom_features features;
- struct wacom_shared *shared;
- struct input_dev *input;
- + __u32 config;
- +};
- +
- +/* Provides common system calls for interacting with wacom tablets via usbfs
- + *
- + * ioctl data for setting led
- + *
- + * The image buffer passed to the wacom device is 64*32 bytes for an Intuos4
- + * Medium and Large. The size for the Smalls is probably the same, but I
- + * haven't verified this yet. Nick Hirsch <nick.hirsch@gmail.com>
- + */
- +struct wacom_led_img {
- + char buf[2048];
- + int btn;
- +};
- +
- +struct wacom_handedness {
- + int left_handed;
- +};
- +
- +struct wacom_led_mode {
- + char led_sel;
- + char led_llv;
- + char led_hlv;
- + char oled_lum;
- };
- +/* consider changing the group to something USB specific */
- +#define WACOM_SET_LED_IMG _IOW(0x00, 0x00, struct wacom_led_img)
- +#define WACOM_SET_LEFT_HANDED _IOW(0x00, 0x01, struct wacom_handedness)
- +#define WACOM_SET_LED_MODE _IOW(0x00, 0x02, struct wacom_led_mode)
- +
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement