mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +00:00
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:
commit
5e75c5f5d7
11 changed files with 761 additions and 187 deletions
|
@ -12,6 +12,42 @@ menuconfig INPUT_KEYBOARD
|
||||||
|
|
||||||
if 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
|
config KEYBOARD_ATKBD
|
||||||
tristate "AT keyboard" if EMBEDDED || !X86
|
tristate "AT keyboard" if EMBEDDED || !X86
|
||||||
default y
|
default y
|
||||||
|
@ -68,16 +104,25 @@ config KEYBOARD_ATKBD_RDI_KEYCODES
|
||||||
right-hand column will be interpreted as the key shown in the
|
right-hand column will be interpreted as the key shown in the
|
||||||
left-hand column.
|
left-hand column.
|
||||||
|
|
||||||
config KEYBOARD_SUNKBD
|
config KEYBOARD_BFIN
|
||||||
tristate "Sun Type 4 and Type 5 keyboard"
|
tristate "Blackfin BF54x keypad support"
|
||||||
select SERIO
|
depends on (BF54x && !BF544)
|
||||||
help
|
help
|
||||||
Say Y here if you want to use a Sun Type 4 or Type 5 keyboard,
|
Say Y here if you want to use the BF54x keypad.
|
||||||
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
|
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
|
config KEYBOARD_LKKBD
|
||||||
tristate "DECstation/VAXstation LK201/LK401 keyboard"
|
tristate "DECstation/VAXstation LK201/LK401 keyboard"
|
||||||
|
@ -91,113 +136,38 @@ config KEYBOARD_LKKBD
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called lkkbd.
|
module will be called lkkbd.
|
||||||
|
|
||||||
config KEYBOARD_LOCOMO
|
config KEYBOARD_EP93XX
|
||||||
tristate "LoCoMo Keyboard Support"
|
tristate "EP93xx Matrix Keypad support"
|
||||||
depends on SHARP_LOCOMO && INPUT_KEYBOARD
|
depends on ARCH_EP93XX
|
||||||
help
|
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
|
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
|
config KEYBOARD_GPIO
|
||||||
tristate "XT keyboard"
|
tristate "GPIO Buttons"
|
||||||
select SERIO
|
depends on GENERIC_GPIO
|
||||||
help
|
help
|
||||||
Say Y here if you want to use the old IBM PC/XT keyboard (or
|
This driver implements support for buttons connected
|
||||||
compatible) on your system. This is only possible with a
|
to GPIO pins of various CPUs (and some other chips).
|
||||||
parallel port keyboard adapter, you cannot connect it to the
|
|
||||||
keyboard port on a PC that runs Linux.
|
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
|
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
|
config KEYBOARD_MATRIX
|
||||||
tristate "Newton keyboard"
|
tristate "GPIO driven matrix keypad support"
|
||||||
select SERIO
|
depends on GENERIC_GPIO
|
||||||
help
|
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
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called newtonkbd.
|
module will be called matrix_keypad.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
config KEYBOARD_HIL_OLD
|
config KEYBOARD_HIL_OLD
|
||||||
tristate "HP HIL keyboard support (simple driver)"
|
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
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called lm8323.
|
module will be called lm8323.
|
||||||
|
|
||||||
config KEYBOARD_OMAP
|
config KEYBOARD_LOCOMO
|
||||||
tristate "TI OMAP keypad support"
|
tristate "LoCoMo Keyboard Support"
|
||||||
depends on (ARCH_OMAP1 || ARCH_OMAP2)
|
depends on SHARP_LOCOMO
|
||||||
help
|
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
|
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
|
config KEYBOARD_PXA27x
|
||||||
tristate "PXA27x/PXA3xx keypad support"
|
tristate "PXA27x/PXA3xx keypad support"
|
||||||
depends on PXA27x || PXA3xx
|
depends on PXA27x || PXA3xx
|
||||||
help
|
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
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called pxa27x_keypad.
|
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
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called pxa930_rotary.
|
module will be called pxa930_rotary.
|
||||||
|
|
||||||
config KEYBOARD_AAED2000
|
config KEYBOARD_SPITZ
|
||||||
tristate "AAED-2000 keyboard"
|
tristate "Spitz keyboard"
|
||||||
depends on MACH_AAED2000
|
depends on PXA_SHARPSL
|
||||||
select INPUT_POLLDEV
|
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Say Y here to enable the keyboard on the Agilent AAED-2000
|
Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
|
||||||
development board.
|
SL-C3000 and Sl-C3100 series of PDAs.
|
||||||
|
|
||||||
To compile this driver as a module, choose M here: the
|
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
|
config KEYBOARD_STOWAWAY
|
||||||
tristate "GPIO Buttons"
|
tristate "Stowaway keyboard"
|
||||||
depends on GENERIC_GPIO
|
select SERIO
|
||||||
help
|
help
|
||||||
This driver implements support for buttons connected
|
Say Y here if you have a Stowaway keyboard on a serial port.
|
||||||
to GPIO pins of various CPUs (and some other chips).
|
Stowaway compatible keyboards like Dicota Input-PDA keyboard
|
||||||
|
are also supported by this driver.
|
||||||
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
|
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
|
config KEYBOARD_SUNKBD
|
||||||
tristate "Maple bus keyboard"
|
tristate "Sun Type 4 and Type 5 keyboard"
|
||||||
depends on SH_DREAMCAST && MAPLE
|
select SERIO
|
||||||
help
|
help
|
||||||
Say Y here if you have a Dreamcast console running Linux and have
|
Say Y here if you want to use a Sun Type 4 or Type 5 keyboard,
|
||||||
a keyboard attached to its Maple bus.
|
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
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called maple_keyb.
|
module will be called sunkbd.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
config KEYBOARD_SH_KEYSC
|
config KEYBOARD_SH_KEYSC
|
||||||
tristate "SuperH KEYSC keypad support"
|
tristate "SuperH KEYSC keypad support"
|
||||||
|
@ -344,13 +320,45 @@ config KEYBOARD_SH_KEYSC
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called sh_keysc.
|
module will be called sh_keysc.
|
||||||
|
|
||||||
config KEYBOARD_EP93XX
|
config KEYBOARD_OMAP
|
||||||
tristate "EP93xx Matrix Keypad support"
|
tristate "TI OMAP keypad support"
|
||||||
depends on ARCH_EP93XX
|
depends on (ARCH_OMAP1 || ARCH_OMAP2)
|
||||||
help
|
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
|
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
|
endif
|
||||||
|
|
|
@ -4,29 +4,30 @@
|
||||||
|
|
||||||
# Each configuration option enables a list of files.
|
# Each configuration option enables a list of files.
|
||||||
|
|
||||||
obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
|
obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
|
||||||
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
|
|
||||||
obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
|
|
||||||
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
|
|
||||||
obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
|
obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
|
||||||
obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o
|
obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o
|
||||||
obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o
|
obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
|
||||||
obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
|
obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
|
||||||
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
|
|
||||||
obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
|
obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
|
||||||
obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
|
obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
|
||||||
obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
|
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
|
||||||
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
|
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
|
||||||
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.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_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_OMAP) += omap-keypad.o
|
||||||
obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o
|
obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o
|
||||||
obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.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_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
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
struct gpio_button_data {
|
struct gpio_button_data {
|
||||||
struct gpio_keys_button *button;
|
struct gpio_keys_button *button;
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
struct delayed_work work;
|
struct timer_list timer;
|
||||||
|
struct work_struct work;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gpio_keys_drvdata {
|
struct gpio_keys_drvdata {
|
||||||
|
@ -40,7 +41,7 @@ struct gpio_keys_drvdata {
|
||||||
static void gpio_keys_report_event(struct work_struct *work)
|
static void gpio_keys_report_event(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct gpio_button_data *bdata =
|
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 gpio_keys_button *button = bdata->button;
|
||||||
struct input_dev *input = bdata->input;
|
struct input_dev *input = bdata->input;
|
||||||
unsigned int type = button->type ?: EV_KEY;
|
unsigned int type = button->type ?: EV_KEY;
|
||||||
|
@ -50,17 +51,25 @@ static void gpio_keys_report_event(struct work_struct *work)
|
||||||
input_sync(input);
|
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)
|
static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct gpio_button_data *bdata = dev_id;
|
struct gpio_button_data *bdata = dev_id;
|
||||||
struct gpio_keys_button *button = bdata->button;
|
struct gpio_keys_button *button = bdata->button;
|
||||||
unsigned long delay;
|
|
||||||
|
|
||||||
BUG_ON(irq != gpio_to_irq(button->gpio));
|
BUG_ON(irq != gpio_to_irq(button->gpio));
|
||||||
|
|
||||||
delay = button->debounce_interval ?
|
if (button->debounce_interval)
|
||||||
msecs_to_jiffies(button->debounce_interval) : 0;
|
mod_timer(&bdata->timer,
|
||||||
schedule_delayed_work(&bdata->work, delay);
|
jiffies + msecs_to_jiffies(button->debounce_interval));
|
||||||
|
else
|
||||||
|
schedule_work(&bdata->work);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +116,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
bdata->input = input;
|
bdata->input = input;
|
||||||
bdata->button = button;
|
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");
|
error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
|
@ -166,7 +177,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
||||||
fail2:
|
fail2:
|
||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
|
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);
|
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++) {
|
for (i = 0; i < pdata->nbuttons; i++) {
|
||||||
int irq = gpio_to_irq(pdata->buttons[i].gpio);
|
int irq = gpio_to_irq(pdata->buttons[i].gpio);
|
||||||
free_irq(irq, &ddata->data[i]);
|
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);
|
gpio_free(pdata->buttons[i].gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
453
drivers/input/keyboard/matrix_keypad.c
Normal file
453
drivers/input/keyboard/matrix_keypad.c
Normal 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");
|
|
@ -46,7 +46,7 @@ static void gpio_mouse_scan(struct input_polled_dev *dev)
|
||||||
input_sync(input);
|
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 gpio_mouse_platform_data *pdata = pdev->dev.platform_data;
|
||||||
struct input_polled_dev *input_poll;
|
struct input_polled_dev *input_poll;
|
||||||
|
@ -170,10 +170,8 @@ static int __devexit gpio_mouse_remove(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* work with hotplug and coldplug */
|
|
||||||
MODULE_ALIAS("platform:gpio_mouse");
|
|
||||||
|
|
||||||
static struct platform_driver gpio_mouse_device_driver = {
|
static struct platform_driver gpio_mouse_device_driver = {
|
||||||
|
.probe = gpio_mouse_probe,
|
||||||
.remove = __devexit_p(gpio_mouse_remove),
|
.remove = __devexit_p(gpio_mouse_remove),
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "gpio_mouse",
|
.name = "gpio_mouse",
|
||||||
|
@ -183,8 +181,7 @@ static struct platform_driver gpio_mouse_device_driver = {
|
||||||
|
|
||||||
static int __init gpio_mouse_init(void)
|
static int __init gpio_mouse_init(void)
|
||||||
{
|
{
|
||||||
return platform_driver_probe(&gpio_mouse_device_driver,
|
return platform_driver_register(&gpio_mouse_device_driver);
|
||||||
gpio_mouse_probe);
|
|
||||||
}
|
}
|
||||||
module_init(gpio_mouse_init);
|
module_init(gpio_mouse_init);
|
||||||
|
|
||||||
|
@ -197,3 +194,5 @@ module_exit(gpio_mouse_exit);
|
||||||
MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
|
MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
|
||||||
MODULE_DESCRIPTION("GPIO mouse driver");
|
MODULE_DESCRIPTION("GPIO mouse driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */
|
||||||
|
|
||||||
|
|
|
@ -392,6 +392,34 @@ static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
|
||||||
DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
|
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"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -934,10 +934,11 @@ static bool i8042_suspended;
|
||||||
|
|
||||||
static int i8042_suspend(struct platform_device *dev, pm_message_t state)
|
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_controller_reset();
|
||||||
i8042_suspended = true;
|
|
||||||
}
|
i8042_suspended = state.event == PM_EVENT_SUSPEND ||
|
||||||
|
state.event == PM_EVENT_FREEZE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -935,10 +935,11 @@ static int serio_suspend(struct device *dev, pm_message_t state)
|
||||||
{
|
{
|
||||||
struct serio *serio = to_serio_port(dev);
|
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_cleanup(serio);
|
||||||
serio->suspended = true;
|
|
||||||
}
|
serio->suspended = state.event == PM_EVENT_SUSPEND ||
|
||||||
|
state.event == PM_EVENT_FREEZE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_STYLUS2, 0);
|
||||||
wacom_report_key(wcombo, BTN_TOUCH, 0);
|
wacom_report_key(wcombo, BTN_TOUCH, 0);
|
||||||
wacom_report_abs(wcombo, ABS_WHEEL, 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_key(wcombo, wacom->tool[idx], 0);
|
||||||
wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
|
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 DTU710", 8, 34080, 27660, 511, 0, PL },
|
||||||
{ "Wacom DTF521", 8, 6282, 4762, 511, 0, PL },
|
{ "Wacom DTF521", 8, 6282, 4762, 511, 0, PL },
|
||||||
{ "Wacom DTF720", 8, 6858, 5506, 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 Cintiq Partner",8, 20480, 15360, 511, 0, PTU },
|
||||||
{ "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
|
{ "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
|
||||||
{ "Wacom Intuos2 6x8", 10, 20320, 16240, 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, 0x37) },
|
||||||
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) },
|
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) },
|
||||||
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) },
|
{ 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, 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, 0x03) },
|
||||||
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) },
|
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) },
|
||||||
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) },
|
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) },
|
||||||
|
|
|
@ -32,8 +32,7 @@
|
||||||
* This driver was tested with firmware revision A4.
|
* This driver was tested with firmware revision A4.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_KEYBOARD_DM355EVM) \
|
#if defined(CONFIG_INPUT_DM355EVM) || defined(CONFIG_INPUT_DM355EVM_MODULE)
|
||||||
|| defined(CONFIG_KEYBOARD_DM355EVM_MODULE)
|
|
||||||
#define msp_has_keyboard() true
|
#define msp_has_keyboard() true
|
||||||
#else
|
#else
|
||||||
#define msp_has_keyboard() false
|
#define msp_has_keyboard() false
|
||||||
|
|
65
include/linux/input/matrix_keypad.h
Normal file
65
include/linux/input/matrix_keypad.h
Normal 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 */
|
Loading…
Reference in a new issue