diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:52:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-09 22:52:01 -0500 |
commit | fa395aaec823b9d1a5800913a6b5d0e6d1c5ced2 (patch) | |
tree | d599abe9f4f48f1737da50fa9a48dadfd08100e3 /drivers/input/keyboard | |
parent | 3e7468313758913c5e4d372f35b271b96bad1298 (diff) | |
parent | 1f26978afd123deb22dd3c7dc75771a02f6e03f6 (diff) |
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: (51 commits)
Input: appletouch - give up maintainership
Input: dm355evm_kbd - switch to using sparse keymap library
Input: wistron_btns - switch to using sparse keymap library
Input: add generic support for sparse keymaps
Input: fix memory leak in force feedback core
Input: wistron - remove identification strings from DMI table
Input: psmouse - remove identification strings from DMI tables
Input: atkbd - remove identification strings from DMI table
Input: i8042 - remove identification strings from DMI tables
DMI: allow omitting ident strings in DMI tables
Input: psmouse - do not carry DMI data around
Input: matrix-keypad - switch to using dev_pm_ops
Input: keyboard - fix lack of locking when traversing handler->h_list
Input: gpio_keys - scan gpio state at probe and resume time
Input: keyboard - add locking around event handling
Input: usbtouchscreen - add support for ET&T TC5UH touchscreen controller
Input: xpad - add two new Xbox 360 devices
Input: polled device - do not start polling if interval is zero
Input: polled device - schedule first poll immediately
Input: add S3C24XX touchscreen driver
...
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/Kconfig | 10 | ||||
-rw-r--r-- | drivers/input/keyboard/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 26 | ||||
-rw-r--r-- | drivers/input/keyboard/davinci_keyscan.c | 337 | ||||
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 134 | ||||
-rw-r--r-- | drivers/input/keyboard/lkkbd.c | 496 | ||||
-rw-r--r-- | drivers/input/keyboard/matrix_keypad.c | 17 |
7 files changed, 686 insertions, 335 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index ee98b1bc5d89..203b88a82b56 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -361,6 +361,16 @@ config KEYBOARD_SH_KEYSC | |||
361 | To compile this driver as a module, choose M here: the | 361 | To compile this driver as a module, choose M here: the |
362 | module will be called sh_keysc. | 362 | module will be called sh_keysc. |
363 | 363 | ||
364 | config KEYBOARD_DAVINCI | ||
365 | tristate "TI DaVinci Key Scan" | ||
366 | depends on ARCH_DAVINCI_DM365 | ||
367 | help | ||
368 | Say Y to enable keypad module support for the TI DaVinci | ||
369 | platforms (DM365). | ||
370 | |||
371 | To compile this driver as a module, choose M here: the | ||
372 | module will be called davinci_keyscan. | ||
373 | |||
364 | config KEYBOARD_OMAP | 374 | config KEYBOARD_OMAP |
365 | tristate "TI OMAP keypad support" | 375 | tristate "TI OMAP keypad support" |
366 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 376 | depends on (ARCH_OMAP1 || ARCH_OMAP2) |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index babad5e58b77..68c017235ce9 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -11,6 +11,7 @@ obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | |||
11 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 11 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
12 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 12 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
13 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o | 13 | obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o |
14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | ||
14 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
15 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
16 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 17 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 28e6110d1ff8..a3573570c52f 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -1567,9 +1567,8 @@ static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) | |||
1567 | return 0; | 1567 | return 0; |
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | 1570 | static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { |
1571 | { | 1571 | { |
1572 | .ident = "Dell Laptop", | ||
1573 | .matches = { | 1572 | .matches = { |
1574 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 1573 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
1575 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1574 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
@@ -1578,7 +1577,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1578 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 1577 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1579 | }, | 1578 | }, |
1580 | { | 1579 | { |
1581 | .ident = "Dell Laptop", | ||
1582 | .matches = { | 1580 | .matches = { |
1583 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | 1581 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
1584 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1582 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
@@ -1587,7 +1585,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1587 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 1585 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1588 | }, | 1586 | }, |
1589 | { | 1587 | { |
1590 | .ident = "HP 2133", | ||
1591 | .matches = { | 1588 | .matches = { |
1592 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1589 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1593 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), | 1590 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), |
@@ -1596,7 +1593,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1596 | .driver_data = atkbd_hp_forced_release_keys, | 1593 | .driver_data = atkbd_hp_forced_release_keys, |
1597 | }, | 1594 | }, |
1598 | { | 1595 | { |
1599 | .ident = "HP Pavilion ZV6100", | ||
1600 | .matches = { | 1596 | .matches = { |
1601 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1597 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1602 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), | 1598 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), |
@@ -1605,7 +1601,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1605 | .driver_data = atkbd_volume_forced_release_keys, | 1601 | .driver_data = atkbd_volume_forced_release_keys, |
1606 | }, | 1602 | }, |
1607 | { | 1603 | { |
1608 | .ident = "HP Presario R4000", | ||
1609 | .matches = { | 1604 | .matches = { |
1610 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1605 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1611 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), | 1606 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), |
@@ -1614,7 +1609,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1614 | .driver_data = atkbd_volume_forced_release_keys, | 1609 | .driver_data = atkbd_volume_forced_release_keys, |
1615 | }, | 1610 | }, |
1616 | { | 1611 | { |
1617 | .ident = "HP Presario R4100", | ||
1618 | .matches = { | 1612 | .matches = { |
1619 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1613 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1620 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), | 1614 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), |
@@ -1623,7 +1617,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1623 | .driver_data = atkbd_volume_forced_release_keys, | 1617 | .driver_data = atkbd_volume_forced_release_keys, |
1624 | }, | 1618 | }, |
1625 | { | 1619 | { |
1626 | .ident = "HP Presario R4200", | ||
1627 | .matches = { | 1620 | .matches = { |
1628 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1621 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1629 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), | 1622 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), |
@@ -1632,7 +1625,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1632 | .driver_data = atkbd_volume_forced_release_keys, | 1625 | .driver_data = atkbd_volume_forced_release_keys, |
1633 | }, | 1626 | }, |
1634 | { | 1627 | { |
1635 | .ident = "Inventec Symphony", | 1628 | /* Inventec Symphony */ |
1636 | .matches = { | 1629 | .matches = { |
1637 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), | 1630 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), |
1638 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), | 1631 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), |
@@ -1641,7 +1634,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1641 | .driver_data = atkbd_volume_forced_release_keys, | 1634 | .driver_data = atkbd_volume_forced_release_keys, |
1642 | }, | 1635 | }, |
1643 | { | 1636 | { |
1644 | .ident = "Samsung NC10", | 1637 | /* Samsung NC10 */ |
1645 | .matches = { | 1638 | .matches = { |
1646 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1639 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1647 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), | 1640 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), |
@@ -1650,7 +1643,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1650 | .driver_data = atkbd_samsung_forced_release_keys, | 1643 | .driver_data = atkbd_samsung_forced_release_keys, |
1651 | }, | 1644 | }, |
1652 | { | 1645 | { |
1653 | .ident = "Samsung NC20", | 1646 | /* Samsung NC20 */ |
1654 | .matches = { | 1647 | .matches = { |
1655 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1648 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1656 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), | 1649 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), |
@@ -1659,7 +1652,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1659 | .driver_data = atkbd_samsung_forced_release_keys, | 1652 | .driver_data = atkbd_samsung_forced_release_keys, |
1660 | }, | 1653 | }, |
1661 | { | 1654 | { |
1662 | .ident = "Samsung SQ45S70S", | 1655 | /* Samsung SQ45S70S */ |
1663 | .matches = { | 1656 | .matches = { |
1664 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1657 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1665 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), | 1658 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), |
@@ -1668,7 +1661,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1668 | .driver_data = atkbd_samsung_forced_release_keys, | 1661 | .driver_data = atkbd_samsung_forced_release_keys, |
1669 | }, | 1662 | }, |
1670 | { | 1663 | { |
1671 | .ident = "Fujitsu Amilo PA 1510", | 1664 | /* Fujitsu Amilo PA 1510 */ |
1672 | .matches = { | 1665 | .matches = { |
1673 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1666 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1674 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), | 1667 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), |
@@ -1677,7 +1670,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1677 | .driver_data = atkbd_volume_forced_release_keys, | 1670 | .driver_data = atkbd_volume_forced_release_keys, |
1678 | }, | 1671 | }, |
1679 | { | 1672 | { |
1680 | .ident = "Fujitsu Amilo Pi 3525", | 1673 | /* Fujitsu Amilo Pi 3525 */ |
1681 | .matches = { | 1674 | .matches = { |
1682 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1675 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1683 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), | 1676 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), |
@@ -1686,7 +1679,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1686 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, | 1679 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, |
1687 | }, | 1680 | }, |
1688 | { | 1681 | { |
1689 | .ident = "Fujitsu Amilo Xi 3650", | 1682 | /* Fujitsu Amilo Xi 3650 */ |
1690 | .matches = { | 1683 | .matches = { |
1691 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1684 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
1692 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), | 1685 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), |
@@ -1695,7 +1688,6 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1695 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, | 1688 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, |
1696 | }, | 1689 | }, |
1697 | { | 1690 | { |
1698 | .ident = "Soltech Corporation TA12", | ||
1699 | .matches = { | 1691 | .matches = { |
1700 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), | 1692 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), |
1701 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), | 1693 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), |
@@ -1704,7 +1696,7 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1704 | .driver_data = atkdb_soltech_ta12_forced_release_keys, | 1696 | .driver_data = atkdb_soltech_ta12_forced_release_keys, |
1705 | }, | 1697 | }, |
1706 | { | 1698 | { |
1707 | .ident = "OQO Model 01+", | 1699 | /* OQO Model 01+ */ |
1708 | .matches = { | 1700 | .matches = { |
1709 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), | 1701 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), |
1710 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), | 1702 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), |
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c new file mode 100644 index 000000000000..6e52d855f637 --- /dev/null +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -0,0 +1,337 @@ | |||
1 | /* | ||
2 | * DaVinci Key Scan Driver for TI platforms | ||
3 | * | ||
4 | * Copyright (C) 2009 Texas Instruments, Inc | ||
5 | * | ||
6 | * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> | ||
7 | * | ||
8 | * Intial Code: Sandeep Paulraj <s-paulraj@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/input.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/errno.h> | ||
33 | |||
34 | #include <asm/irq.h> | ||
35 | |||
36 | #include <mach/hardware.h> | ||
37 | #include <mach/irqs.h> | ||
38 | #include <mach/keyscan.h> | ||
39 | |||
40 | /* Key scan registers */ | ||
41 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 | ||
42 | #define DAVINCI_KEYSCAN_INTENA 0x0004 | ||
43 | #define DAVINCI_KEYSCAN_INTFLAG 0x0008 | ||
44 | #define DAVINCI_KEYSCAN_INTCLR 0x000c | ||
45 | #define DAVINCI_KEYSCAN_STRBWIDTH 0x0010 | ||
46 | #define DAVINCI_KEYSCAN_INTERVAL 0x0014 | ||
47 | #define DAVINCI_KEYSCAN_CONTTIME 0x0018 | ||
48 | #define DAVINCI_KEYSCAN_CURRENTST 0x001c | ||
49 | #define DAVINCI_KEYSCAN_PREVSTATE 0x0020 | ||
50 | #define DAVINCI_KEYSCAN_EMUCTRL 0x0024 | ||
51 | #define DAVINCI_KEYSCAN_IODFTCTRL 0x002c | ||
52 | |||
53 | /* Key Control Register (KEYCTRL) */ | ||
54 | #define DAVINCI_KEYSCAN_KEYEN 0x00000001 | ||
55 | #define DAVINCI_KEYSCAN_PREVMODE 0x00000002 | ||
56 | #define DAVINCI_KEYSCAN_CHATOFF 0x00000004 | ||
57 | #define DAVINCI_KEYSCAN_AUTODET 0x00000008 | ||
58 | #define DAVINCI_KEYSCAN_SCANMODE 0x00000010 | ||
59 | #define DAVINCI_KEYSCAN_OUTTYPE 0x00000020 | ||
60 | |||
61 | /* Masks for the interrupts */ | ||
62 | #define DAVINCI_KEYSCAN_INT_CONT 0x00000008 | ||
63 | #define DAVINCI_KEYSCAN_INT_OFF 0x00000004 | ||
64 | #define DAVINCI_KEYSCAN_INT_ON 0x00000002 | ||
65 | #define DAVINCI_KEYSCAN_INT_CHANGE 0x00000001 | ||
66 | #define DAVINCI_KEYSCAN_INT_ALL 0x0000000f | ||
67 | |||
68 | struct davinci_ks { | ||
69 | struct input_dev *input; | ||
70 | struct davinci_ks_platform_data *pdata; | ||
71 | int irq; | ||
72 | void __iomem *base; | ||
73 | resource_size_t pbase; | ||
74 | size_t base_size; | ||
75 | unsigned short keymap[]; | ||
76 | }; | ||
77 | |||
78 | /* Initializing the kp Module */ | ||
79 | static int __init davinci_ks_initialize(struct davinci_ks *davinci_ks) | ||
80 | { | ||
81 | struct device *dev = &davinci_ks->input->dev; | ||
82 | struct davinci_ks_platform_data *pdata = davinci_ks->pdata; | ||
83 | u32 matrix_ctrl; | ||
84 | |||
85 | /* Enable all interrupts */ | ||
86 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
87 | davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
88 | |||
89 | /* Clear interrupts if any */ | ||
90 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
91 | davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); | ||
92 | |||
93 | /* Setup the scan period = strobe + interval */ | ||
94 | __raw_writel(pdata->strobe, | ||
95 | davinci_ks->base + DAVINCI_KEYSCAN_STRBWIDTH); | ||
96 | __raw_writel(pdata->interval, | ||
97 | davinci_ks->base + DAVINCI_KEYSCAN_INTERVAL); | ||
98 | __raw_writel(0x01, | ||
99 | davinci_ks->base + DAVINCI_KEYSCAN_CONTTIME); | ||
100 | |||
101 | /* Define matrix type */ | ||
102 | switch (pdata->matrix_type) { | ||
103 | case DAVINCI_KEYSCAN_MATRIX_4X4: | ||
104 | matrix_ctrl = 0; | ||
105 | break; | ||
106 | case DAVINCI_KEYSCAN_MATRIX_5X3: | ||
107 | matrix_ctrl = (1 << 6); | ||
108 | break; | ||
109 | default: | ||
110 | dev_err(dev->parent, "wrong matrix type\n"); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | |||
114 | /* Enable key scan module and set matrix type */ | ||
115 | __raw_writel(DAVINCI_KEYSCAN_AUTODET | DAVINCI_KEYSCAN_KEYEN | | ||
116 | matrix_ctrl, davinci_ks->base + DAVINCI_KEYSCAN_KEYCTRL); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static irqreturn_t davinci_ks_interrupt(int irq, void *dev_id) | ||
122 | { | ||
123 | struct davinci_ks *davinci_ks = dev_id; | ||
124 | struct device *dev = &davinci_ks->input->dev; | ||
125 | unsigned short *keymap = davinci_ks->keymap; | ||
126 | int keymapsize = davinci_ks->pdata->keymapsize; | ||
127 | u32 prev_status, new_status, changed; | ||
128 | bool release; | ||
129 | int keycode = KEY_UNKNOWN; | ||
130 | int i; | ||
131 | |||
132 | /* Disable interrupt */ | ||
133 | __raw_writel(0x0, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
134 | |||
135 | /* Reading previous and new status of the key scan */ | ||
136 | prev_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_PREVSTATE); | ||
137 | new_status = __raw_readl(davinci_ks->base + DAVINCI_KEYSCAN_CURRENTST); | ||
138 | |||
139 | changed = prev_status ^ new_status; | ||
140 | |||
141 | if (changed) { | ||
142 | /* | ||
143 | * It goes through all bits in 'changed' to ensure | ||
144 | * that no key changes are being missed | ||
145 | */ | ||
146 | for (i = 0 ; i < keymapsize; i++) { | ||
147 | if ((changed>>i) & 0x1) { | ||
148 | keycode = keymap[i]; | ||
149 | release = (new_status >> i) & 0x1; | ||
150 | dev_dbg(dev->parent, "key %d %s\n", keycode, | ||
151 | release ? "released" : "pressed"); | ||
152 | input_report_key(davinci_ks->input, keycode, | ||
153 | !release); | ||
154 | input_sync(davinci_ks->input); | ||
155 | } | ||
156 | } | ||
157 | /* Clearing interrupt */ | ||
158 | __raw_writel(DAVINCI_KEYSCAN_INT_ALL, | ||
159 | davinci_ks->base + DAVINCI_KEYSCAN_INTCLR); | ||
160 | } | ||
161 | |||
162 | /* Enable interrupts */ | ||
163 | __raw_writel(0x1, davinci_ks->base + DAVINCI_KEYSCAN_INTENA); | ||
164 | |||
165 | return IRQ_HANDLED; | ||
166 | } | ||
167 | |||
168 | static int __init davinci_ks_probe(struct platform_device *pdev) | ||
169 | { | ||
170 | struct davinci_ks *davinci_ks; | ||
171 | struct input_dev *key_dev; | ||
172 | struct resource *res, *mem; | ||
173 | struct device *dev = &pdev->dev; | ||
174 | struct davinci_ks_platform_data *pdata = pdev->dev.platform_data; | ||
175 | int error, i; | ||
176 | |||
177 | if (!pdata->keymap) { | ||
178 | dev_dbg(dev, "no keymap from pdata\n"); | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | davinci_ks = kzalloc(sizeof(struct davinci_ks) + | ||
183 | sizeof(unsigned short) * pdata->keymapsize, GFP_KERNEL); | ||
184 | if (!davinci_ks) { | ||
185 | dev_dbg(dev, "could not allocate memory for private data\n"); | ||
186 | return -ENOMEM; | ||
187 | } | ||
188 | |||
189 | memcpy(davinci_ks->keymap, pdata->keymap, | ||
190 | sizeof(unsigned short) * pdata->keymapsize); | ||
191 | |||
192 | key_dev = input_allocate_device(); | ||
193 | if (!key_dev) { | ||
194 | dev_dbg(dev, "could not allocate input device\n"); | ||
195 | error = -ENOMEM; | ||
196 | goto fail1; | ||
197 | } | ||
198 | |||
199 | davinci_ks->input = key_dev; | ||
200 | |||
201 | davinci_ks->irq = platform_get_irq(pdev, 0); | ||
202 | if (davinci_ks->irq < 0) { | ||
203 | dev_err(dev, "no key scan irq\n"); | ||
204 | error = davinci_ks->irq; | ||
205 | goto fail2; | ||
206 | } | ||
207 | |||
208 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
209 | if (!res) { | ||
210 | dev_err(dev, "no mem resource\n"); | ||
211 | error = -EINVAL; | ||
212 | goto fail2; | ||
213 | } | ||
214 | |||
215 | davinci_ks->pbase = res->start; | ||
216 | davinci_ks->base_size = resource_size(res); | ||
217 | |||
218 | mem = request_mem_region(davinci_ks->pbase, davinci_ks->base_size, | ||
219 | pdev->name); | ||
220 | if (!mem) { | ||
221 | dev_err(dev, "key scan registers at %08x are not free\n", | ||
222 | davinci_ks->pbase); | ||
223 | error = -EBUSY; | ||
224 | goto fail2; | ||
225 | } | ||
226 | |||
227 | davinci_ks->base = ioremap(davinci_ks->pbase, davinci_ks->base_size); | ||
228 | if (!davinci_ks->base) { | ||
229 | dev_err(dev, "can't ioremap MEM resource.\n"); | ||
230 | error = -ENOMEM; | ||
231 | goto fail3; | ||
232 | } | ||
233 | |||
234 | /* Enable auto repeat feature of Linux input subsystem */ | ||
235 | if (pdata->rep) | ||
236 | __set_bit(EV_REP, key_dev->evbit); | ||
237 | |||
238 | /* Setup input device */ | ||
239 | __set_bit(EV_KEY, key_dev->evbit); | ||
240 | |||
241 | /* Setup the platform data */ | ||
242 | davinci_ks->pdata = pdata; | ||
243 | |||
244 | for (i = 0; i < davinci_ks->pdata->keymapsize; i++) | ||
245 | __set_bit(davinci_ks->pdata->keymap[i], key_dev->keybit); | ||
246 | |||
247 | key_dev->name = "davinci_keyscan"; | ||
248 | key_dev->phys = "davinci_keyscan/input0"; | ||
249 | key_dev->dev.parent = &pdev->dev; | ||
250 | key_dev->id.bustype = BUS_HOST; | ||
251 | key_dev->id.vendor = 0x0001; | ||
252 | key_dev->id.product = 0x0001; | ||
253 | key_dev->id.version = 0x0001; | ||
254 | key_dev->keycode = davinci_ks->keymap; | ||
255 | key_dev->keycodesize = sizeof(davinci_ks->keymap[0]); | ||
256 | key_dev->keycodemax = davinci_ks->pdata->keymapsize; | ||
257 | |||
258 | error = input_register_device(davinci_ks->input); | ||
259 | if (error < 0) { | ||
260 | dev_err(dev, "unable to register davinci key scan device\n"); | ||
261 | goto fail4; | ||
262 | } | ||
263 | |||
264 | error = request_irq(davinci_ks->irq, davinci_ks_interrupt, | ||
265 | IRQF_DISABLED, pdev->name, davinci_ks); | ||
266 | if (error < 0) { | ||
267 | dev_err(dev, "unable to register davinci key scan interrupt\n"); | ||
268 | goto fail5; | ||
269 | } | ||
270 | |||
271 | error = davinci_ks_initialize(davinci_ks); | ||
272 | if (error < 0) { | ||
273 | dev_err(dev, "unable to initialize davinci key scan device\n"); | ||
274 | goto fail6; | ||
275 | } | ||
276 | |||
277 | platform_set_drvdata(pdev, davinci_ks); | ||
278 | return 0; | ||
279 | |||
280 | fail6: | ||
281 | free_irq(davinci_ks->irq, davinci_ks); | ||
282 | fail5: | ||
283 | input_unregister_device(davinci_ks->input); | ||
284 | key_dev = NULL; | ||
285 | fail4: | ||
286 | iounmap(davinci_ks->base); | ||
287 | fail3: | ||
288 | release_mem_region(davinci_ks->pbase, davinci_ks->base_size); | ||
289 | fail2: | ||
290 | input_free_device(key_dev); | ||
291 | fail1: | ||
292 | kfree(davinci_ks); | ||
293 | |||
294 | return error; | ||
295 | } | ||
296 | |||
297 | static int __devexit davinci_ks_remove(struct platform_device *pdev) | ||
298 | { | ||
299 | struct davinci_ks *davinci_ks = platform_get_drvdata(pdev); | ||
300 | |||
301 | free_irq(davinci_ks->irq, davinci_ks); | ||
302 | |||
303 | input_unregister_device(davinci_ks->input); | ||
304 | |||
305 | iounmap(davinci_ks->base); | ||
306 | release_mem_region(davinci_ks->pbase, davinci_ks->base_size); | ||
307 | |||
308 | platform_set_drvdata(pdev, NULL); | ||
309 | |||
310 | kfree(davinci_ks); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static struct platform_driver davinci_ks_driver = { | ||
316 | .driver = { | ||
317 | .name = "davinci_keyscan", | ||
318 | .owner = THIS_MODULE, | ||
319 | }, | ||
320 | .remove = __devexit_p(davinci_ks_remove), | ||
321 | }; | ||
322 | |||
323 | static int __init davinci_ks_init(void) | ||
324 | { | ||
325 | return platform_driver_probe(&davinci_ks_driver, davinci_ks_probe); | ||
326 | } | ||
327 | module_init(davinci_ks_init); | ||
328 | |||
329 | static void __exit davinci_ks_exit(void) | ||
330 | { | ||
331 | platform_driver_unregister(&davinci_ks_driver); | ||
332 | } | ||
333 | module_exit(davinci_ks_exit); | ||
334 | |||
335 | MODULE_AUTHOR("Miguel Aguilar"); | ||
336 | MODULE_DESCRIPTION("Texas Instruments DaVinci Key Scan Driver"); | ||
337 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 77d130914259..1aff3b76effd 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -23,8 +23,7 @@ | |||
23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
24 | #include <linux/gpio_keys.h> | 24 | #include <linux/gpio_keys.h> |
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | 26 | #include <linux/gpio.h> | |
27 | #include <asm/gpio.h> | ||
28 | 27 | ||
29 | struct gpio_button_data { | 28 | struct gpio_button_data { |
30 | struct gpio_keys_button *button; | 29 | struct gpio_keys_button *button; |
@@ -38,10 +37,8 @@ struct gpio_keys_drvdata { | |||
38 | struct gpio_button_data data[0]; | 37 | struct gpio_button_data data[0]; |
39 | }; | 38 | }; |
40 | 39 | ||
41 | static void gpio_keys_report_event(struct work_struct *work) | 40 | static void gpio_keys_report_event(struct gpio_button_data *bdata) |
42 | { | 41 | { |
43 | struct gpio_button_data *bdata = | ||
44 | container_of(work, struct gpio_button_data, work); | ||
45 | struct gpio_keys_button *button = bdata->button; | 42 | struct gpio_keys_button *button = bdata->button; |
46 | struct input_dev *input = bdata->input; | 43 | struct input_dev *input = bdata->input; |
47 | unsigned int type = button->type ?: EV_KEY; | 44 | unsigned int type = button->type ?: EV_KEY; |
@@ -51,6 +48,14 @@ static void gpio_keys_report_event(struct work_struct *work) | |||
51 | input_sync(input); | 48 | input_sync(input); |
52 | } | 49 | } |
53 | 50 | ||
51 | static void gpio_keys_work_func(struct work_struct *work) | ||
52 | { | ||
53 | struct gpio_button_data *bdata = | ||
54 | container_of(work, struct gpio_button_data, work); | ||
55 | |||
56 | gpio_keys_report_event(bdata); | ||
57 | } | ||
58 | |||
54 | static void gpio_keys_timer(unsigned long _data) | 59 | static void gpio_keys_timer(unsigned long _data) |
55 | { | 60 | { |
56 | struct gpio_button_data *data = (struct gpio_button_data *)_data; | 61 | struct gpio_button_data *data = (struct gpio_button_data *)_data; |
@@ -74,10 +79,62 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | |||
74 | return IRQ_HANDLED; | 79 | return IRQ_HANDLED; |
75 | } | 80 | } |
76 | 81 | ||
82 | static int __devinit gpio_keys_setup_key(struct device *dev, | ||
83 | struct gpio_button_data *bdata, | ||
84 | struct gpio_keys_button *button) | ||
85 | { | ||
86 | char *desc = button->desc ? button->desc : "gpio_keys"; | ||
87 | int irq, error; | ||
88 | |||
89 | setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); | ||
90 | INIT_WORK(&bdata->work, gpio_keys_work_func); | ||
91 | |||
92 | error = gpio_request(button->gpio, desc); | ||
93 | if (error < 0) { | ||
94 | dev_err(dev, "failed to request GPIO %d, error %d\n", | ||
95 | button->gpio, error); | ||
96 | goto fail2; | ||
97 | } | ||
98 | |||
99 | error = gpio_direction_input(button->gpio); | ||
100 | if (error < 0) { | ||
101 | dev_err(dev, "failed to configure" | ||
102 | " direction for GPIO %d, error %d\n", | ||
103 | button->gpio, error); | ||
104 | goto fail3; | ||
105 | } | ||
106 | |||
107 | irq = gpio_to_irq(button->gpio); | ||
108 | if (irq < 0) { | ||
109 | error = irq; | ||
110 | dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", | ||
111 | button->gpio, error); | ||
112 | goto fail3; | ||
113 | } | ||
114 | |||
115 | error = request_irq(irq, gpio_keys_isr, | ||
116 | IRQF_SHARED | | ||
117 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
118 | desc, bdata); | ||
119 | if (error) { | ||
120 | dev_err(dev, "Unable to claim irq %d; error %d\n", | ||
121 | irq, error); | ||
122 | goto fail3; | ||
123 | } | ||
124 | |||
125 | return 0; | ||
126 | |||
127 | fail3: | ||
128 | gpio_free(button->gpio); | ||
129 | fail2: | ||
130 | return error; | ||
131 | } | ||
132 | |||
77 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | 133 | static int __devinit gpio_keys_probe(struct platform_device *pdev) |
78 | { | 134 | { |
79 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 135 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
80 | struct gpio_keys_drvdata *ddata; | 136 | struct gpio_keys_drvdata *ddata; |
137 | struct device *dev = &pdev->dev; | ||
81 | struct input_dev *input; | 138 | struct input_dev *input; |
82 | int i, error; | 139 | int i, error; |
83 | int wakeup = 0; | 140 | int wakeup = 0; |
@@ -87,6 +144,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
87 | GFP_KERNEL); | 144 | GFP_KERNEL); |
88 | input = input_allocate_device(); | 145 | input = input_allocate_device(); |
89 | if (!ddata || !input) { | 146 | if (!ddata || !input) { |
147 | dev_err(dev, "failed to allocate state\n"); | ||
90 | error = -ENOMEM; | 148 | error = -ENOMEM; |
91 | goto fail1; | 149 | goto fail1; |
92 | } | 150 | } |
@@ -111,52 +169,14 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
111 | for (i = 0; i < pdata->nbuttons; i++) { | 169 | for (i = 0; i < pdata->nbuttons; i++) { |
112 | struct gpio_keys_button *button = &pdata->buttons[i]; | 170 | struct gpio_keys_button *button = &pdata->buttons[i]; |
113 | struct gpio_button_data *bdata = &ddata->data[i]; | 171 | struct gpio_button_data *bdata = &ddata->data[i]; |
114 | int irq; | ||
115 | unsigned int type = button->type ?: EV_KEY; | 172 | unsigned int type = button->type ?: EV_KEY; |
116 | 173 | ||
117 | bdata->input = input; | 174 | bdata->input = input; |
118 | bdata->button = button; | 175 | bdata->button = button; |
119 | setup_timer(&bdata->timer, | ||
120 | gpio_keys_timer, (unsigned long)bdata); | ||
121 | INIT_WORK(&bdata->work, gpio_keys_report_event); | ||
122 | |||
123 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); | ||
124 | if (error < 0) { | ||
125 | pr_err("gpio-keys: failed to request GPIO %d," | ||
126 | " error %d\n", button->gpio, error); | ||
127 | goto fail2; | ||
128 | } | ||
129 | |||
130 | error = gpio_direction_input(button->gpio); | ||
131 | if (error < 0) { | ||
132 | pr_err("gpio-keys: failed to configure input" | ||
133 | " direction for GPIO %d, error %d\n", | ||
134 | button->gpio, error); | ||
135 | gpio_free(button->gpio); | ||
136 | goto fail2; | ||
137 | } | ||
138 | |||
139 | irq = gpio_to_irq(button->gpio); | ||
140 | if (irq < 0) { | ||
141 | error = irq; | ||
142 | pr_err("gpio-keys: Unable to get irq number" | ||
143 | " for GPIO %d, error %d\n", | ||
144 | button->gpio, error); | ||
145 | gpio_free(button->gpio); | ||
146 | goto fail2; | ||
147 | } | ||
148 | 176 | ||
149 | error = request_irq(irq, gpio_keys_isr, | 177 | error = gpio_keys_setup_key(dev, bdata, button); |
150 | IRQF_SHARED | | 178 | if (error) |
151 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
152 | button->desc ? button->desc : "gpio_keys", | ||
153 | bdata); | ||
154 | if (error) { | ||
155 | pr_err("gpio-keys: Unable to claim irq %d; error %d\n", | ||
156 | irq, error); | ||
157 | gpio_free(button->gpio); | ||
158 | goto fail2; | 179 | goto fail2; |
159 | } | ||
160 | 180 | ||
161 | if (button->wakeup) | 181 | if (button->wakeup) |
162 | wakeup = 1; | 182 | wakeup = 1; |
@@ -166,11 +186,16 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
166 | 186 | ||
167 | error = input_register_device(input); | 187 | error = input_register_device(input); |
168 | if (error) { | 188 | if (error) { |
169 | pr_err("gpio-keys: Unable to register input device, " | 189 | dev_err(dev, "Unable to register input device, " |
170 | "error: %d\n", error); | 190 | "error: %d\n", error); |
171 | goto fail2; | 191 | goto fail2; |
172 | } | 192 | } |
173 | 193 | ||
194 | /* get current state of buttons */ | ||
195 | for (i = 0; i < pdata->nbuttons; i++) | ||
196 | gpio_keys_report_event(&ddata->data[i]); | ||
197 | input_sync(input); | ||
198 | |||
174 | device_init_wakeup(&pdev->dev, wakeup); | 199 | device_init_wakeup(&pdev->dev, wakeup); |
175 | 200 | ||
176 | return 0; | 201 | return 0; |
@@ -239,18 +264,21 @@ static int gpio_keys_suspend(struct device *dev) | |||
239 | static int gpio_keys_resume(struct device *dev) | 264 | static int gpio_keys_resume(struct device *dev) |
240 | { | 265 | { |
241 | struct platform_device *pdev = to_platform_device(dev); | 266 | struct platform_device *pdev = to_platform_device(dev); |
267 | struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); | ||
242 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | 268 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; |
243 | int i; | 269 | int i; |
244 | 270 | ||
245 | if (device_may_wakeup(&pdev->dev)) { | 271 | for (i = 0; i < pdata->nbuttons; i++) { |
246 | for (i = 0; i < pdata->nbuttons; i++) { | 272 | |
247 | struct gpio_keys_button *button = &pdata->buttons[i]; | 273 | struct gpio_keys_button *button = &pdata->buttons[i]; |
248 | if (button->wakeup) { | 274 | if (button->wakeup && device_may_wakeup(&pdev->dev)) { |
249 | int irq = gpio_to_irq(button->gpio); | 275 | int irq = gpio_to_irq(button->gpio); |
250 | disable_irq_wake(irq); | 276 | disable_irq_wake(irq); |
251 | } | ||
252 | } | 277 | } |
278 | |||
279 | gpio_keys_report_event(&ddata->data[i]); | ||
253 | } | 280 | } |
281 | input_sync(ddata->input); | ||
254 | 282 | ||
255 | return 0; | 283 | return 0; |
256 | } | 284 | } |
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index f9847e0fb553..fa9bb6d235e2 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -72,9 +72,9 @@ | |||
72 | 72 | ||
73 | #define DRIVER_DESC "LK keyboard driver" | 73 | #define DRIVER_DESC "LK keyboard driver" |
74 | 74 | ||
75 | MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); | 75 | MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>"); |
76 | MODULE_DESCRIPTION (DRIVER_DESC); | 76 | MODULE_DESCRIPTION(DRIVER_DESC); |
77 | MODULE_LICENSE ("GPL"); | 77 | MODULE_LICENSE("GPL"); |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * Known parameters: | 80 | * Known parameters: |
@@ -85,27 +85,27 @@ MODULE_LICENSE ("GPL"); | |||
85 | * Please notice that there's not yet an API to set these at runtime. | 85 | * Please notice that there's not yet an API to set these at runtime. |
86 | */ | 86 | */ |
87 | static int bell_volume = 100; /* % */ | 87 | static int bell_volume = 100; /* % */ |
88 | module_param (bell_volume, int, 0); | 88 | module_param(bell_volume, int, 0); |
89 | MODULE_PARM_DESC (bell_volume, "Bell volume (in %). default is 100%"); | 89 | MODULE_PARM_DESC(bell_volume, "Bell volume (in %). default is 100%"); |
90 | 90 | ||
91 | static int keyclick_volume = 100; /* % */ | 91 | static int keyclick_volume = 100; /* % */ |
92 | module_param (keyclick_volume, int, 0); | 92 | module_param(keyclick_volume, int, 0); |
93 | MODULE_PARM_DESC (keyclick_volume, "Keyclick volume (in %), default is 100%"); | 93 | MODULE_PARM_DESC(keyclick_volume, "Keyclick volume (in %), default is 100%"); |
94 | 94 | ||
95 | static int ctrlclick_volume = 100; /* % */ | 95 | static int ctrlclick_volume = 100; /* % */ |
96 | module_param (ctrlclick_volume, int, 0); | 96 | module_param(ctrlclick_volume, int, 0); |
97 | MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%"); | 97 | MODULE_PARM_DESC(ctrlclick_volume, "Ctrlclick volume (in %), default is 100%"); |
98 | 98 | ||
99 | static int lk201_compose_is_alt; | 99 | static int lk201_compose_is_alt; |
100 | module_param (lk201_compose_is_alt, int, 0); | 100 | module_param(lk201_compose_is_alt, int, 0); |
101 | MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " | 101 | MODULE_PARM_DESC(lk201_compose_is_alt, |
102 | "will act as an Alt key"); | 102 | "If set non-zero, LK201' Compose key will act as an Alt key"); |
103 | 103 | ||
104 | 104 | ||
105 | 105 | ||
106 | #undef LKKBD_DEBUG | 106 | #undef LKKBD_DEBUG |
107 | #ifdef LKKBD_DEBUG | 107 | #ifdef LKKBD_DEBUG |
108 | #define DBG(x...) printk (x) | 108 | #define DBG(x...) printk(x) |
109 | #else | 109 | #else |
110 | #define DBG(x...) do {} while (0) | 110 | #define DBG(x...) do {} while (0) |
111 | #endif | 111 | #endif |
@@ -122,7 +122,7 @@ MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " | |||
122 | #define LK_MODE_DOWN 0x80 | 122 | #define LK_MODE_DOWN 0x80 |
123 | #define LK_MODE_AUTODOWN 0x82 | 123 | #define LK_MODE_AUTODOWN 0x82 |
124 | #define LK_MODE_UPDOWN 0x86 | 124 | #define LK_MODE_UPDOWN 0x86 |
125 | #define LK_CMD_SET_MODE(mode,div) ((mode) | ((div) << 3)) | 125 | #define LK_CMD_SET_MODE(mode, div) ((mode) | ((div) << 3)) |
126 | 126 | ||
127 | /* Misc commands */ | 127 | /* Misc commands */ |
128 | #define LK_CMD_ENABLE_KEYCLICK 0x1b | 128 | #define LK_CMD_ENABLE_KEYCLICK 0x1b |
@@ -152,11 +152,8 @@ MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key " | |||
152 | 152 | ||
153 | #define LK_NUM_KEYCODES 256 | 153 | #define LK_NUM_KEYCODES 256 |
154 | #define LK_NUM_IGNORE_BYTES 6 | 154 | #define LK_NUM_IGNORE_BYTES 6 |
155 | typedef u_int16_t lk_keycode_t; | ||
156 | 155 | ||
157 | 156 | static unsigned short lkkbd_keycode[LK_NUM_KEYCODES] = { | |
158 | |||
159 | static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { | ||
160 | [0x56] = KEY_F1, | 157 | [0x56] = KEY_F1, |
161 | [0x57] = KEY_F2, | 158 | [0x57] = KEY_F2, |
162 | [0x58] = KEY_F3, | 159 | [0x58] = KEY_F3, |
@@ -268,7 +265,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { | |||
268 | }; | 265 | }; |
269 | 266 | ||
270 | #define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do { \ | 267 | #define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do { \ |
271 | if (test_bit (LED, (LK)->dev->led)) \ | 268 | if (test_bit(LED, (LK)->dev->led)) \ |
272 | VAR_ON |= BITS; \ | 269 | VAR_ON |= BITS; \ |
273 | else \ | 270 | else \ |
274 | VAR_OFF |= BITS; \ | 271 | VAR_OFF |= BITS; \ |
@@ -278,7 +275,7 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = { | |||
278 | * Per-keyboard data | 275 | * Per-keyboard data |
279 | */ | 276 | */ |
280 | struct lkkbd { | 277 | struct lkkbd { |
281 | lk_keycode_t keycode[LK_NUM_KEYCODES]; | 278 | unsigned short keycode[LK_NUM_KEYCODES]; |
282 | int ignore_bytes; | 279 | int ignore_bytes; |
283 | unsigned char id[LK_NUM_IGNORE_BYTES]; | 280 | unsigned char id[LK_NUM_IGNORE_BYTES]; |
284 | struct input_dev *dev; | 281 | struct input_dev *dev; |
@@ -301,26 +298,25 @@ static struct { | |||
301 | unsigned char *name; | 298 | unsigned char *name; |
302 | } lk_response[] = { | 299 | } lk_response[] = { |
303 | #define RESPONSE(x) { .value = (x), .name = #x, } | 300 | #define RESPONSE(x) { .value = (x), .name = #x, } |
304 | RESPONSE (LK_STUCK_KEY), | 301 | RESPONSE(LK_STUCK_KEY), |
305 | RESPONSE (LK_SELFTEST_FAILED), | 302 | RESPONSE(LK_SELFTEST_FAILED), |
306 | RESPONSE (LK_ALL_KEYS_UP), | 303 | RESPONSE(LK_ALL_KEYS_UP), |
307 | RESPONSE (LK_METRONOME), | 304 | RESPONSE(LK_METRONOME), |
308 | RESPONSE (LK_OUTPUT_ERROR), | 305 | RESPONSE(LK_OUTPUT_ERROR), |
309 | RESPONSE (LK_INPUT_ERROR), | 306 | RESPONSE(LK_INPUT_ERROR), |
310 | RESPONSE (LK_KBD_LOCKED), | 307 | RESPONSE(LK_KBD_LOCKED), |
311 | RESPONSE (LK_KBD_TEST_MODE_ACK), | 308 | RESPONSE(LK_KBD_TEST_MODE_ACK), |
312 | RESPONSE (LK_PREFIX_KEY_DOWN), | 309 | RESPONSE(LK_PREFIX_KEY_DOWN), |
313 | RESPONSE (LK_MODE_CHANGE_ACK), | 310 | RESPONSE(LK_MODE_CHANGE_ACK), |
314 | RESPONSE (LK_RESPONSE_RESERVED), | 311 | RESPONSE(LK_RESPONSE_RESERVED), |
315 | #undef RESPONSE | 312 | #undef RESPONSE |
316 | }; | 313 | }; |
317 | 314 | ||
318 | static unsigned char * | 315 | static unsigned char *response_name(unsigned char value) |
319 | response_name (unsigned char value) | ||
320 | { | 316 | { |
321 | int i; | 317 | int i; |
322 | 318 | ||
323 | for (i = 0; i < ARRAY_SIZE (lk_response); i++) | 319 | for (i = 0; i < ARRAY_SIZE(lk_response); i++) |
324 | if (lk_response[i].value == value) | 320 | if (lk_response[i].value == value) |
325 | return lk_response[i].name; | 321 | return lk_response[i].name; |
326 | 322 | ||
@@ -331,8 +327,7 @@ response_name (unsigned char value) | |||
331 | /* | 327 | /* |
332 | * Calculate volume parameter byte for a given volume. | 328 | * Calculate volume parameter byte for a given volume. |
333 | */ | 329 | */ |
334 | static unsigned char | 330 | static unsigned char volume_to_hw(int volume_percent) |
335 | volume_to_hw (int volume_percent) | ||
336 | { | 331 | { |
337 | unsigned char ret = 0; | 332 | unsigned char ret = 0; |
338 | 333 | ||
@@ -363,8 +358,7 @@ volume_to_hw (int volume_percent) | |||
363 | return ret; | 358 | return ret; |
364 | } | 359 | } |
365 | 360 | ||
366 | static void | 361 | static void lkkbd_detection_done(struct lkkbd *lk) |
367 | lkkbd_detection_done (struct lkkbd *lk) | ||
368 | { | 362 | { |
369 | int i; | 363 | int i; |
370 | 364 | ||
@@ -377,190 +371,202 @@ lkkbd_detection_done (struct lkkbd *lk) | |||
377 | * Print keyboard name and modify Compose=Alt on user's request. | 371 | * Print keyboard name and modify Compose=Alt on user's request. |
378 | */ | 372 | */ |
379 | switch (lk->id[4]) { | 373 | switch (lk->id[4]) { |
380 | case 1: | 374 | case 1: |
381 | strlcpy (lk->name, "DEC LK201 keyboard", | 375 | strlcpy(lk->name, "DEC LK201 keyboard", sizeof(lk->name)); |
382 | sizeof (lk->name)); | 376 | |
383 | 377 | if (lk201_compose_is_alt) | |
384 | if (lk201_compose_is_alt) | 378 | lk->keycode[0xb1] = KEY_LEFTALT; |
385 | lk->keycode[0xb1] = KEY_LEFTALT; | 379 | break; |
386 | break; | 380 | |
387 | 381 | case 2: | |
388 | case 2: | 382 | strlcpy(lk->name, "DEC LK401 keyboard", sizeof(lk->name)); |
389 | strlcpy (lk->name, "DEC LK401 keyboard", | 383 | break; |
390 | sizeof (lk->name)); | 384 | |
391 | break; | 385 | default: |
392 | 386 | strlcpy(lk->name, "Unknown DEC keyboard", sizeof(lk->name)); | |
393 | default: | 387 | printk(KERN_ERR |
394 | strlcpy (lk->name, "Unknown DEC keyboard", | 388 | "lkkbd: keyboard on %s is unknown, please report to " |
395 | sizeof (lk->name)); | 389 | "Jan-Benedict Glaw <jbglaw@lug-owl.de>\n", lk->phys); |
396 | printk (KERN_ERR "lkkbd: keyboard on %s is unknown, " | 390 | printk(KERN_ERR "lkkbd: keyboard ID'ed as:"); |
397 | "please report to Jan-Benedict Glaw " | 391 | for (i = 0; i < LK_NUM_IGNORE_BYTES; i++) |
398 | "<jbglaw@lug-owl.de>\n", lk->phys); | 392 | printk(" 0x%02x", lk->id[i]); |
399 | printk (KERN_ERR "lkkbd: keyboard ID'ed as:"); | 393 | printk("\n"); |
400 | for (i = 0; i < LK_NUM_IGNORE_BYTES; i++) | 394 | break; |
401 | printk (" 0x%02x", lk->id[i]); | ||
402 | printk ("\n"); | ||
403 | break; | ||
404 | } | 395 | } |
405 | printk (KERN_INFO "lkkbd: keyboard on %s identified as: %s\n", | 396 | |
406 | lk->phys, lk->name); | 397 | printk(KERN_INFO "lkkbd: keyboard on %s identified as: %s\n", |
398 | lk->phys, lk->name); | ||
407 | 399 | ||
408 | /* | 400 | /* |
409 | * Report errors during keyboard boot-up. | 401 | * Report errors during keyboard boot-up. |
410 | */ | 402 | */ |
411 | switch (lk->id[2]) { | 403 | switch (lk->id[2]) { |
412 | case 0x00: | 404 | case 0x00: |
413 | /* All okay */ | 405 | /* All okay */ |
414 | break; | 406 | break; |
415 | 407 | ||
416 | case LK_STUCK_KEY: | 408 | case LK_STUCK_KEY: |
417 | printk (KERN_ERR "lkkbd: Stuck key on keyboard at " | 409 | printk(KERN_ERR "lkkbd: Stuck key on keyboard at %s\n", |
418 | "%s\n", lk->phys); | 410 | lk->phys); |
419 | break; | 411 | break; |
420 | 412 | ||
421 | case LK_SELFTEST_FAILED: | 413 | case LK_SELFTEST_FAILED: |
422 | printk (KERN_ERR "lkkbd: Selftest failed on keyboard " | 414 | printk(KERN_ERR |
423 | "at %s, keyboard may not work " | 415 | "lkkbd: Selftest failed on keyboard at %s, " |
424 | "properly\n", lk->phys); | 416 | "keyboard may not work properly\n", lk->phys); |
425 | break; | 417 | break; |
426 | 418 | ||
427 | default: | 419 | default: |
428 | printk (KERN_ERR "lkkbd: Unknown error %02x on " | 420 | printk(KERN_ERR |
429 | "keyboard at %s\n", lk->id[2], | 421 | "lkkbd: Unknown error %02x on keyboard at %s\n", |
430 | lk->phys); | 422 | lk->id[2], lk->phys); |
431 | break; | 423 | break; |
432 | } | 424 | } |
433 | 425 | ||
434 | /* | 426 | /* |
435 | * Try to hint user if there's a stuck key. | 427 | * Try to hint user if there's a stuck key. |
436 | */ | 428 | */ |
437 | if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0) | 429 | if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0) |
438 | printk (KERN_ERR "Scancode of stuck key is 0x%02x, keycode " | 430 | printk(KERN_ERR |
439 | "is 0x%04x\n", lk->id[3], | 431 | "Scancode of stuck key is 0x%02x, keycode is 0x%04x\n", |
440 | lk->keycode[lk->id[3]]); | 432 | lk->id[3], lk->keycode[lk->id[3]]); |
441 | |||
442 | return; | ||
443 | } | 433 | } |
444 | 434 | ||
445 | /* | 435 | /* |
446 | * lkkbd_interrupt() is called by the low level driver when a character | 436 | * lkkbd_interrupt() is called by the low level driver when a character |
447 | * is received. | 437 | * is received. |
448 | */ | 438 | */ |
449 | static irqreturn_t | 439 | static irqreturn_t lkkbd_interrupt(struct serio *serio, |
450 | lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags) | 440 | unsigned char data, unsigned int flags) |
451 | { | 441 | { |
452 | struct lkkbd *lk = serio_get_drvdata (serio); | 442 | struct lkkbd *lk = serio_get_drvdata(serio); |
443 | struct input_dev *input_dev = lk->dev; | ||
444 | unsigned int keycode; | ||
453 | int i; | 445 | int i; |
454 | 446 | ||
455 | DBG (KERN_INFO "Got byte 0x%02x\n", data); | 447 | DBG(KERN_INFO "Got byte 0x%02x\n", data); |
456 | 448 | ||
457 | if (lk->ignore_bytes > 0) { | 449 | if (lk->ignore_bytes > 0) { |
458 | DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name); | 450 | DBG(KERN_INFO "Ignoring a byte on %s\n", lk->name); |
459 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; | 451 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; |
460 | 452 | ||
461 | if (lk->ignore_bytes == 0) | 453 | if (lk->ignore_bytes == 0) |
462 | lkkbd_detection_done (lk); | 454 | lkkbd_detection_done(lk); |
463 | 455 | ||
464 | return IRQ_HANDLED; | 456 | return IRQ_HANDLED; |
465 | } | 457 | } |
466 | 458 | ||
467 | switch (data) { | 459 | switch (data) { |
468 | case LK_ALL_KEYS_UP: | 460 | case LK_ALL_KEYS_UP: |
469 | for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++) | 461 | for (i = 0; i < ARRAY_SIZE(lkkbd_keycode); i++) |
470 | if (lk->keycode[i] != KEY_RESERVED) | 462 | input_report_key(input_dev, lk->keycode[i], 0); |
471 | input_report_key (lk->dev, lk->keycode[i], 0); | 463 | input_sync(input_dev); |
472 | input_sync (lk->dev); | 464 | break; |
473 | break; | 465 | |
474 | 466 | case 0x01: | |
475 | case 0x01: | 467 | DBG(KERN_INFO "Got 0x01, scheduling re-initialization\n"); |
476 | DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n"); | 468 | lk->ignore_bytes = LK_NUM_IGNORE_BYTES; |
477 | lk->ignore_bytes = LK_NUM_IGNORE_BYTES; | 469 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; |
478 | lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data; | 470 | schedule_work(&lk->tq); |
479 | schedule_work (&lk->tq); | 471 | break; |
480 | break; | 472 | |
481 | 473 | case LK_METRONOME: | |
482 | case LK_METRONOME: | 474 | case LK_OUTPUT_ERROR: |
483 | case LK_OUTPUT_ERROR: | 475 | case LK_INPUT_ERROR: |
484 | case LK_INPUT_ERROR: | 476 | case LK_KBD_LOCKED: |
485 | case LK_KBD_LOCKED: | 477 | case LK_KBD_TEST_MODE_ACK: |
486 | case LK_KBD_TEST_MODE_ACK: | 478 | case LK_PREFIX_KEY_DOWN: |
487 | case LK_PREFIX_KEY_DOWN: | 479 | case LK_MODE_CHANGE_ACK: |
488 | case LK_MODE_CHANGE_ACK: | 480 | case LK_RESPONSE_RESERVED: |
489 | case LK_RESPONSE_RESERVED: | 481 | DBG(KERN_INFO "Got %s and don't know how to handle...\n", |
490 | DBG (KERN_INFO "Got %s and don't know how to handle...\n", | 482 | response_name(data)); |
491 | response_name (data)); | 483 | break; |
492 | break; | 484 | |
493 | 485 | default: | |
494 | default: | 486 | keycode = lk->keycode[data]; |
495 | if (lk->keycode[data] != KEY_RESERVED) { | 487 | if (keycode != KEY_RESERVED) { |
496 | if (!test_bit (lk->keycode[data], lk->dev->key)) | 488 | input_report_key(input_dev, keycode, |
497 | input_report_key (lk->dev, lk->keycode[data], 1); | 489 | !test_bit(keycode, input_dev->key)); |
498 | else | 490 | input_sync(input_dev); |
499 | input_report_key (lk->dev, lk->keycode[data], 0); | 491 | } else { |
500 | input_sync (lk->dev); | 492 | printk(KERN_WARNING |
501 | } else | 493 | "%s: Unknown key with scancode 0x%02x on %s.\n", |
502 | printk (KERN_WARNING "%s: Unknown key with " | 494 | __FILE__, data, lk->name); |
503 | "scancode 0x%02x on %s.\n", | 495 | } |
504 | __FILE__, data, lk->name); | ||
505 | } | 496 | } |
506 | 497 | ||
507 | return IRQ_HANDLED; | 498 | return IRQ_HANDLED; |
508 | } | 499 | } |
509 | 500 | ||
501 | static void lkkbd_toggle_leds(struct lkkbd *lk) | ||
502 | { | ||
503 | struct serio *serio = lk->serio; | ||
504 | unsigned char leds_on = 0; | ||
505 | unsigned char leds_off = 0; | ||
506 | |||
507 | CHECK_LED(lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | ||
508 | CHECK_LED(lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE); | ||
509 | CHECK_LED(lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | ||
510 | CHECK_LED(lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | ||
511 | if (leds_on != 0) { | ||
512 | serio_write(serio, LK_CMD_LED_ON); | ||
513 | serio_write(serio, leds_on); | ||
514 | } | ||
515 | if (leds_off != 0) { | ||
516 | serio_write(serio, LK_CMD_LED_OFF); | ||
517 | serio_write(serio, leds_off); | ||
518 | } | ||
519 | } | ||
520 | |||
521 | static void lkkbd_toggle_keyclick(struct lkkbd *lk, bool on) | ||
522 | { | ||
523 | struct serio *serio = lk->serio; | ||
524 | |||
525 | if (on) { | ||
526 | DBG("%s: Activating key clicks\n", __func__); | ||
527 | serio_write(serio, LK_CMD_ENABLE_KEYCLICK); | ||
528 | serio_write(serio, volume_to_hw(lk->keyclick_volume)); | ||
529 | serio_write(serio, LK_CMD_ENABLE_CTRCLICK); | ||
530 | serio_write(serio, volume_to_hw(lk->ctrlclick_volume)); | ||
531 | } else { | ||
532 | DBG("%s: Deactivating key clicks\n", __func__); | ||
533 | serio_write(serio, LK_CMD_DISABLE_KEYCLICK); | ||
534 | serio_write(serio, LK_CMD_DISABLE_CTRCLICK); | ||
535 | } | ||
536 | |||
537 | } | ||
538 | |||
510 | /* | 539 | /* |
511 | * lkkbd_event() handles events from the input module. | 540 | * lkkbd_event() handles events from the input module. |
512 | */ | 541 | */ |
513 | static int | 542 | static int lkkbd_event(struct input_dev *dev, |
514 | lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | 543 | unsigned int type, unsigned int code, int value) |
515 | int value) | ||
516 | { | 544 | { |
517 | struct lkkbd *lk = input_get_drvdata (dev); | 545 | struct lkkbd *lk = input_get_drvdata(dev); |
518 | unsigned char leds_on = 0; | ||
519 | unsigned char leds_off = 0; | ||
520 | 546 | ||
521 | switch (type) { | 547 | switch (type) { |
522 | case EV_LED: | 548 | case EV_LED: |
523 | CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | 549 | lkkbd_toggle_leds(lk); |
524 | CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE); | 550 | return 0; |
525 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | 551 | |
526 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | 552 | case EV_SND: |
527 | if (leds_on != 0) { | 553 | switch (code) { |
528 | serio_write (lk->serio, LK_CMD_LED_ON); | 554 | case SND_CLICK: |
529 | serio_write (lk->serio, leds_on); | 555 | lkkbd_toggle_keyclick(lk, value); |
530 | } | ||
531 | if (leds_off != 0) { | ||
532 | serio_write (lk->serio, LK_CMD_LED_OFF); | ||
533 | serio_write (lk->serio, leds_off); | ||
534 | } | ||
535 | return 0; | 556 | return 0; |
536 | 557 | ||
537 | case EV_SND: | 558 | case SND_BELL: |
538 | switch (code) { | 559 | if (value != 0) |
539 | case SND_CLICK: | 560 | serio_write(lk->serio, LK_CMD_SOUND_BELL); |
540 | if (value == 0) { | 561 | |
541 | DBG ("%s: Deactivating key clicks\n", __func__); | 562 | return 0; |
542 | serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK); | 563 | } |
543 | serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK); | 564 | |
544 | } else { | 565 | break; |
545 | DBG ("%s: Activating key clicks\n", __func__); | 566 | |
546 | serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK); | 567 | default: |
547 | serio_write (lk->serio, volume_to_hw (lk->keyclick_volume)); | 568 | printk(KERN_ERR "%s(): Got unknown type %d, code %d, value %d\n", |
548 | serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK); | 569 | __func__, type, code, value); |
549 | serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); | ||
550 | } | ||
551 | return 0; | ||
552 | |||
553 | case SND_BELL: | ||
554 | if (value != 0) | ||
555 | serio_write (lk->serio, LK_CMD_SOUND_BELL); | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | break; | ||
560 | |||
561 | default: | ||
562 | printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n", | ||
563 | __func__, type, code, value); | ||
564 | } | 570 | } |
565 | 571 | ||
566 | return -1; | 572 | return -1; |
@@ -570,79 +576,56 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | |||
570 | * lkkbd_reinit() sets leds and beeps to a state the computer remembers they | 576 | * lkkbd_reinit() sets leds and beeps to a state the computer remembers they |
571 | * were in. | 577 | * were in. |
572 | */ | 578 | */ |
573 | static void | 579 | static void lkkbd_reinit(struct work_struct *work) |
574 | lkkbd_reinit (struct work_struct *work) | ||
575 | { | 580 | { |
576 | struct lkkbd *lk = container_of(work, struct lkkbd, tq); | 581 | struct lkkbd *lk = container_of(work, struct lkkbd, tq); |
577 | int division; | 582 | int division; |
578 | unsigned char leds_on = 0; | ||
579 | unsigned char leds_off = 0; | ||
580 | 583 | ||
581 | /* Ask for ID */ | 584 | /* Ask for ID */ |
582 | serio_write (lk->serio, LK_CMD_REQUEST_ID); | 585 | serio_write(lk->serio, LK_CMD_REQUEST_ID); |
583 | 586 | ||
584 | /* Reset parameters */ | 587 | /* Reset parameters */ |
585 | serio_write (lk->serio, LK_CMD_SET_DEFAULTS); | 588 | serio_write(lk->serio, LK_CMD_SET_DEFAULTS); |
586 | 589 | ||
587 | /* Set LEDs */ | 590 | /* Set LEDs */ |
588 | CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK); | 591 | lkkbd_toggle_leds(lk); |
589 | CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE); | ||
590 | CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK); | ||
591 | CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT); | ||
592 | if (leds_on != 0) { | ||
593 | serio_write (lk->serio, LK_CMD_LED_ON); | ||
594 | serio_write (lk->serio, leds_on); | ||
595 | } | ||
596 | if (leds_off != 0) { | ||
597 | serio_write (lk->serio, LK_CMD_LED_OFF); | ||
598 | serio_write (lk->serio, leds_off); | ||
599 | } | ||
600 | 592 | ||
601 | /* | 593 | /* |
602 | * Try to activate extended LK401 mode. This command will | 594 | * Try to activate extended LK401 mode. This command will |
603 | * only work with a LK401 keyboard and grants access to | 595 | * only work with a LK401 keyboard and grants access to |
604 | * LAlt, RAlt, RCompose and RShift. | 596 | * LAlt, RAlt, RCompose and RShift. |
605 | */ | 597 | */ |
606 | serio_write (lk->serio, LK_CMD_ENABLE_LK401); | 598 | serio_write(lk->serio, LK_CMD_ENABLE_LK401); |
607 | 599 | ||
608 | /* Set all keys to UPDOWN mode */ | 600 | /* Set all keys to UPDOWN mode */ |
609 | for (division = 1; division <= 14; division++) | 601 | for (division = 1; division <= 14; division++) |
610 | serio_write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN, | 602 | serio_write(lk->serio, |
611 | division)); | 603 | LK_CMD_SET_MODE(LK_MODE_UPDOWN, division)); |
612 | 604 | ||
613 | /* Enable bell and set volume */ | 605 | /* Enable bell and set volume */ |
614 | serio_write (lk->serio, LK_CMD_ENABLE_BELL); | 606 | serio_write(lk->serio, LK_CMD_ENABLE_BELL); |
615 | serio_write (lk->serio, volume_to_hw (lk->bell_volume)); | 607 | serio_write(lk->serio, volume_to_hw(lk->bell_volume)); |
616 | 608 | ||
617 | /* Enable/disable keyclick (and possibly set volume) */ | 609 | /* Enable/disable keyclick (and possibly set volume) */ |
618 | if (test_bit (SND_CLICK, lk->dev->snd)) { | 610 | lkkbd_toggle_keyclick(lk, test_bit(SND_CLICK, lk->dev->snd)); |
619 | serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK); | ||
620 | serio_write (lk->serio, volume_to_hw (lk->keyclick_volume)); | ||
621 | serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK); | ||
622 | serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume)); | ||
623 | } else { | ||
624 | serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK); | ||
625 | serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK); | ||
626 | } | ||
627 | 611 | ||
628 | /* Sound the bell if needed */ | 612 | /* Sound the bell if needed */ |
629 | if (test_bit (SND_BELL, lk->dev->snd)) | 613 | if (test_bit(SND_BELL, lk->dev->snd)) |
630 | serio_write (lk->serio, LK_CMD_SOUND_BELL); | 614 | serio_write(lk->serio, LK_CMD_SOUND_BELL); |
631 | } | 615 | } |
632 | 616 | ||
633 | /* | 617 | /* |
634 | * lkkbd_connect() probes for a LK keyboard and fills the necessary structures. | 618 | * lkkbd_connect() probes for a LK keyboard and fills the necessary structures. |
635 | */ | 619 | */ |
636 | static int | 620 | static int lkkbd_connect(struct serio *serio, struct serio_driver *drv) |
637 | lkkbd_connect (struct serio *serio, struct serio_driver *drv) | ||
638 | { | 621 | { |
639 | struct lkkbd *lk; | 622 | struct lkkbd *lk; |
640 | struct input_dev *input_dev; | 623 | struct input_dev *input_dev; |
641 | int i; | 624 | int i; |
642 | int err; | 625 | int err; |
643 | 626 | ||
644 | lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL); | 627 | lk = kzalloc(sizeof(struct lkkbd), GFP_KERNEL); |
645 | input_dev = input_allocate_device (); | 628 | input_dev = input_allocate_device(); |
646 | if (!lk || !input_dev) { | 629 | if (!lk || !input_dev) { |
647 | err = -ENOMEM; | 630 | err = -ENOMEM; |
648 | goto fail1; | 631 | goto fail1; |
@@ -650,14 +633,14 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
650 | 633 | ||
651 | lk->serio = serio; | 634 | lk->serio = serio; |
652 | lk->dev = input_dev; | 635 | lk->dev = input_dev; |
653 | INIT_WORK (&lk->tq, lkkbd_reinit); | 636 | INIT_WORK(&lk->tq, lkkbd_reinit); |
654 | lk->bell_volume = bell_volume; | 637 | lk->bell_volume = bell_volume; |
655 | lk->keyclick_volume = keyclick_volume; | 638 | lk->keyclick_volume = keyclick_volume; |
656 | lk->ctrlclick_volume = ctrlclick_volume; | 639 | lk->ctrlclick_volume = ctrlclick_volume; |
657 | memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES); | 640 | memcpy(lk->keycode, lkkbd_keycode, sizeof(lk->keycode)); |
658 | 641 | ||
659 | strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name)); | 642 | strlcpy(lk->name, "DEC LK keyboard", sizeof(lk->name)); |
660 | snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys); | 643 | snprintf(lk->phys, sizeof(lk->phys), "%s/input0", serio->phys); |
661 | 644 | ||
662 | input_dev->name = lk->name; | 645 | input_dev->name = lk->name; |
663 | input_dev->phys = lk->phys; | 646 | input_dev->phys = lk->phys; |
@@ -668,62 +651,61 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
668 | input_dev->dev.parent = &serio->dev; | 651 | input_dev->dev.parent = &serio->dev; |
669 | input_dev->event = lkkbd_event; | 652 | input_dev->event = lkkbd_event; |
670 | 653 | ||
671 | input_set_drvdata (input_dev, lk); | 654 | input_set_drvdata(input_dev, lk); |
672 | 655 | ||
673 | set_bit (EV_KEY, input_dev->evbit); | 656 | __set_bit(EV_KEY, input_dev->evbit); |
674 | set_bit (EV_LED, input_dev->evbit); | 657 | __set_bit(EV_LED, input_dev->evbit); |
675 | set_bit (EV_SND, input_dev->evbit); | 658 | __set_bit(EV_SND, input_dev->evbit); |
676 | set_bit (EV_REP, input_dev->evbit); | 659 | __set_bit(EV_REP, input_dev->evbit); |
677 | set_bit (LED_CAPSL, input_dev->ledbit); | 660 | __set_bit(LED_CAPSL, input_dev->ledbit); |
678 | set_bit (LED_SLEEP, input_dev->ledbit); | 661 | __set_bit(LED_SLEEP, input_dev->ledbit); |
679 | set_bit (LED_COMPOSE, input_dev->ledbit); | 662 | __set_bit(LED_COMPOSE, input_dev->ledbit); |
680 | set_bit (LED_SCROLLL, input_dev->ledbit); | 663 | __set_bit(LED_SCROLLL, input_dev->ledbit); |
681 | set_bit (SND_BELL, input_dev->sndbit); | 664 | __set_bit(SND_BELL, input_dev->sndbit); |
682 | set_bit (SND_CLICK, input_dev->sndbit); | 665 | __set_bit(SND_CLICK, input_dev->sndbit); |
683 | 666 | ||
684 | input_dev->keycode = lk->keycode; | 667 | input_dev->keycode = lk->keycode; |
685 | input_dev->keycodesize = sizeof (lk_keycode_t); | 668 | input_dev->keycodesize = sizeof(lk->keycode[0]); |
686 | input_dev->keycodemax = LK_NUM_KEYCODES; | 669 | input_dev->keycodemax = ARRAY_SIZE(lk->keycode); |
687 | 670 | ||
688 | for (i = 0; i < LK_NUM_KEYCODES; i++) | 671 | for (i = 0; i < LK_NUM_KEYCODES; i++) |
689 | __set_bit (lk->keycode[i], input_dev->keybit); | 672 | __set_bit(lk->keycode[i], input_dev->keybit); |
690 | __clear_bit(KEY_RESERVED, input_dev->keybit); | 673 | __clear_bit(KEY_RESERVED, input_dev->keybit); |
691 | 674 | ||
692 | serio_set_drvdata (serio, lk); | 675 | serio_set_drvdata(serio, lk); |
693 | 676 | ||
694 | err = serio_open (serio, drv); | 677 | err = serio_open(serio, drv); |
695 | if (err) | 678 | if (err) |
696 | goto fail2; | 679 | goto fail2; |
697 | 680 | ||
698 | err = input_register_device (lk->dev); | 681 | err = input_register_device(lk->dev); |
699 | if (err) | 682 | if (err) |
700 | goto fail3; | 683 | goto fail3; |
701 | 684 | ||
702 | serio_write (lk->serio, LK_CMD_POWERCYCLE_RESET); | 685 | serio_write(lk->serio, LK_CMD_POWERCYCLE_RESET); |
703 | 686 | ||
704 | return 0; | 687 | return 0; |
705 | 688 | ||
706 | fail3: serio_close (serio); | 689 | fail3: serio_close(serio); |
707 | fail2: serio_set_drvdata (serio, NULL); | 690 | fail2: serio_set_drvdata(serio, NULL); |
708 | fail1: input_free_device (input_dev); | 691 | fail1: input_free_device(input_dev); |
709 | kfree (lk); | 692 | kfree(lk); |
710 | return err; | 693 | return err; |
711 | } | 694 | } |
712 | 695 | ||
713 | /* | 696 | /* |
714 | * lkkbd_disconnect() unregisters and closes behind us. | 697 | * lkkbd_disconnect() unregisters and closes behind us. |
715 | */ | 698 | */ |
716 | static void | 699 | static void lkkbd_disconnect(struct serio *serio) |
717 | lkkbd_disconnect (struct serio *serio) | ||
718 | { | 700 | { |
719 | struct lkkbd *lk = serio_get_drvdata (serio); | 701 | struct lkkbd *lk = serio_get_drvdata(serio); |
720 | 702 | ||
721 | input_get_device (lk->dev); | 703 | input_get_device(lk->dev); |
722 | input_unregister_device (lk->dev); | 704 | input_unregister_device(lk->dev); |
723 | serio_close (serio); | 705 | serio_close(serio); |
724 | serio_set_drvdata (serio, NULL); | 706 | serio_set_drvdata(serio, NULL); |
725 | input_put_device (lk->dev); | 707 | input_put_device(lk->dev); |
726 | kfree (lk); | 708 | kfree(lk); |
727 | } | 709 | } |
728 | 710 | ||
729 | static struct serio_device_id lkkbd_serio_ids[] = { | 711 | static struct serio_device_id lkkbd_serio_ids[] = { |
@@ -752,18 +734,16 @@ static struct serio_driver lkkbd_drv = { | |||
752 | /* | 734 | /* |
753 | * The functions for insering/removing us as a module. | 735 | * The functions for insering/removing us as a module. |
754 | */ | 736 | */ |
755 | static int __init | 737 | static int __init lkkbd_init(void) |
756 | lkkbd_init (void) | ||
757 | { | 738 | { |
758 | return serio_register_driver(&lkkbd_drv); | 739 | return serio_register_driver(&lkkbd_drv); |
759 | } | 740 | } |
760 | 741 | ||
761 | static void __exit | 742 | static void __exit lkkbd_exit(void) |
762 | lkkbd_exit (void) | ||
763 | { | 743 | { |
764 | serio_unregister_driver(&lkkbd_drv); | 744 | serio_unregister_driver(&lkkbd_drv); |
765 | } | 745 | } |
766 | 746 | ||
767 | module_init (lkkbd_init); | 747 | module_init(lkkbd_init); |
768 | module_exit (lkkbd_exit); | 748 | module_exit(lkkbd_exit); |
769 | 749 | ||
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 91cfe5170265..34f4a29d4973 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -213,8 +213,9 @@ static void matrix_keypad_stop(struct input_dev *dev) | |||
213 | } | 213 | } |
214 | 214 | ||
215 | #ifdef CONFIG_PM | 215 | #ifdef CONFIG_PM |
216 | static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t state) | 216 | static int matrix_keypad_suspend(struct device *dev) |
217 | { | 217 | { |
218 | struct platform_device *pdev = to_platform_device(dev); | ||
218 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 219 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
219 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 220 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
220 | int i; | 221 | int i; |
@@ -228,8 +229,9 @@ static int matrix_keypad_suspend(struct platform_device *pdev, pm_message_t stat | |||
228 | return 0; | 229 | return 0; |
229 | } | 230 | } |
230 | 231 | ||
231 | static int matrix_keypad_resume(struct platform_device *pdev) | 232 | static int matrix_keypad_resume(struct device *dev) |
232 | { | 233 | { |
234 | struct platform_device *pdev = to_platform_device(dev); | ||
233 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); | 235 | struct matrix_keypad *keypad = platform_get_drvdata(pdev); |
234 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; | 236 | const struct matrix_keypad_platform_data *pdata = keypad->pdata; |
235 | int i; | 237 | int i; |
@@ -242,9 +244,9 @@ static int matrix_keypad_resume(struct platform_device *pdev) | |||
242 | 244 | ||
243 | return 0; | 245 | return 0; |
244 | } | 246 | } |
245 | #else | 247 | |
246 | #define matrix_keypad_suspend NULL | 248 | static const SIMPLE_DEV_PM_OPS(matrix_keypad_pm_ops, |
247 | #define matrix_keypad_resume NULL | 249 | matrix_keypad_suspend, matrix_keypad_resume); |
248 | #endif | 250 | #endif |
249 | 251 | ||
250 | static int __devinit init_matrix_gpio(struct platform_device *pdev, | 252 | static int __devinit init_matrix_gpio(struct platform_device *pdev, |
@@ -417,11 +419,12 @@ static int __devexit matrix_keypad_remove(struct platform_device *pdev) | |||
417 | static struct platform_driver matrix_keypad_driver = { | 419 | static struct platform_driver matrix_keypad_driver = { |
418 | .probe = matrix_keypad_probe, | 420 | .probe = matrix_keypad_probe, |
419 | .remove = __devexit_p(matrix_keypad_remove), | 421 | .remove = __devexit_p(matrix_keypad_remove), |
420 | .suspend = matrix_keypad_suspend, | ||
421 | .resume = matrix_keypad_resume, | ||
422 | .driver = { | 422 | .driver = { |
423 | .name = "matrix-keypad", | 423 | .name = "matrix-keypad", |
424 | .owner = THIS_MODULE, | 424 | .owner = THIS_MODULE, |
425 | #ifdef CONFIG_PM | ||
426 | .pm = &matrix_keypad_pm_ops, | ||
427 | #endif | ||
425 | }, | 428 | }, |
426 | }; | 429 | }; |
427 | 430 | ||