]> git.karo-electronics.de Git - karo-tx-linux.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, 8 Jul 2009 16:32:41 +0000 (09:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 8 Jul 2009 16:32:41 +0000 (09:32 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: gpio_mouse - use standard driver registration method
  Input: mark serio and i8042 as suspended when hibernating too
  Input: add support for generic GPIO-based matrix keypad
  Input: arrange keyboards alphabetically
  Input: gpio-keys - avoid possibility of sleeping in timer function
  Input: gpio-keys - revert 'change timer to workqueue'
  Input: dm355evm_keys - fix kconfig symbol names
  Input: wacom - add DTF720a support and fix rotation on Intuos3
  Input: i8042 - more reset quirks for MSI Wind-clone netbooks

drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/matrix_keypad.c [new file with mode: 0644]
drivers/input/mouse/gpio_mouse.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/serio/serio.c
drivers/input/tablet/wacom_wac.c
drivers/mfd/dm355evm_msp.c
include/linux/input/matrix_keypad.h [new file with mode: 0644]

index 9d8f796c6745291f3bd5bccf3a52177c3583c06f..a6b989a9dc07eee021d90e1d6f4ae902da547056 100644 (file)
@@ -12,6 +12,42 @@ menuconfig INPUT_KEYBOARD
 
 if INPUT_KEYBOARD
 
+config KEYBOARD_AAED2000
+       tristate "AAED-2000 keyboard"
+       depends on MACH_AAED2000
+       select INPUT_POLLDEV
+       default y
+       help
+         Say Y here to enable the keyboard on the Agilent AAED-2000
+         development board.
+
+         To compile this driver as a module, choose M here: the
+         module will be called aaed2000_kbd.
+
+config KEYBOARD_AMIGA
+       tristate "Amiga keyboard"
+       depends on AMIGA
+       help
+         Say Y here if you are running Linux on any AMIGA and have a keyboard
+         attached.
+
+         To compile this driver as a module, choose M here: the
+         module will be called amikbd.
+
+config ATARI_KBD_CORE
+       bool
+
+config KEYBOARD_ATARI
+       tristate "Atari keyboard"
+       depends on ATARI
+       select ATARI_KBD_CORE
+       help
+         Say Y here if you are running Linux on any Atari and have a keyboard
+         attached.
+
+         To compile this driver as a module, choose M here: the
+         module will be called atakbd.
+
 config KEYBOARD_ATKBD
        tristate "AT keyboard" if EMBEDDED || !X86
        default y
@@ -68,69 +104,14 @@ config KEYBOARD_ATKBD_RDI_KEYCODES
          right-hand column will be interpreted as the key shown in the
          left-hand column.
 
-config KEYBOARD_SUNKBD
-       tristate "Sun Type 4 and Type 5 keyboard"
-       select SERIO
-       help
-         Say Y here if you want to use a Sun Type 4 or Type 5 keyboard,
-         connected either to the Sun keyboard connector or to an serial
-         (RS-232) port via a simple adapter.
-
-         To compile this driver as a module, choose M here: the
-         module will be called sunkbd.
-
-config KEYBOARD_LKKBD
-       tristate "DECstation/VAXstation LK201/LK401 keyboard"
-       select SERIO
-       help
-         Say Y here if you want to use a LK201 or LK401 style serial
-         keyboard. This keyboard is also useable on PCs if you attach
-         it with the inputattach program. The connector pinout is
-         described within lkkbd.c.
-
-         To compile this driver as a module, choose M here: the
-         module will be called lkkbd.
-
-config KEYBOARD_LOCOMO
-       tristate "LoCoMo Keyboard Support"
-       depends on SHARP_LOCOMO && INPUT_KEYBOARD
-       help
-         Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
-
-         To compile this driver as a module, choose M here: the
-         module will be called locomokbd.
-
-config KEYBOARD_XTKBD
-       tristate "XT keyboard"
-       select SERIO
-       help
-         Say Y here if you want to use the old IBM PC/XT keyboard (or
-         compatible) on your system. This is only possible with a
-         parallel port keyboard adapter, you cannot connect it to the
-         keyboard port on a PC that runs Linux.
-
-         To compile this driver as a module, choose M here: the
-         module will be called xtkbd.
-
-config KEYBOARD_NEWTON
-       tristate "Newton keyboard"
-       select SERIO
-       help
-         Say Y here if you have a Newton keyboard on a serial port.
-
-         To compile this driver as a module, choose M here: the
-         module will be called newtonkbd.
-
-config KEYBOARD_STOWAWAY
-       tristate "Stowaway keyboard"
-       select SERIO
+config KEYBOARD_BFIN
+       tristate "Blackfin BF54x keypad support"
+       depends on (BF54x && !BF544)
        help
-         Say Y here if you have a Stowaway keyboard on a serial port.
-         Stowaway compatible keyboards like Dicota Input-PDA keyboard
-         are also supported by this driver.
+         Say Y here if you want to use the BF54x keypad.
 
          To compile this driver as a module, choose M here: the
-         module will be called stowaway.
+         module will be called bf54x-keys.
 
 config KEYBOARD_CORGI
        tristate "Corgi keyboard"
@@ -143,61 +124,50 @@ config KEYBOARD_CORGI
          To compile this driver as a module, choose M here: the
          module will be called corgikbd.
 
-config KEYBOARD_SPITZ
-       tristate "Spitz keyboard"
-       depends on PXA_SHARPSL
-       default y
+config KEYBOARD_LKKBD
+       tristate "DECstation/VAXstation LK201/LK401 keyboard"
+       select SERIO
        help
-         Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
-         SL-C3000 and Sl-C3100 series of PDAs.
+         Say Y here if you want to use a LK201 or LK401 style serial
+         keyboard. This keyboard is also useable on PCs if you attach
+         it with the inputattach program. The connector pinout is
+         described within lkkbd.c.
 
          To compile this driver as a module, choose M here: the
-         module will be called spitzkbd.
+         module will be called lkkbd.
 
-config KEYBOARD_TOSA
-       tristate "Tosa keyboard"
-       depends on MACH_TOSA
-       default y
+config KEYBOARD_EP93XX
+       tristate "EP93xx Matrix Keypad support"
+       depends on ARCH_EP93XX
        help
-         Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
+         Say Y here to enable the matrix keypad on the Cirrus EP93XX.
 
          To compile this driver as a module, choose M here: the
-         module will be called tosakbd.
+         module will be called ep93xx_keypad.
 
-config KEYBOARD_TOSA_USE_EXT_KEYCODES
-       bool "Tosa keyboard: use extended keycodes"
-       depends on KEYBOARD_TOSA
-       default n
+config KEYBOARD_GPIO
+       tristate "GPIO Buttons"
+       depends on GENERIC_GPIO
        help
-         Say Y here to enable the tosa keyboard driver to generate extended
-         (>= 127) keycodes. Be aware, that they can't be correctly interpreted
-         by either console keyboard driver or by Kdrive keybd driver.
-
-         Say Y only if you know, what you are doing!
+         This driver implements support for buttons connected
+         to GPIO pins of various CPUs (and some other chips).
 
-config KEYBOARD_AMIGA
-       tristate "Amiga keyboard"
-       depends on AMIGA
-       help
-         Say Y here if you are running Linux on any AMIGA and have a keyboard
-         attached.
+         Say Y here if your device has buttons connected
+         directly to such GPIO pins.  Your board-specific
+         setup logic must also provide a platform device,
+         with configuration data saying which GPIOs are used.
 
          To compile this driver as a module, choose M here: the
-         module will be called amikbd.
+         module will be called gpio_keys.
 
-config ATARI_KBD_CORE
-       bool
-
-config KEYBOARD_ATARI
-       tristate "Atari keyboard"
-       depends on ATARI
-       select ATARI_KBD_CORE
+config KEYBOARD_MATRIX
+       tristate "GPIO driven matrix keypad support"
+       depends on GENERIC_GPIO
        help
-         Say Y here if you are running Linux on any Atari and have a keyboard
-         attached.
+         Enable support for GPIO driven matrix keypad.
 
          To compile this driver as a module, choose M here: the
-         module will be called atakbd.
+         module will be called matrix_keypad.
 
 config KEYBOARD_HIL_OLD
        tristate "HP HIL keyboard support (simple driver)"
@@ -261,20 +231,39 @@ config KEYBOARD_LM8323
          To compile this driver as a module, choose M here: the
          module will be called lm8323.
 
-config KEYBOARD_OMAP
-       tristate "TI OMAP keypad support"
-       depends on (ARCH_OMAP1 || ARCH_OMAP2)
+config KEYBOARD_LOCOMO
+       tristate "LoCoMo Keyboard Support"
+       depends on SHARP_LOCOMO
        help
-         Say Y here if you want to use the OMAP keypad.
+         Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
 
          To compile this driver as a module, choose M here: the
-         module will be called omap-keypad.
+         module will be called locomokbd.
+
+config KEYBOARD_MAPLE
+       tristate "Maple bus keyboard"
+       depends on SH_DREAMCAST && MAPLE
+       help
+         Say Y here if you have a Dreamcast console running Linux and have
+         a keyboard attached to its Maple bus.
+
+         To compile this driver as a module, choose M here: the
+         module will be called maple_keyb.
+
+config KEYBOARD_NEWTON
+       tristate "Newton keyboard"
+       select SERIO
+       help
+         Say Y here if you have a Newton keyboard on a serial port.
+
+         To compile this driver as a module, choose M here: the
+         module will be called newtonkbd.
 
 config KEYBOARD_PXA27x
        tristate "PXA27x/PXA3xx keypad support"
        depends on PXA27x || PXA3xx
        help
-         Enable support for PXA27x/PXA3xx keypad controller
+         Enable support for PXA27x/PXA3xx keypad controller.
 
          To compile this driver as a module, choose M here: the
          module will be called pxa27x_keypad.
@@ -288,51 +277,38 @@ config KEYBOARD_PXA930_ROTARY
          To compile this driver as a module, choose M here: the
          module will be called pxa930_rotary.
 
-config KEYBOARD_AAED2000
-       tristate "AAED-2000 keyboard"
-       depends on MACH_AAED2000
-       select INPUT_POLLDEV
+config KEYBOARD_SPITZ
+       tristate "Spitz keyboard"
+       depends on PXA_SHARPSL
        default y
        help
-         Say Y here to enable the keyboard on the Agilent AAED-2000
-         development board.
-
-         To compile this driver as a module, choose M here: the
-         module will be called aaed2000_kbd.
-
-config KEYBOARD_GPIO
-       tristate "GPIO Buttons"
-       depends on GENERIC_GPIO
-       help
-         This driver implements support for buttons connected
-         to GPIO pins of various CPUs (and some other chips).
-
-         Say Y here if your device has buttons connected
-         directly to such GPIO pins.  Your board-specific
-         setup logic must also provide a platform device,
-         with configuration data saying which GPIOs are used.
+         Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
+         SL-C3000 and Sl-C3100 series of PDAs.
 
          To compile this driver as a module, choose M here: the
-         module will be called gpio-keys.
+         module will be called spitzkbd.
 
-config KEYBOARD_MAPLE
-       tristate "Maple bus keyboard"
-       depends on SH_DREAMCAST && MAPLE
+config KEYBOARD_STOWAWAY
+       tristate "Stowaway keyboard"
+       select SERIO
        help
-         Say Y here if you have a Dreamcast console running Linux and have
-         a keyboard attached to its Maple bus.
+         Say Y here if you have a Stowaway keyboard on a serial port.
+         Stowaway compatible keyboards like Dicota Input-PDA keyboard
+         are also supported by this driver.
 
          To compile this driver as a module, choose M here: the
-         module will be called maple_keyb.
+         module will be called stowaway.
 
-config KEYBOARD_BFIN
-       tristate "Blackfin BF54x keypad support"
-       depends on (BF54x && !BF544)
+config KEYBOARD_SUNKBD
+       tristate "Sun Type 4 and Type 5 keyboard"
+       select SERIO
        help
-         Say Y here if you want to use the BF54x keypad.
+         Say Y here if you want to use a Sun Type 4 or Type 5 keyboard,
+         connected either to the Sun keyboard connector or to an serial
+         (RS-232) port via a simple adapter.
 
          To compile this driver as a module, choose M here: the
-         module will be called bf54x-keys.
+         module will be called sunkbd.
 
 config KEYBOARD_SH_KEYSC
        tristate "SuperH KEYSC keypad support"
@@ -344,13 +320,45 @@ config KEYBOARD_SH_KEYSC
          To compile this driver as a module, choose M here: the
          module will be called sh_keysc.
 
-config KEYBOARD_EP93XX
-       tristate "EP93xx Matrix Keypad support"
-       depends on ARCH_EP93XX
+config KEYBOARD_OMAP
+       tristate "TI OMAP keypad support"
+       depends on (ARCH_OMAP1 || ARCH_OMAP2)
        help
-         Say Y here to enable the matrix keypad on the Cirrus EP93XX.
+         Say Y here if you want to use the OMAP keypad.
 
          To compile this driver as a module, choose M here: the
-         module will be called ep93xx_keypad.
+         module will be called omap-keypad.
+
+config KEYBOARD_TOSA
+       tristate "Tosa keyboard"
+       depends on MACH_TOSA
+       default y
+       help
+         Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
+
+         To compile this driver as a module, choose M here: the
+         module will be called tosakbd.
+
+config KEYBOARD_TOSA_USE_EXT_KEYCODES
+       bool "Tosa keyboard: use extended keycodes"
+       depends on KEYBOARD_TOSA
+       help
+         Say Y here to enable the tosa keyboard driver to generate extended
+         (>= 127) keycodes. Be aware, that they can't be correctly interpreted
+         by either console keyboard driver or by Kdrive keybd driver.
+
+         Say Y only if you know, what you are doing!
+
+config KEYBOARD_XTKBD
+       tristate "XT keyboard"
+       select SERIO
+       help
+         Say Y here if you want to use the old IBM PC/XT keyboard (or
+         compatible) on your system. This is only possible with a
+         parallel port keyboard adapter, you cannot connect it to the
+         keyboard port on a PC that runs Linux.
+
+         To compile this driver as a module, choose M here: the
+         module will be called xtkbd.
 
 endif
index 156b647a259b776b07c64b9e2e99ca6d2bad7286..b5b5eae9724fa5f49b651bcd987ebeb5d0707c18 100644 (file)
@@ -4,29 +4,30 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_KEYBOARD_ATKBD)           += atkbd.o
-obj-$(CONFIG_KEYBOARD_SUNKBD)          += sunkbd.o
-obj-$(CONFIG_KEYBOARD_LKKBD)           += lkkbd.o
-obj-$(CONFIG_KEYBOARD_XTKBD)           += xtkbd.o
+obj-$(CONFIG_KEYBOARD_AAED2000)                += aaed2000_kbd.o
 obj-$(CONFIG_KEYBOARD_AMIGA)           += amikbd.o
 obj-$(CONFIG_KEYBOARD_ATARI)           += atakbd.o
-obj-$(CONFIG_KEYBOARD_LOCOMO)          += locomokbd.o
-obj-$(CONFIG_KEYBOARD_NEWTON)          += newtonkbd.o
-obj-$(CONFIG_KEYBOARD_STOWAWAY)                += stowaway.o
+obj-$(CONFIG_KEYBOARD_ATKBD)           += atkbd.o
+obj-$(CONFIG_KEYBOARD_BFIN)            += bf54x-keys.o
 obj-$(CONFIG_KEYBOARD_CORGI)           += corgikbd.o
-obj-$(CONFIG_KEYBOARD_SPITZ)           += spitzkbd.o
-obj-$(CONFIG_KEYBOARD_TOSA)            += tosakbd.o
+obj-$(CONFIG_KEYBOARD_EP93XX)          += ep93xx_keypad.o
+obj-$(CONFIG_KEYBOARD_GPIO)            += gpio_keys.o
 obj-$(CONFIG_KEYBOARD_HIL)             += hil_kbd.o
 obj-$(CONFIG_KEYBOARD_HIL_OLD)         += hilkbd.o
+obj-$(CONFIG_KEYBOARD_HP6XX)           += jornada680_kbd.o
+obj-$(CONFIG_KEYBOARD_HP7XX)           += jornada720_kbd.o
+obj-$(CONFIG_KEYBOARD_LKKBD)           += lkkbd.o
 obj-$(CONFIG_KEYBOARD_LM8323)          += lm8323.o
+obj-$(CONFIG_KEYBOARD_LOCOMO)          += locomokbd.o
+obj-$(CONFIG_KEYBOARD_MAPLE)           += maple_keyb.o
+obj-$(CONFIG_KEYBOARD_MATRIX)          += matrix_keypad.o
+obj-$(CONFIG_KEYBOARD_NEWTON)          += newtonkbd.o
 obj-$(CONFIG_KEYBOARD_OMAP)            += omap-keypad.o
 obj-$(CONFIG_KEYBOARD_PXA27x)          += pxa27x_keypad.o
 obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)   += pxa930_rotary.o
-obj-$(CONFIG_KEYBOARD_AAED2000)                += aaed2000_kbd.o
-obj-$(CONFIG_KEYBOARD_GPIO)            += gpio_keys.o
-obj-$(CONFIG_KEYBOARD_HP6XX)           += jornada680_kbd.o
-obj-$(CONFIG_KEYBOARD_HP7XX)           += jornada720_kbd.o
-obj-$(CONFIG_KEYBOARD_MAPLE)           += maple_keyb.o
-obj-$(CONFIG_KEYBOARD_BFIN)            += bf54x-keys.o
 obj-$(CONFIG_KEYBOARD_SH_KEYSC)                += sh_keysc.o
-obj-$(CONFIG_KEYBOARD_EP93XX)          += ep93xx_keypad.o
+obj-$(CONFIG_KEYBOARD_SPITZ)           += spitzkbd.o
+obj-$(CONFIG_KEYBOARD_STOWAWAY)                += stowaway.o
+obj-$(CONFIG_KEYBOARD_SUNKBD)          += sunkbd.o
+obj-$(CONFIG_KEYBOARD_TOSA)            += tosakbd.o
+obj-$(CONFIG_KEYBOARD_XTKBD)           += xtkbd.o
index 2157cd7de00ced20c2d253bce59f6a5f37401841..efed0c9e242ed1880f618aa73c67ae0a1eab470b 100644 (file)
@@ -29,7 +29,8 @@
 struct gpio_button_data {
        struct gpio_keys_button *button;
        struct input_dev *input;
-       struct delayed_work work;
+       struct timer_list timer;
+       struct work_struct work;
 };
 
 struct gpio_keys_drvdata {
@@ -40,7 +41,7 @@ struct gpio_keys_drvdata {
 static void gpio_keys_report_event(struct work_struct *work)
 {
        struct gpio_button_data *bdata =
-               container_of(work, struct gpio_button_data, work.work);
+               container_of(work, struct gpio_button_data, work);
        struct gpio_keys_button *button = bdata->button;
        struct input_dev *input = bdata->input;
        unsigned int type = button->type ?: EV_KEY;
@@ -50,17 +51,25 @@ static void gpio_keys_report_event(struct work_struct *work)
        input_sync(input);
 }
 
+static void gpio_keys_timer(unsigned long _data)
+{
+       struct gpio_button_data *data = (struct gpio_button_data *)_data;
+
+       schedule_work(&data->work);
+}
+
 static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
 {
        struct gpio_button_data *bdata = dev_id;
        struct gpio_keys_button *button = bdata->button;
-       unsigned long delay;
 
        BUG_ON(irq != gpio_to_irq(button->gpio));
 
-       delay = button->debounce_interval ?
-                       msecs_to_jiffies(button->debounce_interval) : 0;
-       schedule_delayed_work(&bdata->work, delay);
+       if (button->debounce_interval)
+               mod_timer(&bdata->timer,
+                       jiffies + msecs_to_jiffies(button->debounce_interval));
+       else
+               schedule_work(&bdata->work);
 
        return IRQ_HANDLED;
 }
@@ -107,7 +116,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 
                bdata->input = input;
                bdata->button = button;
-               INIT_DELAYED_WORK(&bdata->work, gpio_keys_report_event);
+               setup_timer(&bdata->timer,
+                           gpio_keys_timer, (unsigned long)bdata);
+               INIT_WORK(&bdata->work, gpio_keys_report_event);
 
                error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
                if (error < 0) {
@@ -166,7 +177,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
  fail2:
        while (--i >= 0) {
                free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
-               cancel_delayed_work_sync(&ddata->data[i].work);
+               if (pdata->buttons[i].debounce_interval)
+                       del_timer_sync(&ddata->data[i].timer);
+               cancel_work_sync(&ddata->data[i].work);
                gpio_free(pdata->buttons[i].gpio);
        }
 
@@ -190,7 +203,9 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
        for (i = 0; i < pdata->nbuttons; i++) {
                int irq = gpio_to_irq(pdata->buttons[i].gpio);
                free_irq(irq, &ddata->data[i]);
-               cancel_delayed_work_sync(&ddata->data[i].work);
+               if (pdata->buttons[i].debounce_interval)
+                       del_timer_sync(&ddata->data[i].timer);
+               cancel_work_sync(&ddata->data[i].work);
                gpio_free(pdata->buttons[i].gpio);
        }
 
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
new file mode 100644 (file)
index 0000000..e9b2e7c
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ *  GPIO driven matrix keyboard driver
+ *
+ *  Copyright (c) 2008 Marek Vasut <marek.vasut@gmail.com>
+ *
+ *  Based on corgikbd.c
+ *
+ *  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.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/input/matrix_keypad.h>
+
+struct matrix_keypad {
+       const struct matrix_keypad_platform_data *pdata;
+       struct input_dev *input_dev;
+       unsigned short *keycodes;
+
+       uint32_t last_key_state[MATRIX_MAX_COLS];
+       struct delayed_work work;
+       bool scan_pending;
+       bool stopped;
+       spinlock_t lock;
+};
+
+/*
+ * NOTE: normally the GPIO has to be put into HiZ when de-activated to cause
+ * minmal side effect when scanning other columns, here it is configured to
+ * be input, and it should work on most platforms.
+ */
+static void __activate_col(const struct matrix_keypad_platform_data *pdata,
+                          int col, bool on)
+{
+       bool level_on = !pdata->active_low;
+
+       if (on) {
+               gpio_direction_output(pdata->col_gpios[col], level_on);
+       } else {
+               gpio_set_value_cansleep(pdata->col_gpios[col], !level_on);
+               gpio_direction_input(pdata->col_gpios[col]);
+       }
+}
+
+static void activate_col(const struct matrix_keypad_platform_data *pdata,
+                        int col, bool on)
+{
+       __activate_col(pdata, col, on);
+
+       if (on && pdata->col_scan_delay_us)
+               udelay(pdata->col_scan_delay_us);
+}
+
+static void activate_all_cols(const struct matrix_keypad_platform_data *pdata,
+                             bool on)
+{
+       int col;
+
+       for (col = 0; col < pdata->num_col_gpios; col++)
+               __activate_col(pdata, col, on);
+}
+
+static bool row_asserted(const struct matrix_keypad_platform_data *pdata,
+                        int row)
+{
+       return gpio_get_value_cansleep(pdata->row_gpios[row]) ?
+                       !pdata->active_low : pdata->active_low;
+}
+
+static void enable_row_irqs(struct matrix_keypad *keypad)
+{
+       const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+       int i;
+
+       for (i = 0; i < pdata->num_row_gpios; i++)
+               enable_irq(gpio_to_irq(pdata->row_gpios[i]));
+}
+
+static void disable_row_irqs(struct matrix_keypad *keypad)
+{
+       const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+       int i;
+
+       for (i = 0; i < pdata->num_row_gpios; i++)
+               disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i]));
+}
+
+/*
+ * This gets the keys from keyboard and reports it to input subsystem
+ */
+static void matrix_keypad_scan(struct work_struct *work)
+{
+       struct matrix_keypad *keypad =
+               container_of(work, struct matrix_keypad, work.work);
+       struct input_dev *input_dev = keypad->input_dev;
+       const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+       uint32_t new_state[MATRIX_MAX_COLS];
+       int row, col, code;
+
+       /* de-activate all columns for scanning */
+       activate_all_cols(pdata, false);
+
+       memset(new_state, 0, sizeof(new_state));
+
+       /* assert each column and read the row status out */
+       for (col = 0; col < pdata->num_col_gpios; col++) {
+
+               activate_col(pdata, col, true);
+
+               for (row = 0; row < pdata->num_row_gpios; row++)
+                       new_state[col] |=
+                               row_asserted(pdata, row) ? (1 << row) : 0;
+
+               activate_col(pdata, col, false);
+       }
+
+       for (col = 0; col < pdata->num_col_gpios; col++) {
+               uint32_t bits_changed;
+
+               bits_changed = keypad->last_key_state[col] ^ new_state[col];
+               if (bits_changed == 0)
+                       continue;
+
+               for (row = 0; row < pdata->num_row_gpios; row++) {
+                       if ((bits_changed & (1 << row)) == 0)
+                               continue;
+
+                       code = (row << 4) + col;
+                       input_event(input_dev, EV_MSC, MSC_SCAN, code);
+                       input_report_key(input_dev,
+                                        keypad->keycodes[code],
+                                        new_state[col] & (1 << row));
+               }
+       }
+       input_sync(input_dev);
+
+       memcpy(keypad->last_key_state, new_state, sizeof(new_state));
+
+       activate_all_cols(pdata, true);
+
+       /* Enable IRQs again */
+       spin_lock_irq(&keypad->lock);
+       keypad->scan_pending = false;
+       enable_row_irqs(keypad);
+       spin_unlock_irq(&keypad->lock);
+}
+
+static irqreturn_t matrix_keypad_interrupt(int irq, void *id)
+{
+       struct matrix_keypad *keypad = id;
+       unsigned long flags;
+
+       spin_lock_irqsave(&keypad->lock, flags);
+
+       /*
+        * See if another IRQ beaten us to it and scheduled the
+        * scan already. In that case we should not try to
+        * disable IRQs again.
+        */
+       if (unlikely(keypad->scan_pending || keypad->stopped))
+               goto out;
+
+       disable_row_irqs(keypad);
+       keypad->scan_pending = true;
+       schedule_delayed_work(&keypad->work,
+               msecs_to_jiffies(keypad->pdata->debounce_ms));
+
+out:
+       spin_unlock_irqrestore(&keypad->lock, flags);
+       return IRQ_HANDLED;
+}
+
+static int matrix_keypad_start(struct input_dev *dev)
+{
+       struct matrix_keypad *keypad = input_get_drvdata(dev);
+
+       keypad->stopped = false;
+       mb();
+
+       /*
+        * Schedule an immediate key scan to capture current key state;
+        * columns will be activated and IRQs be enabled after the scan.
+        */
+       schedule_delayed_work(&keypad->work, 0);
+
+       return 0;
+}
+
+static void matrix_keypad_stop(struct input_dev *dev)
+{
+       struct matrix_keypad *keypad = input_get_drvdata(dev);
+
+       keypad->stopped = true;
+       mb();
+       flush_work(&keypad->work.work);
+       /*
+        * matrix_keypad_scan() will leave IRQs enabled;
+        * we should disable them now.
+        */
+       disable_row_irqs(keypad);
+}
+
+#ifdef CONFIG_PM
+static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct matrix_keypad *keypad = platform_get_drvdata(pdev);
+       const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+       int i;
+
+       matrix_keypad_stop(keypad->input_dev);
+
+       if (device_may_wakeup(&pdev->dev))
+               for (i = 0; i < pdata->num_row_gpios; i++)
+                       enable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
+
+       return 0;
+}
+
+static int matrix_keypad_resume(struct platform_device *pdev)
+{
+       struct matrix_keypad *keypad = platform_get_drvdata(pdev);
+       const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+       int i;
+
+       if (device_may_wakeup(&pdev->dev))
+               for (i = 0; i < pdata->num_row_gpios; i++)
+                       disable_irq_wake(gpio_to_irq(pdata->row_gpios[i]));
+
+       matrix_keypad_start(keypad->input_dev);
+
+       return 0;
+}
+#else
+#define matrix_keypad_suspend  NULL
+#define matrix_keypad_resume   NULL
+#endif
+
+static int __devinit init_matrix_gpio(struct platform_device *pdev,
+                                       struct matrix_keypad *keypad)
+{
+       const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+       int i, err = -EINVAL;
+
+       /* initialized strobe lines as outputs, activated */
+       for (i = 0; i < pdata->num_col_gpios; i++) {
+               err = gpio_request(pdata->col_gpios[i], "matrix_kbd_col");
+               if (err) {
+                       dev_err(&pdev->dev,
+                               "failed to request GPIO%d for COL%d\n",
+                               pdata->col_gpios[i], i);
+                       goto err_free_cols;
+               }
+
+               gpio_direction_output(pdata->col_gpios[i], !pdata->active_low);
+       }
+
+       for (i = 0; i < pdata->num_row_gpios; i++) {
+               err = gpio_request(pdata->row_gpios[i], "matrix_kbd_row");
+               if (err) {
+                       dev_err(&pdev->dev,
+                               "failed to request GPIO%d for ROW%d\n",
+                               pdata->row_gpios[i], i);
+                       goto err_free_rows;
+               }
+
+               gpio_direction_input(pdata->row_gpios[i]);
+       }
+
+       for (i = 0; i < pdata->num_row_gpios; i++) {
+               err = request_irq(gpio_to_irq(pdata->row_gpios[i]),
+                               matrix_keypad_interrupt,
+                               IRQF_DISABLED |
+                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+                               "matrix-keypad", keypad);
+               if (err) {
+                       dev_err(&pdev->dev,
+                               "Unable to acquire interrupt for GPIO line %i\n",
+                               pdata->row_gpios[i]);
+                       goto err_free_irqs;
+               }
+       }
+
+       /* initialized as disabled - enabled by input->open */
+       disable_row_irqs(keypad);
+       return 0;
+
+err_free_irqs:
+       while (--i >= 0)
+               free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
+       i = pdata->num_row_gpios;
+err_free_rows:
+       while (--i >= 0)
+               gpio_free(pdata->row_gpios[i]);
+       i = pdata->num_col_gpios;
+err_free_cols:
+       while (--i >= 0)
+               gpio_free(pdata->col_gpios[i]);
+
+       return err;
+}
+
+static int __devinit matrix_keypad_probe(struct platform_device *pdev)
+{
+       const struct matrix_keypad_platform_data *pdata;
+       const struct matrix_keymap_data *keymap_data;
+       struct matrix_keypad *keypad;
+       struct input_dev *input_dev;
+       unsigned short *keycodes;
+       int i;
+       int err;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata) {
+               dev_err(&pdev->dev, "no platform data defined\n");
+               return -EINVAL;
+       }
+
+       keymap_data = pdata->keymap_data;
+       if (!keymap_data) {
+               dev_err(&pdev->dev, "no keymap data defined\n");
+               return -EINVAL;
+       }
+
+       if (!keymap_data->max_keymap_size) {
+               dev_err(&pdev->dev, "invalid keymap data supplied\n");
+               return -EINVAL;
+       }
+
+       keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL);
+       keycodes = kzalloc(keymap_data->max_keymap_size *
+                               sizeof(keypad->keycodes),
+                          GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!keypad || !keycodes || !input_dev) {
+               err = -ENOMEM;
+               goto err_free_mem;
+       }
+
+       keypad->input_dev = input_dev;
+       keypad->pdata = pdata;
+       keypad->keycodes = keycodes;
+       keypad->stopped = true;
+       INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan);
+       spin_lock_init(&keypad->lock);
+
+       input_dev->name         = pdev->name;
+       input_dev->id.bustype   = BUS_HOST;
+       input_dev->dev.parent   = &pdev->dev;
+       input_dev->evbit[0]     = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+       input_dev->open         = matrix_keypad_start;
+       input_dev->close        = matrix_keypad_stop;
+
+       input_dev->keycode      = keycodes;
+       input_dev->keycodesize  = sizeof(*keycodes);
+       input_dev->keycodemax   = keymap_data->max_keymap_size;
+
+       for (i = 0; i < keymap_data->keymap_size; i++) {
+               unsigned int key = keymap_data->keymap[i];
+               unsigned int row = KEY_ROW(key);
+               unsigned int col = KEY_COL(key);
+               unsigned short code = KEY_VAL(key);
+
+               keycodes[(row << 4) + col] = code;
+               __set_bit(code, input_dev->keybit);
+       }
+       __clear_bit(KEY_RESERVED, input_dev->keybit);
+
+       input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+       input_set_drvdata(input_dev, keypad);
+
+       err = init_matrix_gpio(pdev, keypad);
+       if (err)
+               goto err_free_mem;
+
+       err = input_register_device(keypad->input_dev);
+       if (err)
+               goto err_free_mem;
+
+       device_init_wakeup(&pdev->dev, pdata->wakeup);
+       platform_set_drvdata(pdev, keypad);
+
+       return 0;
+
+err_free_mem:
+       input_free_device(input_dev);
+       kfree(keycodes);
+       kfree(keypad);
+       return err;
+}
+
+static int __devexit matrix_keypad_remove(struct platform_device *pdev)
+{
+       struct matrix_keypad *keypad = platform_get_drvdata(pdev);
+       const struct matrix_keypad_platform_data *pdata = keypad->pdata;
+       int i;
+
+       device_init_wakeup(&pdev->dev, 0);
+
+       for (i = 0; i < pdata->num_row_gpios; i++) {
+               free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
+               gpio_free(pdata->row_gpios[i]);
+       }
+
+       for (i = 0; i < pdata->num_col_gpios; i++)
+               gpio_free(pdata->col_gpios[i]);
+
+       input_unregister_device(keypad->input_dev);
+       platform_set_drvdata(pdev, NULL);
+       kfree(keypad->keycodes);
+       kfree(keypad);
+
+       return 0;
+}
+
+static struct platform_driver matrix_keypad_driver = {
+       .probe          = matrix_keypad_probe,
+       .remove         = __devexit_p(matrix_keypad_remove),
+       .suspend        = matrix_keypad_suspend,
+       .resume         = matrix_keypad_resume,
+       .driver         = {
+               .name   = "matrix-keypad",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init matrix_keypad_init(void)
+{
+       return platform_driver_register(&matrix_keypad_driver);
+}
+
+static void __exit matrix_keypad_exit(void)
+{
+       platform_driver_unregister(&matrix_keypad_driver);
+}
+
+module_init(matrix_keypad_init);
+module_exit(matrix_keypad_exit);
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("GPIO Driven Matrix Keypad Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:matrix-keypad");
index 5e5eb88d8d1e04e48b5a0668300ecf56cbe6017d..7b6ce178f1b67d64c92e2e969d256bbe381a86e7 100644 (file)
@@ -46,7 +46,7 @@ static void gpio_mouse_scan(struct input_polled_dev *dev)
        input_sync(input);
 }
 
-static int __init gpio_mouse_probe(struct platform_device *pdev)
+static int __devinit gpio_mouse_probe(struct platform_device *pdev)
 {
        struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data;
        struct input_polled_dev *input_poll;
@@ -170,10 +170,8 @@ static int __devexit gpio_mouse_remove(struct platform_device *pdev)
        return 0;
 }
 
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:gpio_mouse");
-
 static struct platform_driver gpio_mouse_device_driver = {
+       .probe          = gpio_mouse_probe,
        .remove         = __devexit_p(gpio_mouse_remove),
        .driver         = {
                .name   = "gpio_mouse",
@@ -183,8 +181,7 @@ static struct platform_driver gpio_mouse_device_driver = {
 
 static int __init gpio_mouse_init(void)
 {
-       return platform_driver_probe(&gpio_mouse_device_driver,
-                       gpio_mouse_probe);
+       return platform_driver_register(&gpio_mouse_device_driver);
 }
 module_init(gpio_mouse_init);
 
@@ -197,3 +194,5 @@ module_exit(gpio_mouse_exit);
 MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
 MODULE_DESCRIPTION("GPIO mouse driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */
+
index fb8a3cd3ffd0ab4685e8e68f5f14b07068266b94..924e8ed7f2cf777f5d48767c18d5618027c031e6 100644 (file)
@@ -392,6 +392,34 @@ static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
                },
        },
+       {
+               .ident = "Acer Aspire One 150",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+               },
+       },
+       {
+               .ident = "Advent 4211",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
+               },
+       },
+       {
+               .ident = "Medion Akoya Mini E1210",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
+               },
+       },
+       {
+               .ident = "Mivvy M310",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
+               },
+       },
        { }
 };
 
index f919bf57293c9fad56d625aa1e497655eda5a04a..582245c497ebfe1e6ff5b8fbe513a31e483de35f 100644 (file)
@@ -934,10 +934,11 @@ static bool i8042_suspended;
 
 static int i8042_suspend(struct platform_device *dev, pm_message_t state)
 {
-       if (!i8042_suspended && state.event == PM_EVENT_SUSPEND) {
+       if (!i8042_suspended && state.event == PM_EVENT_SUSPEND)
                i8042_controller_reset();
-               i8042_suspended = true;
-       }
+
+       i8042_suspended = state.event == PM_EVENT_SUSPEND ||
+                         state.event == PM_EVENT_FREEZE;
 
        return 0;
 }
index fb17573f8f2d90e88072714b0a8fc4b7eb142616..d66f4944f2a0efc0a18508d9c4707bf069567830 100644 (file)
@@ -935,10 +935,11 @@ static int serio_suspend(struct device *dev, pm_message_t state)
 {
        struct serio *serio = to_serio_port(dev);
 
-       if (!serio->suspended && state.event == PM_EVENT_SUSPEND) {
+       if (!serio->suspended && state.event == PM_EVENT_SUSPEND)
                serio_cleanup(serio);
-               serio->suspended = true;
-       }
+
+       serio->suspended = state.event == PM_EVENT_SUSPEND ||
+                          state.event == PM_EVENT_FREEZE;
 
        return 0;
 }
index 38bf86384aeba4d7b5393f43179e2c4bf55864b9..c896d6a21b7ee6fa53eb8853ff6535a65ae194af 100644 (file)
@@ -384,6 +384,8 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_STYLUS2, 0);
                        wacom_report_key(wcombo, BTN_TOUCH, 0);
                        wacom_report_abs(wcombo, ABS_WHEEL, 0);
+                       if (wacom->features->type >= INTUOS3S)
+                               wacom_report_abs(wcombo, ABS_Z, 0);
                }
                wacom_report_key(wcombo, wacom->tool[idx], 0);
                wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
@@ -836,6 +838,7 @@ static struct wacom_features wacom_features[] = {
        { "Wacom DTU710",        8,  34080, 27660,  511,  0, PL },
        { "Wacom DTF521",        8,   6282,  4762,  511,  0, PL },
        { "Wacom DTF720",        8,   6858,  5506,  511,  0, PL },
+       { "Wacom DTF720a",       8,   6858,  5506,  511,  0, PL },
        { "Wacom Cintiq Partner",8,  20480, 15360,  511,  0, PTU },
        { "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 31, INTUOS },
        { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 31, INTUOS },
@@ -897,8 +900,9 @@ static struct usb_device_id wacom_ids[] = {
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) },
-       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) },
+       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) },
+       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC2) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) },
index 7ac12cb0be4a70f8b2bc30279ff56964e030ae0d..5b6e58a3ba46c3934e5ef96bdfcc2479172c20d7 100644 (file)
@@ -32,8 +32,7 @@
  * This driver was tested with firmware revision A4.
  */
 
-#if defined(CONFIG_KEYBOARD_DM355EVM) \
-               || defined(CONFIG_KEYBOARD_DM355EVM_MODULE)
+#if defined(CONFIG_INPUT_DM355EVM) || defined(CONFIG_INPUT_DM355EVM_MODULE)
 #define msp_has_keyboard()     true
 #else
 #define msp_has_keyboard()     false
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
new file mode 100644 (file)
index 0000000..7964516
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef _MATRIX_KEYPAD_H
+#define _MATRIX_KEYPAD_H
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+#define MATRIX_MAX_ROWS                16
+#define MATRIX_MAX_COLS                16
+
+#define KEY(row, col, val)     ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\
+                                (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\
+                                (val & 0xffff))
+
+#define KEY_ROW(k)             (((k) >> 24) & 0xff)
+#define KEY_COL(k)             (((k) >> 16) & 0xff)
+#define KEY_VAL(k)             ((k) & 0xffff)
+
+/**
+ * struct matrix_keymap_data - keymap for matrix keyboards
+ * @keymap: pointer to array of uint32 values encoded with KEY() macro
+ *     representing keymap
+ * @keymap_size: number of entries (initialized) in this keymap
+ * @max_keymap_size: maximum size of keymap supported by the device
+ *
+ * This structure is supposed to be used by platform code to supply
+ * keymaps to drivers that implement matrix-like keypads/keyboards.
+ */
+struct matrix_keymap_data {
+       const uint32_t *keymap;
+       unsigned int    keymap_size;
+       unsigned int    max_keymap_size;
+};
+
+/**
+ * struct matrix_keypad_platform_data - platform-dependent keypad data
+ * @keymap_data: pointer to &matrix_keymap_data
+ * @row_gpios: array of gpio numbers reporesenting rows
+ * @col_gpios: array of gpio numbers reporesenting colums
+ * @num_row_gpios: actual number of row gpios used by device
+ * @num_col_gpios: actual number of col gpios used by device
+ * @col_scan_delay_us: delay, measured in microseconds, that is
+ *     needed before we can keypad after activating column gpio
+ * @debounce_ms: debounce interval in milliseconds
+ *
+ * This structure represents platform-specific data that use used by
+ * matrix_keypad driver to perform proper initialization.
+ */
+struct matrix_keypad_platform_data {
+       const struct matrix_keymap_data *keymap_data;
+
+       unsigned int    row_gpios[MATRIX_MAX_ROWS];
+       unsigned int    col_gpios[MATRIX_MAX_COLS];
+       unsigned int    num_row_gpios;
+       unsigned int    num_col_gpios;
+
+       unsigned int    col_scan_delay_us;
+
+       /* key debounce interval in milli-second */
+       unsigned int    debounce_ms;
+
+       bool            active_low;
+       bool            wakeup;
+};
+
+#endif /* _MATRIX_KEYPAD_H */