/* linux/arch/arm/mach-msm/board-kaiser-keypad.c * * Copyright (C) 2007 Google, Inc. * Author: Marcin Baliniak * based on Brian Swetland * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * 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. * */ #include #include #include #include #include #include #include #include #include #include #include static unsigned int kaiser_row_gpios[] = {23, 30, 31, 32, 33, 34, 35, 78}; static unsigned int kaiser_col_gpios[] = { 36, 37, 38, 39, 40, 41, 42 }; #define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(kaiser_col_gpios) + (col)) static unsigned short kaiser_keymap[ARRAY_SIZE(kaiser_col_gpios) * ARRAY_SIZE(kaiser_row_gpios)] = { [KEYMAP_INDEX(0, 0)] = KEY_MENU,// (keyboard menu) [KEYMAP_INDEX(0, 1)] = KEY_OK,// (keyboard ok) [KEYMAP_INDEX(0, 2)] = KEY_TAB,// [KEYMAP_INDEX(0, 3)] = KEY_V,// [KEYMAP_INDEX(0, 4)] = KEY_SPACE,// [KEYMAP_INDEX(0, 5)] = KEY_DOT,// [KEYMAP_INDEX(0, 6)] = KEY_ENTER, // [KEYMAP_INDEX(1, 0)] = KEY_1, [KEYMAP_INDEX(1, 1)] = KEY_2, [KEYMAP_INDEX(1, 2)] = KEY_3, [KEYMAP_INDEX(1, 3)] = KEY_MENU,// [KEYMAP_INDEX(1, 4)] = KEY_1, // hangup [KEYMAP_INDEX(1, 5)] = KEY_OK,// [KEYMAP_INDEX(1, 6)] = KEY_2,// call [KEYMAP_INDEX(2, 0)] = KEY_LEFTALT,// Fn [KEYMAP_INDEX(2, 1)] = KEY_X,// [KEYMAP_INDEX(2, 2)] = KEY_C,// [KEYMAP_INDEX(2, 3)] = KEY_G,// [KEYMAP_INDEX(2, 4)] = KEY_B,// [KEYMAP_INDEX(2, 5)] = KEY_M,// [KEYMAP_INDEX(2, 6)] = KEY_BACKSPACE,// [KEYMAP_INDEX(3, 0)] = KEY_RIGHTSHIFT,// [KEYMAP_INDEX(3, 1)] = KEY_Z,// [KEYMAP_INDEX(3, 2)] = KEY_F,// [KEYMAP_INDEX(3, 3)] = KEY_Y,// [KEYMAP_INDEX(3, 4)] = KEY_H,// [KEYMAP_INDEX(3, 5)] = KEY_N,// [KEYMAP_INDEX(3, 6)] = KEY_L,// [KEYMAP_INDEX(4, 0)] = KEY_A,// [KEYMAP_INDEX(4, 1)] = KEY_S,// [KEYMAP_INDEX(4, 2)] = KEY_D,// [KEYMAP_INDEX(4, 3)] = KEY_T,// [KEYMAP_INDEX(4, 4)] = KEY_J,// [KEYMAP_INDEX(4, 5)] = KEY_K,// [KEYMAP_INDEX(4, 6)] = KEY_P,// [KEYMAP_INDEX(5, 0)] = KEY_Q,// [KEYMAP_INDEX(5, 1)] = KEY_W,// [KEYMAP_INDEX(5, 2)] = KEY_E,// [KEYMAP_INDEX(5, 3)] = KEY_R,// [KEYMAP_INDEX(5, 4)] = KEY_U,// [KEYMAP_INDEX(5, 5)] = KEY_I,// [KEYMAP_INDEX(5, 6)] = KEY_O, // //dummy mapping for test only [KEYMAP_INDEX(6, 0)] = KEY_4,// [KEYMAP_INDEX(6, 1)] = KEY_5,// [KEYMAP_INDEX(6, 2)] = KEY_6,// [KEYMAP_INDEX(6, 3)] = KEY_7,// [KEYMAP_INDEX(6, 4)] = KEY_8,// [KEYMAP_INDEX(6, 5)] = KEY_9,// [KEYMAP_INDEX(6, 6)] = KEY_0,// [KEYMAP_INDEX(7, 0)] = KEY_4,// [KEYMAP_INDEX(7, 1)] = KEY_5,// [KEYMAP_INDEX(7, 2)] = KEY_6,// [KEYMAP_INDEX(7, 3)] = KEY_7,// [KEYMAP_INDEX(7, 4)] = KEY_8,// [KEYMAP_INDEX(7, 5)] = KEY_9,// [KEYMAP_INDEX(7, 6)] = KEY_0,// }; #define KEY_SHIFT 0x10000 static unsigned int kaiser_keymap_plus_fn[ARRAY_SIZE(kaiser_col_gpios) * ARRAY_SIZE(kaiser_row_gpios)] = { [KEYMAP_INDEX(0, 0)] = KEY_SEMICOLON,// ; [KEYMAP_INDEX(0, 1)] = KEY_WLAN,// [KEYMAP_INDEX(0, 2)] = KEY_TAB,// [KEYMAP_INDEX(0, 3)] = KEY_SHIFT | KEY_8,// * [KEYMAP_INDEX(0, 4)] = KEY_SPACE, [KEYMAP_INDEX(0, 5)] = KEY_0,// [KEYMAP_INDEX(0, 6)] = KEY_ENTER, [KEYMAP_INDEX(1, 0)] = KEY_1, [KEYMAP_INDEX(1, 1)] = KEY_2, [KEYMAP_INDEX(1, 2)] = KEY_3, [KEYMAP_INDEX(1, 3)] = KEY_MENU,// [KEYMAP_INDEX(1, 4)] = KEY_E, // hangup [KEYMAP_INDEX(1, 5)] = KEY_OK,// [KEYMAP_INDEX(1, 6)] = KEY_C,// call [KEYMAP_INDEX(2, 0)] = KEY_LEFTALT,// Fn [KEYMAP_INDEX(2, 1)] = KEY_SHIFT | KEY_7,// * [KEYMAP_INDEX(2, 2)] = KEY_SHIFT | KEY_SEMICOLON,// : [KEYMAP_INDEX(2, 3)] = KEY_SHIFT | KEY_EQUAL,// = [KEYMAP_INDEX(2, 4)] = KEY_7,// [KEYMAP_INDEX(2, 5)] = KEY_9,// [KEYMAP_INDEX(2, 6)] = KEY_DELETE,// [KEYMAP_INDEX(3, 0)] = KEY_CAPSLOCK,// [KEYMAP_INDEX(3, 1)] = KEY_APOSTROPHE,// ' [KEYMAP_INDEX(3, 2)] = KEY_MINUS,// - [KEYMAP_INDEX(3, 3)] = KEY_1,// [KEYMAP_INDEX(3, 4)] = KEY_4,// [KEYMAP_INDEX(3, 5)] = KEY_8,// [KEYMAP_INDEX(3, 6)] = KEY_EQUAL,// [KEYMAP_INDEX(4, 0)] = KEY_SHIFT | KEY_MINUS,// _ [KEYMAP_INDEX(4, 1)] = KEY_SHIFT | KEY_APOSTROPHE,// " [KEYMAP_INDEX(4, 2)] = KEY_SHIFT | KEY_5,// % [KEYMAP_INDEX(4, 3)] = KEY_SHIFT | KEY_3,// # [KEYMAP_INDEX(4, 4)] = KEY_5,// [KEYMAP_INDEX(4, 5)] = KEY_6,// [KEYMAP_INDEX(4, 6)] = KEY_SHIFT | KEY_0,// ) [KEYMAP_INDEX(5, 0)] = KEY_SHIFT | KEY_2,// @ [KEYMAP_INDEX(5, 1)] = KEY_SHIFT | KEY_1,// ! [KEYMAP_INDEX(5, 2)] = KEY_SHIFT | KEY_BACKSLASH,// ? [KEYMAP_INDEX(5, 3)] = KEY_BACKSLASH,// [KEYMAP_INDEX(5, 4)] = KEY_2,// [KEYMAP_INDEX(5, 5)] = KEY_3,// [KEYMAP_INDEX(5, 6)] = KEY_SHIFT | KEY_9,// ( //dummy mapping for test only [KEYMAP_INDEX(6, 0)] = KEY_4,// [KEYMAP_INDEX(6, 1)] = KEY_5,// [KEYMAP_INDEX(6, 2)] = KEY_6,// [KEYMAP_INDEX(6, 3)] = KEY_7,// [KEYMAP_INDEX(6, 4)] = KEY_8,// [KEYMAP_INDEX(6, 5)] = KEY_9,// [KEYMAP_INDEX(6, 6)] = KEY_0,// }; int Fn_pressed=0; int Capslock_pressed=0; void kaiser_key_event(struct input_dev *input_dev, int key_index, int pressed) { unsigned short key; if (pressed == 0) return; //if we relese Fn key, keymapping need to be change if (key_index == KEYMAP_INDEX(2, 0)) { Fn_pressed++; if (Fn_pressed > 2) Fn_pressed=0; Capslock_pressed =0; return; } //if we relese Fn key, keymapping need to be change if (key_index == KEYMAP_INDEX(3, 0)) { Capslock_pressed++; if (Capslock_pressed > 2) Capslock_pressed=0; Fn_pressed = 0; return; } if (Fn_pressed) { if (Fn_pressed == 1) Fn_pressed=0; key = (kaiser_keymap_plus_fn[key_index] & 0xffff); if (kaiser_keymap_plus_fn[key_index] & KEY_SHIFT) input_report_key(input_dev, KEY_RIGHTSHIFT, 1); printk("\nSHIFT:0x%X, %d\n",kaiser_keymap_plus_fn[key_index],key_index); input_report_key(input_dev, key, 1); input_report_key(input_dev, key, 0); if (kaiser_keymap_plus_fn[key_index] & KEY_SHIFT) input_report_key(input_dev, KEY_RIGHTSHIFT, 0); input_sync(input_dev); return; } if (Capslock_pressed) { if (Capslock_pressed == 1) Capslock_pressed=0; input_report_key(input_dev, KEY_RIGHTSHIFT, 1); input_report_key(input_dev, kaiser_keymap[key_index], 1); input_report_key(input_dev, kaiser_keymap[key_index], 0); input_report_key(input_dev, KEY_RIGHTSHIFT, 0); input_sync(input_dev); return; } input_report_key(input_dev,kaiser_keymap[key_index],1); input_report_key(input_dev,kaiser_keymap[key_index],0); input_sync(input_dev); } static struct gpio_event_matrix_info kaiser_matrix_info = { .info.func = gpio_event_matrix_func, .info.report_key_event = kaiser_key_event, .keymap = kaiser_keymap, .output_gpios = kaiser_row_gpios, .input_gpios = kaiser_col_gpios, .noutputs = ARRAY_SIZE(kaiser_row_gpios), .ninputs = ARRAY_SIZE(kaiser_col_gpios), .settle_time.tv.nsec = 0, .poll_time.tv.nsec = 20 * NSEC_PER_MSEC, .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE | GPIOKPF_PRINT_UNMAPPED_KEYS }; struct gpio_event_info *kaiser_keypad_info[] = { &kaiser_matrix_info.info }; static struct gpio_event_platform_data kaiser_keypad_data = { .name = "kaiser_keypad", .info = kaiser_keypad_info, .info_count = ARRAY_SIZE(kaiser_keypad_info) }; static struct platform_device kaiser_keypad_device = { .name = GPIO_EVENT_DEV_NAME, .id = -1, .dev = { .platform_data = &kaiser_keypad_data, }, }; void kaiser_init_keypad(void) { platform_device_register(&kaiser_keypad_device); }