Rewrite keypad driver to keep only one default matrix keymap. Also add an interface to pass the platform data via "mrst_keypad_set_pdata." Howerver, this keypad controller also provides direct key function. That one matrix keymap is not enough in this driver. It's necessary that adding another default keymap for direct key. So, there would be two default keymap. One for keypad matrix; one for direct key.
Signed-off-by: Jekyll Lai <[email protected]> --- drivers/input/keyboard/intel_mid_keypad.c | 402 ++++++++++++----------------- include/linux/input/intel_mid_keypad.h | 32 +++ 2 files changed, 193 insertions(+), 241 deletions(-) create mode 100644 include/linux/input/intel_mid_keypad.h diff --git a/drivers/input/keyboard/intel_mid_keypad.c b/drivers/input/keyboard/intel_mid_keypad.c index b41d50f..a7197cf 100644 --- a/drivers/input/keyboard/intel_mid_keypad.c +++ b/drivers/input/keyboard/intel_mid_keypad.c @@ -1,11 +1,10 @@ /* - * linux/drivers/input/keyboard/intel_mid_keypad.c - * * Driver for the matrix keypad controller on MID platform. * * Copyright (c) 2009 Intel Corporation. * Created: Sep 18, 2008 * Updated: May 14, 2010 + * Copyright (C) 2011 Jekyll Lai, Wistron <[email protected]> * * Based on pxa27x_keypad.c by Rodolfo Giometti <[email protected]> * pxa27x_keypad.c is based on a previous implementation by Kevin O'Connor @@ -28,7 +27,7 @@ */ #define DRV_NAME "mrst_keypad" -#define DRV_VERSION "0.0.1" +#define DRV_VERSION "1.3" #define MRST_KEYPAD_DRIVER_NAME DRV_NAME " " DRV_VERSION #include <linux/kernel.h> @@ -40,6 +39,7 @@ #include <linux/device.h> #include <linux/err.h> #include <linux/gpio.h> +#include <linux/input/intel_mid_keypad.h> /* * Keypad Controller registers @@ -105,7 +105,6 @@ #define KEYPAD_MATRIX_GPIO_OUT_PIN 32 #define KEYPAD_DIRECT_GPIO_IN_PIN 40 - #define keypad_readl(off) readl(keypad->mmio_base + (off)) #define keypad_writel(off, v) writel((v), keypad->mmio_base + (off)) @@ -114,60 +113,91 @@ #define MAX_MATRIX_KEY_ROWS (8) #define MAX_MATRIX_KEY_COLS (8) +#define MATRIX_ROW_SHIFT 3 #define DEBOUNCE_INTERVAL 100 #define KEY_HALFSHUTTER KEY_PROG1 #define KEY_FULLSHUTTER KEY_CAMERA -static unsigned int mrst_keycode[MAX_MATRIX_KEY_NUM] = { - KEY_F, KEY_D, KEY_E, KEY_GRAVE, KEY_C, KEY_R, KEY_4, KEY_V, - KEY_NUMLOCK, KEY_LEFTCTRL, KEY_Z, KEY_W, KEY_2, KEY_X, KEY_S, KEY_3, - KEY_EQUAL, KEY_N, KEY_H, KEY_U, KEY_7, KEY_M, KEY_J, KEY_8, - KEY_6, KEY_5, KEY_APOSTROPHE, KEY_G, KEY_T, KEY_SPACE, KEY_B, KEY_Y, - KEY_MINUS, KEY_0, KEY_LEFT, KEY_SEMICOLON, KEY_P, KEY_DOWN, KEY_UP, - KEY_BACKSPACE, - KEY_L, KEY_K, KEY_I, KEY_SLASH, KEY_COMMA, KEY_O, KEY_9, KEY_DOT, - KEY_Q, KEY_TAB, KEY_ESC, KEY_LEFTSHIFT, KEY_CAPSLOCK, KEY_1, KEY_FN, - KEY_A, - 0, KEY_RIGHTSHIFT, KEY_ENTER, 0, KEY_RIGHT, 0, 0, 0, +static unsigned int mrst_default_keymap[] = { + KEY(0, 0, KEY_1), + KEY(0, 1, KEY_8), + KEY(0, 2, KEY_T), + KEY(0, 3, KEY_S), + KEY(0, 4, KEY_L), + KEY(0, 5, KEY_N), + + KEY(1, 0, KEY_2), + KEY(1, 1, KEY_9), + KEY(1, 2, KEY_Y), + KEY(1, 3, KEY_D), + KEY(1, 4, KEY_BACKSPACE), + KEY(1, 5, KEY_M), + + KEY(2, 0, KEY_3), + KEY(2, 1, KEY_0), + KEY(2, 2, KEY_U), + KEY(2, 3, KEY_F), + KEY(2, 4, KEY_Z), + KEY(2, 5, KEY_F23), + + KEY(3, 0, KEY_4), + KEY(3, 1, KEY_Q), + KEY(3, 2, KEY_I), + KEY(3, 3, KEY_G), + KEY(3, 4, KEY_X), + KEY(3, 5, KEY_F24), + + KEY(4, 0, KEY_5), + KEY(4, 1, KEY_W), + KEY(4, 2, KEY_O), + KEY(4, 3, KEY_H), + KEY(4, 4, KEY_C), + KEY(4, 5, KEY_COMMA), + + KEY(5, 0, KEY_6), + KEY(5, 1, KEY_E), + KEY(5, 2, KEY_P), + KEY(5, 3, KEY_J), + KEY(5, 4, KEY_V), + KEY(5, 5, KEY_DOT), + + KEY(6, 0, KEY_7), + KEY(6, 1, KEY_R), + KEY(6, 2, KEY_A), + KEY(6, 3, KEY_K), + KEY(6, 4, KEY_B), + KEY(6, 5, KEY_SPACE), + + KEY(7, 0, KEY_LEFTSHIFT), + KEY(7, 1, KEY_RIGHTALT), + KEY(7, 2, KEY_ENTER), }; -/* NumLk key mapping */ -static unsigned int mrst_keycode_numlck[MAX_MATRIX_KEY_NUM] = { - KEY_F, KEY_D, KEY_E, KEY_GRAVE, KEY_C, KEY_R, KEY_4, KEY_V, - KEY_NUMLOCK, KEY_LEFTCTRL, KEY_Z, KEY_W, KEY_2, KEY_X, KEY_S, KEY_3, - KEY_EQUAL, KEY_N, KEY_H, KEY_KP4, KEY_KP7, KEY_KP0, KEY_KP1, KEY_KP8, - KEY_6, KEY_5, KEY_APOSTROPHE, KEY_G, KEY_T, KEY_SPACE, KEY_B, KEY_Y, - KEY_MINUS, KEY_KPSLASH, KEY_LEFT, KEY_KPMINUS, KEY_KPASTERISK, - KEY_DOWN, KEY_UP, KEY_BACKSPACE, - KEY_KP3, KEY_KP2, KEY_KP5, KEY_SLASH, KEY_KPDOT, KEY_KP6, KEY_KP9, - KEY_KPPLUS, - KEY_Q, KEY_TAB, KEY_ESC, KEY_LEFTSHIFT, KEY_CAPSLOCK, KEY_1, KEY_FN, - KEY_A, - 0, KEY_RIGHTSHIFT, KEY_ENTER, 0, KEY_RIGHT, 0, 0, 0, +/* default direct key map */ +static const u32 mrst_default_direct_keymap[] = { + KEY(0, 0, KEY_VOLUMEUP), + KEY(0, 1, KEY_VOLUMEDOWN), + KEY(0, 2, KEY_HALFSHUTTER), + KEY(0, 3, KEY_FULLSHUTTER), }; -/* Fn key mapping */ -static unsigned int mrst_keycode_fn[MAX_MATRIX_KEY_NUM] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - KEY_LEFTBRACE, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, KEY_HOME, 0, 0, KEY_PAGEDOWN, KEY_PAGEUP, 0, - 0, 0, 0, KEY_RIGHTBRACE, KEY_LEFTBRACE, 0, 0, KEY_RIGHTBRACE, - 0, 0, 0, KEY_LEFTSHIFT, 0, 0, KEY_FN, 0, - 0, KEY_RIGHTSHIFT, 0, 0, KEY_END, 0, 0, 0, +static const struct mrst_keypad_platform_data *mrst_keypad_pdata; + +static const struct matrix_keymap_data mrst_default_keymap_data = { + .keymap = mrst_default_keymap, + .keymap_size = ARRAY_SIZE(mrst_default_keymap), }; -/* direct key map */ -static unsigned int mrst_direct_keycode[MAX_DIRECT_KEY_NUM] = { - KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_HALFSHUTTER, KEY_FULLSHUTTER, +static const struct matrix_keymap_data mrst_default_direct_keymap_data = { + .keymap = mrst_default_direct_keymap, + .keymap_size = ARRAY_SIZE(mrst_default_direct_keymap), }; struct mrst_keypad { - struct input_dev *input_dev; void __iomem *mmio_base; + unsigned int irq; unsigned int matrix_key_rows; unsigned int matrix_key_cols; @@ -176,8 +206,7 @@ struct mrst_keypad { /* key debounce interval */ unsigned int debounce_interval; - /* matrix key code map */ - unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; + const struct matrix_keymap_data *keymap_data; /* state row bits of each column scan */ uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS]; @@ -187,7 +216,10 @@ struct mrst_keypad { int direct_key_num; - unsigned int direct_key_map[MAX_DIRECT_KEY_NUM]; + const struct matrix_keymap_data *direct_keymap_data; + + unsigned short keycode[MAX_MATRIX_KEY_NUM]; + unsigned short direct_keycode[MAX_DIRECT_KEY_NUM]; /* rotary encoders 0 */ int enable_rotary0; @@ -204,134 +236,61 @@ struct mrst_keypad { int rotary_rel_code[2]; int rotary_up_key[2]; int rotary_down_key[2]; - - /* Fn key */ - int fn; - - /* Number Lock key */ - int numlck; - - /* FIXME: - * Keypad controller likely issues fake interrupts - * when direct key status registers were first initialized - * This value assures this interrupt will not be proceeded. - */ - int count; }; static void mrst_keypad_build_keycode(struct mrst_keypad *keypad) { struct input_dev *input_dev = keypad->input_dev; - unsigned int *key; - int i, code; + 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; - - /* three sets of keycode here */ - if (keypad->fn) - memcpy(keypad->matrix_keycodes, mrst_keycode_fn, - sizeof(keypad->matrix_keycodes)); - else if (keypad->numlck) - memcpy(keypad->matrix_keycodes, mrst_keycode_numlck, - sizeof(keypad->matrix_keycodes)); - else - memcpy(keypad->matrix_keycodes, mrst_keycode, - sizeof(keypad->matrix_keycodes)); - - memcpy(keypad->direct_key_map, mrst_direct_keycode, - sizeof(keypad->direct_key_map)); - - key = &keypad->matrix_keycodes[0]; - for (i = 0; i < MAX_MATRIX_KEY_NUM; i++, key++) { - code = (*key) & 0xffffff; - set_bit(code, input_dev->keybit); - } - - key = &keypad->direct_key_map[0]; - for (i = 0; i < MAX_DIRECT_KEY_NUM; i++, key++) { - code = (*key) & 0xffffff; - set_bit(code, input_dev->keybit); + keymap_data = &mrst_default_keymap_data; + + if (mrst_keypad_pdata) { + 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; } - keypad->direct_key_num = MAX_DIRECT_KEY_NUM; - keypad->enable_rotary0 = 0; - keypad->enable_rotary1 = 0; - -} + matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, + input_dev->keycode, input_dev->keybit); -static inline unsigned int lookup_matrix_keycode( - struct mrst_keypad *keypad, int row, int col) -{ - return keypad->matrix_keycodes[(row << 3) + col]; + if (keypad->direct_key_num) { + matrix_keypad_build_keymap(direct_keymap_data, MATRIX_ROW_SHIFT, + keypad->direct_keycode, input_dev->keybit); + } } -static void handle_constant_keypress(struct mrst_keypad *keypad, - int num, int col, int row, - int state) +int __init mrst_keypad_set_pdata(const struct mrst_keypad_platform_data *data) { - struct input_dev *dev = keypad->input_dev; - - switch (num) { - case 0: - if (keypad->fn) - keypad->fn = 0; - /* Manually release special keys (Fn combinations) */ - if (test_bit(KEY_LEFTBRACE, dev->key)) - input_report_key(dev, KEY_LEFTBRACE, 0); - if (test_bit(KEY_RIGHTBRACE, dev->key)) - input_report_key(dev, KEY_RIGHTBRACE, 0); - if (test_bit(KEY_HOME, dev->key)) - input_report_key(dev, KEY_RIGHTBRACE, 0); - if (test_bit(KEY_END, dev->key)) - input_report_key(dev, KEY_END, 0); - if (test_bit(KEY_PAGEUP, dev->key)) - input_report_key(dev, KEY_RIGHTBRACE, 0); - if (test_bit(KEY_PAGEDOWN, dev->key)) - input_report_key(dev, KEY_RIGHTBRACE, 0); + if (mrst_keypad_pdata) + return -EBUSY; + if (!data) + return -EINVAL; - return; - - case 1: - /* if Fn pressed */ - if (col == 6 && row == 6) - keypad->fn = 1; - /* key '[' */ - else if ((col == 0 && row == 2) && state) { - keypad->fn = 0; - set_bit(KEY_EQUAL, dev->key); - dev->repeat_key = KEY_EQUAL; - } - /* key ']' */ - else if ((col == 3 && row == 5) && state) { - keypad->fn = 0; - set_bit(KEY_SLASH, dev->key); - dev->repeat_key = KEY_SLASH; - } - /* key '{' */ - else if ((col == 4 && row == 5) && state) { - keypad->fn = 0; - set_bit(KEY_COMMA, dev->key); - dev->repeat_key = KEY_COMMA; - } - /* key '}' */ - else if ((col == 7 && row == 5) && state) { - keypad->fn = 0; - set_bit(KEY_DOT, dev->key); - dev->repeat_key = KEY_DOT; - } + mrst_keypad_pdata = kmemdup(data, sizeof(*data), GFP_KERNEL); + if (!mrst_keypad_pdata) + return -ENOMEM; - return; - default: - ; - } + return 0; } static void mrst_keypad_scan_matrix(struct mrst_keypad *keypad) { - int row, col, num_keys_pressed = 0; + int row, col, code, num_keys_pressed = 0; uint32_t new_state[MAX_MATRIX_KEY_COLS]; uint32_t kpas = keypad_readl(KPAS); int status; @@ -342,9 +301,6 @@ static void mrst_keypad_scan_matrix(struct mrst_keypad *keypad) if (num_keys_pressed == 0) { status = keypad->matrix_key_state[0] & (1 << 0); - handle_constant_keypress(keypad, num_keys_pressed, 0, 0, - status); - goto scan; } @@ -354,16 +310,8 @@ static void mrst_keypad_scan_matrix(struct mrst_keypad *keypad) /* if invalid row/col, treat as no key pressed */ if (col < MAX_MATRIX_KEY_COLS && - row < MAX_MATRIX_KEY_ROWS) { - - /* if NumLk pressed */ - if (col == 0 && row == 1) - keypad->numlck = !keypad->numlck; - + row < MAX_MATRIX_KEY_ROWS) { status = keypad->matrix_key_state[col] & (1 << row); - handle_constant_keypress(keypad, num_keys_pressed, col, - row, status); - new_state[col] = (1 << row); } @@ -384,35 +332,9 @@ static void mrst_keypad_scan_matrix(struct mrst_keypad *keypad) new_state[5] = (kpasmkp2 >> 16) & KPASMKP_MKC_MASK; new_state[6] = kpasmkp3 & KPASMKP_MKC_MASK; new_state[7] = (kpasmkp3 >> 16) & KPASMKP_MKC_MASK; - - /* if Fn is pressed, all SHIFT is ignored, except when { - * or } is pressed */ - if (new_state[6] & 0x40) { - keypad->fn = 1; - new_state[3] &= ~0x40; - new_state[1] &= ~0x80; - } - - if (keypad->fn == 1) { - /* if { or } pressed */ - if ((new_state[4] & 0x20) || (new_state[7] & 0x20)) { - /* as if LEFTSHIFT is pressed */ - new_state[3] |= 0x40; - /* as if Fn not pressed */ - new_state[6] &= ~0x40; - } - /* if [ or ] pressed */ - if ((new_state[0] & 0x04) || (new_state[3] & 0x20)) - /* as if Fn not pressed */ - new_state[6] &= ~0x40; - } } - scan: - /* re-build keycode */ - mrst_keypad_build_keycode(keypad); - for (col = 0; col < keypad->matrix_key_cols; col++) { uint32_t bits_changed; @@ -424,8 +346,9 @@ scan: if ((bits_changed & (1 << row)) == 0) continue; + code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); input_report_key(keypad->input_dev, - lookup_matrix_keycode(keypad, row, col), + keypad->keycode[code], new_state[col] & (1 << row)); } } @@ -493,7 +416,7 @@ static void mrst_keypad_scan_direct(struct mrst_keypad *keypad) if (keypad->enable_rotary0 || keypad->enable_rotary1) mrst_keypad_scan_rotary(keypad); - if ((keypad->direct_key_map == NULL) || (++keypad->count == 1)) { + if (!keypad->direct_key_num) { keypad->direct_key_state = 0; return; } @@ -508,13 +431,13 @@ static void mrst_keypad_scan_direct(struct mrst_keypad *keypad) for (i = 0; i < keypad->direct_key_num; i++) { if (bits_changed & (1 << i)) { input_report_key(keypad->input_dev, - keypad->direct_key_map[i], + keypad->direct_keycode[i], (new_state & (1 << i))); } } + input_sync(keypad->input_dev); keypad->direct_key_state = new_state; - } static irqreturn_t mrst_keypad_irq_handler(int irq, void *dev_id) @@ -531,17 +454,18 @@ static irqreturn_t mrst_keypad_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static int mrst_keypad_gpio_init(void) + +static int mrst_keypad_gpio_init(struct mrst_keypad *keypad) { int i, err, cnt = 0; int pins = KEYPAD_MATRIX_GPIO_IN_PIN + MAX_MATRIX_KEY_ROWS + - MAX_MATRIX_KEY_COLS + MAX_DIRECT_KEY_NUM; + MAX_MATRIX_KEY_COLS + keypad->direct_key_num; /* explicitely tell which pins have been occupied... */ for (i = KEYPAD_MATRIX_GPIO_IN_PIN; i < pins; i++, cnt++) { err = gpio_request(i, NULL); if (err) { - printk(KERN_ERR "GPIO pin %d failed to request.\n", i); + pr_err(DRV_NAME "GPIO pin %d failed to request.\n", i); goto err_request; } } @@ -554,7 +478,7 @@ static int mrst_keypad_gpio_init(void) /* set action is executed in gpio_direction_output() */ gpio_direction_output(KEYPAD_MATRIX_GPIO_OUT_PIN + i, 1); - for (i = 0; i < MAX_DIRECT_KEY_NUM; i++) + for (i = 0; i < keypad->direct_key_num; i++) gpio_direction_input(KEYPAD_DIRECT_GPIO_IN_PIN + i); return 0; @@ -611,20 +535,24 @@ static int mrst_keypad_open(struct input_dev *dev) struct mrst_keypad *keypad = input_get_drvdata(dev); int err; - err = mrst_keypad_gpio_init(); + err = mrst_keypad_gpio_init(keypad); if (err) return err; mrst_keypad_config(keypad); + enable_irq(keypad->irq); return 0; } static void mrst_keypad_close(struct input_dev *dev) { + struct mrst_keypad *keypad = input_get_drvdata(dev); int pins = KEYPAD_MATRIX_GPIO_IN_PIN + MAX_MATRIX_KEY_ROWS + - MAX_MATRIX_KEY_COLS + MAX_DIRECT_KEY_NUM; + MAX_MATRIX_KEY_COLS + keypad->direct_key_num; int i; + + disable_irq(keypad->irq); /* free occupied pins */ for (i = KEYPAD_MATRIX_GPIO_IN_PIN; i < pins; i++) gpio_free(i); @@ -637,43 +565,39 @@ static int __devinit mrst_keypad_probe(struct pci_dev *pdev, struct input_dev *input_dev; int error; -#ifndef MODULE - printk(KERN_INFO MRST_KEYPAD_DRIVER_NAME "\n"); -#endif - - keypad = kzalloc(sizeof(struct mrst_keypad), GFP_KERNEL); - if (keypad == NULL) { - dev_err(&pdev->dev, "failed to allocate driver data\n"); - return -ENOMEM; - } + /* Disable flag will turn off keypad support */ + if (mrst_keypad_pdata && mrst_keypad_pdata->disable) + return 0; error = pci_enable_device(pdev); if (error || (pdev->irq < 0)) { dev_err(&pdev->dev, "failed to enable device/get irq\n"); - error = -ENXIO; - goto failed_free; + return -ENXIO; + } + + keypad = kzalloc(sizeof(struct mrst_keypad), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!keypad || !input_dev) { + dev_err(&pdev->dev, "failed to allocate driver data\n"); + error = -ENOMEM; + goto failed_free_mem; } + keypad->input_dev = input_dev; + keypad->irq = pdev->irq; + error = pci_request_regions(pdev, DRV_NAME); if (error) { dev_err(&pdev->dev, "failed to request I/O memory\n"); - goto failed_free; + goto failed_free_mem; } keypad->mmio_base = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); - if (keypad->mmio_base == NULL) { + if (!keypad->mmio_base) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); error = -ENXIO; - goto failed_free_mem; - } - - /* Create and register the input driver. */ - input_dev = input_allocate_device(); - if (!input_dev) { - dev_err(&pdev->dev, "failed to allocate input device\n"); - error = -ENOMEM; - goto failed_free_io; + goto failed_free_mem_region; } input_dev->name = pci_name(pdev); @@ -681,17 +605,11 @@ static int __devinit mrst_keypad_probe(struct pci_dev *pdev, input_dev->open = mrst_keypad_open; input_dev->close = mrst_keypad_close; input_dev->dev.parent = &pdev->dev; - - input_dev->keycode = keypad->matrix_keycodes; - input_dev->keycodesize = sizeof(unsigned int); - input_dev->keycodemax = ARRAY_SIZE(mrst_keycode); - - keypad->input_dev = input_dev; - keypad->fn = 0; - keypad->numlck = 0; - /*FIXME*/keypad->count = 0; input_set_drvdata(input_dev, keypad); + input_dev->keycode = keypad->keycode; + input_dev->keycodesize = sizeof(unsigned int); + input_dev->keycodemax = ARRAY_SIZE(mrst_default_keymap); input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL); @@ -701,10 +619,12 @@ static int __devinit mrst_keypad_probe(struct pci_dev *pdev, error = request_irq(pdev->irq, mrst_keypad_irq_handler, IRQF_SHARED, pci_name(pdev), keypad); if (error) { - dev_err(&pdev->dev, "failed to request IRQ\n"); - goto failed_free_dev; + dev_err(&pdev->dev, "failed to request keyboard IRQ\n"); + goto failed_free_iounmap; } + disable_irq(pdev->irq); + /* Register the input device */ error = input_register_device(input_dev); if (error) { @@ -712,20 +632,19 @@ static int __devinit mrst_keypad_probe(struct pci_dev *pdev, goto failed_free_irq; } - printk(KERN_INFO "*** keypad driver load successfully ***\n"); return 0; failed_free_irq: free_irq(pdev->irq, keypad); pci_set_drvdata(pdev, NULL); -failed_free_dev: - input_free_device(input_dev); -failed_free_io: +failed_free_iounmap: iounmap(keypad->mmio_base); -failed_free_mem: +failed_free_mem_region: pci_release_regions(pdev); -failed_free: +failed_free_mem: + input_free_device(input_dev); kfree(keypad); + return error; } @@ -734,12 +653,12 @@ static void __devexit mrst_keypad_remove(struct pci_dev *pdev) struct mrst_keypad *keypad = pci_get_drvdata(pdev); int i; int pins = KEYPAD_MATRIX_GPIO_IN_PIN + MAX_MATRIX_KEY_ROWS + - MAX_MATRIX_KEY_COLS + MAX_DIRECT_KEY_NUM; + MAX_MATRIX_KEY_COLS + keypad->direct_key_num; + free_irq(pdev->irq, keypad); for (i = pins - 1; i > KEYPAD_MATRIX_GPIO_IN_PIN; i--) gpio_free(i); - free_irq(pdev->irq, keypad); input_unregister_device(keypad->input_dev); iounmap(keypad->mmio_base); pci_release_regions(pdev); @@ -760,7 +679,7 @@ static struct pci_driver mrst_keypad_driver = { .remove = __devexit_p(mrst_keypad_remove), #ifdef CONFIG_PM .suspend = NULL, - .resume = NULL, + .resume = NULL, #endif /* CONFIG_PM */ }; @@ -779,3 +698,4 @@ module_exit(mrst_keypad_exit); MODULE_DESCRIPTION("MRST Keypad Controller Driver"); MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Jekyll Lai <[email protected]>"); diff --git a/include/linux/input/intel_mid_keypad.h b/include/linux/input/intel_mid_keypad.h new file mode 100644 index 0000000..4295db4 --- /dev/null +++ b/include/linux/input/intel_mid_keypad.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010 Jekyll Lai, Wistron <[email protected]> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/platform_device.h> +#include <linux/input/matrix_keypad.h> + +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.0.4 _______________________________________________ MeeGo-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
