Merge branch 'next' into for-linus
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 20 Mar 2012 00:02:01 +0000 (17:02 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 20 Mar 2012 00:02:01 +0000 (17:02 -0700)
1  2 
drivers/input/evdev.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c

diff --combined drivers/input/evdev.c
@@@ -20,7 -20,7 +20,7 @@@
  #include <linux/slab.h>
  #include <linux/module.h>
  #include <linux/init.h>
- #include <linux/input.h>
+ #include <linux/input/mt.h>
  #include <linux/major.h>
  #include <linux/device.h>
  #include "input-compat.h"
@@@ -46,6 -46,7 +46,7 @@@ struct evdev_client 
        struct fasync_struct *fasync;
        struct evdev *evdev;
        struct list_head node;
+       int clkid;
        unsigned int bufsize;
        struct input_event buffer[];
  };
@@@ -54,8 -55,12 +55,12 @@@ static struct evdev *evdev_table[EVDEV_
  static DEFINE_MUTEX(evdev_table_mutex);
  
  static void evdev_pass_event(struct evdev_client *client,
-                            struct input_event *event)
+                            struct input_event *event,
+                            ktime_t mono, ktime_t real)
  {
+       event->time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
+                                       mono : real);
        /* Interrupts are disabled, just acquire the lock. */
        spin_lock(&client->buffer_lock);
  
@@@ -94,8 -99,11 +99,11 @@@ static void evdev_event(struct input_ha
        struct evdev *evdev = handle->private;
        struct evdev_client *client;
        struct input_event event;
+       ktime_t time_mono, time_real;
+       time_mono = ktime_get();
+       time_real = ktime_sub(time_mono, ktime_get_monotonic_offset());
  
-       do_gettimeofday(&event.time);
        event.type = type;
        event.code = code;
        event.value = value;
        rcu_read_lock();
  
        client = rcu_dereference(evdev->grab);
        if (client)
-               evdev_pass_event(client, &event);
+               evdev_pass_event(client, &event, time_mono, time_real);
        else
                list_for_each_entry_rcu(client, &evdev->client_list, node)
-                       evdev_pass_event(client, &event);
+                       evdev_pass_event(client, &event, time_mono, time_real);
  
        rcu_read_unlock();
  
@@@ -332,7 -341,7 +341,7 @@@ static ssize_t evdev_write(struct file 
        struct evdev_client *client = file->private_data;
        struct evdev *evdev = client->evdev;
        struct input_event event;
 -      int retval;
 +      int retval = 0;
  
        if (count < input_event_size())
                return -EINVAL;
@@@ -623,6 -632,28 +632,28 @@@ static int evdev_handle_set_keycode_v2(
        return input_set_keycode(dev, &ke);
  }
  
+ static int evdev_handle_mt_request(struct input_dev *dev,
+                                  unsigned int size,
+                                  int __user *ip)
+ {
+       const struct input_mt_slot *mt = dev->mt;
+       unsigned int code;
+       int max_slots;
+       int i;
+       if (get_user(code, &ip[0]))
+               return -EFAULT;
+       if (!input_is_mt_value(code))
+               return -EINVAL;
+       max_slots = (size - sizeof(__u32)) / sizeof(__s32);
+       for (i = 0; i < dev->mtsize && i < max_slots; i++)
+               if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i]))
+                       return -EFAULT;
+       return 0;
+ }
  static long evdev_do_ioctl(struct file *file, unsigned int cmd,
                           void __user *p, int compat_mode)
  {
                else
                        return evdev_ungrab(evdev, client);
  
+       case EVIOCSCLOCKID:
+               if (copy_from_user(&i, p, sizeof(unsigned int)))
+                       return -EFAULT;
+               if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME)
+                       return -EINVAL;
+               client->clkid = i;
+               return 0;
        case EVIOCGKEYCODE:
                return evdev_handle_get_keycode(dev, p);
  
                return bits_to_user(dev->propbit, INPUT_PROP_MAX,
                                    size, p, compat_mode);
  
+       case EVIOCGMTSLOTS(0):
+               return evdev_handle_mt_request(dev, size, ip);
        case EVIOCGKEY(0):
                return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
  
@@@ -176,7 -176,7 +176,7 @@@ static int wacom_parse_logical_collecti
  
                /* Logical collection is only used by 3rd gen Bamboo Touch */
                features->pktlen = WACOM_PKGLEN_BBTOUCH3;
-               features->device_type = BTN_TOOL_DOUBLETAP;
+               features->device_type = BTN_TOOL_FINGER;
  
                /*
                 * Stylus and Touch have same active area
                 * data before its overwritten.
                 */
                features->x_phy =
 -                      (features->x_max * features->x_resolution) / 100;
 +                      (features->x_max * 100) / features->x_resolution;
                features->y_phy =
 -                      (features->y_max * features->y_resolution) / 100;
 +                      (features->y_max * 100) / features->y_resolution;
  
                features->x_max = features->y_max =
                        get_unaligned_le16(&report[10]);
@@@ -286,12 -286,10 +286,10 @@@ static int wacom_parse_hid(struct usb_i
                                                if (features->type == TABLETPC2FG) {
                                                        /* need to reset back */
                                                        features->pktlen = WACOM_PKGLEN_TPC2FG;
-                                                       features->device_type = BTN_TOOL_DOUBLETAP;
                                                }
                                                if (features->type == BAMBOO_PT) {
                                                        /* need to reset back */
                                                        features->pktlen = WACOM_PKGLEN_BBTOUCH;
-                                                       features->device_type = BTN_TOOL_DOUBLETAP;
                                                        features->x_phy =
                                                                get_unaligned_le16(&report[i + 5]);
                                                        features->x_max =
                                                if (features->type == TABLETPC2FG) {
                                                        /* need to reset back */
                                                        features->pktlen = WACOM_PKGLEN_TPC2FG;
-                                                       features->device_type = BTN_TOOL_DOUBLETAP;
                                                        features->y_max =
                                                                get_unaligned_le16(&report[i + 3]);
                                                        features->y_phy =
                                                } else if (features->type == BAMBOO_PT) {
                                                        /* need to reset back */
                                                        features->pktlen = WACOM_PKGLEN_BBTOUCH;
-                                                       features->device_type = BTN_TOOL_DOUBLETAP;
                                                        features->y_phy =
                                                                get_unaligned_le16(&report[i + 3]);
                                                        features->y_max =
@@@ -1000,21 -996,4 +996,4 @@@ static struct usb_driver wacom_driver 
        .supports_autosuspend = 1,
  };
  
- static int __init wacom_init(void)
- {
-       int result;
-       result = usb_register(&wacom_driver);
-       if (result == 0)
-               printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
-                      DRIVER_DESC "\n");
-       return result;
- }
- static void __exit wacom_exit(void)
- {
-       usb_deregister(&wacom_driver);
- }
- module_init(wacom_init);
- module_exit(wacom_exit);
+ module_usb_driver(wacom_driver);
@@@ -832,12 -832,24 +832,24 @@@ static int wacom_tpc_irq(struct wacom_w
  
        dbg("wacom_tpc_irq: received report #%d", data[0]);
  
-       if (len == WACOM_PKGLEN_TPC1FG || data[0] == WACOM_REPORT_TPC1FG)
-               return wacom_tpc_single_touch(wacom, len);
-       else if (data[0] == WACOM_REPORT_TPC2FG)
-               return wacom_tpc_mt_touch(wacom);
-       else if (data[0] == WACOM_REPORT_PENABLED)
-               return wacom_tpc_pen(wacom);
+       switch (len) {
+       case WACOM_PKGLEN_TPC1FG:
+                return wacom_tpc_single_touch(wacom, len);
+       case WACOM_PKGLEN_TPC2FG:
+               return wacom_tpc_mt_touch(wacom);
+       default:
+               switch (data[0]) {
+               case WACOM_REPORT_TPC1FG:
+               case WACOM_REPORT_TPCHID:
+               case WACOM_REPORT_TPCST:
+                       return wacom_tpc_single_touch(wacom, len);
+               case WACOM_REPORT_PENABLED:
+                       return wacom_tpc_pen(wacom);
+               }
+       }
  
        return 0;
  }
@@@ -926,7 -938,7 +938,7 @@@ static int wacom_bpt3_touch(struct waco
  {
        struct input_dev *input = wacom->input;
        unsigned char *data = wacom->data;
 -      int count = data[1] & 0x03;
 +      int count = data[1] & 0x07;
        int i;
  
        if (data[0] != 0x02)
@@@ -1317,7 -1329,7 +1329,7 @@@ void wacom_setup_input_capabilities(str
                break;
  
        case TABLETPC2FG:
-               if (features->device_type == BTN_TOOL_DOUBLETAP) {
+               if (features->device_type == BTN_TOOL_FINGER) {
  
                        input_mt_init_slots(input_dev, 2);
                        input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
  
                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
  
-               if (features->device_type == BTN_TOOL_DOUBLETAP) {
+               if (features->device_type == BTN_TOOL_FINGER) {
                        __set_bit(BTN_LEFT, input_dev->keybit);
                        __set_bit(BTN_FORWARD, input_dev->keybit);
                        __set_bit(BTN_BACK, input_dev->keybit);