summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2010-06-11 11:25:53 +0530
committerGary King <gking@nvidia.com>2010-06-11 17:38:13 -0700
commitb8d318dfb907abef7caf4ebcf85928ae60bb3dd0 (patch)
tree8d476a3ecb5b738cc7ea4ebe36496487429e9cd1
parent119e28566f08bf1bb775fe6e8139de7a9413d432 (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. Change-Id: I9fd34f82abef86157a92aabcb01cc3ebe0059886 Reviewed-on: http://git-master/r/2420 Reviewed-by: Gary King <gking@nvidia.com> Tested-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/board-common.c15
-rw-r--r--arch/arm/mach-tegra/board-nvodm.c60
-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.c36
4 files changed, 127 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-common.c b/arch/arm/mach-tegra/board-common.c
index b4354b04bb2d..1cc943ddaa18 100644
--- a/arch/arm/mach-tegra/board-common.c
+++ b/arch/arm/mach-tegra/board-common.c
@@ -151,6 +151,18 @@ static struct platform_device tegra_kbc_device = {
};
#endif
+#ifdef CONFIG_KEYBOARD_GPIO
+extern 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,
+ }
+};
+#endif
+
+
#ifdef CONFIG_TEGRA_IOVMM_GART
static struct resource tegra_gart_resources[] = {
[0] = {
@@ -213,6 +225,9 @@ static struct platform_device *tegra_devices[] __initdata = {
#ifdef CONFIG_KEYBOARD_TEGRA
&tegra_kbc_device,
#endif
+#ifdef CONFIG_KEYBOARD_GPIO
+ &tegra_button_device,
+#endif
#ifdef CONFIG_USB_GADGET_TEGRA
&tegra_udc_device,
#endif
diff --git a/arch/arm/mach-tegra/board-nvodm.c b/arch/arm/mach-tegra/board-nvodm.c
index 8d6a1b6b5b36..4bcf91cb302d 100644
--- a/arch/arm/mach-tegra/board-nvodm.c
+++ b/arch/arm/mach-tegra/board-nvodm.c
@@ -61,6 +61,13 @@
#include "board.h"
#include "nvrm_pmu.h"
+#ifdef CONFIG_KEYBOARD_GPIO
+#include "nvodm_query_gpio.h"
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#endif
+
+
NvRmGpioHandle s_hGpioGlobal;
static u64 tegra_dma_mask = DMA_BIT_MASK(32);
@@ -750,6 +757,58 @@ static noinline void __init tegra_setup_kbc(void)
static void tegra_setup_kbc(void) { }
#endif
+#ifdef CONFIG_KEYBOARD_GPIO
+struct gpio_keys_platform_data tegra_button_data;
+static char *gpio_key_names = "gpio_keys";
+static noinline void __init tegra_setup_gpio_key(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");
+ return;
+ }
+
+ tegra_buttons = kzalloc(ngpiokeys * sizeof(struct gpio_keys_button),
+ GFP_KERNEL);
+ if (!tegra_buttons) {
+ pr_err("Memory allocation failed for tegra_buttons\n");
+ return;
+ }
+
+ 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;
+ }
+
+ tegra_button_data.buttons = tegra_buttons;
+ tegra_button_data.nbuttons = ngpiokeys;
+ return;
+}
+#else
+static void tegra_setup_gpio_key(void) { }
+#endif
+
+
#ifdef CONFIG_RTC_DRV_TEGRA_ODM
static struct platform_device tegra_rtc_device = {
.name = "tegra_rtc",
@@ -1356,6 +1415,7 @@ void __init tegra_setup_nvodm(bool standard_i2c, bool standard_spi)
tegra_setup_sdhci();
tegra_setup_rfkill();
tegra_setup_kbc();
+ tegra_setup_gpio_key();
if (standard_i2c)
tegra_setup_i2c();
if (standard_spi)
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..a18d2644239a 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,27 @@ 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},
+ {KEY_MENU, 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]},
+ {NVODM_PORT('v'), 2, NvOdmGpioPinActiveState_Low, (void *)&s_GpioPinKeyInfo[5]},
+};
+
static const NvOdmGpioPinInfo s_Battery[] = {
// Low Battery
{NVODM_PORT('w'), 3, NvOdmGpioPinActiveState_Low},
@@ -161,6 +187,7 @@ static const NvOdmGpioPinInfo s_Battery[] = {
const NvOdmGpioPinInfo *NvOdmQueryGpioPinMap(NvOdmGpioPinGroup Group,
NvU32 Instance, NvU32 *pCount)
{
+ NvOdmBoardInfo BoardInfo;
switch (Group)
{
case NvOdmGpioPinGroup_Display:
@@ -229,6 +256,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;