Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

* '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
This commit is contained in:
Linus Torvalds 2009-07-08 09:32:41 -07:00
commit 5e75c5f5d7
11 changed files with 761 additions and 187 deletions

View 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,16 +104,25 @@ 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
config KEYBOARD_BFIN
tristate "Blackfin BF54x keypad support"
depends on (BF54x && !BF544)
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.
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 sunkbd.
module will be called bf54x-keys.
config KEYBOARD_CORGI
tristate "Corgi keyboard"
depends on PXA_SHARPSL
default y
help
Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
series of PDAs.
To compile this driver as a module, choose M here: the
module will be called corgikbd.
config KEYBOARD_LKKBD
tristate "DECstation/VAXstation LK201/LK401 keyboard"
@ -91,113 +136,38 @@ config KEYBOARD_LKKBD
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
config KEYBOARD_EP93XX
tristate "EP93xx Matrix Keypad support"
depends on ARCH_EP93XX
help
Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
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 locomokbd.
module will be called ep93xx_keypad.
config KEYBOARD_XTKBD
tristate "XT keyboard"
select SERIO
config KEYBOARD_GPIO
tristate "GPIO Buttons"
depends on GENERIC_GPIO
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.
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.
To compile this driver as a module, choose M here: the
module will be called xtkbd.
module will be called gpio_keys.
config KEYBOARD_NEWTON
tristate "Newton keyboard"
select SERIO
config KEYBOARD_MATRIX
tristate "GPIO driven matrix keypad support"
depends on GENERIC_GPIO
help
Say Y here if you have a Newton keyboard on a serial port.
Enable support for GPIO driven matrix keypad.
To compile this driver as a module, choose M here: the
module will be called newtonkbd.
config KEYBOARD_STOWAWAY
tristate "Stowaway keyboard"
select SERIO
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.
To compile this driver as a module, choose M here: the
module will be called stowaway.
config KEYBOARD_CORGI
tristate "Corgi keyboard"
depends on PXA_SHARPSL
default y
help
Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
series of PDAs.
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
help
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 spitzkbd.
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
default n
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_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.
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.
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 aaed2000_kbd.
module will be called spitzkbd.
config KEYBOARD_GPIO
tristate "GPIO Buttons"
depends on GENERIC_GPIO
config KEYBOARD_STOWAWAY
tristate "Stowaway keyboard"
select SERIO
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 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 gpio-keys.
module will be called stowaway.
config KEYBOARD_MAPLE
tristate "Maple bus keyboard"
depends on SH_DREAMCAST && MAPLE
config KEYBOARD_SUNKBD
tristate "Sun Type 4 and Type 5 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 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 maple_keyb.
config KEYBOARD_BFIN
tristate "Blackfin BF54x keypad support"
depends on (BF54x && !BF544)
help
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 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

View 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

View 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);
}

View File

@ -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");

View 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 */

View 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"),
},
},
{ }
};

View 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;
}

View 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;
}

View 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) },

View 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

View File

@ -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 */