Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Linus Torvalds [Sun, 14 Mar 2010 18:13:54 +0000 (11:13 -0700)]
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: i8042 - add ALDI/MEDION netbook E1222 to qurik reset table
  Input: ALPS - fix stuck buttons on some touchpads
  Input: wm831x-on - convert to use genirq
  Input: ads7846 - add wakeup support
  Input: appletouch - fix integer overflow issue
  Input: ad7877 - increase pen up imeout
  Input: ads7846 - add support for AD7843 parts
  Input: bf54x-keys - fix system hang when pressing a key
  Input: alps - add support for the touchpad on Toshiba Tecra A11-11L
  Input: remove BKL, fix input_open_file() locking
  Input: serio_raw - remove BKL
  Input: mousedev - remove BKL
  Input: add driver for TWL4030 vibrator device
  Input: enable remote wakeup for PNP i8042 keyboard ports
  Input: scancode in get/set_keycodes should be unsigned
  Input: i8042 - use platfrom_create_bundle() helper
  Input: wacom - merge out and in prox events
  Input: gamecon - fix off by one range check
  Input: wacom - replace WACOM_PKGLEN_PENABLED

33 files changed:
drivers/hid/hid-input.c
drivers/input/evdev.c
drivers/input/input.c
drivers/input/joystick/gamecon.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/ati_remote2.c
drivers/input/misc/twl4030-vibra.c [new file with mode: 0644]
drivers/input/misc/winbond-cir.c
drivers/input/misc/wm831x-on.c
drivers/input/mouse/alps.c
drivers/input/mouse/appletouch.c
drivers/input/mousedev.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/serio/serio_raw.c
drivers/input/sparse-keymap.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/tablet/wacom_wac.h
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/ad7877.c
drivers/input/touchscreen/ads7846.c
drivers/media/IR/ir-keytable.c
drivers/media/dvb/dvb-usb/dvb-usb-remote.c
drivers/platform/x86/dell-wmi.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/panasonic-laptop.c
drivers/platform/x86/topstar-laptop.c
drivers/platform/x86/toshiba_acpi.c
include/linux/input.h
include/linux/spi/ads7846.h

index 79d9edd..7a0d2e4 100644 (file)
@@ -68,22 +68,25 @@ static const struct {
 #define map_key_clear(c)       hid_map_usage_clear(hidinput, usage, &bit, \
                &max, EV_KEY, (c))
 
-static inline int match_scancode(int code, int scancode)
+static inline int match_scancode(unsigned int code, unsigned int scancode)
 {
        if (scancode == 0)
                return 1;
-       return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode);
+
+       return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
 }
 
-static inline int match_keycode(int code, int keycode)
+static inline int match_keycode(unsigned int code, unsigned int keycode)
 {
        if (keycode == 0)
                return 1;
-       return (code == keycode);
+
+       return code == keycode;
 }
 
 static struct hid_usage *hidinput_find_key(struct hid_device *hid,
-               int scancode, int keycode)
+                                          unsigned int scancode,
+                                          unsigned int keycode)
 {
        int i, j, k;
        struct hid_report *report;
@@ -105,8 +108,8 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid,
        return NULL;
 }
 
-static int hidinput_getkeycode(struct input_dev *dev, int scancode,
-                               int *keycode)
+static int hidinput_getkeycode(struct input_dev *dev,
+                              unsigned int scancode, unsigned int *keycode)
 {
        struct hid_device *hid = input_get_drvdata(dev);
        struct hid_usage *usage;
@@ -119,16 +122,13 @@ static int hidinput_getkeycode(struct input_dev *dev, int scancode,
        return -EINVAL;
 }
 
-static int hidinput_setkeycode(struct input_dev *dev, int scancode,
-                               int keycode)
+static int hidinput_setkeycode(struct input_dev *dev,
+                              unsigned int scancode, unsigned int keycode)
 {
        struct hid_device *hid = input_get_drvdata(dev);
        struct hid_usage *usage;
        int old_keycode;
 
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
        usage = hidinput_find_key(hid, scancode, 0);
        if (usage) {
                old_keycode = usage->code;
index 9f9816b..2ee6c7a 100644 (file)
@@ -515,7 +515,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
        struct input_absinfo abs;
        struct ff_effect effect;
        int __user *ip = (int __user *)p;
-       int i, t, u, v;
+       unsigned int i, t, u, v;
        int error;
 
        switch (cmd) {
index 41168d5..e2aad0a 100644 (file)
@@ -582,7 +582,8 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode)
 }
 
 static int input_default_getkeycode(struct input_dev *dev,
-                                   int scancode, int *keycode)
+                                   unsigned int scancode,
+                                   unsigned int *keycode)
 {
        if (!dev->keycodesize)
                return -EINVAL;
@@ -596,7 +597,8 @@ static int input_default_getkeycode(struct input_dev *dev,
 }
 
 static int input_default_setkeycode(struct input_dev *dev,
-                                   int scancode, int keycode)
+                                   unsigned int scancode,
+                                   unsigned int keycode)
 {
        int old_keycode;
        int i;
@@ -654,11 +656,9 @@ static int input_default_setkeycode(struct input_dev *dev,
  * This function should be called by anyone interested in retrieving current
  * keymap. Presently keyboard and evdev handlers use it.
  */
-int input_get_keycode(struct input_dev *dev, int scancode, int *keycode)
+int input_get_keycode(struct input_dev *dev,
+                     unsigned int scancode, unsigned int *keycode)
 {
-       if (scancode < 0)
-               return -EINVAL;
-
        return dev->getkeycode(dev, scancode, keycode);
 }
 EXPORT_SYMBOL(input_get_keycode);
@@ -672,16 +672,14 @@ EXPORT_SYMBOL(input_get_keycode);
  * This function should be called by anyone needing to update current
  * keymap. Presently keyboard and evdev handlers use it.
  */
-int input_set_keycode(struct input_dev *dev, int scancode, int keycode)
+int input_set_keycode(struct input_dev *dev,
+                     unsigned int scancode, unsigned int keycode)
 {
        unsigned long flags;
        int old_keycode;
        int retval;
 
-       if (scancode < 0)
-               return -EINVAL;
-
-       if (keycode < 0 || keycode > KEY_MAX)
+       if (keycode > KEY_MAX)
                return -EINVAL;
 
        spin_lock_irqsave(&dev->event_lock, flags);
@@ -1881,35 +1879,37 @@ static int input_open_file(struct inode *inode, struct file *file)
        const struct file_operations *old_fops, *new_fops = NULL;
        int err;
 
-       lock_kernel();
+       err = mutex_lock_interruptible(&input_mutex);
+       if (err)
+               return err;
+
        /* No load-on-demand here? */
        handler = input_table[iminor(inode) >> 5];
-       if (!handler || !(new_fops = fops_get(handler->fops))) {
-               err = -ENODEV;
-               goto out;
-       }
+       if (handler)
+               new_fops = fops_get(handler->fops);
+
+       mutex_unlock(&input_mutex);
 
        /*
         * That's _really_ odd. Usually NULL ->open means "nothing special",
         * not "no device". Oh, well...
         */
-       if (!new_fops->open) {
+       if (!new_fops || !new_fops->open) {
                fops_put(new_fops);
                err = -ENODEV;
                goto out;
        }
+
        old_fops = file->f_op;
        file->f_op = new_fops;
 
        err = new_fops->open(inode, file);
-
        if (err) {
                fops_put(file->f_op);
                file->f_op = fops_get(old_fops);
        }
        fops_put(old_fops);
 out:
-       unlock_kernel();
        return err;
 }
 
index ae998d9..7a55714 100644 (file)
@@ -819,7 +819,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
        int i;
        int err;
 
-       if (pad_type < 1 || pad_type > GC_MAX) {
+       if (pad_type < 1 || pad_type >= GC_MAX) {
                pr_err("Pad type %d unknown\n", pad_type);
                return -EINVAL;
        }
index fe376a2..593c052 100644 (file)
@@ -162,7 +162,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id)
        input_sync(input);
 
        if (bfin_kpad_get_keypressed(bf54x_kpad)) {
-               disable_irq(bf54x_kpad->irq);
+               disable_irq_nosync(bf54x_kpad->irq);
                bf54x_kpad->lastkey = key;
                mod_timer(&bf54x_kpad->timer,
                          jiffies + bf54x_kpad->keyup_test_jiffies);
index 7097bfe..23140a3 100644 (file)
@@ -214,6 +214,17 @@ config INPUT_TWL4030_PWRBUTTON
          To compile this driver as a module, choose M here. The module will
          be called twl4030_pwrbutton.
 
+config INPUT_TWL4030_VIBRA
+       tristate "Support for TWL4030 Vibrator"
+       depends on TWL4030_CORE
+       select TWL4030_CODEC
+       select INPUT_FF_MEMLESS
+       help
+         This option enables support for TWL4030 Vibrator Driver.
+
+         To compile this driver as a module, choose M here. The module will
+         be called twl4030_vibra.
+
 config INPUT_UINPUT
        tristate "User level driver support"
        help
index b611615..7e95a5d 100644 (file)
@@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)       += rotary_encoder.o
 obj-$(CONFIG_INPUT_SGI_BTNS)           += sgi_btns.o
 obj-$(CONFIG_INPUT_SPARCSPKR)          += sparcspkr.o
 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)  += twl4030-pwrbutton.o
+obj-$(CONFIG_INPUT_TWL4030_VIBRA)      += twl4030-vibra.o
 obj-$(CONFIG_INPUT_UINPUT)             += uinput.o
 obj-$(CONFIG_INPUT_WINBOND_CIR)                += winbond-cir.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)       += wistron_btns.o
index 0501f0e..15be543 100644 (file)
@@ -474,10 +474,11 @@ static void ati_remote2_complete_key(struct urb *urb)
 }
 
 static int ati_remote2_getkeycode(struct input_dev *idev,
-                                 int scancode, int *keycode)
+                                 unsigned int scancode, unsigned int *keycode)
 {
        struct ati_remote2 *ar2 = input_get_drvdata(idev);
-       int index, mode;
+       unsigned int mode;
+       int index;
 
        mode = scancode >> 8;
        if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -491,10 +492,12 @@ static int ati_remote2_getkeycode(struct input_dev *idev,
        return 0;
 }
 
-static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode)
+static int ati_remote2_setkeycode(struct input_dev *idev,
+                                 unsigned int scancode, unsigned int keycode)
 {
        struct ati_remote2 *ar2 = input_get_drvdata(idev);
-       int index, mode, old_keycode;
+       unsigned int mode, old_keycode;
+       int index;
 
        mode = scancode >> 8;
        if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask))
@@ -504,9 +507,6 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc
        if (index < 0)
                return -EINVAL;
 
-       if (keycode < KEY_RESERVED || keycode > KEY_MAX)
-               return -EINVAL;
-
        old_keycode = ar2->keycode[mode][index];
        ar2->keycode[mode][index] = keycode;
        __set_bit(keycode, idev->keybit);
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
new file mode 100644 (file)
index 0000000..2fb79e0
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * twl4030-vibra.c - TWL4030 Vibrator driver
+ *
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Written by Henrik Saari <henrik.saari@nokia.com>
+ * Updates by Felipe Balbi <felipe.balbi@nokia.com>
+ * Input by Jari Vanhala <ext-jari.vanhala@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/i2c/twl.h>
+#include <linux/mfd/twl4030-codec.h>
+#include <linux/input.h>
+
+/* MODULE ID2 */
+#define LEDEN          0x00
+
+/* ForceFeedback */
+#define EFFECT_DIR_180_DEG     0x8000 /* range is 0 - 0xFFFF */
+
+struct vibra_info {
+       struct device           *dev;
+       struct input_dev        *input_dev;
+
+       struct workqueue_struct *workqueue;
+       struct work_struct      play_work;
+
+       bool                    enabled;
+       int                     speed;
+       int                     direction;
+
+       bool                    coexist;
+};
+
+static void vibra_disable_leds(void)
+{
+       u8 reg;
+
+       /* Disable LEDA & LEDB, cannot be used with vibra (PWM) */
+       twl_i2c_read_u8(TWL4030_MODULE_LED, &reg, LEDEN);
+       reg &= ~0x03;
+       twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg);
+}
+
+/* Powers H-Bridge and enables audio clk */
+static void vibra_enable(struct vibra_info *info)
+{
+       u8 reg;
+
+       twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
+
+       /* turn H-Bridge on */
+       twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+                       &reg, TWL4030_REG_VIBRA_CTL);
+       twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+                        (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
+
+       twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
+
+       info->enabled = true;
+}
+
+static void vibra_disable(struct vibra_info *info)
+{
+       u8 reg;
+
+       /* Power down H-Bridge */
+       twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+                       &reg, TWL4030_REG_VIBRA_CTL);
+       twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+                        (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
+
+       twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
+       twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
+
+       info->enabled = false;
+}
+
+static void vibra_play_work(struct work_struct *work)
+{
+       struct vibra_info *info = container_of(work,
+                       struct vibra_info, play_work);
+       int dir;
+       int pwm;
+       u8 reg;
+
+       dir = info->direction;
+       pwm = info->speed;
+
+       twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+                       &reg, TWL4030_REG_VIBRA_CTL);
+       if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) {
+
+               if (!info->enabled)
+                       vibra_enable(info);
+
+               /* set vibra rotation direction */
+               twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
+                               &reg, TWL4030_REG_VIBRA_CTL);
+               reg = (dir) ? (reg | TWL4030_VIBRA_DIR) :
+                       (reg & ~TWL4030_VIBRA_DIR);
+               twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+                                reg, TWL4030_REG_VIBRA_CTL);
+
+               /* set PWM, 1 = max, 255 = min */
+               twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
+                                256 - pwm, TWL4030_REG_VIBRA_SET);
+       } else {
+               if (info->enabled)
+                       vibra_disable(info);
+       }
+}
+
+/*** Input/ForceFeedback ***/
+
+static int vibra_play(struct input_dev *input, void *data,
+                     struct ff_effect *effect)
+{
+       struct vibra_info *info = input_get_drvdata(input);
+
+       info->speed = effect->u.rumble.strong_magnitude >> 8;
+       if (!info->speed)
+               info->speed = effect->u.rumble.weak_magnitude >> 9;
+       info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1;
+       queue_work(info->workqueue, &info->play_work);
+       return 0;
+}
+
+static int twl4030_vibra_open(struct input_dev *input)
+{
+       struct vibra_info *info = input_get_drvdata(input);
+
+       info->workqueue = create_singlethread_workqueue("vibra");
+       if (info->workqueue == NULL) {
+               dev_err(&input->dev, "couldn't create workqueue\n");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+static void twl4030_vibra_close(struct input_dev *input)
+{
+       struct vibra_info *info = input_get_drvdata(input);
+
+       cancel_work_sync(&info->play_work);
+       INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */
+       destroy_workqueue(info->workqueue);
+       info->workqueue = NULL;
+
+       if (info->enabled)
+               vibra_disable(info);
+}
+
+/*** Module ***/
+#if CONFIG_PM
+static int twl4030_vibra_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct vibra_info *info = platform_get_drvdata(pdev);
+
+       if (info->enabled)
+               vibra_disable(info);
+
+       return 0;
+}
+
+static int twl4030_vibra_resume(struct device *dev)
+{
+       vibra_disable_leds();
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
+                        twl4030_vibra_suspend, twl4030_vibra_resume);
+#endif
+
+static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
+{
+       struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data;
+       struct vibra_info *info;
+       int ret;
+
+       if (!pdata) {
+               dev_dbg(&pdev->dev, "platform_data not available\n");
+               return -EINVAL;
+       }
+
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       info->dev = &pdev->dev;
+       info->coexist = pdata->coexist;
+       INIT_WORK(&info->play_work, vibra_play_work);
+
+       info->input_dev = input_allocate_device();
+       if (info->input_dev == NULL) {
+               dev_err(&pdev->dev, "couldn't allocate input device\n");
+               ret = -ENOMEM;
+               goto err_kzalloc;
+       }
+
+       input_set_drvdata(info->input_dev, info);
+
+       info->input_dev->name = "twl4030:vibrator";
+       info->input_dev->id.version = 1;
+       info->input_dev->dev.parent = pdev->dev.parent;
+       info->input_dev->open = twl4030_vibra_open;
+       info->input_dev->close = twl4030_vibra_close;
+       __set_bit(FF_RUMBLE, info->input_dev->ffbit);
+
+       ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
+       if (ret < 0) {
+               dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
+               goto err_ialloc;
+       }
+
+       ret = input_register_device(info->input_dev);
+       if (ret < 0) {
+               dev_dbg(&pdev->dev, "couldn't register input device\n");
+               goto err_iff;
+       }
+
+       vibra_disable_leds();
+
+       platform_set_drvdata(pdev, info);
+       return 0;
+
+err_iff:
+       input_ff_destroy(info->input_dev);
+err_ialloc:
+       input_free_device(info->input_dev);
+err_kzalloc:
+       kfree(info);
+       return ret;
+}
+
+static int __devexit twl4030_vibra_remove(struct platform_device *pdev)
+{
+       struct vibra_info *info = platform_get_drvdata(pdev);
+
+       /* this also free ff-memless and calls close if needed */
+       input_unregister_device(info->input_dev);
+       kfree(info);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver twl4030_vibra_driver = {
+       .probe          = twl4030_vibra_probe,
+       .remove         = __devexit_p(twl4030_vibra_remove),
+       .driver         = {
+               .name   = "twl4030_codec_vibra",
+               .owner  = THIS_MODULE,
+#ifdef CONFIG_PM
+               .pm     = &twl4030_vibra_pm_ops,
+#endif
+       },
+};
+
+static int __init twl4030_vibra_init(void)
+{
+       return platform_driver_register(&twl4030_vibra_driver);
+}
+module_init(twl4030_vibra_init);
+
+static void __exit twl4030_vibra_exit(void)
+{
+       platform_driver_unregister(&twl4030_vibra_driver);
+}
+module_exit(twl4030_vibra_exit);
+
+MODULE_ALIAS("platform:twl4030_codec_vibra");
+
+MODULE_DESCRIPTION("TWL4030 Vibra driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nokia Corporation");
index cbec3df..9c155a4 100644 (file)
@@ -385,26 +385,24 @@ wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode)
 }
 
 static int
-wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+wbcir_getkeycode(struct input_dev *dev,
+                unsigned int scancode, unsigned int *keycode)
 {
        struct wbcir_data *data = input_get_drvdata(dev);
 
-       *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode);
+       *keycode = wbcir_do_getkeycode(data, scancode);
        return 0;
 }
 
 static int
-wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode)
+wbcir_setkeycode(struct input_dev *dev,
+                unsigned int scancode, unsigned int keycode)
 {
        struct wbcir_data *data = input_get_drvdata(dev);
        struct wbcir_keyentry *keyentry;
        struct wbcir_keyentry *new_keyentry;
        unsigned long flags;
        unsigned int old_keycode = KEY_RESERVED;
-       u32 scancode = (u32)sscancode;
-
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
 
        new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL);
        if (!new_keyentry)
index ba4f5dd..1e54bce 100644 (file)
@@ -97,8 +97,9 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
        wm831x_on->dev->phys = "wm831x_on/input0";
        wm831x_on->dev->dev.parent = &pdev->dev;
 
-       ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq,
-                                IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on);
+       ret = request_threaded_irq(irq, NULL, wm831x_on_irq,
+                                  IRQF_TRIGGER_RISING, "wm831x_on",
+                                  wm831x_on);
        if (ret < 0) {
                dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret);
                goto err_input_dev;
@@ -114,7 +115,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
        return 0;
 
 err_irq:
-       wm831x_free_irq(wm831x, irq, NULL);
+       free_irq(irq, wm831x_on);
 err_input_dev:
        input_free_device(wm831x_on->dev);
 err:
@@ -127,7 +128,7 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev)
        struct wm831x_on *wm831x_on = platform_get_drvdata(pdev);
        int irq = platform_get_irq(pdev, 0);
 
-       wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on);
+       free_irq(irq, wm831x_on);
        cancel_delayed_work_sync(&wm831x_on->work);
        input_unregister_device(wm831x_on->dev);
        kfree(wm831x_on);
index f93c2c0..7490f1d 100644 (file)
@@ -63,6 +63,8 @@ static const struct alps_model_info alps_model_data[] = {
        { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
                ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
        { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },          /* Dell Vostro 1400 */
+       { { 0x52, 0x01, 0x14 }, 0xff, 0xff,
+               ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },      /* Toshiba Tecra A11-11L */
 };
 
 /*
@@ -118,40 +120,27 @@ static void alps_report_buttons(struct psmouse *psmouse,
                                struct input_dev *dev1, struct input_dev *dev2,
                                int left, int right, int middle)
 {
-       struct alps_data *priv = psmouse->private;
-       const struct alps_model_info *model = priv->i;
-
-       if (model->flags & ALPS_PS2_INTERLEAVED) {
-               struct input_dev *dev;
+       struct input_dev *dev;
 
-               /*
-                * If shared button has already been reported on the
-                * other device (dev2) then this event should be also
-                * sent through that device.
-                */
-               dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
-               input_report_key(dev, BTN_LEFT, left);
+       /*
+        * If shared button has already been reported on the
+        * other device (dev2) then this event should be also
+        * sent through that device.
+        */
+       dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
+       input_report_key(dev, BTN_LEFT, left);
 
-               dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
-               input_report_key(dev, BTN_RIGHT, right);
+       dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
+       input_report_key(dev, BTN_RIGHT, right);
 
-               dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
-               input_report_key(dev, BTN_MIDDLE, middle);
+       dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
+       input_report_key(dev, BTN_MIDDLE, middle);
 
-               /*
-                * Sync the _other_ device now, we'll do the first
-                * device later once we report the rest of the events.
-                */
-               input_sync(dev2);
-       } else {
-               /*
-                * For devices with non-interleaved packets we know what
-                * device buttons belong to so we can simply report them.
-                */
-               input_report_key(dev1, BTN_LEFT, left);
-               input_report_key(dev1, BTN_RIGHT, right);
-               input_report_key(dev1, BTN_MIDDLE, middle);
-       }
+       /*
+        * Sync the _other_ device now, we'll do the first
+        * device later once we report the rest of the events.
+        */
+       input_sync(dev2);
 }
 
 static void alps_process_packet(struct psmouse *psmouse)
index 908b5b4..53ec7dd 100644 (file)
@@ -205,8 +205,8 @@ struct atp {
        bool                    overflow_warned;
        int                     x_old;          /* last reported x/y, */
        int                     y_old;          /* used for smoothing */
-       signed char             xy_cur[ATP_XSENSORS + ATP_YSENSORS];
-       signed char             xy_old[ATP_XSENSORS + ATP_YSENSORS];
+       u8                      xy_cur[ATP_XSENSORS + ATP_YSENSORS];
+       u8                      xy_old[ATP_XSENSORS + ATP_YSENSORS];
        int                     xy_acc[ATP_XSENSORS + ATP_YSENSORS];
        int                     idlecount;      /* number of empty packets */
        struct work_struct      work;
@@ -531,7 +531,7 @@ static void atp_complete_geyser_1_2(struct urb *urb)
 
        for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
                /* accumulate the change */
-               signed char change = dev->xy_old[i] - dev->xy_cur[i];
+               int change = dev->xy_old[i] - dev->xy_cur[i];
                dev->xy_acc[i] -= change;
 
                /* prevent down drifting */
index a13d80f..f34b22b 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -542,10 +541,8 @@ static int mousedev_open(struct inode *inode, struct file *file)
        if (i >= MOUSEDEV_MINORS)
                return -ENODEV;
 
-       lock_kernel();
        error = mutex_lock_interruptible(&mousedev_table_mutex);
        if (error) {
-               unlock_kernel();
                return error;
        }
        mousedev = mousedev_table[i];
@@ -554,7 +551,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
        mutex_unlock(&mousedev_table_mutex);
 
        if (!mousedev) {
-               unlock_kernel();
                return -ENODEV;
        }
 
@@ -575,7 +571,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
                goto err_free_client;
 
        file->private_data = client;
-       unlock_kernel();
        return 0;
 
  err_free_client:
@@ -583,7 +578,6 @@ static int mousedev_open(struct inode *inode, struct file *file)
        kfree(client);
  err_put_mousedev:
        put_device(&mousedev->dev);
-       unlock_kernel();
        return error;
 }
 
index 2a5982e..ead0494 100644 (file)
@@ -442,6 +442,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
                },
        },
        {
+               /* Medion Akoya E1222 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
+               },
+       },
+       {
                /* Mivvy M310 */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
@@ -624,6 +631,9 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
                strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
        }
 
+       /* Keyboard ports are always supposed to be wakeup-enabled */
+       device_set_wakeup_enable(&dev->dev, true);
+
        i8042_pnp_kbd_devices++;
        return 0;
 }
index ff4d77c..9302ba0 100644 (file)
@@ -1386,6 +1386,8 @@ static int __init i8042_probe(struct platform_device *dev)
 {
        int error;
 
+       i8042_platform_device = dev;
+
        error = i8042_controller_selftest();
        if (error)
                return error;
@@ -1421,6 +1423,7 @@ static int __init i8042_probe(struct platform_device *dev)
        i8042_free_aux_ports(); /* in case KBD failed but AUX not */
        i8042_free_irqs();
        i8042_controller_reset();
+       i8042_platform_device = NULL;
 
        return error;
 }
@@ -1430,6 +1433,7 @@ static int __devexit i8042_remove(struct platform_device *dev)
        i8042_unregister_ports();
        i8042_free_irqs();
        i8042_controller_reset();
+       i8042_platform_device = NULL;
 
        return 0;
 }
@@ -1448,6 +1452,7 @@ static struct platform_driver i8042_driver = {
 
 static int __init i8042_init(void)
 {
+       struct platform_device *pdev;
        int err;
 
        dbg_init();
@@ -1460,31 +1465,18 @@ static int __init i8042_init(void)
        if (err)
                goto err_platform_exit;
 
-       i8042_platform_device = platform_device_alloc("i8042", -1);
-       if (!i8042_platform_device) {
-               err = -ENOMEM;
+       pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);
+       if (IS_ERR(pdev)) {
+               err = PTR_ERR(pdev);
                goto err_platform_exit;
        }
 
-       err = platform_device_add(i8042_platform_device);
-       if (err)
-               goto err_free_device;
-
-       err = platform_driver_probe(&i8042_driver, i8042_probe);
-       if (err)
-               goto err_del_device;
-
        panic_blink = i8042_panic_blink;
 
        return 0;
 
- err_del_device:
-       platform_device_del(i8042_platform_device);
- err_free_device:
-       platform_device_put(i8042_platform_device);
  err_platform_exit:
        i8042_platform_exit();
-
        return err;
 }
 
index 27fdaaf..9986648 100644 (file)
@@ -81,12 +81,12 @@ static int serio_raw_open(struct inode *inode, struct file *file)
        struct serio_raw_list *list;
        int retval = 0;
 
-       lock_kernel();
        retval = mutex_lock_interruptible(&serio_raw_mutex);
        if (retval)
-               goto out_bkl;
+               return retval;
 
-       if (!(serio_raw = serio_raw_locate(iminor(inode)))) {
+       serio_raw = serio_raw_locate(iminor(inode));
+       if (!serio_raw) {
                retval = -ENODEV;
                goto out;
        }
@@ -96,7 +96,8 @@ static int serio_raw_open(struct inode *inode, struct file *file)
                goto out;
        }
 
-       if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) {
+       list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL);
+       if (!list) {
                retval = -ENOMEM;
                goto out;
        }
@@ -109,8 +110,6 @@ static int serio_raw_open(struct inode *inode, struct file *file)
 
 out:
        mutex_unlock(&serio_raw_mutex);
-out_bkl:
-       unlock_kernel();
        return retval;
 }
 
index fbd3987..e6bde55 100644 (file)
@@ -64,7 +64,8 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
 EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
 
 static int sparse_keymap_getkeycode(struct input_dev *dev,
-                                   int scancode, int *keycode)
+                                   unsigned int scancode,
+                                   unsigned int *keycode)
 {
        const struct key_entry *key =
                        sparse_keymap_entry_from_scancode(dev, scancode);
@@ -78,7 +79,8 @@ static int sparse_keymap_getkeycode(struct input_dev *dev,
 }
 
 static int sparse_keymap_setkeycode(struct input_dev *dev,
-                                   int scancode, int keycode)
+                                   unsigned int scancode,
+                                   unsigned int keycode)
 {
        struct key_entry *key;
        int old_keycode;
index a1770e6..8b5d287 100644 (file)
@@ -371,7 +371,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
                                        } else if (pen) {
                                                /* penabled only accepts exact bytes of data */
                                                if (features->type == TABLETPC2FG)
-                                                       features->pktlen = WACOM_PKGLEN_PENABLED;
+                                                       features->pktlen = WACOM_PKGLEN_GRAPHIRE;
                                                features->device_type = BTN_TOOL_PEN;
                                                features->x_max =
                                                        wacom_le16_to_cpu(&report[i + 3]);
@@ -410,7 +410,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
                                        } else if (pen) {
                                                /* penabled only accepts exact bytes of data */
                                                if (features->type == TABLETPC2FG)
-                                                       features->pktlen = WACOM_PKGLEN_PENABLED;
+                                                       features->pktlen = WACOM_PKGLEN_GRAPHIRE;
                                                features->device_type = BTN_TOOL_PEN;
                                                features->y_max =
                                                        wacom_le16_to_cpu(&report[i + 3]);
index 3d81443..b3ba343 100644 (file)
@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 {
        struct wacom_features *features = &wacom->features;
        unsigned char *data = wacom->data;
-       int x, y, rw;
-       static int penData = 0;
+       int x, y, prox;
+       int rw = 0;
+       int retval = 0;
 
        if (data[0] != WACOM_REPORT_PENABLED) {
                dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
-               return 0;
+               goto exit;
        }
 
-       if (data[1] & 0x80) {
-               /* in prox and not a pad data */
-               penData = 1;
-
-               switch ((data[1] >> 5) & 3) {
+       prox = data[1] & 0x80;
+       if (prox || wacom->id[0]) {
+               if (prox) {
+                       switch ((data[1] >> 5) & 3) {
 
                        case 0: /* Pen */
                                wacom->tool[0] = BTN_TOOL_PEN;
@@ -181,23 +181,13 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 
                        case 2: /* Mouse with wheel */
                                wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
-                               if (features->type == WACOM_G4 || features->type == WACOM_MO) {
-                                       rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
-                                       wacom_report_rel(wcombo, REL_WHEEL, -rw);
-                               } else
-                                       wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]);
                                /* fall through */
 
                        case 3: /* Mouse without wheel */
                                wacom->tool[0] = BTN_TOOL_MOUSE;
                                wacom->id[0] = CURSOR_DEVICE_ID;
-                               wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
-                               wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
-                               if (features->type == WACOM_G4 || features->type == WACOM_MO)
-                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
-                               else
-                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
                                break;
+                       }
                }
                x = wacom_le16_to_cpu(&data[2]);
                y = wacom_le16_to_cpu(&data[4]);
@@ -208,36 +198,32 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
                        wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
                        wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
-               }
-               wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
-               wacom_report_key(wcombo, wacom->tool[0], 1);
-       } else if (wacom->id[0]) {
-               wacom_report_abs(wcombo, ABS_X, 0);
-               wacom_report_abs(wcombo, ABS_Y, 0);
-               if (wacom->tool[0] == BTN_TOOL_MOUSE) {
-                       wacom_report_key(wcombo, BTN_LEFT, 0);
-                       wacom_report_key(wcombo, BTN_RIGHT, 0);
-                       wacom_report_abs(wcombo, ABS_DISTANCE, 0);
                } else {
-                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
-                       wacom_report_key(wcombo, BTN_TOUCH, 0);
-                       wacom_report_key(wcombo, BTN_STYLUS, 0);
-                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+                       wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
+                       wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
+                       if (features->type == WACOM_G4 ||
+                                       features->type == WACOM_MO) {
+                               wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
+                               rw = (signed)(data[7] & 0x04) - (data[7] & 0x03);
+                       } else {
+                               wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
+                               rw = -(signed)data[6];
+                       }
+                       wacom_report_rel(wcombo, REL_WHEEL, rw);
                }
-               wacom->id[0] = 0;
-               wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
-               wacom_report_key(wcombo, wacom->tool[0], 0);
+
+               if (!prox)
+                       wacom->id[0] = 0;
+               wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
+               wacom_report_key(wcombo, wacom->tool[0], prox);
+               wacom_input_sync(wcombo); /* sync last event */
        }
 
        /* send pad data */
        switch (features->type) {
            case WACOM_G4:
-               if (data[7] & 0xf8) {
-                       if (penData) {
-                               wacom_input_sync(wcombo); /* sync last event */
-                               if (!wacom->id[0])
-                                       penData = 0;
-                       }
+               prox = data[7] & 0xf8;
+               if (prox || wacom->id[1]) {
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
                        wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
@@ -245,29 +231,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_rel(wcombo, REL_WHEEL, rw);
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
-                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
-               } else if (wacom->id[1]) {
-                       if (penData) {
-                               wacom_input_sync(wcombo); /* sync last event */
-                               if (!wacom->id[0])
-                                       penData = 0;
-                       }
-                       wacom->id[1] = 0;
-                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
-                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
-                       wacom_report_rel(wcombo, REL_WHEEL, 0);
-                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
-                       wacom_report_abs(wcombo, ABS_MISC, 0);
+                       if (!prox)
+                               wacom->id[1] = 0;
+                       wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
+               retval = 1;
                break;
            case WACOM_MO:
-               if ((data[7] & 0xf8) || (data[8] & 0xff)) {
-                       if (penData) {
-                               wacom_input_sync(wcombo); /* sync last event */
-                               if (!wacom->id[0])
-                                       penData = 0;
-                       }
+               prox = (data[7] & 0xf8) || data[8];
+               if (prox || wacom->id[1]) {
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
                        wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -275,27 +248,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
                        wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
+                       if (!prox)
+                               wacom->id[1] = 0;
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
-               } else if (wacom->id[1]) {
-                       if (penData) {
-                               wacom_input_sync(wcombo); /* sync last event */
-                               if (!wacom->id[0])
-                                       penData = 0;
-                       }
-                       wacom->id[1] = 0;
-                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
-                       wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
-                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
-                       wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
-                       wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
-                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
-                       wacom_report_abs(wcombo, ABS_MISC, 0);
-                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
+               retval = 1;
                break;
        }
-       return 1;
+exit:
+       return retval;
 }
 
 static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
@@ -636,9 +598,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
 static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx)
 {
        wacom_report_abs(wcombo, ABS_X,
-               (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8));
+               data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_Y,
-               (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8));
+               data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
        wacom_report_key(wcombo, wacom->tool[idx], 1);
        if (idx)
@@ -782,31 +744,24 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
 
                touchInProx = 0;
 
-               if (prox) { /* in prox */
-                       if (!wacom->id[0]) {
-                               /* 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;
-                       }
-                       wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
-                       wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
-                       wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
-                       wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
-                       pressure = ((data[7] & 0x01) << 8) | data[6];
-                       if (pressure < 0)
-                               pressure = features->pressure_max + pressure + 1;
-                       wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
-                       wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
-               } else {
-                       wacom_report_abs(wcombo, ABS_X, 0);
-                       wacom_report_abs(wcombo, ABS_Y, 0);
-                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
-                       wacom_report_key(wcombo, BTN_STYLUS, 0);
-                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
-                       wacom_report_key(wcombo, BTN_TOUCH, 0);
+               if (!wacom->id[0]) { /* first in 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;
+               }
+               wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
+               wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
+               wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
+               wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
+               pressure = ((data[7] & 0x01) << 8) | data[6];
+               if (pressure < 0)
+                       pressure = features->pressure_max + pressure + 1;
+               wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
+               wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
+               if (!prox) { /* out-prox */
                        wacom->id[0] = 0;
                        /* pen is out so touch can be enabled now */
                        touchInProx = 1;
@@ -1028,7 +983,7 @@ static const struct wacom_features wacom_features_0x93 =
 static const struct wacom_features wacom_features_0x9A =
        { "Wacom ISDv4 9A",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC };
 static const struct wacom_features wacom_features_0x9F =
-       { "Wacom ISDv4 9F",       WACOM_PKGLEN_PENABLED,  26202, 16325,  255,  0, TABLETPC };
+       { "Wacom ISDv4 9F",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,  0, TABLETPC };
 static const struct wacom_features wacom_features_0xE2 =
        { "Wacom ISDv4 E2",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,  0, TABLETPC2FG };
 static const struct wacom_features wacom_features_0xE3 =
index 8590b1e..b50cf04 100644 (file)
@@ -17,7 +17,6 @@
 #define WACOM_PKGLEN_GRAPHIRE   8
 #define WACOM_PKGLEN_BBFUN      9
 #define WACOM_PKGLEN_INTUOS    10
-#define WACOM_PKGLEN_PENABLED   8
 #define WACOM_PKGLEN_TPC1FG     5
 #define WACOM_PKGLEN_TPC2FG    14
 
index 7208654..8a8fa4d 100644 (file)
@@ -24,17 +24,18 @@ config TOUCHSCREEN_88PM860X
          module will be called 88pm860x-ts.
 
 config TOUCHSCREEN_ADS7846
-       tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
+       tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens"
        depends on SPI_MASTER
        depends on HWMON = n || HWMON
        help
          Say Y here if you have a touchscreen interface using the
-         ADS7846/TSC2046 or ADS7843 controller, and your board-specific
-         setup code includes that in its table of SPI devices.
+         ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller,
+         and your board-specific setup code includes that in its
+         table of SPI devices.
 
          If HWMON is selected, and the driver is told the reference voltage
          on your board, you will also get hwmon interfaces for the voltage
-         (and on ads7846/tsc2046, temperature) sensors of this chip.
+         (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip.
 
          If unsure, say N (but it's safe to say "Y").
 
index eb83939..e019d53 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/spi/ad7877.h>
 #include <asm/irq.h>
 
-#define        TS_PEN_UP_TIMEOUT       msecs_to_jiffies(50)
+#define        TS_PEN_UP_TIMEOUT       msecs_to_jiffies(100)
 
 #define MAX_SPI_FREQ_HZ                        20000000
 #define        MAX_12BIT                       ((1<<12)-1)
index 8b05d8e..532279c 100644 (file)
@@ -36,6 +36,7 @@
  * TSC2046 is just newer ads7846 silicon.
  * Support for ads7843 tested on Atmel at91sam926x-EK.
  * Support for ads7845 has only been stubbed in.
+ * Support for Analog Devices AD7873 and AD7843 tested.
  *
  * IRQ handling needs a workaround because of a shortcoming in handling
  * edge triggered IRQs on some platforms like the OMAP1/2. These
@@ -821,6 +822,9 @@ static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
 
        spin_unlock_irq(&ts->lock);
 
+       if (device_may_wakeup(&ts->spi->dev))
+               enable_irq_wake(ts->spi->irq);
+
        return 0;
 
 }
@@ -829,6 +833,9 @@ static int ads7846_resume(struct spi_device *spi)
 {
        struct ads7846 *ts = dev_get_drvdata(&spi->dev);
 
+       if (device_may_wakeup(&ts->spi->dev))
+               disable_irq_wake(ts->spi->irq);
+
        spin_lock_irq(&ts->lock);
 
        ts->is_suspended = 0;
@@ -984,6 +991,15 @@ static int __devinit ads7846_probe(struct spi_device *spi)
 
        vref = pdata->keep_vref_on;
 
+       if (ts->model == 7873) {
+               /* The AD7873 is almost identical to the ADS7846
+                * keep VREF off during differential/ratiometric
+                * conversion modes
+                */
+               ts->model = 7846;
+               vref = 0;
+       }
+
        /* set up the transfers to read touchscreen state; this assumes we
         * use formula #2 for pressure, not #3.
         */
@@ -1191,6 +1207,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
        if (err)
                goto err_remove_attr_group;
 
+       device_init_wakeup(&spi->dev, pdata->wakeup);
+
        return 0;
 
  err_remove_attr_group:
@@ -1220,6 +1238,8 @@ static int __devexit ads7846_remove(struct spi_device *spi)
 {
        struct ads7846          *ts = dev_get_drvdata(&spi->dev);
 
+       device_init_wakeup(&spi->dev, false);
+
        ads784x_hwmon_unregister(spi, ts);
        input_unregister_device(ts->input);
 
index 0903f53..0a3b4ed 100644 (file)
@@ -123,7 +123,7 @@ static int ir_copy_table(struct ir_scancode_table *destin,
  * If the key is not found, returns -EINVAL, otherwise, returns 0.
  */
 static int ir_getkeycode(struct input_dev *dev,
-                        int scancode, int *keycode)
+                        unsigned int scancode, unsigned int *keycode)
 {
        int elem;
        struct ir_input_dev *ir_dev = input_get_drvdata(dev);
@@ -291,7 +291,7 @@ static int ir_insert_key(struct ir_scancode_table *rc_tab,
  * If the key is not found, returns -EINVAL, otherwise, returns 0.
  */
 static int ir_setkeycode(struct input_dev *dev,
-                        int scancode, int keycode)
+                        unsigned int scancode, unsigned int keycode)
 {
        int rc = 0;
        struct ir_input_dev *ir_dev = input_get_drvdata(dev);
index a03ef7e..852fe89 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/usb/input.h>
 
 static int dvb_usb_getkeycode(struct input_dev *dev,
-                                   int scancode, int *keycode)
+                               unsigned int scancode, unsigned int *keycode)
 {
        struct dvb_usb_device *d = input_get_drvdata(dev);
 
@@ -39,7 +39,7 @@ static int dvb_usb_getkeycode(struct input_dev *dev,
 }
 
 static int dvb_usb_setkeycode(struct input_dev *dev,
-                                   int scancode, int keycode)
+                               unsigned int scancode, unsigned int keycode)
 {
        struct dvb_usb_device *d = input_get_drvdata(dev);
 
index 1b1dddb..bed764e 100644 (file)
@@ -142,7 +142,7 @@ static struct key_entry *dell_wmi_keymap = dell_legacy_wmi_keymap;
 
 static struct input_dev *dell_wmi_input_dev;
 
-static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
+static struct key_entry *dell_wmi_get_entry_by_scancode(unsigned int code)
 {
        struct key_entry *key;
 
@@ -153,7 +153,7 @@ static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
        return NULL;
 }
 
-static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
+static struct key_entry *dell_wmi_get_entry_by_keycode(unsigned int keycode)
 {
        struct key_entry *key;
 
@@ -164,8 +164,8 @@ static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
        return NULL;
 }
 
-static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
-                              int *keycode)
+static int dell_wmi_getkeycode(struct input_dev *dev,
+                               unsigned int scancode, unsigned int *keycode)
 {
        struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
 
@@ -177,13 +177,11 @@ static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
        return -EINVAL;
 }
 
-static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int dell_wmi_setkeycode(struct input_dev *dev,
+                               unsigned int scancode, unsigned int keycode)
 {
        struct key_entry *key;
-       int old_keycode;
-
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
+       unsigned int old_keycode;
 
        key = dell_wmi_get_entry_by_scancode(scancode);
        if (key && key->type == KE_KEY) {
index 7ccf33c..5608636 100644 (file)
@@ -278,7 +278,7 @@ static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als);
 static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
 static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
 
-static struct key_entry *hp_wmi_get_entry_by_scancode(int code)
+static struct key_entry *hp_wmi_get_entry_by_scancode(unsigned int code)
 {
        struct key_entry *key;
 
@@ -289,7 +289,7 @@ static struct key_entry *hp_wmi_get_entry_by_scancode(int code)
        return NULL;
 }
 
-static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode)
+static struct key_entry *hp_wmi_get_entry_by_keycode(unsigned int keycode)
 {
        struct key_entry *key;
 
@@ -300,7 +300,8 @@ static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode)
        return NULL;
 }
 
-static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int hp_wmi_getkeycode(struct input_dev *dev,
+                            unsigned int scancode, unsigned int *keycode)
 {
        struct key_entry *key = hp_wmi_get_entry_by_scancode(scancode);
 
@@ -312,13 +313,11 @@ static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode)
        return -EINVAL;
 }
 
-static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int hp_wmi_setkeycode(struct input_dev *dev,
+                            unsigned int scancode, unsigned int keycode)
 {
        struct key_entry *key;
-       int old_keycode;
-
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
+       unsigned int old_keycode;
 
        key = hp_wmi_get_entry_by_scancode(scancode);
        if (key && key->type == KE_KEY) {
index fe7cf01..c9fc479 100644 (file)
@@ -200,7 +200,7 @@ static struct acpi_driver acpi_pcc_driver = {
 };
 
 #define KEYMAP_SIZE            11
-static const int initial_keymap[KEYMAP_SIZE] = {
+static const unsigned int initial_keymap[KEYMAP_SIZE] = {
        /*  0 */ KEY_RESERVED,
        /*  1 */ KEY_BRIGHTNESSDOWN,
        /*  2 */ KEY_BRIGHTNESSUP,
@@ -222,7 +222,7 @@ struct pcc_acpi {
        struct acpi_device      *device;
        struct input_dev        *input_dev;
        struct backlight_device *backlight;
-       int                     keymap[KEYMAP_SIZE];
+       unsigned int            keymap[KEYMAP_SIZE];
 };
 
 struct pcc_keyinput {
@@ -445,7 +445,8 @@ static struct attribute_group pcc_attr_group = {
 
 /* hotkey input device driver */
 
-static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int pcc_getkeycode(struct input_dev *dev,
+                         unsigned int scancode, unsigned int *keycode)
 {
        struct pcc_acpi *pcc = input_get_drvdata(dev);
 
@@ -457,7 +458,7 @@ static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
        return 0;
 }
 
-static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode)
+static int keymap_get_by_keycode(struct pcc_acpi *pcc, unsigned int keycode)
 {
        int i;
 
@@ -469,7 +470,8 @@ static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode)
        return 0;
 }
 
-static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int pcc_setkeycode(struct input_dev *dev,
+                         unsigned int scancode, unsigned int keycode)
 {
        struct pcc_acpi *pcc = input_get_drvdata(dev);
        int oldkeycode;
@@ -477,9 +479,6 @@ static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode)
        if (scancode >= ARRAY_SIZE(pcc->keymap))
                return -EINVAL;
 
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
        oldkeycode = pcc->keymap[scancode];
        pcc->keymap[scancode] = keycode;
 
index 02f3d4e..4d6516f 100644 (file)
@@ -46,7 +46,7 @@ static struct tps_key_entry topstar_keymap[] = {
        { }
 };
 
-static struct tps_key_entry *tps_get_key_by_scancode(int code)
+static struct tps_key_entry *tps_get_key_by_scancode(unsigned int code)
 {
        struct tps_key_entry *key;
 
@@ -57,7 +57,7 @@ static struct tps_key_entry *tps_get_key_by_scancode(int code)
        return NULL;
 }
 
-static struct tps_key_entry *tps_get_key_by_keycode(int code)
+static struct tps_key_entry *tps_get_key_by_keycode(unsigned int code)
 {
        struct tps_key_entry *key;
 
@@ -126,7 +126,8 @@ static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state)
        return 0;
 }
 
-static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode)
+static int topstar_getkeycode(struct input_dev *dev,
+                               unsigned int scancode, unsigned int *keycode)
 {
        struct tps_key_entry *key = tps_get_key_by_scancode(scancode);
 
@@ -137,14 +138,12 @@ static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode)
        return 0;
 }
 
-static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode)
+static int topstar_setkeycode(struct input_dev *dev,
+                               unsigned int scancode, unsigned int keycode)
 {
        struct tps_key_entry *key;
        int old_keycode;
 
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
        key = tps_get_key_by_scancode(scancode);
 
        if (!key)
index 405b969..789240d 100644 (file)
@@ -745,7 +745,7 @@ static struct backlight_ops toshiba_backlight_data = {
         .update_status  = set_lcd_status,
 };
 
-static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code)
+static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code)
 {
        struct key_entry *key;
 
@@ -756,7 +756,7 @@ static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code)
        return NULL;
 }
 
-static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code)
+static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code)
 {
        struct key_entry *key;
 
@@ -767,8 +767,8 @@ static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code)
        return NULL;
 }
 
-static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode,
-                                  int *keycode)
+static int toshiba_acpi_getkeycode(struct input_dev *dev,
+                                  unsigned int scancode, unsigned int *keycode)
 {
        struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode);
 
@@ -780,14 +780,11 @@ static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode,
        return -EINVAL;
 }
 
-static int toshiba_acpi_setkeycode(struct input_dev *dev, int scancode,
-                                  int keycode)
+static int toshiba_acpi_setkeycode(struct input_dev *dev,
+                                  unsigned int scancode, unsigned int keycode)
 {
        struct key_entry *key;
-       int old_keycode;
-
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
+       unsigned int old_keycode;
 
        key = toshiba_acpi_get_entry_by_scancode(scancode);
        if (key && key->type == KE_KEY) {
index dc24eff..7ed2251 100644 (file)
@@ -58,10 +58,10 @@ struct input_absinfo {
 
 #define EVIOCGVERSION          _IOR('E', 0x01, int)                    /* get driver version */
 #define EVIOCGID               _IOR('E', 0x02, struct input_id)        /* get device ID */
-#define EVIOCGREP              _IOR('E', 0x03, int[2])                 /* get repeat settings */
-#define EVIOCSREP              _IOW('E', 0x03, int[2])                 /* set repeat settings */
-#define EVIOCGKEYCODE          _IOR('E', 0x04, int[2])                 /* get keycode */
-#define EVIOCSKEYCODE          _IOW('E', 0x04, int[2])                 /* set keycode */
+#define EVIOCGREP              _IOR('E', 0x03, unsigned int[2])        /* get repeat settings */
+#define EVIOCSREP              _IOW('E', 0x03, unsigned int[2])        /* set repeat settings */
+#define EVIOCGKEYCODE          _IOR('E', 0x04, unsigned int[2])        /* get keycode */
+#define EVIOCSKEYCODE          _IOW('E', 0x04, unsigned int[2])        /* set keycode */
 
 #define EVIOCGNAME(len)                _IOC(_IOC_READ, 'E', 0x06, len)         /* get device name */
 #define EVIOCGPHYS(len)                _IOC(_IOC_READ, 'E', 0x07, len)         /* get physical location */
@@ -1142,8 +1142,10 @@ struct input_dev {
        unsigned int keycodemax;
        unsigned int keycodesize;
        void *keycode;
-       int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
-       int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);
+       int (*setkeycode)(struct input_dev *dev,
+                         unsigned int scancode, unsigned int keycode);
+       int (*getkeycode)(struct input_dev *dev,
+                         unsigned int scancode, unsigned int *keycode);
 
        struct ff_device *ff;
 
@@ -1415,8 +1417,10 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
        dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
 }
 
-int input_get_keycode(struct input_dev *dev, int scancode, int *keycode);
-int input_set_keycode(struct input_dev *dev, int scancode, int keycode);
+int input_get_keycode(struct input_dev *dev,
+                     unsigned int scancode, unsigned int *keycode);
+int input_set_keycode(struct input_dev *dev,
+                     unsigned int scancode, unsigned int keycode);
 
 extern struct class input_class;
 
index 51948eb..b4ae570 100644 (file)
@@ -12,7 +12,7 @@ enum ads7846_filter {
 };
 
 struct ads7846_platform_data {
-       u16     model;                  /* 7843, 7845, 7846. */
+       u16     model;                  /* 7843, 7845, 7846, 7873. */
        u16     vref_delay_usecs;       /* 0 for external vref; etc */
        u16     vref_mv;                /* external vref value, milliVolts */
        bool    keep_vref_on;           /* set to keep vref on for differential
@@ -53,5 +53,6 @@ struct ads7846_platform_data {
        int     (*filter)       (void *filter_data, int data_idx, int *val);
        void    (*filter_cleanup)(void *filter_data);
        void    (*wait_for_sync)(void);
+       bool    wakeup;
 };