Merge commit 'v3.5-rc5' into next
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 4 Jul 2012 20:13:55 +0000 (13:13 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 4 Jul 2012 20:13:55 +0000 (13:13 -0700)
Documentation/devicetree/bindings/input/twl6040-vibra.txt [deleted file]
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/nomadik-ske-keypad.c
drivers/input/misc/ab8500-ponkey.c
drivers/input/misc/twl6040-vibra.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/tablet/wacom_wac.h

diff --git a/Documentation/devicetree/bindings/input/twl6040-vibra.txt b/Documentation/devicetree/bindings/input/twl6040-vibra.txt
deleted file mode 100644 (file)
index 5b1918b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-Vibra driver for the twl6040 family
-
-The vibra driver is a child of the twl6040 MFD dirver.
-Documentation/devicetree/bindings/mfd/twl6040.txt
-
-Required properties:
-- compatible : Must be "ti,twl6040-vibra";
-- interrupts: 4, Vibra overcurrent interrupt
-- vddvibl-supply: Regulator supplying the left vibra motor
-- vddvibr-supply: Regulator supplying the right vibra motor
-- vibldrv_res: Board specific left driver resistance
-- vibrdrv_res: Board specific right driver resistance
-- viblmotor_res: Board specific left motor resistance
-- vibrmotor_res: Board specific right motor resistance
-
-Optional properties:
-- vddvibl_uV: If the vddvibl default voltage need to be changed
-- vddvibr_uV: If the vddvibr default voltage need to be changed
-
-Example:
-/*
- * 8-channel high quality low-power audio codec
- * http://www.ti.com/lit/ds/symlink/twl6040.pdf
- */
-twl6040: twl6040@4b {
-       ...
-       twl6040_vibra: twl6040@1 {
-               compatible = "ti,twl6040-vibra";
-               interrupts = <4>;
-               vddvibl-supply = <&vbat>;
-               vddvibr-supply = <&vbat>;
-               vibldrv_res = <8>;
-               vibrdrv_res = <3>;
-               viblmotor_res = <10>;
-               vibrmotor_res = <10>;
-       };
-};
index 62bfce4..cbb1add 100644 (file)
@@ -559,7 +559,6 @@ static int gpio_keys_get_devtree_pdata(struct device *dev,
        pdata->rep = !!of_get_property(node, "autorepeat", NULL);
 
        /* First count the subnodes */
-       pdata->nbuttons = 0;
        pp = NULL;
        while ((pp = of_get_next_child(node, pp)))
                pdata->nbuttons++;
index 4ea4341..a880e74 100644 (file)
@@ -49,6 +49,7 @@
 #define SKE_ASR3       0x2C
 
 #define SKE_NUM_ASRX_REGISTERS (4)
+#define        KEY_PRESSED_DELAY       10
 
 /**
  * struct ske_keypad  - data structure used by keypad driver
@@ -92,7 +93,7 @@ static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr,
 static int __init ske_keypad_chip_init(struct ske_keypad *keypad)
 {
        u32 value;
-       int timeout = 50;
+       int timeout = keypad->board->debounce_ms;
 
        /* check SKE_RIS to be 0 */
        while ((readl(keypad->reg_base + SKE_RIS) != 0x00000000) && timeout--)
@@ -135,12 +136,37 @@ static int __init ske_keypad_chip_init(struct ske_keypad *keypad)
        return 0;
 }
 
-static void ske_keypad_read_data(struct ske_keypad *keypad)
+static void ske_keypad_report(struct ske_keypad *keypad, u8 status, int col)
 {
+       int row = 0, code, pos;
        struct input_dev *input = keypad->input;
-       u16 status;
-       int col = 0, row = 0, code;
-       int ske_asr, ske_ris, key_pressed, i;
+       u32 ske_ris;
+       int key_pressed;
+       int num_of_rows;
+
+       /* find out the row */
+       num_of_rows = hweight8(status);
+       do {
+               pos = __ffs(status);
+               row = pos;
+               status &= ~(1 << pos);
+
+               code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT);
+               ske_ris = readl(keypad->reg_base + SKE_RIS);
+               key_pressed = ske_ris & SKE_KPRISA;
+
+               input_event(input, EV_MSC, MSC_SCAN, code);
+               input_report_key(input, keypad->keymap[code], key_pressed);
+               input_sync(input);
+               num_of_rows--;
+       } while (num_of_rows);
+}
+
+static void ske_keypad_read_data(struct ske_keypad *keypad)
+{
+       u8 status;
+       int col = 0;
+       int ske_asr, i;
 
        /*
         * Read the auto scan registers
@@ -154,44 +180,38 @@ static void ske_keypad_read_data(struct ske_keypad *keypad)
                if (!ske_asr)
                        continue;
 
-               /* now that ASRx is zero, find out the column x and row y*/
-               if (ske_asr & 0xff) {
+               /* now that ASRx is zero, find out the coloumn x and row y */
+               status = ske_asr & 0xff;
+               if (status) {
                        col = i * 2;
-                       status = ske_asr & 0xff;
-               } else {
+                       ske_keypad_report(keypad, status, col);
+               }
+               status = (ske_asr & 0xff00) >> 8;
+               if (status) {
                        col = (i * 2) + 1;
-                       status = (ske_asr & 0xff00) >> 8;
+                       ske_keypad_report(keypad, status, col);
                }
-
-               /* find out the row */
-               row = __ffs(status);
-
-               code = MATRIX_SCAN_CODE(row, col, SKE_KEYPAD_ROW_SHIFT);
-               ske_ris = readl(keypad->reg_base + SKE_RIS);
-               key_pressed = ske_ris & SKE_KPRISA;
-
-               input_event(input, EV_MSC, MSC_SCAN, code);
-               input_report_key(input, keypad->keymap[code], key_pressed);
-               input_sync(input);
        }
 }
 
 static irqreturn_t ske_keypad_irq(int irq, void *dev_id)
 {
        struct ske_keypad *keypad = dev_id;
-       int retries = 20;
+       int timeout = keypad->board->debounce_ms;
 
        /* disable auto scan interrupt; mask the interrupt generated */
        ske_keypad_set_bits(keypad, SKE_IMSC, ~SKE_KPIMA, 0x0);
        ske_keypad_set_bits(keypad, SKE_ICR, 0x0, SKE_KPICA);
 
-       while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --retries)
-               msleep(5);
+       while ((readl(keypad->reg_base + SKE_CR) & SKE_KPASON) && --timeout)
+               cpu_relax();
 
-       if (retries) {
-               /* SKEx registers are stable and can be read */
-               ske_keypad_read_data(keypad);
-       }
+       /* SKEx registers are stable and can be read */
+       ske_keypad_read_data(keypad);
+
+       /* wait until raw interrupt is clear */
+       while ((readl(keypad->reg_base + SKE_RIS)) && --timeout)
+               msleep(KEY_PRESSED_DELAY);
 
        /* enable auto scan interrupts */
        ske_keypad_set_bits(keypad, SKE_IMSC, 0x0, SKE_KPIMA);
index 350fd0c..84ec691 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/abx500/ab8500.h>
+#include <linux/of.h>
 #include <linux/slab.h>
 
 /**
@@ -131,10 +132,18 @@ static int __devexit ab8500_ponkey_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id ab8500_ponkey_match[] = {
+       { .compatible = "stericsson,ab8500-ponkey", },
+       {}
+};
+#endif
+
 static struct platform_driver ab8500_ponkey_driver = {
        .driver         = {
                .name   = "ab8500-poweron-key",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(ab8500_ponkey_match),
        },
        .probe          = ab8500_ponkey_probe,
        .remove         = __devexit_p(ab8500_ponkey_remove),
index c34f6c0..c8a288a 100644 (file)
@@ -251,7 +251,6 @@ static int twl6040_vibra_suspend(struct device *dev)
 
        return 0;
 }
-
 #endif
 
 static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL);
@@ -259,13 +258,19 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL);
 static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
 {
        struct twl6040_vibra_data *pdata = pdev->dev.platform_data;
-       struct device_node *node = pdev->dev.of_node;
+       struct device *twl6040_core_dev = pdev->dev.parent;
+       struct device_node *twl6040_core_node = NULL;
        struct vibra_info *info;
        int vddvibl_uV = 0;
        int vddvibr_uV = 0;
        int ret;
 
-       if (!pdata && !node) {
+#ifdef CONFIG_OF
+       twl6040_core_node = of_find_node_by_name(twl6040_core_dev->of_node,
+                                                "vibra");
+#endif
+
+       if (!pdata && !twl6040_core_node) {
                dev_err(&pdev->dev, "platform_data not available\n");
                return -EINVAL;
        }
@@ -287,14 +292,18 @@ static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
                vddvibl_uV = pdata->vddvibl_uV;
                vddvibr_uV = pdata->vddvibr_uV;
        } else {
-               of_property_read_u32(node, "vibldrv_res", &info->vibldrv_res);
-               of_property_read_u32(node, "vibrdrv_res", &info->vibrdrv_res);
-               of_property_read_u32(node, "viblmotor_res",
+               of_property_read_u32(twl6040_core_node, "ti,vibldrv-res",
+                                    &info->vibldrv_res);
+               of_property_read_u32(twl6040_core_node, "ti,vibrdrv-res",
+                                    &info->vibrdrv_res);
+               of_property_read_u32(twl6040_core_node, "ti,viblmotor-res",
                                     &info->viblmotor_res);
-               of_property_read_u32(node, "vibrmotor_res",
+               of_property_read_u32(twl6040_core_node, "ti,vibrmotor-res",
                                     &info->vibrmotor_res);
-               of_property_read_u32(node, "vddvibl_uV", &vddvibl_uV);
-               of_property_read_u32(node, "vddvibr_uV", &vddvibr_uV);
+               of_property_read_u32(twl6040_core_node, "ti,vddvibl-uV",
+                                    &vddvibl_uV);
+               of_property_read_u32(twl6040_core_node, "ti,vddvibr-uV",
+                                    &vddvibr_uV);
        }
 
        if ((!info->vibldrv_res && !info->viblmotor_res) ||
@@ -351,8 +360,12 @@ static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
 
        info->supplies[0].supply = "vddvibl";
        info->supplies[1].supply = "vddvibr";
-       ret = regulator_bulk_get(info->dev, ARRAY_SIZE(info->supplies),
-                                info->supplies);
+       /*
+        * When booted with Device tree the regulators are attached to the
+        * parent device (twl6040 MFD core)
+        */
+       ret = regulator_bulk_get(pdata ? info->dev : twl6040_core_dev,
+                                ARRAY_SIZE(info->supplies), info->supplies);
        if (ret) {
                dev_err(info->dev, "couldn't get regulators %d\n", ret);
                goto err_regulator;
@@ -418,12 +431,6 @@ static int __devexit twl6040_vibra_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct of_device_id twl6040_vibra_of_match[] = {
-       {.compatible = "ti,twl6040-vibra", },
-       { },
-};
-MODULE_DEVICE_TABLE(of, twl6040_vibra_of_match);
-
 static struct platform_driver twl6040_vibra_driver = {
        .probe          = twl6040_vibra_probe,
        .remove         = __devexit_p(twl6040_vibra_remove),
@@ -431,7 +438,6 @@ static struct platform_driver twl6040_vibra_driver = {
                .name   = "twl6040-vibra",
                .owner  = THIS_MODULE,
                .pm     = &twl6040_vibra_pm_ops,
-               .of_match_table = twl6040_vibra_of_match,
        },
 };
 module_platform_driver(twl6040_vibra_driver);
index cad5602..9a854e2 100644 (file)
@@ -443,8 +443,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
        /* ask to report Wacom data */
        if (features->device_type == BTN_TOOL_FINGER) {
                /* if it is an MT Tablet PC touch */
-               if (features->type == TABLETPC2FG ||
-                   features->type == MTSCREEN) {
+               if (features->type > TABLETPC) {
                        do {
                                rep_data[0] = 3;
                                rep_data[1] = 4;
@@ -463,7 +462,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
                        } while ((error < 0 || rep_data[1] != 4) &&
                                 limit++ < WAC_MSG_RETRIES);
                }
-       } else if (features->type != TABLETPC &&
+       } else if (features->type <= BAMBOO_PT &&
                   features->type != WIRELESS &&
                   features->device_type == BTN_TOOL_PEN) {
                do {
@@ -507,16 +506,13 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
                if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
                        features->device_type = 0;
                } else if (intf->cur_altsetting->desc.bInterfaceNumber == 2) {
-                       features->device_type = BTN_TOOL_DOUBLETAP;
+                       features->device_type = BTN_TOOL_FINGER;
                        features->pktlen = WACOM_PKGLEN_BBTOUCH3;
                }
        }
 
        /* only devices that support touch need to retrieve the info */
-       if (features->type != TABLETPC &&
-           features->type != TABLETPC2FG &&
-           features->type != BAMBOO_PT &&
-           features->type != MTSCREEN) {
+       if (features->type < BAMBOO_PT) {
                goto out;
        }
 
@@ -858,6 +854,7 @@ static int wacom_initialize_leds(struct wacom *wacom)
 
        /* Initialize default values */
        switch (wacom->wacom_wac.features.type) {
+       case INTUOS4S:
        case INTUOS4:
        case INTUOS4L:
                wacom->led.select[0] = 0;
@@ -911,6 +908,7 @@ static int wacom_initialize_leds(struct wacom *wacom)
 static void wacom_destroy_leds(struct wacom *wacom)
 {
        switch (wacom->wacom_wac.features.type) {
+       case INTUOS4S:
        case INTUOS4:
        case INTUOS4L:
                sysfs_remove_group(&wacom->intf->dev.kobj,
@@ -970,6 +968,10 @@ static int wacom_initialize_battery(struct wacom *wacom)
 
                error = power_supply_register(&wacom->usbdev->dev,
                                              &wacom->battery);
+
+               if (!error)
+                       power_supply_powers(&wacom->battery,
+                                           &wacom->usbdev->dev);
        }
 
        return error;
@@ -977,8 +979,11 @@ static int wacom_initialize_battery(struct wacom *wacom)
 
 static void wacom_destroy_battery(struct wacom *wacom)
 {
-       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR)
+       if (wacom->wacom_wac.features.quirks & WACOM_QUIRK_MONITOR &&
+           wacom->battery.dev) {
                power_supply_unregister(&wacom->battery);
+               wacom->battery.dev = NULL;
+       }
 }
 
 static int wacom_register_input(struct wacom *wacom)
@@ -1025,23 +1030,30 @@ 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 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 devices.
+        * remove any existing input and battery devices.
         */
 
+       wacom_destroy_battery(wacom);
+
        /* Stylus interface */
-       wacom = usb_get_intfdata(usbdev->config->interface[1]);
-       if (wacom->wacom_wac.input)
-               input_unregister_device(wacom->wacom_wac.input);
-       wacom->wacom_wac.input = NULL;
+       wacom1 = usb_get_intfdata(usbdev->config->interface[1]);
+       wacom_wac1 = &(wacom1->wacom_wac);
+       if (wacom_wac1->input)
+               input_unregister_device(wacom_wac1->input);
+       wacom_wac1->input = NULL;
 
        /* Touch interface */
-       wacom = usb_get_intfdata(usbdev->config->interface[2]);
-       if (wacom->wacom_wac.input)
-               input_unregister_device(wacom->wacom_wac.input);
-       wacom->wacom_wac.input = NULL;
+       wacom2 = usb_get_intfdata(usbdev->config->interface[2]);
+       wacom_wac2 = &(wacom2->wacom_wac);
+       if (wacom_wac2->input)
+               input_unregister_device(wacom_wac2->input);
+       wacom_wac2->input = NULL;
 
        if (wacom_wac->pid == 0) {
                dev_info(&wacom->intf->dev, "wireless tablet disconnected\n");
@@ -1066,24 +1078,39 @@ static void wacom_wireless_work(struct work_struct *work)
                }
 
                /* Stylus interface */
-               wacom = usb_get_intfdata(usbdev->config->interface[1]);
-               wacom_wac = &wacom->wacom_wac;
-               wacom_wac->features =
+               wacom_wac1->features =
                        *((struct wacom_features *)id->driver_info);
-               wacom_wac->features.device_type = BTN_TOOL_PEN;
-               wacom_register_input(wacom);
+               wacom_wac1->features.device_type = BTN_TOOL_PEN;
+               error = wacom_register_input(wacom1);
+               if (error)
+                       goto fail1;
 
                /* Touch interface */
-               wacom = usb_get_intfdata(usbdev->config->interface[2]);
-               wacom_wac = &wacom->wacom_wac;
-               wacom_wac->features =
+               wacom_wac2->features =
                        *((struct wacom_features *)id->driver_info);
-               wacom_wac->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
-               wacom_wac->features.device_type = BTN_TOOL_FINGER;
-               wacom_set_phy_from_res(&wacom_wac->features);
-               wacom_wac->features.x_max = wacom_wac->features.y_max = 4096;
-               wacom_register_input(wacom);
+               wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
+               wacom_wac2->features.device_type = BTN_TOOL_FINGER;
+               wacom_set_phy_from_res(&wacom_wac2->features);
+               wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096;
+               error = wacom_register_input(wacom2);
+               if (error)
+                       goto fail2;
+
+               error = wacom_initialize_battery(wacom);
+               if (error)
+                       goto fail3;
        }
+
+       return;
+
+fail3:
+       input_unregister_device(wacom_wac2->input);
+       wacom_wac2->input = NULL;
+fail2:
+       input_unregister_device(wacom_wac1->input);
+       wacom_wac1->input = NULL;
+fail1:
+       return;
 }
 
 static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1147,10 +1174,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
                        features->device_type = BTN_TOOL_FINGER;
                        features->pktlen = WACOM_PKGLEN_BBTOUCH3;
 
-                       features->x_phy =
-                               (features->x_max * 100) / features->x_resolution;
-                       features->y_phy =
-                               (features->y_max * 100) / features->y_resolution;
+                       wacom_set_phy_from_res(features);
 
                        features->x_max = 4096;
                        features->y_max = 4096;
@@ -1186,14 +1210,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        if (error)
                goto fail4;
 
-       error = wacom_initialize_battery(wacom);
-       if (error)
-               goto fail5;
-
        if (!(features->quirks & WACOM_QUIRK_NO_INPUT)) {
                error = wacom_register_input(wacom);
                if (error)
-                       goto fail6;
+                       goto fail5;
        }
 
        /* Note that if query fails it is not a hard failure */
@@ -1208,7 +1228,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
 
        return 0;
 
- fail6: wacom_destroy_battery(wacom);
  fail5: wacom_destroy_leds(wacom);
  fail4:        wacom_remove_shared_data(wacom_wac);
  fail3:        usb_free_urb(wacom->irq);
index 004bc1b..6533f44 100644 (file)
@@ -248,7 +248,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom)
                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] & 0x01) << 8));
+                       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);
@@ -888,7 +888,7 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
                        prox = data[0] & 0x01;
                        x = get_unaligned_le16(&data[1]);
                        y = get_unaligned_le16(&data[3]);
-               } else { /* with capacity */
+               } else {
                        prox = data[1] & 0x01;
                        x = le16_to_cpup((__le16 *)&data[2]);
                        y = le16_to_cpup((__le16 *)&data[4]);
@@ -961,6 +961,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
                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:
@@ -1244,6 +1245,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
                break;
 
        case TABLETPC:
+       case TABLETPCE:
        case TABLETPC2FG:
        case MTSCREEN:
                sync = wacom_tpc_irq(wacom_wac, len);
@@ -1317,10 +1319,8 @@ void wacom_setup_device_quirks(struct wacom_features *features)
        }
 
        /* these device have multiple inputs */
-       if (features->type == TABLETPC || features->type == TABLETPC2FG ||
-           features->type == BAMBOO_PT || features->type == WIRELESS ||
-           (features->type >= INTUOS5S && features->type <= INTUOS5L) ||
-           features->type == MTSCREEN)
+       if (features->type >= WIRELESS ||
+           (features->type >= INTUOS5S && features->type <= INTUOS5L))
                features->quirks |= WACOM_QUIRK_MULTI_INPUT;
 
        /* quirk for bamboo touch with 2 low res touches */
@@ -1547,10 +1547,8 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
                break;
 
-       case TABLETPC2FG:
        case MTSCREEN:
                if (features->device_type == BTN_TOOL_FINGER) {
-
                        wacom_wac->slots = kmalloc(features->touch_max *
                                                        sizeof(int),
                                                   GFP_KERNEL);
@@ -1559,7 +1557,11 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
 
                        for (i = 0; i < features->touch_max; i++)
                                wacom_wac->slots[i] = -1;
+               }
+               /* fall through */
 
+       case TABLETPC2FG:
+               if (features->device_type == BTN_TOOL_FINGER) {
                        input_mt_init_slots(input_dev, features->touch_max);
                        input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
                                        0, MT_TOOL_MAX, 0, 0);
@@ -1571,6 +1573,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
                /* fall through */
 
        case TABLETPC:
+       case TABLETPCE:
                __clear_bit(ABS_MISC, input_dev->absbit);
 
                __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
@@ -1888,6 +1891,12 @@ static const struct wacom_features wacom_features_0xE6 =
 static const struct wacom_features wacom_features_0xEC =
        { "Wacom ISDv4 EC",       WACOM_PKGLEN_GRAPHIRE,  25710, 14500,  255,
          0, TABLETPC,    WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0xED =
+       { "Wacom ISDv4 ED",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
+         0, TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0xEF =
+       { "Wacom ISDv4 EF",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
+         0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
 static const struct wacom_features wacom_features_0x47 =
        { "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023,
          31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -2062,6 +2071,8 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0xE5) },
        { USB_DEVICE_WACOM(0xE6) },
        { USB_DEVICE_WACOM(0xEC) },
+       { USB_DEVICE_WACOM(0xED) },
+       { USB_DEVICE_WACOM(0xEF) },
        { USB_DEVICE_WACOM(0x47) },
        { USB_DEVICE_WACOM(0xF4) },
        { USB_DEVICE_LENOVO(0x6004) },
index 78fbd3f..bd5d37b 100644 (file)
@@ -48,6 +48,7 @@
 #define WACOM_REPORT_TPCMT             13
 #define WACOM_REPORT_TPCHID            15
 #define WACOM_REPORT_TPCST             16
+#define WACOM_REPORT_TPC1FGE           18
 
 /* device quirks */
 #define WACOM_QUIRK_MULTI_INPUT                0x0001
@@ -62,8 +63,6 @@ enum {
        PTU,
        PL,
        DTU,
-       BAMBOO_PT,
-       WIRELESS,
        INTUOS,
        INTUOS3S,
        INTUOS3,
@@ -79,7 +78,10 @@ enum {
        CINTIQ,
        WACOM_BEE,
        WACOM_MO,
-       TABLETPC,
+       WIRELESS,
+       BAMBOO_PT,
+       TABLETPC,   /* add new TPC below */
+       TABLETPCE,
        TABLETPC2FG,
        MTSCREEN,
        MAX_TYPE