]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 31 Dec 2014 00:59:59 +0000 (16:59 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 31 Dec 2014 00:59:59 +0000 (16:59 -0800)
Pull input layer fixes from Dmitry Torokhov:
 "Fixes for v7 protocol for ALPS devices and few other driver fixes.

  Also users can request input events to be stamped with boot time
  timestamps, in addition to real and monotonic timestamps"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: hil_kbd - fix incorrect use of init_completion
  Input: alps - v7: document the v7 touchpad packet protocol
  Input: alps - v7: fix finger counting for > 2 fingers on clickpads
  Input: alps - v7: sometimes a single touch is reported in mt[1]
  Input: alps - v7: ignore new packets
  Input: evdev - add CLOCK_BOOTTIME support
  Input: psmouse - expose drift duration for IBM trackpoints
  Input: stmpe - bias keypad columns properly
  Input: stmpe - enforce device tree only mode
  mfd: stmpe: add pull up/down register offsets for STMPE
  Input: optimize events_per_packet count calculation
  Input: edt-ft5x06 - fixed a macro coding style issue
  Input: gpio_keys - replace timer and workqueue with delayed workqueue
  Input: gpio_keys - allow separating gpio and irq in device tree

15 files changed:
Documentation/devicetree/bindings/input/gpio-keys.txt
Documentation/devicetree/bindings/input/stmpe-keypad.txt
drivers/input/evdev.c
drivers/input/input.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/hil_kbd.c
drivers/input/keyboard/stmpe-keypad.c
drivers/input/mouse/alps.c
drivers/input/mouse/trackpoint.c
drivers/input/mouse/trackpoint.h
drivers/input/touchscreen/edt-ft5x06.c
drivers/mfd/stmpe.c
drivers/mfd/stmpe.h
include/linux/mfd/stmpe.h

index a4a38fcf2ed61d1fa3db42e053fb8259f2ffcc71..44b705767aca45ea1366c6e624f0515c8cb78b99 100644 (file)
@@ -10,12 +10,13 @@ Optional properties:
 Each button (key) is represented as a sub-node of "gpio-keys":
 Subnode properties:
 
+       - gpios: OF device-tree gpio specification.
+       - interrupts: the interrupt line for that input.
        - label: Descriptive name of the key.
        - linux,code: Keycode to emit.
 
-Required mutual exclusive subnode-properties:
-       - gpios: OF device-tree gpio specification.
-       - interrupts: the interrupt line for that input
+Note that either "interrupts" or "gpios" properties can be omitted, but not
+both at the same time. Specifying both properties is allowed.
 
 Optional subnode-properties:
        - linux,input-type: Specify event type this button/key generates.
@@ -23,6 +24,9 @@ Optional subnode-properties:
        - debounce-interval: Debouncing interval time in milliseconds.
          If not specified defaults to 5.
        - gpio-key,wakeup: Boolean, button can wake-up the system.
+       - linux,can-disable: Boolean, indicates that button is connected
+         to dedicated (not shared) interrupt which can be disabled to
+         suppress events from the button.
 
 Example nodes:
 
index 1b97222e8a0bfe30d88f9d921195b721ecd65194..12bb771d66d446647722ba3e423aabc3734f77bc 100644 (file)
@@ -8,6 +8,8 @@ Optional properties:
  - debounce-interval        : Debouncing interval time in milliseconds
  - st,scan-count            : Scanning cycles elapsed before key data is updated
  - st,no-autorepeat         : If specified device will not autorepeat
+ - keypad,num-rows          : See ./matrix-keymap.txt
+ - keypad,num-columns       : See ./matrix-keymap.txt
 
 Example:
 
index 8afa28e4570ed099bb3fb9fc4b2d7e1c1a5ba9d6..18d4b2c8fe55092aa8e31c411faf051d968fb49d 100644 (file)
 #include <linux/cdev.h>
 #include "input-compat.h"
 
+enum evdev_clock_type {
+       EV_CLK_REAL = 0,
+       EV_CLK_MONO,
+       EV_CLK_BOOT,
+       EV_CLK_MAX
+};
+
 struct evdev {
        int open;
        struct input_handle handle;
@@ -49,12 +56,32 @@ struct evdev_client {
        struct fasync_struct *fasync;
        struct evdev *evdev;
        struct list_head node;
-       int clkid;
+       int clk_type;
        bool revoked;
        unsigned int bufsize;
        struct input_event buffer[];
 };
 
+static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
+{
+       switch (clkid) {
+
+       case CLOCK_REALTIME:
+               client->clk_type = EV_CLK_REAL;
+               break;
+       case CLOCK_MONOTONIC:
+               client->clk_type = EV_CLK_MONO;
+               break;
+       case CLOCK_BOOTTIME:
+               client->clk_type = EV_CLK_BOOT;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 /* flush queued events of type @type, caller must hold client->buffer_lock */
 static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
 {
@@ -108,8 +135,11 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
        struct input_event ev;
        ktime_t time;
 
-       time = (client->clkid == CLOCK_MONOTONIC) ?
-               ktime_get() : ktime_get_real();
+       time = client->clk_type == EV_CLK_REAL ?
+                       ktime_get_real() :
+                       client->clk_type == EV_CLK_MONO ?
+                               ktime_get() :
+                               ktime_get_boottime();
 
        ev.time = ktime_to_timeval(time);
        ev.type = EV_SYN;
@@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client,
 
 static void evdev_pass_values(struct evdev_client *client,
                        const struct input_value *vals, unsigned int count,
-                       ktime_t mono, ktime_t real)
+                       ktime_t *ev_time)
 {
        struct evdev *evdev = client->evdev;
        const struct input_value *v;
@@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client,
        if (client->revoked)
                return;
 
-       event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
-                                     mono : real);
+       event.time = ktime_to_timeval(ev_time[client->clk_type]);
 
        /* Interrupts are disabled, just acquire the lock. */
        spin_lock(&client->buffer_lock);
@@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle,
 {
        struct evdev *evdev = handle->private;
        struct evdev_client *client;
-       ktime_t time_mono, time_real;
+       ktime_t ev_time[EV_CLK_MAX];
 
-       time_mono = ktime_get();
-       time_real = ktime_mono_to_real(time_mono);
+       ev_time[EV_CLK_MONO] = ktime_get();
+       ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]);
+       ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],
+                                                TK_OFFS_BOOT);
 
        rcu_read_lock();
 
        client = rcu_dereference(evdev->grab);
 
        if (client)
-               evdev_pass_values(client, vals, count, time_mono, time_real);
+               evdev_pass_values(client, vals, count, ev_time);
        else
                list_for_each_entry_rcu(client, &evdev->client_list, node)
-                       evdev_pass_values(client, vals, count,
-                                         time_mono, time_real);
+                       evdev_pass_values(client, vals, count, ev_time);
 
        rcu_read_unlock();
 }
@@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
        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;
+
+               return evdev_set_clk_type(client, i);
 
        case EVIOCGKEYCODE:
                return evdev_handle_get_keycode(dev, p);
index 04217c2e345c0ddcaa8e5b1d2525dbb14b5854fe..213e3a1903ee1ddecf84a797ba19da6fa8d7b50c 100644 (file)
@@ -1974,18 +1974,22 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
 
        events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */
 
-       for (i = 0; i < ABS_CNT; i++) {
-               if (test_bit(i, dev->absbit)) {
-                       if (input_is_mt_axis(i))
-                               events += mt_slots;
-                       else
-                               events++;
+       if (test_bit(EV_ABS, dev->evbit)) {
+               for (i = 0; i < ABS_CNT; i++) {
+                       if (test_bit(i, dev->absbit)) {
+                               if (input_is_mt_axis(i))
+                                       events += mt_slots;
+                               else
+                                       events++;
+                       }
                }
        }
 
-       for (i = 0; i < REL_CNT; i++)
-               if (test_bit(i, dev->relbit))
-                       events++;
+       if (test_bit(EV_REL, dev->evbit)) {
+               for (i = 0; i < REL_CNT; i++)
+                       if (test_bit(i, dev->relbit))
+                               events++;
+       }
 
        /* Make room for KEY and MSC events */
        events += 7;
index 96ee26c555e02dd2b69530382170ae3e365facc4..a5d9b3f3c8714ee5a307e166afa4bf90e23864bf 100644 (file)
@@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC
 config KEYBOARD_STMPE
        tristate "STMPE keypad support"
        depends on MFD_STMPE
+       depends on OF
        select INPUT_MATRIXKMAP
        help
          Say Y here if you want to use the keypad controller on STMPE I/O
index d4dd78a7d56b5b1bf3dbe8865025bd5559a82ce2..883d6aed5b9ac12f47bc3a137bbf8e61c0bd1ec2 100644 (file)
 struct gpio_button_data {
        const struct gpio_keys_button *button;
        struct input_dev *input;
-       struct timer_list timer;
-       struct work_struct work;
-       unsigned int timer_debounce;    /* in msecs */
+
+       struct timer_list release_timer;
+       unsigned int release_delay;     /* in msecs, for IRQ-only buttons */
+
+       struct delayed_work work;
+       unsigned int software_debounce; /* in msecs, for GPIO-driven buttons */
+
        unsigned int irq;
        spinlock_t lock;
        bool disabled;
@@ -116,11 +120,14 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
 {
        if (!bdata->disabled) {
                /*
-                * Disable IRQ and possible debouncing timer.
+                * Disable IRQ and associated timer/work structure.
                 */
                disable_irq(bdata->irq);
-               if (bdata->timer_debounce)
-                       del_timer_sync(&bdata->timer);
+
+               if (gpio_is_valid(bdata->button->gpio))
+                       cancel_delayed_work_sync(&bdata->work);
+               else
+                       del_timer_sync(&bdata->release_timer);
 
                bdata->disabled = true;
        }
@@ -343,7 +350,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
 static void gpio_keys_gpio_work_func(struct work_struct *work)
 {
        struct gpio_button_data *bdata =
-               container_of(work, struct gpio_button_data, work);
+               container_of(work, struct gpio_button_data, work.work);
 
        gpio_keys_gpio_report_event(bdata);
 
@@ -351,13 +358,6 @@ static void gpio_keys_gpio_work_func(struct work_struct *work)
                pm_relax(bdata->input->dev.parent);
 }
 
-static void gpio_keys_gpio_timer(unsigned long _data)
-{
-       struct gpio_button_data *bdata = (struct gpio_button_data *)_data;
-
-       schedule_work(&bdata->work);
-}
-
 static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
 {
        struct gpio_button_data *bdata = dev_id;
@@ -366,11 +366,10 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
 
        if (bdata->button->wakeup)
                pm_stay_awake(bdata->input->dev.parent);
-       if (bdata->timer_debounce)
-               mod_timer(&bdata->timer,
-                       jiffies + msecs_to_jiffies(bdata->timer_debounce));
-       else
-               schedule_work(&bdata->work);
+
+       mod_delayed_work(system_wq,
+                        &bdata->work,
+                        msecs_to_jiffies(bdata->software_debounce));
 
        return IRQ_HANDLED;
 }
@@ -408,7 +407,7 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
                input_event(input, EV_KEY, button->code, 1);
                input_sync(input);
 
-               if (!bdata->timer_debounce) {
+               if (!bdata->release_delay) {
                        input_event(input, EV_KEY, button->code, 0);
                        input_sync(input);
                        goto out;
@@ -417,9 +416,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
                bdata->key_pressed = true;
        }
 
-       if (bdata->timer_debounce)
-               mod_timer(&bdata->timer,
-                       jiffies + msecs_to_jiffies(bdata->timer_debounce));
+       if (bdata->release_delay)
+               mod_timer(&bdata->release_timer,
+                       jiffies + msecs_to_jiffies(bdata->release_delay));
 out:
        spin_unlock_irqrestore(&bdata->lock, flags);
        return IRQ_HANDLED;
@@ -429,10 +428,10 @@ static void gpio_keys_quiesce_key(void *data)
 {
        struct gpio_button_data *bdata = data;
 
-       if (bdata->timer_debounce)
-               del_timer_sync(&bdata->timer);
-
-       cancel_work_sync(&bdata->work);
+       if (gpio_is_valid(bdata->button->gpio))
+               cancel_delayed_work_sync(&bdata->work);
+       else
+               del_timer_sync(&bdata->release_timer);
 }
 
 static int gpio_keys_setup_key(struct platform_device *pdev,
@@ -466,23 +465,25 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
                                        button->debounce_interval * 1000);
                        /* use timer if gpiolib doesn't provide debounce */
                        if (error < 0)
-                               bdata->timer_debounce =
+                               bdata->software_debounce =
                                                button->debounce_interval;
                }
 
-               irq = gpio_to_irq(button->gpio);
-               if (irq < 0) {
-                       error = irq;
-                       dev_err(dev,
-                               "Unable to get irq number for GPIO %d, error %d\n",
-                               button->gpio, error);
-                       return error;
+               if (button->irq) {
+                       bdata->irq = button->irq;
+               } else {
+                       irq = gpio_to_irq(button->gpio);
+                       if (irq < 0) {
+                               error = irq;
+                               dev_err(dev,
+                                       "Unable to get irq number for GPIO %d, error %d\n",
+                                       button->gpio, error);
+                               return error;
+                       }
+                       bdata->irq = irq;
                }
-               bdata->irq = irq;
 
-               INIT_WORK(&bdata->work, gpio_keys_gpio_work_func);
-               setup_timer(&bdata->timer,
-                           gpio_keys_gpio_timer, (unsigned long)bdata);
+               INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func);
 
                isr = gpio_keys_gpio_isr;
                irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
@@ -499,8 +500,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
                        return -EINVAL;
                }
 
-               bdata->timer_debounce = button->debounce_interval;
-               setup_timer(&bdata->timer,
+               bdata->release_delay = button->debounce_interval;
+               setup_timer(&bdata->release_timer,
                            gpio_keys_irq_timer, (unsigned long)bdata);
 
                isr = gpio_keys_irq_isr;
@@ -510,7 +511,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
        input_set_capability(input, button->type ?: EV_KEY, button->code);
 
        /*
-        * Install custom action to cancel debounce timer and
+        * Install custom action to cancel release timer and
         * workqueue item.
         */
        error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata);
@@ -618,33 +619,30 @@ gpio_keys_get_devtree_pdata(struct device *dev)
 
        i = 0;
        for_each_child_of_node(node, pp) {
-               int gpio = -1;
                enum of_gpio_flags flags;
 
                button = &pdata->buttons[i++];
 
-               if (!of_find_property(pp, "gpios", NULL)) {
-                       button->irq = irq_of_parse_and_map(pp, 0);
-                       if (button->irq == 0) {
-                               i--;
-                               pdata->nbuttons--;
-                               dev_warn(dev, "Found button without gpios or irqs\n");
-                               continue;
-                       }
-               } else {
-                       gpio = of_get_gpio_flags(pp, 0, &flags);
-                       if (gpio < 0) {
-                               error = gpio;
+               button->gpio = of_get_gpio_flags(pp, 0, &flags);
+               if (button->gpio < 0) {
+                       error = button->gpio;
+                       if (error != -ENOENT) {
                                if (error != -EPROBE_DEFER)
                                        dev_err(dev,
                                                "Failed to get gpio flags, error: %d\n",
                                                error);
                                return ERR_PTR(error);
                        }
+               } else {
+                       button->active_low = flags & OF_GPIO_ACTIVE_LOW;
                }
 
-               button->gpio = gpio;
-               button->active_low = flags & OF_GPIO_ACTIVE_LOW;
+               button->irq = irq_of_parse_and_map(pp, 0);
+
+               if (!gpio_is_valid(button->gpio) && !button->irq) {
+                       dev_err(dev, "Found button without gpios or irqs\n");
+                       return ERR_PTR(-EINVAL);
+               }
 
                if (of_property_read_u32(pp, "linux,code", &button->code)) {
                        dev_err(dev, "Button without keycode: 0x%x\n",
@@ -659,6 +657,8 @@ gpio_keys_get_devtree_pdata(struct device *dev)
 
                button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
 
+               button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL);
+
                if (of_property_read_u32(pp, "debounce-interval",
                                         &button->debounce_interval))
                        button->debounce_interval = 5;
index 610a8af795a1f5b090b73d7bb8919bf41d3e331a..5b152f25a8e1ff72e613608f08876b3098627469 100644 (file)
@@ -473,7 +473,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
        if (error)
                goto bail1;
 
-       init_completion(&dev->cmd_done);
+       reinit_completion(&dev->cmd_done);
        serio_write(serio, 0);
        serio_write(serio, 0);
        serio_write(serio, HIL_PKT_CMD >> 8);
@@ -482,7 +482,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
        if (error)
                goto bail1;
 
-       init_completion(&dev->cmd_done);
+       reinit_completion(&dev->cmd_done);
        serio_write(serio, 0);
        serio_write(serio, 0);
        serio_write(serio, HIL_PKT_CMD >> 8);
@@ -491,7 +491,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
        if (error)
                goto bail1;
 
-       init_completion(&dev->cmd_done);
+       reinit_completion(&dev->cmd_done);
        serio_write(serio, 0);
        serio_write(serio, 0);
        serio_write(serio, HIL_PKT_CMD >> 8);
index ef5e67fb567e701365767a9949dd3ea722e4f260..fe6e3f22eed76157c42a1d9b873b01e34f38b5f2 100644 (file)
 #define STMPE_KEYPAD_MAX_ROWS          8
 #define STMPE_KEYPAD_MAX_COLS          8
 #define STMPE_KEYPAD_ROW_SHIFT         3
-#define STMPE_KEYPAD_KEYMAP_SIZE       \
+#define STMPE_KEYPAD_KEYMAP_MAX_SIZE \
        (STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS)
 
 /**
  * struct stmpe_keypad_variant - model-specific attributes
  * @auto_increment: whether the KPC_DATA_BYTE register address
  *                 auto-increments on multiple read
+ * @set_pullup: whether the pins need to have their pull-ups set
  * @num_data: number of data bytes
  * @num_normal_data: number of normal keys' data bytes
  * @max_cols: maximum number of columns supported
@@ -61,6 +62,7 @@
  */
 struct stmpe_keypad_variant {
        bool            auto_increment;
+       bool            set_pullup;
        int             num_data;
        int             num_normal_data;
        int             max_cols;
@@ -81,6 +83,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
        },
        [STMPE2401] = {
                .auto_increment         = false,
+               .set_pullup             = true,
                .num_data               = 3,
                .num_normal_data        = 2,
                .max_cols               = 8,
@@ -90,6 +93,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
        },
        [STMPE2403] = {
                .auto_increment         = true,
+               .set_pullup             = true,
                .num_data               = 5,
                .num_normal_data        = 3,
                .max_cols               = 8,
@@ -99,16 +103,30 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
        },
 };
 
+/**
+ * struct stmpe_keypad - STMPE keypad state container
+ * @stmpe: pointer to parent STMPE device
+ * @input: spawned input device
+ * @variant: STMPE variant
+ * @debounce_ms: debounce interval, in ms.  Maximum is
+ *              %STMPE_KEYPAD_MAX_DEBOUNCE.
+ * @scan_count: number of key scanning cycles to confirm key data.
+ *             Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT.
+ * @no_autorepeat: disable key autorepeat
+ * @rows: bitmask for the rows
+ * @cols: bitmask for the columns
+ * @keymap: the keymap
+ */
 struct stmpe_keypad {
        struct stmpe *stmpe;
        struct input_dev *input;
        const struct stmpe_keypad_variant *variant;
-       const struct stmpe_keypad_platform_data *plat;
-
+       unsigned int debounce_ms;
+       unsigned int scan_count;
+       bool no_autorepeat;
        unsigned int rows;
        unsigned int cols;
-
-       unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE];
+       unsigned short keymap[STMPE_KEYPAD_KEYMAP_MAX_SIZE];
 };
 
 static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data)
@@ -171,7 +189,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
        unsigned int col_gpios = variant->col_gpios;
        unsigned int row_gpios = variant->row_gpios;
        struct stmpe *stmpe = keypad->stmpe;
+       u8 pureg = stmpe->regs[STMPE_IDX_GPPUR_LSB];
        unsigned int pins = 0;
+       unsigned int pu_pins = 0;
+       int ret;
        int i;
 
        /*
@@ -188,8 +209,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
        for (i = 0; i < variant->max_cols; i++) {
                int num = __ffs(col_gpios);
 
-               if (keypad->cols & (1 << i))
+               if (keypad->cols & (1 << i)) {
                        pins |= 1 << num;
+                       pu_pins |= 1 << num;
+               }
 
                col_gpios &= ~(1 << num);
        }
@@ -203,20 +226,43 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
                row_gpios &= ~(1 << num);
        }
 
-       return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD);
+       ret = stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD);
+       if (ret)
+               return ret;
+
+       /*
+        * On STMPE24xx, set pin bias to pull-up on all keypad input
+        * pins (columns), this incidentally happen to be maximum 8 pins
+        * and placed at GPIO0-7 so only the LSB of the pull up register
+        * ever needs to be written.
+        */
+       if (variant->set_pullup) {
+               u8 val;
+
+               ret = stmpe_reg_read(stmpe, pureg);
+               if (ret)
+                       return ret;
+
+               /* Do not touch unused pins, may be used for GPIO */
+               val = ret & ~pu_pins;
+               val |= pu_pins;
+
+               ret = stmpe_reg_write(stmpe, pureg, val);
+       }
+
+       return 0;
 }
 
 static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
 {
-       const struct stmpe_keypad_platform_data *plat = keypad->plat;
        const struct stmpe_keypad_variant *variant = keypad->variant;
        struct stmpe *stmpe = keypad->stmpe;
        int ret;
 
-       if (plat->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
+       if (keypad->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
                return -EINVAL;
 
-       if (plat->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT)
+       if (keypad->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT)
                return -EINVAL;
 
        ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD);
@@ -245,7 +291,7 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
 
        ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB,
                             STMPE_KPC_CTRL_MSB_SCAN_COUNT,
-                            plat->scan_count << 4);
+                            keypad->scan_count << 4);
        if (ret < 0)
                return ret;
 
@@ -253,17 +299,18 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
                              STMPE_KPC_CTRL_LSB_SCAN |
                              STMPE_KPC_CTRL_LSB_DEBOUNCE,
                              STMPE_KPC_CTRL_LSB_SCAN |
-                             (plat->debounce_ms << 1));
+                             (keypad->debounce_ms << 1));
 }
 
-static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad)
+static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad,
+                                       u32 used_rows, u32 used_cols)
 {
        int row, col;
 
-       for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) {
-               for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) {
+       for (row = 0; row < used_rows; row++) {
+               for (col = 0; col < used_cols; col++) {
                        int code = MATRIX_SCAN_CODE(row, col,
-                                               STMPE_KEYPAD_ROW_SHIFT);
+                                                   STMPE_KEYPAD_ROW_SHIFT);
                        if (keypad->keymap[code] != KEY_RESERVED) {
                                keypad->rows |= 1 << row;
                                keypad->cols |= 1 << col;
@@ -272,51 +319,17 @@ static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad)
        }
 }
 
-#ifdef CONFIG_OF
-static const struct stmpe_keypad_platform_data *
-stmpe_keypad_of_probe(struct device *dev)
-{
-       struct device_node *np = dev->of_node;
-       struct stmpe_keypad_platform_data *plat;
-
-       if (!np)
-               return ERR_PTR(-ENODEV);
-
-       plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL);
-       if (!plat)
-               return ERR_PTR(-ENOMEM);
-
-       of_property_read_u32(np, "debounce-interval", &plat->debounce_ms);
-       of_property_read_u32(np, "st,scan-count", &plat->scan_count);
-
-       plat->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat");
-
-       return plat;
-}
-#else
-static inline const struct stmpe_keypad_platform_data *
-stmpe_keypad_of_probe(struct device *dev)
-{
-       return ERR_PTR(-EINVAL);
-}
-#endif
-
 static int stmpe_keypad_probe(struct platform_device *pdev)
 {
        struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
-       const struct stmpe_keypad_platform_data *plat;
+       struct device_node *np = pdev->dev.of_node;
        struct stmpe_keypad *keypad;
        struct input_dev *input;
+       u32 rows;
+       u32 cols;
        int error;
        int irq;
 
-       plat = stmpe->pdata->keypad;
-       if (!plat) {
-               plat = stmpe_keypad_of_probe(&pdev->dev);
-               if (IS_ERR(plat))
-                       return PTR_ERR(plat);
-       }
-
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
                return irq;
@@ -326,6 +339,13 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
        if (!keypad)
                return -ENOMEM;
 
+       keypad->stmpe = stmpe;
+       keypad->variant = &stmpe_keypad_variants[stmpe->partnum];
+
+       of_property_read_u32(np, "debounce-interval", &keypad->debounce_ms);
+       of_property_read_u32(np, "st,scan-count", &keypad->scan_count);
+       keypad->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat");
+
        input = devm_input_allocate_device(&pdev->dev);
        if (!input)
                return -ENOMEM;
@@ -334,23 +354,22 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
        input->id.bustype = BUS_I2C;
        input->dev.parent = &pdev->dev;
 
-       error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
-                                          STMPE_KEYPAD_MAX_ROWS,
-                                          STMPE_KEYPAD_MAX_COLS,
+       error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols);
+       if (error)
+               return error;
+
+       error = matrix_keypad_build_keymap(NULL, NULL, rows, cols,
                                           keypad->keymap, input);
        if (error)
                return error;
 
        input_set_capability(input, EV_MSC, MSC_SCAN);
-       if (!plat->no_autorepeat)
+       if (!keypad->no_autorepeat)
                __set_bit(EV_REP, input->evbit);
 
-       stmpe_keypad_fill_used_pins(keypad);
+       stmpe_keypad_fill_used_pins(keypad, rows, cols);
 
-       keypad->stmpe = stmpe;
-       keypad->plat = plat;
        keypad->input = input;
-       keypad->variant = &stmpe_keypad_variants[stmpe->partnum];
 
        error = stmpe_keypad_chip_init(keypad);
        if (error < 0)
index d125a019383f10155dcafb88903f47e0f5297080..d88d73d835526a16d2e5e4e48c6a2562c802a4cf 100644 (file)
@@ -881,6 +881,34 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
                                          unsigned char *pkt,
                                          unsigned char pkt_id)
 {
+       /*
+        *       packet-fmt    b7   b6    b5   b4   b3   b2   b1   b0
+        * Byte0 TWO & MULTI    L    1     R    M    1 Y0-2 Y0-1 Y0-0
+        * Byte0 NEW            L    1  X1-5    1    1 Y0-2 Y0-1 Y0-0
+        * Byte1            Y0-10 Y0-9  Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3
+        * Byte2            X0-11    1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5
+        * Byte3            X1-11    1  X0-4 X0-3    1 X0-2 X0-1 X0-0
+        * Byte4 TWO        X1-10  TWO  X1-9 X1-8 X1-7 X1-6 X1-5 X1-4
+        * Byte4 MULTI      X1-10  TWO  X1-9 X1-8 X1-7 X1-6 Y1-5    1
+        * Byte4 NEW        X1-10  TWO  X1-9 X1-8 X1-7 X1-6    0    0
+        * Byte5 TWO & NEW  Y1-10    0  Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4
+        * Byte5 MULTI      Y1-10    0  Y1-9 Y1-8 Y1-7 Y1-6  F-1  F-0
+        * L:         Left button
+        * R / M:     Non-clickpads: Right / Middle button
+        *            Clickpads: When > 2 fingers are down, and some fingers
+        *            are in the button area, then the 2 coordinates reported
+        *            are for fingers outside the button area and these report
+        *            extra fingers being present in the right / left button
+        *            area. Note these fingers are not added to the F field!
+        *            so if a TWO packet is received and R = 1 then there are
+        *            3 fingers down, etc.
+        * TWO:       1: Two touches present, byte 0/4/5 are in TWO fmt
+        *            0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt
+        *               otherwise byte 0 bit 4 must be set and byte 0/4/5 are
+        *               in NEW fmt
+        * F:         Number of fingers - 3, 0 means 3 fingers, 1 means 4 ...
+        */
+
        mt[0].x = ((pkt[2] & 0x80) << 4);
        mt[0].x |= ((pkt[2] & 0x3F) << 5);
        mt[0].x |= ((pkt[3] & 0x30) >> 1);
@@ -919,18 +947,21 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
 
 static int alps_get_mt_count(struct input_mt_pos *mt)
 {
-       int i;
+       int i, fingers = 0;
 
-       for (i = 0; i < MAX_TOUCHES && mt[i].x != 0 && mt[i].y != 0; i++)
-               /* empty */;
+       for (i = 0; i < MAX_TOUCHES; i++) {
+               if (mt[i].x != 0 || mt[i].y != 0)
+                       fingers++;
+       }
 
-       return i;
+       return fingers;
 }
 
 static int alps_decode_packet_v7(struct alps_fields *f,
                                  unsigned char *p,
                                  struct psmouse *psmouse)
 {
+       struct alps_data *priv = psmouse->private;
        unsigned char pkt_id;
 
        pkt_id = alps_get_packet_id_v7(p);
@@ -938,19 +969,52 @@ static int alps_decode_packet_v7(struct alps_fields *f,
                return 0;
        if (pkt_id == V7_PACKET_ID_UNKNOWN)
                return -1;
+       /*
+        * NEW packets are send to indicate a discontinuity in the finger
+        * coordinate reporting. Specifically a finger may have moved from
+        * slot 0 to 1 or vice versa. INPUT_MT_TRACK takes care of this for
+        * us.
+        *
+        * NEW packets have 3 problems:
+        * 1) They do not contain middle / right button info (on non clickpads)
+        *    this can be worked around by preserving the old button state
+        * 2) They do not contain an accurate fingercount, and they are
+        *    typically send when the number of fingers changes. We cannot use
+        *    the old finger count as that may mismatch with the amount of
+        *    touch coordinates we've available in the NEW packet
+        * 3) Their x data for the second touch is inaccurate leading to
+        *    a possible jump of the x coordinate by 16 units when the first
+        *    non NEW packet comes in
+        * Since problems 2 & 3 cannot be worked around, just ignore them.
+        */
+       if (pkt_id == V7_PACKET_ID_NEW)
+               return 1;
 
        alps_get_finger_coordinate_v7(f->mt, p, pkt_id);
 
-       if (pkt_id == V7_PACKET_ID_TWO || pkt_id == V7_PACKET_ID_MULTI) {
-               f->left = (p[0] & 0x80) >> 7;
+       if (pkt_id == V7_PACKET_ID_TWO)
+               f->fingers = alps_get_mt_count(f->mt);
+       else /* pkt_id == V7_PACKET_ID_MULTI */
+               f->fingers = 3 + (p[5] & 0x03);
+
+       f->left = (p[0] & 0x80) >> 7;
+       if (priv->flags & ALPS_BUTTONPAD) {
+               if (p[0] & 0x20)
+                       f->fingers++;
+               if (p[0] & 0x10)
+                       f->fingers++;
+       } else {
                f->right = (p[0] & 0x20) >> 5;
                f->middle = (p[0] & 0x10) >> 4;
        }
 
-       if (pkt_id == V7_PACKET_ID_TWO)
-               f->fingers = alps_get_mt_count(f->mt);
-       else if (pkt_id == V7_PACKET_ID_MULTI)
-               f->fingers = 3 + (p[5] & 0x03);
+       /* Sometimes a single touch is reported in mt[1] rather then mt[0] */
+       if (f->fingers == 1 && f->mt[0].x == 0 && f->mt[0].y == 0) {
+               f->mt[0].x = f->mt[1].x;
+               f->mt[0].y = f->mt[1].y;
+               f->mt[1].x = 0;
+               f->mt[1].y = 0;
+       }
 
        return 0;
 }
index 30c8b6998808fa452a19e437c33bd7e9db8a0888..354d47ecd66a01c8b0ab732eb038bbad19857d19 100644 (file)
@@ -227,6 +227,7 @@ TRACKPOINT_INT_ATTR(thresh, TP_THRESH, TP_DEF_THRESH);
 TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH, TP_DEF_UP_THRESH);
 TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME);
 TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV);
+TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME);
 
 TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0,
                    TP_DEF_PTSON);
@@ -246,6 +247,7 @@ static struct attribute *trackpoint_attrs[] = {
        &psmouse_attr_upthresh.dattr.attr,
        &psmouse_attr_ztime.dattr.attr,
        &psmouse_attr_jenks.dattr.attr,
+       &psmouse_attr_drift_time.dattr.attr,
        &psmouse_attr_press_to_select.dattr.attr,
        &psmouse_attr_skipback.dattr.attr,
        &psmouse_attr_ext_dev.dattr.attr,
@@ -312,6 +314,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state)
        TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, upthresh);
        TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, ztime);
        TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, jenks);
+       TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, drift_time);
 
        /* toggles */
        TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, press_to_select);
@@ -332,6 +335,7 @@ static void trackpoint_defaults(struct trackpoint_data *tp)
        TRACKPOINT_SET_POWER_ON_DEFAULT(tp, upthresh);
        TRACKPOINT_SET_POWER_ON_DEFAULT(tp, ztime);
        TRACKPOINT_SET_POWER_ON_DEFAULT(tp, jenks);
+       TRACKPOINT_SET_POWER_ON_DEFAULT(tp, drift_time);
        TRACKPOINT_SET_POWER_ON_DEFAULT(tp, inertia);
 
        /* toggles */
index ecd0547964a570048a2ad9ecf228d9eda98290a3..5617ed3a7d7a15d0f9769086afb8c740b5739fcc 100644 (file)
@@ -70,6 +70,9 @@
 #define TP_UP_THRESH           0x5A    /* Used to generate a 'click' on Z-axis */
 #define TP_Z_TIME              0x5E    /* How sharp of a press */
 #define TP_JENKS_CURV          0x5D    /* Minimum curvature for double click */
+#define TP_DRIFT_TIME          0x5F    /* How long a 'hands off' condition */
+                                       /* must last (x*107ms) for drift */
+                                       /* correction to occur */
 
 /*
  * Toggling Flag bits
 #define TP_DEF_UP_THRESH       0xFF
 #define TP_DEF_Z_TIME          0x26
 #define TP_DEF_JENKS_CURV      0x87
+#define TP_DEF_DRIFT_TIME      0x05
 
 /* Toggles */
 #define TP_DEF_MB              0x00
@@ -137,6 +141,7 @@ struct trackpoint_data
        unsigned char draghys, mindrag;
        unsigned char thresh, upthresh;
        unsigned char ztime, jenks;
+       unsigned char drift_time;
 
        /* toggles */
        unsigned char press_to_select;
index 3793fcc7e5db31117404e819272da27f4fd15d90..d4c24fb7704f5e2d87f299ac01e2aa2ba5866521 100644 (file)
@@ -850,9 +850,11 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
 }
 
 #define EDT_ATTR_CHECKSET(name, reg) \
+do {                                                           \
        if (pdata->name >= edt_ft5x06_attr_##name.limit_low &&          \
            pdata->name <= edt_ft5x06_attr_##name.limit_high)           \
-               edt_ft5x06_register_write(tsdata, reg, pdata->name)
+               edt_ft5x06_register_write(tsdata, reg, pdata->name);    \
+} while (0)
 
 #define EDT_GET_PROP(name, reg) {                              \
        u32 val;                                                \
index e2f9df1c0c361f0d0e66bf782817af6170e49dc5..2d7fae94c861013c594463705e05ea413275e4d0 100644 (file)
@@ -519,6 +519,7 @@ static const u8 stmpe1601_regs[] = {
        [STMPE_IDX_GPDR_LSB]    = STMPE1601_REG_GPIO_SET_DIR_LSB,
        [STMPE_IDX_GPRER_LSB]   = STMPE1601_REG_GPIO_RE_LSB,
        [STMPE_IDX_GPFER_LSB]   = STMPE1601_REG_GPIO_FE_LSB,
+       [STMPE_IDX_GPPUR_LSB]   = STMPE1601_REG_GPIO_PU_LSB,
        [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB,
        [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
        [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB,
@@ -667,6 +668,7 @@ static const u8 stmpe1801_regs[] = {
        [STMPE_IDX_GPDR_LSB]    = STMPE1801_REG_GPIO_SET_DIR_LOW,
        [STMPE_IDX_GPRER_LSB]   = STMPE1801_REG_GPIO_RE_LOW,
        [STMPE_IDX_GPFER_LSB]   = STMPE1801_REG_GPIO_FE_LOW,
+       [STMPE_IDX_GPPUR_LSB]   = STMPE1801_REG_GPIO_PULL_UP_LOW,
        [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW,
        [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW,
 };
@@ -750,6 +752,8 @@ static const u8 stmpe24xx_regs[] = {
        [STMPE_IDX_GPDR_LSB]    = STMPE24XX_REG_GPDR_LSB,
        [STMPE_IDX_GPRER_LSB]   = STMPE24XX_REG_GPRER_LSB,
        [STMPE_IDX_GPFER_LSB]   = STMPE24XX_REG_GPFER_LSB,
+       [STMPE_IDX_GPPUR_LSB]   = STMPE24XX_REG_GPPUR_LSB,
+       [STMPE_IDX_GPPDR_LSB]   = STMPE24XX_REG_GPPDR_LSB,
        [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB,
        [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB,
        [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB,
index bee0abf82040001664c07e82c646e0e3e5afc259..84adb46b3e2fea599f069072f2f48190602092e9 100644 (file)
@@ -188,6 +188,7 @@ int stmpe_remove(struct stmpe *stmpe);
 #define STMPE1601_REG_GPIO_ED_MSB              0x8A
 #define STMPE1601_REG_GPIO_RE_LSB              0x8D
 #define STMPE1601_REG_GPIO_FE_LSB              0x8F
+#define STMPE1601_REG_GPIO_PU_LSB              0x91
 #define STMPE1601_REG_GPIO_AF_U_MSB            0x92
 
 #define STMPE1601_SYS_CTRL_ENABLE_GPIO         (1 << 3)
@@ -276,6 +277,8 @@ int stmpe_remove(struct stmpe *stmpe);
 #define STMPE24XX_REG_GPEDR_MSB                0x8C
 #define STMPE24XX_REG_GPRER_LSB                0x91
 #define STMPE24XX_REG_GPFER_LSB                0x94
+#define STMPE24XX_REG_GPPUR_LSB                0x97
+#define STMPE24XX_REG_GPPDR_LSB                0x9a
 #define STMPE24XX_REG_GPAFR_U_MSB      0x9B
 
 #define STMPE24XX_SYS_CTRL_ENABLE_GPIO         (1 << 3)
index 575a86c7fcbd2d2b4168d25c3ee20c275e84fc0e..f742b6717d52af2d83aaebaa6d5ff22a72cf786b 100644 (file)
@@ -50,6 +50,8 @@ enum {
        STMPE_IDX_GPEDR_MSB,
        STMPE_IDX_GPRER_LSB,
        STMPE_IDX_GPFER_LSB,
+       STMPE_IDX_GPPUR_LSB,
+       STMPE_IDX_GPPDR_LSB,
        STMPE_IDX_GPAFR_U_MSB,
        STMPE_IDX_IEGPIOR_LSB,
        STMPE_IDX_ISGPIOR_LSB,
@@ -113,24 +115,6 @@ extern int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins,
 extern int stmpe_enable(struct stmpe *stmpe, unsigned int blocks);
 extern int stmpe_disable(struct stmpe *stmpe, unsigned int blocks);
 
-struct matrix_keymap_data;
-
-/**
- * struct stmpe_keypad_platform_data - STMPE keypad platform data
- * @keymap_data: key map table and size
- * @debounce_ms: debounce interval, in ms.  Maximum is
- *              %STMPE_KEYPAD_MAX_DEBOUNCE.
- * @scan_count: number of key scanning cycles to confirm key data.
- *             Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT.
- * @no_autorepeat: disable key autorepeat
- */
-struct stmpe_keypad_platform_data {
-       const struct matrix_keymap_data *keymap_data;
-       unsigned int debounce_ms;
-       unsigned int scan_count;
-       bool no_autorepeat;
-};
-
 #define STMPE_GPIO_NOREQ_811_TOUCH     (0xf0)
 
 /**
@@ -199,7 +183,6 @@ struct stmpe_ts_platform_data {
  * @irq_gpio: gpio number over which irq will be requested (significant only if
  *           irq_over_gpio is true)
  * @gpio: GPIO-specific platform data
- * @keypad: keypad-specific platform data
  * @ts: touchscreen-specific platform data
  */
 struct stmpe_platform_data {
@@ -212,7 +195,6 @@ struct stmpe_platform_data {
        int autosleep_timeout;
 
        struct stmpe_gpio_platform_data *gpio;
-       struct stmpe_keypad_platform_data *keypad;
        struct stmpe_ts_platform_data *ts;
 };