diff options
author | Gary King <gking@nvidia.com> | 2010-05-25 18:01:29 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-05-26 13:44:02 -0700 |
commit | 01af3d44e93a99a68c13595f5bc77e93b6230043 (patch) | |
tree | ae2fa84e19be7f2602ec489e2860442fdd5efd09 /arch/arm/mach-tegra/board-nvodm.c | |
parent | 9325f7a9386bef0158277fcef77b789c96c02e06 (diff) |
[ARM/tegra] board-nvodm: generate KBC platform data from ODM kit
move the kbc platform data generation out of the hard-coded table for
harmony and generate it at init time based on the return values from
the ODM kit
Change-Id: Icea4ee6b9fb61a15a01e4044a20e92671057d35f
Diffstat (limited to 'arch/arm/mach-tegra/board-nvodm.c')
-rw-r--r-- | arch/arm/mach-tegra/board-nvodm.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-nvodm.c b/arch/arm/mach-tegra/board-nvodm.c index a0cf19397e17..3a9b037050ef 100644 --- a/arch/arm/mach-tegra/board-nvodm.c +++ b/arch/arm/mach-tegra/board-nvodm.c @@ -38,6 +38,7 @@ #include <mach/sdhci.h> #include <mach/nand.h> #include <mach/regulator.h> +#include <mach/kbc.h> #include <mach/nvrm_linux.h> @@ -48,6 +49,9 @@ #include "nvodm_query_gpio.h" #include "nvrm_pinmux.h" #include "nvrm_module.h" +#include "nvodm_kbc.h" +#include "nvodm_query_kbc.h" +#include "nvodm_kbc_keymapping.h" NvRmGpioHandle s_hGpioGlobal; @@ -633,6 +637,108 @@ static void __init tegra_setup_hcd(void) static inline void tegra_setup_hcd(void) { } #endif +#ifdef CONFIG_KEYBOARD_TEGRA +struct tegra_kbc_plat tegra_kbc_platform; + +static void tegra_setup_kbc(void) +{ + struct tegra_kbc_plat *pdata = &tegra_kbc_platform; + const NvOdmPeripheralConnectivity *conn; + NvOdmPeripheralSearch srch_attr = NvOdmPeripheralSearch_IoModule; + const struct NvOdmKeyVirtTableDetail **vkeys; + NvU32 srch_val = NvOdmIoModule_Kbd; + NvU32 temp; + NvU64 guid; + NvU32 i, j, k; + NvU32 cols=0; + NvU32 rows=0; + NvU32 *wake_row; + NvU32 *wake_col; + NvU32 wake_num; + NvU32 vnum; + + pdata->keymap = kzalloc(sizeof(*pdata->keymap)*KBC_MAX_KEY, GFP_KERNEL); + if (!pdata->keymap) { + pr_err("%s: out of memory for key mapping\n", __func__); + return; + } + if (NvOdmKbcIsSelectKeysWkUpEnabled(&wake_row, &wake_col, &wake_num)) { + BUG_ON(!wake_num || wake_num>=KBC_MAX_KEY); + pdata->wake_cfg = kzalloc(sizeof(*pdata->wake_cfg)*wake_num, + GFP_KERNEL); + if (pdata->wake_cfg) { + pdata->wake_cnt = (int)wake_num; + for (i=0; i<wake_num; i++) { + pdata->wake_cfg[i].row=wake_row[i]; + pdata->wake_cfg[i].col=wake_col[i]; + } + } else + pr_err("disabling wakeup key filtering due to " + "out-of-memory error\n"); + } + + NvOdmKbcGetParameter(NvOdmKbcParameter_DebounceTime, 1, &temp); + + /* debounce time is reported from ODM in terms of clock ticks. */ + pdata->debounce_cnt = temp; + + /* repeat cycle is reported from ODM in milliseconds, + * but needs to be specified in 32KHz ticks */ + NvOdmKbcGetParameter(NvOdmKbcParameter_RepeatCycleTime, 1, &temp); + pdata->repeat_cnt = temp * 32; + + temp = NvOdmPeripheralEnumerate(&srch_attr, &srch_val, 1, &guid, 1); + if (!temp) { + kfree(pdata->keymap); + pr_err("%s: failed to find keyboard module\n", __func__); + return; + } + conn = NvOdmPeripheralGetGuid(guid); + if (!conn) { + kfree(pdata->keymap); + pr_err("%s: failed to find keyboard\n", __func__); + return; + } + + for (i=0; i<conn->NumAddress; i++) { + NvU32 addr = conn->AddressList[i].Address; + + if (conn->AddressList[i].Interface!=NvOdmIoModule_Kbd) continue; + + if (conn->AddressList[i].Instance) { + pdata->pin_cfg[addr].num = cols++; + pdata->pin_cfg[addr].is_col = true; + } else { + pdata->pin_cfg[addr].num = rows++; + pdata->pin_cfg[addr].is_row = true; + } + } + + for (i=0; i<KBC_MAX_KEY; i++) + pdata->keymap[i] = -1; + + vnum = NvOdmKbcKeyMappingGetVirtualKeyMappingList(&vkeys); + + for (i=0; i<rows; i++) { + for (j=0; j<cols; j++) { + NvU32 sc = NvOdmKbcGetKeyCode(i, j, rows, cols); + for (k=0; k<vnum; k++) { + if (sc >= vkeys[k]->StartScanCode && + sc <= vkeys[k]->EndScanCode) { + sc -= vkeys[k]->StartScanCode; + sc = vkeys[k]->pVirtualKeyTable[sc]; + if (!sc) continue; + pdata->keymap[kbc_indexof(i,j)]=sc; + } + + } + } + } +} +#else +static void tegra_setup_kbc(void) { } +#endif + #ifdef CONFIG_RTC_DRV_TEGRA_ODM static struct platform_device tegra_rtc_device = { .name = "tegra_rtc", @@ -799,6 +905,7 @@ void __init tegra_setup_nvodm(void) tegra_setup_hsuart(); tegra_setup_sdhci(); tegra_setup_rfkill(); + tegra_setup_kbc(); platform_add_devices(nvodm_devices, ARRAY_SIZE(nvodm_devices)); pm_power_off = tegra_system_power_off; } |