summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2010-05-28 15:07:47 +0530
committerGary King <gking@nvidia.com>2010-05-28 08:55:56 -0700
commit78edd4a2d67fdd8907afdb596fc9993356668512 (patch)
treecd30f1f70585b39f88bd6effc3089dd8a4263208
parente0b21639f2b6aa8fa51558853a0519a04abc32ce (diff)
tegra: gpio based keyboard driver for E1206 platform.
Adding the gpio based keyboard driver support for the E1206 based platform. The gpio-key driver will get the platform data from odm. The odm will return gpio pin group information for E1206 based platfrom otherwise return NULL. The gpio pin information is converted to platform data which will be used by the gpio key driver. Tested on harmony and E1206 based board. The keys are working fine in E1206 based platform. Change-Id: I5d8d0949a45155c56f10afbe258d5b329a0fb1ce Reviewed-on: http://git-master/r/1536 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> Tested-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-by: Jitendra Aditya Lanka <jlanka@nvidia.com> Tested-by: Jitendra Aditya Lanka <jlanka@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/configs/tegra_harmony_android_defconfig4
-rw-r--r--arch/arm/mach-tegra/board_nvodm.c38
-rw-r--r--arch/arm/mach-tegra/include/nvodm_query_gpio.h16
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c34
-rw-r--r--arch/arm/mach-tegra/odm_to_plat.c62
5 files changed, 121 insertions, 33 deletions
diff --git a/arch/arm/configs/tegra_harmony_android_defconfig b/arch/arm/configs/tegra_harmony_android_defconfig
index b6f4c1123e82..267b634a2ac8 100644
--- a/arch/arm/configs/tegra_harmony_android_defconfig
+++ b/arch/arm/configs/tegra_harmony_android_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.29
-# Wed May 26 13:21:56 2010
+# Fri May 28 14:52:38 2010
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -866,7 +866,7 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_KEYBOARD_GPIO=y
# CONFIG_KEYBOARD_TEGRA is not set
# CONFIG_KEYBOARD_TEGRA_GPIO is not set
CONFIG_KEYBOARD_TEGRA_NVEC=y
diff --git a/arch/arm/mach-tegra/board_nvodm.c b/arch/arm/mach-tegra/board_nvodm.c
index 1e3ccd349fc7..cfa7f9d68164 100644
--- a/arch/arm/mach-tegra/board_nvodm.c
+++ b/arch/arm/mach-tegra/board_nvodm.c
@@ -28,11 +28,6 @@
#include <linux/i2c.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
-#if defined(CONFIG_KEYBOARD_GPIO)
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
-#include "include/mach/gpio-names.h"
-#endif
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -138,30 +133,9 @@ static struct platform_device tegra_nand_device =
#endif
-#if defined(CONFIG_KEYBOARD_GPIO)
-static struct gpio_keys_button tegra_buttons[] = {
- {
- .gpio = TEGRA_GPIO_PU5,
- .code = SW_LID,
- .desc = "LID",
- .active_low = 0,
- .type = EV_SW,
- .wakeup = 1,
- }
-};
-
-static struct gpio_keys_platform_data tegra_button_data = {
- .buttons = tegra_buttons,
- .nbuttons = ARRAY_SIZE(tegra_buttons),
-};
-
-static struct platform_device tegra_button_device = {
- .name = "gpio-keys",
- .id = 3,
- .dev = {
- .platform_data = &tegra_button_data,
- }
-};
+#ifdef CONFIG_KEYBOARD_GPIO
+extern struct platform_device *get_gpio_key_platform_data(void);
+static struct platform_device *tegra_button_device;
#endif
#ifdef CONFIG_RTC_DRV_TEGRA_ODM
@@ -615,8 +589,10 @@ static void __init tegra_machine_init(void)
tegra_set_voltage( NV_VDD_PEX_CLK_ODM_ID, 0);
#endif
-#if defined(CONFIG_KEYBOARD_GPIO)
- platform_device_register(&tegra_button_device);
+#ifdef CONFIG_KEYBOARD_GPIO
+ tegra_button_device = get_gpio_key_platform_data();
+ if (tegra_button_device)
+ platform_device_register(tegra_button_device);
#endif
pm_power_off = tegra_system_power_off;
diff --git a/arch/arm/mach-tegra/include/nvodm_query_gpio.h b/arch/arm/mach-tegra/include/nvodm_query_gpio.h
index dd6461a2483d..fe69335e99e1 100644
--- a/arch/arm/mach-tegra/include/nvodm_query_gpio.h
+++ b/arch/arm/mach-tegra/include/nvodm_query_gpio.h
@@ -332,6 +332,18 @@ typedef enum
} NvOdmGpioPinActiveState;
/**
+ * Holds the GPIO key information.
+ */
+typedef struct NvOdmGpioPinKeyInfo_t {
+ /// Holds the code of the gpio if used as keys.
+ NvU32 Code;
+ /// Holds the debounce time in ms to stablize the gpio pins state.
+ NvU32 DebounceTimeMs;
+ /// Holds the wakeup state.
+ NvBool Wakeup;
+} NvOdmGpioPinKeyInfo;
+
+/**
* Holds the GPIO pin information.
*/
typedef struct NvOdmGpioPinInfo_t {
@@ -343,6 +355,10 @@ typedef struct NvOdmGpioPinInfo_t {
/// state is defined by each pin. For example, for a USB cable connect virtual pin,
/// the active state is when the cable is connected.
NvOdmGpioPinActiveState activeState;
+
+ /// Holds the gpio pin specific data;
+ void *GpioPinSpecificData;
+
} NvOdmGpioPinInfo;
#define NVODM_GPIO_INVALID_PORT 0xFF
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c
index 8d384db176ee..a8aa460bd103 100644
--- a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c
@@ -33,10 +33,15 @@
#include "nvodm_query_gpio.h"
#include "nvodm_services.h"
#include "nvrm_drf.h"
+#include "nvodm_query_discovery.h"
+
+#include "linux/input.h"
#define NVODM_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define NVODM_PORT(x) ((x) - 'a')
+#define EEPROM_ID_E1206 0x0C06
+
static const NvOdmGpioPinInfo s_vi[] = {
{NVODM_PORT('t'), 3, NvOdmGpioPinActiveState_High}, // EN_VDDIO_SD
};
@@ -153,6 +158,25 @@ static const NvOdmGpioPinInfo s_WakeFromKeyBoard[] = {
{NVODM_PORT('a'), 0, NvOdmGpioPinActiveState_Low} // EC Keyboard Wakeup
};
+// Gpio based keypad
+static const NvOdmGpioPinKeyInfo s_GpioPinKeyInfo[] = {
+ {KEY_MENU, 10, NV_TRUE},
+ {KEY_HOME, 10, NV_TRUE},
+ {KEY_BACK, 10, NV_TRUE},
+ {KEY_F3, 10, NV_TRUE},
+ {KEY_F4, 10, NV_TRUE},
+};
+
+
+// Gpio based keypad
+static const NvOdmGpioPinInfo s_GpioKeyBoard[] = {
+ {NVODM_PORT('q'), 0, NvOdmGpioPinActiveState_Low, (void *)&s_GpioPinKeyInfo[0]},
+ {NVODM_PORT('q'), 1, NvOdmGpioPinActiveState_Low, (void *)&s_GpioPinKeyInfo[1]},
+ {NVODM_PORT('q'), 2, NvOdmGpioPinActiveState_Low, (void *)&s_GpioPinKeyInfo[2]},
+ {NVODM_PORT('q'), 3, NvOdmGpioPinActiveState_Low, (void *)&s_GpioPinKeyInfo[3]},
+ {NVODM_PORT('q'), 4, NvOdmGpioPinActiveState_Low, (void *)&s_GpioPinKeyInfo[4]},
+};
+
static const NvOdmGpioPinInfo s_Battery[] = {
// Low Battery
{NVODM_PORT('w'), 3, NvOdmGpioPinActiveState_Low},
@@ -161,6 +185,7 @@ static const NvOdmGpioPinInfo s_Battery[] = {
const NvOdmGpioPinInfo *NvOdmQueryGpioPinMap(NvOdmGpioPinGroup Group,
NvU32 Instance, NvU32 *pCount)
{
+ NvOdmBoardInfo BoardInfo;
switch (Group)
{
case NvOdmGpioPinGroup_Display:
@@ -229,6 +254,15 @@ const NvOdmGpioPinInfo *NvOdmQueryGpioPinMap(NvOdmGpioPinGroup Group,
*pCount = NVODM_ARRAY_SIZE(s_WakeFromKeyBoard);
return s_WakeFromKeyBoard;
+ case NvOdmGpioPinGroup_keypadMisc:
+ if (NvOdmPeripheralGetBoardInfo(EEPROM_ID_E1206, &BoardInfo))
+ {
+ *pCount = NVODM_ARRAY_SIZE(s_GpioKeyBoard);
+ return s_GpioKeyBoard;
+ }
+ *pCount = 0;
+ return NULL;
+
case NvOdmGpioPinGroup_Battery:
*pCount = NVODM_ARRAY_SIZE(s_Battery);
return s_Battery;
diff --git a/arch/arm/mach-tegra/odm_to_plat.c b/arch/arm/mach-tegra/odm_to_plat.c
index b152ef2cf88f..21095b4fc5ef 100644
--- a/arch/arm/mach-tegra/odm_to_plat.c
+++ b/arch/arm/mach-tegra/odm_to_plat.c
@@ -30,6 +30,12 @@
#include "nvodm_query_kbc.h"
#include "nvodm_kbc_keymapping.h"
+#ifdef CONFIG_KEYBOARD_GPIO
+#include "nvodm_query_gpio.h"
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#endif
+
#ifdef CONFIG_KEYBOARD_TEGRA
struct tegra_kbc_plat *tegra_kbc_odm_to_plat(void)
{
@@ -128,3 +134,59 @@ struct tegra_kbc_plat *tegra_kbc_odm_to_plat(void)
return pdata;
}
#endif
+
+#ifdef CONFIG_KEYBOARD_GPIO
+static struct gpio_keys_platform_data tegra_button_data;
+static struct platform_device tegra_button_device = {
+ .name = "gpio-keys",
+ .id = 3,
+ .dev = {
+ .platform_data = &tegra_button_data,
+ }
+};
+static char *gpio_key_names = "gpio_keys";
+struct platform_device *get_gpio_key_platform_data(void)
+{
+ struct gpio_keys_button *tegra_buttons = NULL;
+ int ngpiokeys = 0;
+ const NvOdmGpioPinInfo *gpio_key_info;
+ int i;
+ NvOdmGpioPinKeyInfo *gpio_pin_info = NULL;
+
+ gpio_key_info = NvOdmQueryGpioPinMap(NvOdmGpioPinGroup_keypadMisc, 0, &ngpiokeys);
+
+ if (!ngpiokeys) {
+ pr_info("No gpio is configured as buttons\n");
+ goto end;
+ }
+ tegra_buttons = kzalloc(ngpiokeys * sizeof(struct gpio_keys_button), GFP_KERNEL);
+ if (!tegra_buttons) {
+ pr_err("Memory allocation failed for tegra_buttons\n");
+ return NULL;
+ }
+
+ for (i = 0; i < ngpiokeys; ++i) {
+ tegra_buttons[i].gpio =
+ (int)(gpio_key_info[i].Port*8 + gpio_key_info[i].Pin);
+
+ gpio_pin_info = gpio_key_info[i].GpioPinSpecificData;
+ tegra_buttons[i].code = (int)gpio_pin_info->Code;
+ tegra_buttons[i].desc = gpio_key_names;
+
+ if (gpio_key_info[i].activeState == NvOdmGpioPinActiveState_Low)
+ tegra_buttons[i].active_low = 1;
+ else
+ tegra_buttons[i].active_low = 0;
+
+ tegra_buttons[i].type = EV_KEY;
+ tegra_buttons[i].wakeup = (gpio_pin_info->Wakeup)? 1: 0;
+ tegra_buttons[i].debounce_interval =
+ gpio_pin_info->DebounceTimeMs;
+ }
+
+end:
+ tegra_button_data.buttons = tegra_buttons;
+ tegra_button_data.nbuttons = ngpiokeys;
+ return &tegra_button_device;
+}
+#endif