* [PATCH] keypad: platform_data and 24xx support -exp
@ 2005-12-10 13:02 Komal Shah
2006-01-14 0:37 ` Tony Lindgren
0 siblings, 1 reply; 5+ messages in thread
From: Komal Shah @ 2005-12-10 13:02 UTC (permalink / raw)
To: linux-omap-open-source
[-- Attachment #1: Type: text/plain, Size: 956 bytes --]
Tony/Brian,
I have attached patch which includes:
o Modification suggested by Brian Swetland
o Added platform_data structure
- keymap is moved to appropriate board files.
- rows and cols fields are not used in the driver yet.
- rep bit is added.
o IRQ resource
o Added 24xx+menelaus keypad support - tested.
TODO/FIXME:
o appropriate place for test_keymap.
o Removing NUM_COLS/ROWS #defines and replacing with
platform_data->rows/cols.
o Moving request_gpio/free_gpio to board specific file, by introducing
one function in platform_data ? Is this ok? e.g get/put_gpios. As
driver should work as module too.
o How to handle row_/col_gpio_num array and set_/get_gpio_val functions
? I want to keep them out of this keypad.c. Any suggestions?
---Komal Shah
http://komalshah.blogspot.com/
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
[-- Attachment #2: 3036529173-kbp-exp.patch --]
[-- Type: text/plain, Size: 26824 bytes --]
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 0fc2e0f..371a704 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -37,10 +37,50 @@
#include <asm/arch/mux.h>
#include <asm/arch/tc.h>
#include <asm/arch/usb.h>
+#include <asm/arch/keypad.h>
#include <asm/arch/common.h>
extern int omap_gpio_init(void);
+static int h2_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_3),
+ KEY(0, 3, KEY_F10),
+ KEY(0, 4, KEY_F5),
+ KEY(0, 5, KEY_9),
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_2),
+ KEY(1, 3, KEY_F9),
+ KEY(1, 4, KEY_F7),
+ KEY(1, 5, KEY_0),
+ KEY(2, 0, KEY_ENTER),
+ KEY(2, 1, KEY_6),
+ KEY(2, 2, KEY_1),
+ KEY(2, 3, KEY_F2),
+ KEY(2, 4, KEY_F6),
+ KEY(2, 5, KEY_HOME),
+ KEY(3, 0, KEY_8),
+ KEY(3, 1, KEY_5),
+ KEY(3, 2, KEY_F12),
+ KEY(3, 3, KEY_F3),
+ KEY(3, 4, KEY_F8),
+ KEY(3, 5, KEY_END),
+ KEY(4, 0, KEY_7),
+ KEY(4, 1, KEY_4),
+ KEY(4, 2, KEY_F11),
+ KEY(4, 3, KEY_F1),
+ KEY(4, 4, KEY_F4),
+ KEY(4, 5, KEY_ESC),
+ KEY(5, 0, KEY_F13),
+ KEY(5, 1, KEY_F14),
+ KEY(5, 2, KEY_F15),
+ KEY(5, 3, KEY_F16),
+ KEY(5, 4, KEY_SLEEP),
+ 0
+};
+
static struct mtd_partition h2_nor_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -171,10 +211,36 @@ static struct platform_device h2_smc91x_
.resource = h2_smc91x_resources,
};
+static struct resource h2_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct omap_kp_platform_data h2_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap = h2_keymap,
+ .rep = 1,
+};
+
+static struct platform_device h2_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &h2_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(h2_kp_resources),
+ .resource = h2_kp_resources,
+};
+
static struct platform_device *h2_devices[] __initdata = {
&h2_nor_device,
&h2_nand_device,
&h2_smc91x_device,
+ &h2_kp_device,
};
static void __init h2_init_smc91x(void)
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 2953d38..5b83cca 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -24,6 +24,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/input.h>
#include <asm/setup.h>
#include <asm/page.h>
@@ -38,10 +39,50 @@
#include <asm/arch/mux.h>
#include <asm/arch/tc.h>
#include <asm/arch/usb.h>
+#include <asm/arch/keypad.h>
#include <asm/arch/common.h>
extern int omap_gpio_init(void);
+static int h3_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_3),
+ KEY(0, 3, KEY_F10),
+ KEY(0, 4, KEY_F5),
+ KEY(0, 5, KEY_9),
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_2),
+ KEY(1, 3, KEY_F9),
+ KEY(1, 4, KEY_F7),
+ KEY(1, 5, KEY_0),
+ KEY(2, 0, KEY_ENTER),
+ KEY(2, 1, KEY_6),
+ KEY(2, 2, KEY_1),
+ KEY(2, 3, KEY_F2),
+ KEY(2, 4, KEY_F6),
+ KEY(2, 5, KEY_HOME),
+ KEY(3, 0, KEY_8),
+ KEY(3, 1, KEY_5),
+ KEY(3, 2, KEY_F12),
+ KEY(3, 3, KEY_F3),
+ KEY(3, 4, KEY_F8),
+ KEY(3, 5, KEY_END),
+ KEY(4, 0, KEY_7),
+ KEY(4, 1, KEY_4),
+ KEY(4, 2, KEY_F11),
+ KEY(4, 3, KEY_F1),
+ KEY(4, 4, KEY_F4),
+ KEY(4, 5, KEY_ESC),
+ KEY(5, 0, KEY_F13),
+ KEY(5, 1, KEY_F14),
+ KEY(5, 2, KEY_F15),
+ KEY(5, 3, KEY_F16),
+ KEY(5, 4, KEY_SLEEP),
+ 0
+};
+
static struct mtd_partition nor_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -193,11 +234,37 @@ static struct platform_device intlat_dev
.resource = intlat_resources,
};
+static struct resource h3_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct omap_kp_platform_data h3_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap = h3_keymap,
+ .rep = 1,
+};
+
+static struct platform_device h3_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &h3_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(h3_kp_resources),
+ .resource = h3_kp_resources,
+};
+
static struct platform_device *devices[] __initdata = {
&nor_device,
&nand_device,
&smc91x_device,
&intlat_device,
+ &h3_kp_device,
};
static struct omap_usb_config h3_usb_config __initdata = {
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 95f1ff3..a7e4585 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/input.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -34,8 +35,22 @@
#include <asm/arch/gpio.h>
#include <asm/arch/tc.h>
#include <asm/arch/usb.h>
+#include <asm/arch/keypad.h>
#include <asm/arch/common.h>
+static int innovator_keymap[] = {
+ KEY(0, 0, KEY_F1),
+ KEY(0, 3, KEY_DOWN),
+ KEY(1, 1, KEY_F2),
+ KEY(1, 2, KEY_RIGHT),
+ KEY(2, 0, KEY_F3),
+ KEY(2, 1, KEY_F4),
+ KEY(2, 2, KEY_UP),
+ KEY(3, 2, KEY_ENTER),
+ KEY(3, 3, KEY_LEFT),
+ 0
+};
+
static struct mtd_partition innovator_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -97,6 +112,30 @@ static struct platform_device innovator_
.resource = &innovator_flash_resource,
};
+static struct resource innovator_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct omap_kp_platform_data innovator_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap = innovator_keymap,
+};
+
+static struct platform_device innovator_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &innovator_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(innovator_kp_resources),
+ .resource = innovator_kp_resources,
+};
+
#ifdef CONFIG_ARCH_OMAP15XX
/* Only FPGA needs to be mapped here. All others are done with ioremap */
@@ -132,6 +171,7 @@ static struct platform_device innovator1
static struct platform_device *innovator1510_devices[] __initdata = {
&innovator_flash_device,
&innovator1510_smc91x_device,
+ &innovator_kp_device,
};
#endif /* CONFIG_ARCH_OMAP15XX */
@@ -161,6 +201,7 @@ static struct platform_device innovator1
static struct platform_device *innovator1610_devices[] __initdata = {
&innovator_flash_device,
&innovator1610_smc91x_device,
+ &innovator_kp_device,
};
#endif /* CONFIG_ARCH_OMAP16XX */
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index e990e1b..013a4dd 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -33,6 +33,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/input.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -44,8 +45,22 @@
#include <asm/arch/usb.h>
#include <asm/arch/mux.h>
#include <asm/arch/tc.h>
+#include <asm/arch/keypad.h>
#include <asm/arch/common.h>
+static int osk_keymap[] = {
+ KEY(0, 0, KEY_F1),
+ KEY(0, 3, KEY_UP),
+ KEY(1, 1, KEY_LEFTCTRL),
+ KEY(1, 2, KEY_LEFT),
+ KEY(2, 0, KEY_SPACE),
+ KEY(2, 1, KEY_ESC),
+ KEY(2, 2, KEY_DOWN),
+ KEY(3, 2, KEY_ENTER),
+ KEY(3, 3, KEY_RIGHT),
+ 0
+};
+
static struct mtd_partition osk_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -138,11 +153,36 @@ static struct platform_device osk5912_mc
.id = 1,
};
+static struct resource osk5912_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct omap_kp_platform_data osk_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap = osk_keymap,
+};
+
+static struct platform_device osk5912_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &osk_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(osk5912_kp_resources),
+ .resource = osk5912_kp_resources,
+};
+
static struct platform_device *osk5912_devices[] __initdata = {
&osk5912_flash_device,
&osk5912_smc91x_device,
&osk5912_cf_device,
&osk5912_mcbsp1_device,
+ &osk5912_kp_device,
};
static void __init osk_init_smc91x(void)
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index dd8069a..98c7cdc 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -18,6 +18,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/input.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -29,9 +30,44 @@
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include <asm/arch/fpga.h>
+#include <asm/arch/keypad.h>
#include <asm/arch/common.h>
#include <asm/arch/board.h>
+static int p2_keymap[] = {
+ KEY(0,0,KEY_UP),
+ KEY(0,1,KEY_RIGHT),
+ KEY(0,2,KEY_LEFT),
+ KEY(0,3,KEY_DOWN),
+ KEY(0,4,KEY_CENTER),
+ KEY(0,5,KEY_0_5),
+ KEY(1,0,KEY_SOFT2),
+ KEY(1,1,KEY_SEND),
+ KEY(1,2,KEY_END),
+ KEY(1,3,KEY_VOLUMEDOWN),
+ KEY(1,4,KEY_VOLUMEUP),
+ KEY(1,5,KEY_RECORD),
+ KEY(2,0,KEY_SOFT1),
+ KEY(2,1,KEY_3),
+ KEY(2,2,KEY_6),
+ KEY(2,3,KEY_9),
+ KEY(2,4,KEY_SHARP),
+ KEY(2,5,KEY_2_5),
+ KEY(3,0,KEY_BACK),
+ KEY(3,1,KEY_2),
+ KEY(3,2,KEY_5),
+ KEY(3,3,KEY_8),
+ KEY(3,4,KEY_0),
+ KEY(3,5,KEY_HEADSETHOOK),
+ KEY(4,0,KEY_HOME),
+ KEY(4,1,KEY_1),
+ KEY(4,2,KEY_4),
+ KEY(4,3,KEY_7),
+ KEY(4,4,KEY_STAR),
+ KEY(4,5,KEY_POWER),
+ 0
+};
+
static struct resource smc91x_resources[] = {
[0] = {
.start = H2P2_DBG_FPGA_ETHR_START, /* Physical */
@@ -126,10 +162,35 @@ static struct platform_device smc91x_dev
.resource = smc91x_resources,
};
+static struct resource kp_resources[] = {
+ [0] = {
+ .start = INT_730_MPUIO_KEYPAD,
+ .end = INT_730_MPUIO_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct omap_kp_platform_data kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap = p2_keymap,
+};
+
+static struct platform_device kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &kp_data,
+ },
+ .num_resources = ARRAY_SIZE(kp_resources),
+ .resource = kp_resources,
+};
+
static struct platform_device *devices[] __initdata = {
&nor_device,
&nand_device,
&smc91x_device,
+ &kp_device,
};
#define P2_NAND_RB_GPIO_PIN 62
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 6a5e88d..c0f12a4 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -17,6 +17,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/delay.h>
+#include <linux/input.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -29,11 +30,46 @@
#include <asm/arch/usb.h>
#include <asm/arch/board.h>
#include <asm/arch/common.h>
+#include <asm/arch/keypad.h>
#include "prcm-regs.h"
#include <asm/io.h>
#include <asm/delay.h>
+static int h4_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_A),
+ KEY(0, 3, KEY_B),
+ KEY(0, 4, KEY_C),
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_E),
+ KEY(1, 3, KEY_F),
+ KEY(1, 4, KEY_G),
+ KEY(2, 0, KEY_ENTER),
+ KEY(2, 1, KEY_I),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_K),
+ KEY(2, 4, KEY_3),
+ KEY(3, 0, KEY_M),
+ KEY(3, 1, KEY_N),
+ KEY(3, 2, KEY_O),
+ KEY(3, 3, KEY_P),
+ KEY(3, 4, KEY_Q),
+ KEY(4, 0, KEY_R),
+ KEY(4, 1, KEY_4),
+ KEY(4, 2, KEY_T),
+ KEY(4, 3, KEY_U),
+ KEY(4, 4, KEY_ENTER),
+ KEY(5, 0, KEY_V),
+ KEY(5, 1, KEY_W),
+ KEY(5, 2, KEY_L),
+ KEY(5, 3, KEY_S),
+ KEY(5, 4, KEY_ENTER),
+ 0
+};
+
static struct mtd_partition h4_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -108,9 +144,25 @@ static struct platform_device h4_smc91x_
.resource = h4_smc91x_resources,
};
+static struct omap_kp_platform_data h4_kp_data = {
+ .rows = 6,
+ .cols = 7,
+ .keymap = h4_keymap,
+ .rep = 1,
+};
+
+static struct platform_device h4_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &h4_kp_data,
+ },
+};
+
static struct platform_device *h4_devices[] __initdata = {
&h4_smc91x_device,
&h4_flash_device,
+ &h4_kp_device,
};
static inline void __init h4_init_smc91x(void)
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index ea46548..ab4eaae 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -54,6 +54,26 @@ MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c,
MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
+/* Keypad GPIO*/
+MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1)
+MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1)
+MUX_CFG_24XX("V18_24XX_KBR2", 0x139, 3, 1, 1, 1)
+MUX_CFG_24XX("M21_24XX_KBR3", 0xc9, 3, 1, 1, 1)
+MUX_CFG_24XX("E5__24XX_KBR4", 0x138, 3, 1, 1, 1)
+MUX_CFG_24XX("M18_24XX_KBR5", 0x10e, 3, 1, 1, 1)
+MUX_CFG_24XX("R20_24XX_KBC0", 0x108, 3, 0, 0, 1)
+MUX_CFG_24XX("M14_24XX_KBC1", 0x109, 3, 0, 0, 1)
+MUX_CFG_24XX("H19_24XX_KBC2", 0x114, 3, 0, 0, 1)
+MUX_CFG_24XX("V17_24XX_KBC3", 0x135, 3, 0, 0, 1)
+MUX_CFG_24XX("P21_24XX_KBC4", 0xca, 3, 0, 0, 1)
+MUX_CFG_24XX("L14_24XX_KBC5", 0x10f, 3, 0, 0, 1)
+MUX_CFG_24XX("N19_24XX_KBC6", 0x110, 3, 0, 0, 1)
+
+/* 24xx Meneluase Keypad GPIO */
+MUX_CFG_24XX("B3__24XX_KBR5", 0x30, 3, 1, 1, 1)
+MUX_CFG_24XX("AA4_24XX_KBC2", 0xe7, 3, 0, 0, 1)
+MUX_CFG_24XX("B13_24XX_KBC6", 0x110, 3, 0, 0, 1)
+
};
int __init omap2_mux_init(void)
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 1bb1058..cc22364 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -24,6 +24,7 @@
#include <asm/arch/board.h>
#include <asm/arch/mux.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/menelaus.h>
void omap_nop_release(struct device *dev)
@@ -126,6 +127,26 @@ static void omap_init_kp(void)
omap_cfg_reg(E4_730_KBC2);
omap_cfg_reg(F4_730_KBC3);
omap_cfg_reg(E3_730_KBC4);
+ } else if (machine_is_omap_h4()) {
+ omap_cfg_reg(T19_24XX_KBR0);
+ omap_cfg_reg(R19_24XX_KBR1);
+ omap_cfg_reg(V18_24XX_KBR2);
+ omap_cfg_reg(M21_24XX_KBR3);
+ omap_cfg_reg(E5__24XX_KBR4);
+ if (omap_has_menelaus()) {
+ omap_cfg_reg(B3__24XX_KBR5);
+ omap_cfg_reg(AA4_24XX_KBC2);
+ omap_cfg_reg(B13_24XX_KBC6);
+ } else {
+ omap_cfg_reg(M18_24XX_KBR5);
+ omap_cfg_reg(H19_24XX_KBC2);
+ omap_cfg_reg(N19_24XX_KBC6);
+ }
+ omap_cfg_reg(R20_24XX_KBC0);
+ omap_cfg_reg(M14_24XX_KBC1);
+ omap_cfg_reg(V17_24XX_KBC3);
+ omap_cfg_reg(P21_24XX_KBC4);
+ omap_cfg_reg(L14_24XX_KBC5);
}
}
#else
diff --git a/drivers/char/omap-rtc.c b/drivers/char/omap-rtc.c
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index a52757c..303915d 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -196,7 +196,7 @@ config KEYBOARD_HIL
config KEYBOARD_OMAP
tristate "TI OMAP keypad support"
- depends on ARCH_OMAP1
+ depends on (ARCH_OMAP1 || ARCH_OMAP2)
help
Say Y here if you want to use the OMAP keypad.
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 15351bb..95c6967 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -35,6 +35,8 @@
#include <asm/arch/irqs.h>
#include <asm/arch/gpio.h>
#include <asm/arch/hardware.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/menelaus.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <asm/mach-types.h>
@@ -42,60 +44,30 @@
#undef NEW_BOARD_LEARNING_MODE
+#ifdef CONFIG_MACH_OMAP_H4
+#define NUM_ROWS 6
+#define NUM_COLS 7
+#else
+#define NUM_ROWS 8
+#define NUM_COLS 8
+#endif
+
static void omap_kp_tasklet(unsigned long);
static void omap_kp_timer(unsigned long);
static unsigned char keypad_state[8];
-static unsigned int keypad_irq = INT_KEYBOARD;
+
+static unsigned int row_gpio_num[NUM_ROWS] = { 88, 89, 124, 11, 6, 96 };
+static unsigned int col_gpio_num[NUM_COLS] = { 90, 91, 100, 36, 12, 97, 98 };
struct omap_kp {
struct input_dev *input;
struct timer_list timer;
+ unsigned int irq;
};
DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
-#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
-
-static int h2_keymap[] = {
- KEY(0, 0, KEY_LEFT),
- KEY(0, 1, KEY_RIGHT),
- KEY(0, 2, KEY_3),
- KEY(0, 3, KEY_F10),
- KEY(0, 4, KEY_F5),
- KEY(0, 5, KEY_9),
- KEY(1, 0, KEY_DOWN),
- KEY(1, 1, KEY_UP),
- KEY(1, 2, KEY_2),
- KEY(1, 3, KEY_F9),
- KEY(1, 4, KEY_F7),
- KEY(1, 5, KEY_0),
- KEY(2, 0, KEY_ENTER),
- KEY(2, 1, KEY_6),
- KEY(2, 2, KEY_1),
- KEY(2, 3, KEY_F2),
- KEY(2, 4, KEY_F6),
- KEY(2, 5, KEY_HOME),
- KEY(3, 0, KEY_8),
- KEY(3, 1, KEY_5),
- KEY(3, 2, KEY_F12),
- KEY(3, 3, KEY_F3),
- KEY(3, 4, KEY_F8),
- KEY(3, 5, KEY_END),
- KEY(4, 0, KEY_7),
- KEY(4, 1, KEY_4),
- KEY(4, 2, KEY_F11),
- KEY(4, 3, KEY_F1),
- KEY(4, 4, KEY_F4),
- KEY(4, 5, KEY_ESC),
- KEY(5, 0, KEY_F13),
- KEY(5, 1, KEY_F14),
- KEY(5, 2, KEY_F15),
- KEY(5, 3, KEY_F16),
- KEY(5, 4, KEY_SLEEP),
- 0
-};
-
static int test_keymap[] = {
KEY(0, 0, KEY_F4),
KEY(1, 0, KEY_LEFT),
@@ -109,73 +81,44 @@ static int test_keymap[] = {
0
};
-static int innovator_keymap[] = {
- KEY(0, 0, KEY_F1),
- KEY(0, 3, KEY_DOWN),
- KEY(1, 1, KEY_F2),
- KEY(1, 2, KEY_RIGHT),
- KEY(2, 0, KEY_F3),
- KEY(2, 1, KEY_F4),
- KEY(2, 2, KEY_UP),
- KEY(3, 2, KEY_ENTER),
- KEY(3, 3, KEY_LEFT),
- 0
-};
+static int *keymap;
-static int osk_keymap[] = {
- KEY(0, 0, KEY_F1),
- KEY(0, 3, KEY_UP),
- KEY(1, 1, KEY_LEFTCTRL),
- KEY(1, 2, KEY_LEFT),
- KEY(2, 0, KEY_SPACE),
- KEY(2, 1, KEY_ESC),
- KEY(2, 2, KEY_DOWN),
- KEY(3, 2, KEY_ENTER),
- KEY(3, 3, KEY_RIGHT),
- 0
-};
-
-static int p2_keymap[] = {
- KEY(0,0,KEY_UP),
- KEY(0,1,KEY_RIGHT),
- KEY(0,2,KEY_LEFT),
- KEY(0,3,KEY_DOWN),
- KEY(0,4,KEY_CENTER),
- KEY(0,5,KEY_0_5),
- KEY(1,0,KEY_SOFT2),
- KEY(1,1,KEY_SEND),
- KEY(1,2,KEY_END),
- KEY(1,3,KEY_VOLUMEDOWN),
- KEY(1,4,KEY_VOLUMEUP),
- KEY(1,5,KEY_RECORD),
- KEY(2,0,KEY_SOFT1),
- KEY(2,1,KEY_3),
- KEY(2,2,KEY_6),
- KEY(2,3,KEY_9),
- KEY(2,4,KEY_SHARP),
- KEY(2,5,KEY_2_5),
- KEY(3,0,KEY_BACK),
- KEY(3,1,KEY_2),
- KEY(3,2,KEY_5),
- KEY(3,3,KEY_8),
- KEY(3,4,KEY_0),
- KEY(3,5,KEY_HEADSETHOOK),
- KEY(4,0,KEY_HOME),
- KEY(4,1,KEY_1),
- KEY(4,2,KEY_4),
- KEY(4,3,KEY_7),
- KEY(4,4,KEY_STAR),
- KEY(4,5,KEY_POWER),
- 0
-};
+static void set_col_gpio_val(u8 value)
+{
+ int col;
-static int *keymap;
+ for (col = 0; col < NUM_COLS; col++) {
+ if (value & (1 << col))
+ omap_set_gpio_dataout(col_gpio_num[col], 1);
+ else
+ omap_set_gpio_dataout(col_gpio_num[col], 0);
+ }
+}
+
+static u8 get_row_gpio_val(void)
+{
+ int row;
+ u8 value = 0;
+
+ for (row = 0; row < NUM_ROWS; row++) {
+ if (omap_get_gpio_datain(row_gpio_num[row]))
+ value |= (1 << row);
+ }
+ return value;
+}
static irqreturn_t omap_kp_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
/* disable keyboard interrupt and schedule for handling */
- omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ if (machine_is_omap_h4()) {
+ int i;
+ for (i = 0; i < NUM_ROWS; i++)
+ disable_irq(OMAP_GPIO_IRQ(row_gpio_num[i]));
+ } else {
+ /* disable keyboard interrupt and schedule for handling */
+ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ }
tasklet_schedule(&kp_tasklet);
return IRQ_HANDLED;
@@ -190,21 +133,29 @@ static void omap_kp_scan_keypad(unsigned
{
int col = 0;
- /* read the keypad status */
- omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
- for (col = 0; col < 8; col++) {
- omap_writew(~(1 << col) & 0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
-
- if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()) {
- udelay(9);
- } else {
- udelay(4);
+ if (!machine_is_omap_h4()) {
+ /* read the keypad status */
+ omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+ for (col = 0; col < 8; col++) {
+ omap_writew(~(1 << col) & 0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+
+ if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()) {
+ udelay(9);
+ } else {
+ udelay(4);
+ }
+ state[col] = ~omap_readw(OMAP_MPUIO_BASE + OMAP_MPUIO_KBR_LATCH) & 0xff;
}
-
- state[col] = ~omap_readw(OMAP_MPUIO_BASE + OMAP_MPUIO_KBR_LATCH) & 0xff;
+ omap_writew(0x00, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+ udelay(2);
+ } else {
+ /* read the keypad status */
+ for (col = 0; col < NUM_COLS; col++) {
+ set_col_gpio_val(~(1 << col));
+ state[col] = ~(get_row_gpio_val()) & 0x3f;
+ }
+ set_col_gpio_val(0);
}
- omap_writew(0x00, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
- udelay(2);
}
static inline int omap_kp_find_key(int col, int row)
@@ -221,7 +172,7 @@ static inline int omap_kp_find_key(int c
static void omap_kp_tasklet(unsigned long data)
{
struct omap_kp *omap_kp_data = (struct omap_kp *) data;
- unsigned char new_state[8], changed, key_down = 0;
+ unsigned char new_state[NUM_COLS], changed, key_down = 0;
int col, row;
int spurious = 0;
@@ -229,13 +180,13 @@ static void omap_kp_tasklet(unsigned lon
omap_kp_scan_keypad(new_state);
/* check for changes and print those */
- for (col = 0; col < 8; col++) {
+ for (col = 0; col < NUM_COLS; col++) {
changed = new_state[col] ^ keypad_state[col];
key_down |= new_state[col];
if (changed == 0)
continue;
- for (row = 0; row < 8; row++) {
+ for (row = 0; row < NUM_ROWS; row++) {
int key;
if (!(changed & (1 << row)))
continue;
@@ -266,8 +217,14 @@ static void omap_kp_tasklet(unsigned lon
delay = 2 * HZ;
mod_timer(&omap_kp_data->timer, jiffies + delay);
} else {
- /* enable interrupts */
- omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ if (machine_is_omap_h4()) {
+ int i;
+ for (i = 0; i < NUM_ROWS; i++)
+ enable_irq(OMAP_GPIO_IRQ(row_gpio_num[i]));
+ } else {
+ /* enable interrupts */
+ omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ }
}
}
@@ -294,6 +251,8 @@ static int __init omap_kp_probe(struct p
{
struct omap_kp *omap_kp;
struct input_dev *input_dev;
+ struct omap_kp_platform_data *pdata =
+ pdev->dev.platform_data;
int i;
omap_kp = kzalloc(sizeof(struct omap_kp), GFP_KERNEL);
@@ -309,20 +268,46 @@ static int __init omap_kp_probe(struct p
omap_kp->input = input_dev;
/* Disable the interrupt for the MPUIO keyboard */
- omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ if (!machine_is_omap_h4())
+ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
- if (machine_is_omap_h2() || machine_is_omap_h3()) {
- keymap = h2_keymap;
- set_bit(EV_REP, input_dev->evbit);
- } else if (machine_is_omap_innovator()) {
- keymap = innovator_keymap;
- } else if (machine_is_omap_osk()) {
- keymap = osk_keymap;
- } else if (machine_is_omap_perseus2()) {
- keymap = p2_keymap;
- keypad_irq = INT_730_MPUIO_KEYPAD;
- } else {
+ if (!pdata->keymap)
keymap = test_keymap;
+ else
+ keymap = pdata->keymap;
+
+ if (pdata->rep)
+ set_bit(EV_REP, input_dev->evbit);
+
+ if (machine_is_omap_h4()) {
+ if (omap_has_menelaus()) {
+ row_gpio_num[5] = 0;
+ col_gpio_num[2] = 15;
+ col_gpio_num[6] = 18;
+ }
+ }
+
+ if (machine_is_omap_h4()) {
+ /* Cols: outputs */
+ for (i = 0; i < NUM_COLS; i++) {
+ if (omap_request_gpio(col_gpio_num[i]) < 0) {
+ printk(KERN_ERR "Failed to request"
+ "GPIO%d for keypad\n",
+ col_gpio_num[i]);
+ return -EINVAL;
+ }
+ omap_set_gpio_direction(col_gpio_num[i], 0);
+ }
+ /* Rows: inputs */
+ for (i = 0; i < NUM_ROWS; i++) {
+ if (omap_request_gpio(row_gpio_num[i]) < 0) {
+ printk(KERN_ERR "Failed to request"
+ "GPIO%d for keypad\n",
+ row_gpio_num[i]);
+ return -EINVAL;
+ }
+ omap_set_gpio_direction(row_gpio_num[i], 1);
+ }
}
init_timer(&omap_kp->timer);
@@ -331,9 +316,14 @@ static int __init omap_kp_probe(struct p
/* get the irq and init timer*/
tasklet_enable(&kp_tasklet);
- if (request_irq(keypad_irq, omap_kp_interrupt, 0,
- "omap-keypad", 0) < 0)
- return -EINVAL;
+ kp_tasklet.data = (unsigned long) omap_kp;
+
+ omap_kp->irq = platform_get_irq(pdev, 0);
+ if (omap_kp->irq) {
+ if (request_irq(omap_kp->irq, omap_kp_interrupt, 0,
+ "omap-keypad", 0) < 0)
+ return -EINVAL;
+ }
/* setup input device */
set_bit(EV_KEY, input_dev->evbit);
@@ -350,8 +340,17 @@ static int __init omap_kp_probe(struct p
}
/* scan current status and enable interrupt */
omap_kp_scan_keypad(keypad_state);
- omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ if (!machine_is_omap_h4()) {
+ omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ } else {
+ for (i = 0; i < NUM_ROWS; i++) {
+ if (request_irq(OMAP_GPIO_IRQ(row_gpio_num[i]), omap_kp_interrupt, 0,
+ "omap-keypad", 0) < 0)
+ return -EINVAL;
+ set_irq_type(OMAP_GPIO_IRQ(row_gpio_num[i]), IRQT_FALLING);
+ }
+ }
return 0;
}
@@ -361,9 +360,19 @@ static int omap_kp_remove(struct platfor
/* disable keypad interrupt handling */
tasklet_disable(&kp_tasklet);
- omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ if (machine_is_omap_h4()) {
+ int i;
+ for (i = 0; i < NUM_COLS; i++)
+ omap_free_gpio(col_gpio_num[i]);
+ for (i = 0; i < NUM_ROWS; i++) {
+ omap_free_gpio(row_gpio_num[i]);
+ free_irq(OMAP_GPIO_IRQ(row_gpio_num[i]), 0);
+ }
+ } else {
+ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+ free_irq(omap_kp->irq, 0);
+ }
- free_irq(keypad_irq, 0);
del_timer_sync(&omap_kp->timer);
/* unregister everything */
diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
diff --git a/include/asm-arm/arch-omap/keypad.h b/include/asm-arm/arch-omap/keypad.h
new file mode 100644
index 0000000..5884529
--- /dev/null
+++ b/include/asm-arm/arch-omap/keypad.h
@@ -0,0 +1,13 @@
+#ifndef ASMARM_ARCH_KEYPAD_H
+#define ASMARM_ARCH_KEYPAD_H
+
+struct omap_kp_platform_data {
+ int rows;
+ int cols;
+ int *keymap;
+ unsigned int rep:1;
+};
+
+#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
+
+#endif
diff --git a/include/asm-arm/arch-omap/menelaus.h b/include/asm-arm/arch-omap/menelaus.h
diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
index 8d1c62e..a9ec625 100644
--- a/include/asm-arm/arch-omap/mux.h
+++ b/include/asm-arm/arch-omap/mux.h
@@ -410,6 +410,27 @@ enum omap24xx_index {
/* 24xx GPIO */
Y20_24XX_GPIO60,
M15_24XX_GPIO92,
+
+
+ /* Keypad GPIO*/
+ T19_24XX_KBR0,
+ R19_24XX_KBR1,
+ V18_24XX_KBR2,
+ M21_24XX_KBR3,
+ E5__24XX_KBR4,
+ M18_24XX_KBR5,
+ R20_24XX_KBC0,
+ M14_24XX_KBC1,
+ H19_24XX_KBC2,
+ V17_24XX_KBC3,
+ P21_24XX_KBC4,
+ L14_24XX_KBC5,
+ N19_24XX_KBC6,
+
+ /* 24xx Meneluas Keypad GPIO */
+ B3__24XX_KBR5,
+ AA4_24XX_KBC2,
+ B13_24XX_KBC6,
};
#ifdef CONFIG_OMAP_MUX
diff --git a/include/asm-arm/arch-pxa/mmc.h b/include/asm-arm/arch-pxa/mmc.h
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] keypad: platform_data and 24xx support -exp
2005-12-10 13:02 [PATCH] keypad: platform_data and 24xx support -exp Komal Shah
@ 2006-01-14 0:37 ` Tony Lindgren
2006-01-14 2:04 ` lamikr
0 siblings, 1 reply; 5+ messages in thread
From: Tony Lindgren @ 2006-01-14 0:37 UTC (permalink / raw)
To: Komal Shah; +Cc: linux-omap-open-source
* Komal Shah <komal_shah802003@yahoo.com> [051210 05:03]:
> Tony/Brian,
>
> I have attached patch which includes:
>
> o Modification suggested by Brian Swetland
> o Added platform_data structure
> - keymap is moved to appropriate board files.
> - rows and cols fields are not used in the driver yet.
> - rep bit is added.
> o IRQ resource
> o Added 24xx+menelaus keypad support - tested.
>
> TODO/FIXME:
> o appropriate place for test_keymap.
>
> o Removing NUM_COLS/ROWS #defines and replacing with
> platform_data->rows/cols.
>
> o Moving request_gpio/free_gpio to board specific file, by introducing
> one function in platform_data ? Is this ok? e.g get/put_gpios. As
> driver should work as module too.
>
> o How to handle row_/col_gpio_num array and set_/get_gpio_val functions
> ? I want to keep them out of this keypad.c. Any suggestions?
I like this patch, takes care of the keypad mapping problems nicely.
Can you please refresh it?
Tony
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] keypad: platform_data and 24xx support -exp
2006-01-14 0:37 ` Tony Lindgren
@ 2006-01-14 2:04 ` lamikr
2006-01-20 23:02 ` Tony Lindgren
0 siblings, 1 reply; 5+ messages in thread
From: lamikr @ 2006-01-14 2:04 UTC (permalink / raw)
To: Tony Lindgren; +Cc: linux-omap-open-source
[-- Attachment #1: Type: text/plain, Size: 1205 bytes --]
Has anybody needed a joypad driver for the omap-boards?
I have made changes to keypad driver so that it will support h6300 joypad ok, but I think my approach is a little bit hackish.
The iPAQ h6300 joypad has 5 sensors that are located in following diagonal locations
UL - Up/Left
DL - Down/Left
DR - Down/Right
UR - Up/Right
CT - Center
If I press the key-pad for example to North, the joypad will generate 3 keydown events. (CT, UL and UR)
Same logic applies to all 4 main directions both when the key is pressed down or released.
Therefore I have put the driver to listen the real sensor events, but instead of sending them to userspace
I will calculate a "virtual" key event (up, right, down or left) and send that to the userspace.
I am not yet proposing this patch to be applied to omap kernel, but would anyway like to hear
some suggestions how to handle this kind of situation.
Mika
>I like this patch, takes care of the keypad mapping problems nicely.
>Can you please refresh it?
>
>Tony
>_______________________________________________
>Linux-omap-open-source mailing list
>Linux-omap-open-source@linux.omap.com
>http://linux.omap.com/mailman/listinfo/linux-omap-open-source
>
>
>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: h6300_omap_keypad.patch --]
[-- Type: text/x-patch; name="h6300_omap_keypad.patch", Size: 10009 bytes --]
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 7e851e2..157ef8d 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -5,10 +5,11 @@
*
* Copyright (C) 2003 Nokia Corporation
* Written by Timo Teräs <ext-timo.teras@nokia.com>
+ * iPAQ h6300 key and joypad support added by Mika Laitio. (2005)
*
* Added support for H2 & H3 Keypad
* Copyright (C) 2004 Texas Instruments
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -41,13 +42,16 @@
#include <asm/arch/mux.h>
#undef NEW_BOARD_LEARNING_MODE
+//#define NEW_BOARD_LEARNING_MODE 1
static void omap_kp_tasklet(unsigned long);
-static void omap_kp_timer(unsigned long);
+static void omap_§kp_timer(unsigned long);
static unsigned char keypad_state[8];
static unsigned int keypad_irq = INT_KEYBOARD;
+static int prevJoypadKeycodePressEmulated;
+
struct omap_kp {
struct input_dev *input;
struct timer_list timer;
@@ -169,6 +173,47 @@ static int p2_keymap[] = {
0
};
+#define _h6300_KEY_CALENDAR 67 // xmodmap 75 aka F9
+#define _H6300_KEY_TELEPHONE 68 // xmodmap 76 aka F10
+#define _H6300_KEY_HOMEPAGE 87 // xmodmap 87 aka Num_Lock
+#define _H6300_KEY_MAIL 88 // xmodmap 88 aka Scroll_Lock
+
+/*
+ * Following 5 keypad events are not really sent to userspace.
+ * Instead if the good combination of them is sent, then that is send.
+ * (up, right, down, left, enter)
+ */
+#define _H6300_JOYPAD_UP_RIGHT 1 // 00001
+#define _H6300_JOYPAD_DOWN_RIGHT 2 // 00010
+#define _h6300_JOYPAD_DOWN_LEFT 4 // 00100
+#define _h6300_JOYPAD_UP_LEFT 8 // 01000
+#define _H6300_JOYPAD_KEY_OK 16 // 10000
+
+static int h6300_keymap[] = {
+ KEY(2, 0, _h6300_KEY_CALENDAR), // address button in the bottom left
+ KEY(2, 3, _H6300_KEY_TELEPHONE), // start call button in the bottom
+ KEY(3, 1, _H6300_KEY_HOMEPAGE), // stop call button in the bottom
+ KEY(3, 4, _H6300_KEY_MAIL), // messaging button in the bottom right
+
+ KEY(0, 0, KEY_VOLUMEUP), // volume up button in the right side
+ KEY(0, 1, KEY_VOLUMEDOWN), // volume down button in the right side
+ KEY(3, 2, KEY_RECORD), // record button in the left side
+
+ KEY(1, 0, _h6300_JOYPAD_UP_LEFT),
+ KEY(1, 1, _h6300_JOYPAD_DOWN_LEFT),
+ KEY(1, 2, _H6300_JOYPAD_KEY_OK),
+ KEY(1, 3, _H6300_JOYPAD_DOWN_RIGHT),
+ KEY(1, 4, _H6300_JOYPAD_UP_RIGHT),
+
+ KEY(5, 0, KEY_RIGHT),
+ KEY(5, 1, KEY_DOWN),
+ KEY(5, 2, KEY_LEFT),
+ KEY(5, 3, KEY_UP),
+ KEY(5, 4, KEY_ENTER),
+
+ 0
+};
+
static int *keymap;
static irqreturn_t omap_kp_interrupt(int irq, void *dev_id,
@@ -195,7 +240,8 @@ static void omap_kp_scan_keypad(unsigned
for (col = 0; col < 8; col++) {
omap_writew(~(1 << col) & 0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
- if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()) {
+ if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3() || machine_is_h6300()) {
+ // makes keyboard act a little bit slower
udelay(9);
} else {
udelay(4);
@@ -218,17 +264,26 @@ static inline int omap_kp_find_key(int c
return -1;
}
+int is_key_down(unsigned char new_state[],
+ int col,
+ int row)
+{
+ return (new_state[col] & (1 << row)) ? 1 : 0;
+}
+
static void omap_kp_tasklet(unsigned long data)
{
struct omap_kp *omap_kp_data = (struct omap_kp *) data;
unsigned char new_state[8], changed, key_down = 0;
int col, row;
int spurious = 0;
+ int report_key, report_col, report_row, joypad_checked; // h6300-joypad specific variables
/* check for any changes */
omap_kp_scan_keypad(new_state);
/* check for changes and print those */
+ joypad_checked = 0;
for (col = 0; col < 8; col++) {
changed = new_state[col] ^ keypad_state[col];
key_down |= new_state[col];
@@ -250,9 +305,173 @@ static void omap_kp_tasklet(unsigned lon
spurious = 1;
continue;
}
-
- input_report_key(omap_kp_data->input, key,
- new_state[col] & (1 << row));
+ if (machine_is_h6300() &&
+ ((col == 1) || (col == 5)))
+ {
+ if (col == 5)
+ {
+ continue;
+ }
+ if ((joypad_checked == 0) &&
+ ((key == _H6300_JOYPAD_KEY_OK) ||
+ (key == _h6300_JOYPAD_UP_LEFT) ||
+ (key == _H6300_JOYPAD_UP_RIGHT) ||
+ (key == _H6300_JOYPAD_DOWN_RIGHT) ||
+ (key == _h6300_JOYPAD_DOWN_LEFT)))
+ {
+ if (is_key_down(new_state, col, row))
+ {
+ /*
+ * only enter pressed
+ * 1 0 0 _H6300_JOYPAD_KEY_OK 0 0
+ * --> 100100 == 36
+ */
+ if (new_state[1] == 36)
+ {
+ joypad_checked = 1;
+ prevJoypadKeycodePressEmulated = KEY_ENTER;
+ new_state[5] = 48; //110000
+ report_key = prevJoypadKeycodePressEmulated;
+ report_col = 5;
+ report_row = 4;
+ input_report_key(omap_kp_data->input,
+ report_key,
+ new_state[report_col] & (1 << report_row));
+ }
+ /*
+ * enter, up_left and up_right sensors pressed.
+ * 1 _H6300_JOYPAD_UP_RIGHT 0 _H6300_JOYPAD_KEY_OK 0 _h6300_JOYPAD_UP_LEFT
+ * --> 110101 == 53
+ * OR
+ * 1 KEY_UP_RIGHT 0 0 0 _h6300_JOYPAD_UP_LEFT
+ * --> 110001 == 42
+ * --> move to up
+ */
+ else if ((new_state[1] == 53) ||
+ (new_state[1] == 49))
+ {
+ joypad_checked = 1;
+ prevJoypadKeycodePressEmulated = KEY_UP;
+ new_state[5] = 40; //101000
+ report_key = prevJoypadKeycodePressEmulated;
+ report_col = 5;
+ report_row = 3;
+ input_report_key(omap_kp_data->input,
+ report_key,
+ new_state[report_col] & (1 << report_row));
+ }
+ /*
+ * enter, down_left and down_right sensors pressed
+ * --> 101110 == 46
+ * OR
+ * down_left and down_right
+ * -->101010 == 42
+ * --> move to down
+ */
+ else if ((new_state[1] == 46) ||
+ (new_state[1] == 42))
+ {
+ joypad_checked = 1;
+ prevJoypadKeycodePressEmulated = KEY_DOWN;
+ new_state[5] = 34; //100010
+ report_key = prevJoypadKeycodePressEmulated;
+ report_col = 5;
+ report_row = 1;
+ input_report_key(omap_kp_data->input,
+ report_key,
+ new_state[report_col] & (1 << report_row));
+ }
+ /*
+ * enter, up_right and down_right sensors pressed
+ * --> 111100 == 60
+ * or
+ * down_right and up_right
+ * --> 111000 == 56
+ * --> move to right
+ */
+ else if ((new_state[1] == 60) ||
+ (new_state[1] == 56))
+ {
+ joypad_checked = 1;
+ prevJoypadKeycodePressEmulated = KEY_RIGHT;
+ new_state[5] = 33; //100001
+ report_key = prevJoypadKeycodePressEmulated;
+ report_col = 5;
+ report_row = 0;
+ input_report_key(omap_kp_data->input,
+ report_key,
+ new_state[report_col] & (1 << report_row));
+ }
+ /*
+ * enter, up_left and down_left sensors pressed
+ * --> 100111 == 39
+ * or up_left and down_left
+ * --> 100011 == 35
+ * --> move to left
+ */
+ else if ((new_state[1] == 39) ||
+ (new_state[1] == 35))
+ {
+ joypad_checked = 1;
+ prevJoypadKeycodePressEmulated = KEY_LEFT;
+ new_state[5] = 36; //100100
+ report_key = prevJoypadKeycodePressEmulated;
+ report_col = 5;
+ report_row = 2;
+ input_report_key(omap_kp_data->input,
+ report_key,
+ new_state[report_col] & (1 << report_row));
+ }
+ else
+ {
+ //printk("missed new_state = %d\n", new_state[1]);
+ }
+ }
+ else
+ {
+ if (prevJoypadKeycodePressEmulated != 0)
+ {
+ // report key up event
+ joypad_checked = 1;
+ new_state[5] = 32; //100000
+ report_key = prevJoypadKeycodePressEmulated;
+ report_col = 5;
+ switch(prevJoypadKeycodePressEmulated)
+ {
+ case KEY_RIGHT:
+ report_row = 0;
+ break;
+ case KEY_DOWN:
+ report_row = 1;
+ break;
+ case KEY_LEFT:
+ report_row = 2;
+ break;
+ case KEY_UP:
+ report_row = 3;
+ break;
+ case KEY_ENTER:
+ report_row = 4;
+ break;
+ default:
+ printk(KERN_WARNING "Unknown iPAQ h6300 column 1 key = %d released. This should newer happen!\n",
+ key);
+ report_row = 0;
+ }
+ input_report_key(omap_kp_data->input,
+ report_key,
+ new_state[report_col] & (1 << report_row));
+ prevJoypadKeycodePressEmulated = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ input_report_key(omap_kp_data->input, // &omap_kp_dev,
+ key,
+ new_state[col] & (1 << row));
+ }
#endif
}
}
@@ -321,9 +540,15 @@ static int __init omap_kp_probe(struct p
} else if (machine_is_omap_perseus2()) {
keymap = p2_keymap;
keypad_irq = INT_730_MPUIO_KEYPAD;
+ } else if (machine_is_h6300()) {
+ keymap = h6300_keymap;
+ // set keyboard to send repeated key events if key is hold down
+ set_bit(EV_REP, §.evbit);
} else {
+ printk("omap_keypad.c, keyMap = test_keymap\n");
keymap = test_keymap;
}
+ prevJoypadKeycodePressEmulated = 0;
init_timer(&omap_kp->timer);
omap_kp->timer.function = omap_kp_timer;
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] keypad: platform_data and 24xx support -exp
2006-01-14 2:04 ` lamikr
@ 2006-01-20 23:02 ` Tony Lindgren
2006-01-20 23:27 ` lamikr
0 siblings, 1 reply; 5+ messages in thread
From: Tony Lindgren @ 2006-01-20 23:02 UTC (permalink / raw)
To: lamikr; +Cc: linux-omap-open-source
Hi Mika,
* lamikr <lamikr@cc.jyu.fi> [060113 17:57]:
> Has anybody needed a joypad driver for the omap-boards?
> I have made changes to keypad driver so that it will support h6300 joypad ok, but I think my approach is a little bit hackish.
> The iPAQ h6300 joypad has 5 sensors that are located in following diagonal locations
>
> UL - Up/Left
> DL - Down/Left
> DR - Down/Right
> UR - Up/Right
> CT - Center
>
> If I press the key-pad for example to North, the joypad will generate 3 keydown events. (CT, UL and UR)
> Same logic applies to all 4 main directions both when the key is pressed down or released.
> Therefore I have put the driver to listen the real sensor events, but instead of sending them to userspace
> I will calculate a "virtual" key event (up, right, down or left) and send that to the userspace.
>
> I am not yet proposing this patch to be applied to omap kernel, but would anyway like to hear
> some suggestions how to handle this kind of situation.
Maybe you could update it now against the current git tree?
Now that all the key mappings are done in board-*.c files it should be
easy to add support for h6300 too.
Tony
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] keypad: platform_data and 24xx support -exp
2006-01-20 23:02 ` Tony Lindgren
@ 2006-01-20 23:27 ` lamikr
0 siblings, 0 replies; 5+ messages in thread
From: lamikr @ 2006-01-20 23:27 UTC (permalink / raw)
To: Tony Lindgren; +Cc: linux-omap-open-source
Yes, I will to pull the latest changes from git and try to make the merge soon.
There is still couple of issues we want to resolve before starting to submit h6300 patches.
Mika
Tony Lindgren wrote:
>Hi Mika,
>
>* lamikr <lamikr@cc.jyu.fi> [060113 17:57]:
>
>
>>Has anybody needed a joypad driver for the omap-boards?
>>I have made changes to keypad driver so that it will support h6300 joypad ok, but I think my approach is a little bit hackish.
>>The iPAQ h6300 joypad has 5 sensors that are located in following diagonal locations
>>
>> UL - Up/Left
>> DL - Down/Left
>> DR - Down/Right
>> UR - Up/Right
>> CT - Center
>>
>>If I press the key-pad for example to North, the joypad will generate 3 keydown events. (CT, UL and UR)
>>Same logic applies to all 4 main directions both when the key is pressed down or released.
>>Therefore I have put the driver to listen the real sensor events, but instead of sending them to userspace
>>I will calculate a "virtual" key event (up, right, down or left) and send that to the userspace.
>>
>>I am not yet proposing this patch to be applied to omap kernel, but would anyway like to hear
>>some suggestions how to handle this kind of situation.
>>
>>
>
>Maybe you could update it now against the current git tree?
>
>Now that all the key mappings are done in board-*.c files it should be
>easy to add support for h6300 too.
>
>Tony
>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-01-20 23:27 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-10 13:02 [PATCH] keypad: platform_data and 24xx support -exp Komal Shah
2006-01-14 0:37 ` Tony Lindgren
2006-01-14 2:04 ` lamikr
2006-01-20 23:02 ` Tony Lindgren
2006-01-20 23:27 ` lamikr
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox