diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2010-05-28 15:07:47 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-05-28 08:55:56 -0700 |
commit | 78edd4a2d67fdd8907afdb596fc9993356668512 (patch) | |
tree | cd30f1f70585b39f88bd6effc3089dd8a4263208 | |
parent | e0b21639f2b6aa8fa51558853a0519a04abc32ce (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_defconfig | 4 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board_nvodm.c | 38 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/nvodm_query_gpio.h | 16 | ||||
-rw-r--r-- | arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c | 34 | ||||
-rw-r--r-- | arch/arm/mach-tegra/odm_to_plat.c | 62 |
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 |