Right now the driver programs the number of matrix rows, cols, debounce interval, direct key nums and rotary info. This information is passed into the driver from pdata, a new platform data structure. This information should really be programmed into the KPC register by firmware, and then read by the driver via the pci shim layer. This patch removes this info from the pdata structure and implements the code to read this info from the KPC register. Because firmware doesn't actually behave the way it should right now, this patch creates a pci quirk for the langwell keypad which programs the KPC register.
Signed-off-by: Kristen Carlson Accardi <[email protected]> --- arch/x86/pci/mrst.c | 31 ++++++++++++ drivers/input/keyboard/intel_mid_keypad.c | 74 ++++++----------------------- include/linux/input/intel_mid_keypad.h | 3 - 3 files changed, 46 insertions(+), 62 deletions(-) diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c index cb29191..64320f9 100644 --- a/arch/x86/pci/mrst.c +++ b/arch/x86/pci/mrst.c @@ -265,3 +265,34 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixed_bar_fixup); + +/* + * The Firmware should program the Langwell keypad registers to indicate + * system specific configuration. This quirk can be removed when firmware + * actually does this properly. + */ +static void __devinit langwell_keypad_fixup(struct pci_dev *dev) +{ + void __iomem *base; + u32 val; + + base = pci_ioremap_bar(dev, 0); + + if (base == NULL) + return; + + val = readl(base); + + /* set the KPC register */ + if (val == 0) + writel(0x3f9ff8c3, base); + + val = readl(base + 0x24); + + /* set the debounce interval (KPKDI) */ + if (val == 0) + writel(100, base + 0x24); + + iounmap(base); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0805, langwell_keypad_fixup); diff --git a/drivers/input/keyboard/intel_mid_keypad.c b/drivers/input/keyboard/intel_mid_keypad.c index 0716fd7..6095503 100644 --- a/drivers/input/keyboard/intel_mid_keypad.c +++ b/drivers/input/keyboard/intel_mid_keypad.c @@ -201,10 +201,7 @@ struct mrst_keypad { unsigned int matrix_key_rows; unsigned int matrix_key_cols; - int matrix_key_map_size; - - /* key debounce interval */ - unsigned int debounce_interval; + unsigned int row_shift; const struct matrix_keymap_data *keymap_data; @@ -244,33 +241,24 @@ static void mrst_keypad_build_keycode(struct mrst_keypad *keypad) const struct matrix_keymap_data *keymap_data; const struct matrix_keymap_data *direct_keymap_data; - keypad->matrix_key_rows = MAX_MATRIX_KEY_ROWS; - keypad->matrix_key_cols = MAX_MATRIX_KEY_COLS; - keypad->matrix_key_map_size = MAX_MATRIX_KEY_NUM; - keypad->debounce_interval = DEBOUNCE_INTERVAL; keymap_data = &mrst_default_keymap_data; if (mrst_keypad_pdata) { - if (mrst_keypad_pdata->keymap_data) + if (mrst_keypad_pdata->keymap_data) { keymap_data = mrst_keypad_pdata->keymap_data; - - if (mrst_keypad_pdata->direct_key_num) { - keypad->direct_key_num = - mrst_keypad_pdata->direct_key_num; direct_keymap_data = mrst_keypad_pdata->direct_keymap_data ?: &mrst_default_direct_keymap_data; } - keypad->enable_rotary0 = mrst_keypad_pdata->enable_rotary0 ?: 0; - keypad->enable_rotary1 = mrst_keypad_pdata->enable_rotary1 ?: 0; } - matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, + matrix_keypad_build_keymap(keymap_data, keypad->row_shift, input_dev->keycode, input_dev->keybit); if (keypad->direct_key_num) { - matrix_keypad_build_keymap(direct_keymap_data, MATRIX_ROW_SHIFT, - keypad->direct_keycode, input_dev->keybit); + matrix_keypad_build_keymap(direct_keymap_data, + keypad->row_shift, keypad->direct_keycode, + input_dev->keybit); } } @@ -491,45 +479,6 @@ err_request: return err; } -static void mrst_keypad_config(struct mrst_keypad *keypad) -{ - unsigned int mask = 0, direct_key_num = 0; - unsigned long kpc = 0; - - /* enable matrix keys with automatic scan */ - if (keypad->matrix_key_rows && keypad->matrix_key_cols) { - kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; - kpc |= KPC_MKRN(keypad->matrix_key_rows) | - KPC_MKCN(keypad->matrix_key_cols); - } - - /* enable rotary key, debounce interval same as direct keys */ - if (keypad->enable_rotary0) { - mask |= 0x03; - direct_key_num = 2; - kpc |= KPC_REE0; - } - - if (keypad->enable_rotary1) { - mask |= 0x0c; - direct_key_num = 4; - kpc |= KPC_REE1; - } - - if (keypad->direct_key_num > direct_key_num) - direct_key_num = keypad->direct_key_num; - - keypad->direct_key_mask = ((2 << direct_key_num) - 1) & ~mask; - - /* enable direct key */ - if (direct_key_num) - kpc |= KPC_DE | KPC_DIE | KPC_DKN(direct_key_num); - - keypad_writel(KPC, kpc); - keypad_writel(KPREC, DEFAULT_KPREC); - keypad_writel(KPKDI, keypad->debounce_interval); -} - static int mrst_keypad_open(struct input_dev *dev) { struct mrst_keypad *keypad = input_get_drvdata(dev); @@ -538,7 +487,7 @@ static int mrst_keypad_open(struct input_dev *dev) err = mrst_keypad_gpio_init(keypad); if (err) return err; - mrst_keypad_config(keypad); + enable_irq(keypad->irq); return 0; @@ -564,6 +513,7 @@ static int __devinit mrst_keypad_probe(struct pci_dev *pdev, struct mrst_keypad *keypad; struct input_dev *input_dev; int error; + u32 kpc; /* Disable flag will turn off keypad support */ if (mrst_keypad_pdata && mrst_keypad_pdata->disable) @@ -600,6 +550,11 @@ static int __devinit mrst_keypad_probe(struct pci_dev *pdev, goto failed_free_mem_region; } + kpc = keypad_readl(KPC); + keypad->matrix_key_rows = ((kpc >> 26) & 0x7) + 1; + keypad->matrix_key_cols = ((kpc >> 23) & 0x7) + 1; + keypad->row_shift = get_count_order(keypad->matrix_key_cols); + input_dev->name = pci_name(pdev); input_dev->id.bustype = BUS_PCI; input_dev->open = mrst_keypad_open; @@ -609,7 +564,8 @@ static int __devinit mrst_keypad_probe(struct pci_dev *pdev, input_dev->keycode = keypad->keycode; input_dev->keycodesize = sizeof(unsigned int); - input_dev->keycodemax = ARRAY_SIZE(mrst_default_keymap); + input_dev->keycodemax = keypad->matrix_key_rows << keypad->row_shift; + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL); diff --git a/include/linux/input/intel_mid_keypad.h b/include/linux/input/intel_mid_keypad.h index 4295db4..8a64e34 100644 --- a/include/linux/input/intel_mid_keypad.h +++ b/include/linux/input/intel_mid_keypad.h @@ -24,9 +24,6 @@ struct mrst_keypad_platform_data { const struct matrix_keymap_data *keymap_data; const struct matrix_keymap_data *direct_keymap_data; int disable; - int direct_key_num; - int enable_rotary0; - int enable_rotary1; }; int mrst_keypad_set_pdata(const struct mrst_keypad_platform_data *data); -- 1.7.3.1 _______________________________________________ MeeGo-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
