FROM:http://blog.csdn.net/aree/article/details/28683741
按键没有hal层
设备中断-------驱动------>内核按键码(SCANCODE)-------*.kl--------> android keycode(char*)--------- KeycodeLabels.h ------>android keyevent(int, KeyEvent.java)
B:android keycode(char*)--------------- *.kcm/*.kcm.bin ------------>显示字符(char)
---
\alps\frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java
- public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
- if (!mSystemBooted) {
- // If we have not yet booted, don't let key events do anything.
- return 0;
- }
- // Handle special keys.
- switch (keyCode) {
- //add by //SCAN_123 ---
- case KeyEvent.KEYCODE_FN:
- if (down){
- fnflag = (!fnflag);
- Log.i(TAG, "fn status is " + fnflag);
- result &= ~ACTION_PASS_TO_USER;
- //add fn icon trs 2012-07-20
- Intent intent = new Intent(Intent.ACTION_FN_STATUS);
- intent.putExtra("fn_status", fnflag);
- mContext.sendBroadcast(intent);
- }
- break;
- case KeyEvent.KEYCODE_F1:
- case KeyEvent.KEYCODE_F2:
- case KeyEvent.KEYCODE_F3:
- case KeyEvent.KEYCODE_F4:
- if (!down){
- handleFKeys(keyCode);
- }
- result &= ~ACTION_PASS_TO_USER;
- break;
- //add end//SCAN_123 ---
event hub alps\frameworks\base\services\input\
event read
------------- alps\frameworks\base\core\java\android\view\KeyEvent.java 上层
- public class KeyEvent extends InputEvent implements Parcelable {
- /** Key code constant: Unknown key code. */
- public static final int KEYCODE_UNKNOWN = 0;
- /** Key code constant: Soft Left key.
- * Usually situated below the display on phones and used as a multi-function
- * feature key for selecting a software defined function shown on the bottom left
- * of the display. */
- public static final int KEYCODE_SOFT_LEFT = 1;
- /** Key code constant: Soft Right key.
- * Usually situated below the display on phones and used as a multi-function
- * feature key for selecting a software defined function shown on the bottom right
- * of the display. */
- public static final int KEYCODE_SOFT_RIGHT = 2;
- /** Key code constant: Home key.
- * This key is handled by the framework and is never delivered to applications. */
- public static final int KEYCODE_HOME = 3;
- /** Key code constant: Back key. */
- public static final int KEYCODE_BACK = 4;
- /** Key code constant: Call key. */
- public static final int KEYCODE_CALL = 5;
- public static final int KEYCODE_KANA = 218;
- /** Key code constant: Assist key.
- * Launches the global assist activity. Not delivered to applications. */
- public static final int KEYCODE_ASSIST = 219;
- public static final int KEYCODE_SCAN = 220;//sam add
- public static final int KEYCODE_SCAN_LEFT = 221;
- public static final int KEYCODE_SCAN_RIGHT = 222;
- public static final int KEYCODE_FN = 223;
- private static final int LAST_KEYCODE = KEYCODE_FN;//KEYCODE_ASSIST;////
- private static void populateKeycodeSymbolicNames() {
- SparseArray<String> names = KEYCODE_SYMBOLIC_NAMES;
- names.append(KEYCODE_UNKNOWN, "KEYCODE_UNKNOWN");
- names.append(KEYCODE_SOFT_LEFT, "KEYCODE_SOFT_LEFT");
- names.append(KEYCODE_SOFT_RIGHT, "KEYCODE_SOFT_RIGHT");
- names.append(KEYCODE_HOME, "KEYCODE_HOME");
- names.append(KEYCODE_BACK, "KEYCODE_BACK");
- names.append(KEYCODE_CALL, "KEYCODE_CALL");
- names.append(KEYCODE_ENDCALL, "KEYCODE_ENDCALL");
- names.append(KEYCODE_0, "KEYCODE_0");
alps\frameworks\base\api\17.txt // android API 17 = android4.2 //找到 17.txt文件改 //可能需要使用命令:./make update-api
- field public static final int KEYCODE_HOME = 3; // 0x3 //与上面的数字值要一样。
- ...
- field public static final int META_SHIFT_RIGHT_ON = 128; // 0x80
- field public static final int META_SYM_ON = 4; // 0x4
- field public static final int KEYCODE_SCAN = 220; // 0xdc
- field public static final int KEYCODE_SCAN_LEFT = 221; // 0xdd
- field public static final int KEYCODE_SCAN_RIGHT = 221; // 0xde
---
alpsAteam\frameworks\native\include\android\keycodes.h
- AKEYCODE_KANA = 218,
- AKEYCODE_ASSIST = 219,
- AKEYCODE_SCAN = 220,//sam add
- AKEYCODE_SCAN_LEFT = 221,
- AKEYCODE_SCAN_RIGHT = 222,
- AKEYCODE_FN = 223,
- // NOTE: If you add a new keycode here you must also add it to several other files.
- // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
- };
---
\alps\frameworks\base\libs\androidfw\Input.cpp
- bool KeyEvent::isSystemKey(int32_t keyCode) {
- switch (keyCode) {
- case AKEYCODE_MENU:
- case AKEYCODE_SOFT_RIGHT:
- case AKEYCODE_HOME:
- case AKEYCODE_BACK:
- case AKEYCODE_CALL:
- ....
- case AKEYCODE_SEARCH:
- case AKEYCODE_SCAN://sam add --below...
- case AKEYCODE_SCAN_LEFT:
- case AKEYCODE_SCAN_RIGHT:
- case AKEYCODE_FN:
- case AKEYCODE_F1:
- case AKEYCODE_F2:
- case AKEYCODE_F3:
- case AKEYCODE_F4:
- return true;
- }
----
alps\frameworks\native\include\input\KeycodeLabels.h...
static const KeycodeLabel KEYCODES[] = {//下层与上层的对照,能过字符串把两个数字来找的。
- { "SOFT_LEFT", 1 },
- { "SOFT_RIGHT", 2 },
- { "HOME", 3 },
- { "BACK", 4 },
- ...
- { "KANA", 218 },
- { "ASSIST", 219 },
- { "SCAN", 220 },//sam add
- { "SCAN_LEFT", 221 },
- { "SCAN_RIGHT", 222 },
- { "FN", 223 },
- // NOTE: If you add a new keycode here you must also add it to several other files.
- // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
- { NULL, 0 }
- };
mtk-kpd.kl //底层
....
- key 102 HOME
- ...
- key 59 F1
- key 60 F2
- key 61 F3
- key 62 F4
- key 464 FN
- key 220 SCAN
- key 125 SCAN_LEFT
- key 128 SCAN_RIGHT
...
----
//mt6571/72可以做18个的扩展键盘(3个row pin和3个col pin),但做不了更多,
3*3*2 =power , volume ,
更多keypad需要做8*8 (8 row pin 和8 col pin)
也可以外挂一个键盘ic来做。
-----
//mtk默认pmic有两个key ,一个是 power key,另一个是 vlume down key/home key/
在codegen.dws中
[KEYPAD Setting]页面,有一个PowerKey use EINT ,选中,则会打开了这个开关 KPD_PWRKEY_USE_EINT在mediatek\kernel\drivers\keypad\kpd.c中使用到.一般我们不用EINT做power key,而是默认使用pmic做power key.
- </pre><pre code_snippet_id="378654" snippet_file_name="blog_20140605_4_3325559" name="code" class="cpp">alps\mediatek\platform\mt6572\kernel\drivers\keypad\kpd.c
- /*
- * Copyright (C) 2010 MediaTek, Inc.
- *
- * Author: Terry Chang <[email protected]>
- *
- * 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 <linux/init.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/input.h>
- #include <linux/workqueue.h>
- #include <linux/timer.h>
- #include <linux/interrupt.h>
- #include <linux/fs.h>
- #include <linux/miscdevice.h>
- #include <linux/platform_device.h>
- #include <linux/earlysuspend.h>
- #include <linux/spinlock.h>
- #include <asm/atomic.h>
- #include <asm/uaccess.h>
- #include <mach/mt_reg_base.h>
- #include <mach/mt_boot.h>
- #include <mtk_kpd.h> /* custom file */
- #include <mach/irqs.h>
- #include <mach/eint.h>
- #include <mach/mt_gpio.h>
- #include <mach/mt_pmic_wrap.h>
- #include <mach/mt_sleep.h>
- #include <mach/kpd.h>
- #include <mach/sync_write.h>
- #include <linux/aee.h>
- #if 1 //ATA_TEST
- #define KPD_AUTOTEST_BY_KP
- #endif
- #define KPD_NAME "mtk-kpd"
- /* Keypad registers */
- #define KP_STA (KP_BASE + 0x0000)
- #define KP_MEM1 (KP_BASE + 0x0004)
- #define KP_MEM2 (KP_BASE + 0x0008)
- #define KP_MEM3 (KP_BASE + 0x000c)
- #define KP_MEM4 (KP_BASE + 0x0010)
- #define KP_MEM5 (KP_BASE + 0x0014)
- #define KP_DEBOUNCE (KP_BASE + 0x0018)
- #define KP_SCAN_TIMING (KP_BASE + 0x001C)
- #define KP_SEL (KP_BASE + 0x0020)
- #define KP_EN (KP_BASE + 0x0024)
- #define KPD_NUM_MEMS 5
- #define KPD_MEM5_BITS 8
- #define KPD_NUM_KEYS 72 /* 4 * 16 + KPD_MEM5_BITS */
- #define KPD_DEBOUNCE_MASK ((1U << 14) - 1)
- #define KPD_SAY "kpd: "
- #if KPD_DEBUG
- #define kpd_print(fmt, arg...) printk(KPD_SAY fmt, ##arg)
- #else
- #define kpd_print(fmt, arg...) do {} while (0)
- #endif
- static struct input_dev *kpd_input_dev;
- static bool kpd_suspend = false;
- static int kpd_show_hw_keycode = 1;
- static int kpd_show_register = 1;
- static int kpd_enable_lprst = 1;
- /* for AEE manual dump */
- #if 0
- static bool kpd_volumn_down_flag = false;
- static bool kpd_volumn_up_flag = false;
- static inline void check_aee_dump()
- {
- if( (kpd_volumn_down_flag == true) && (kpd_volumn_up_flag == true))
- {
- printk(KPD_SAY "kpd_volumn_up+ volumn_down,will trige DB\n");
- aee_kernel_reminding("manual dump ", "Triggered by press KEY_VOLUMEUP+KEY_VOLUMEDOWN");
- }
- }
- #endif
- /* for backlight control */
- #if KPD_DRV_CTRL_BACKLIGHT
- static void kpd_switch_backlight(struct work_struct *work);
- static void kpd_backlight_timeout(unsigned long data);
- static DECLARE_WORK(kpd_backlight_work, kpd_switch_backlight);
- static DEFINE_TIMER(kpd_backlight_timer, kpd_backlight_timeout, 0, 0);
- static unsigned long kpd_wake_keybit[BITS_TO_LONGS(KEY_CNT)];
- static u16 kpd_wake_key[] __initdata = KPD_BACKLIGHT_WAKE_KEY;
- static volatile bool kpd_backlight_on;
- static atomic_t kpd_key_pressed = ATOMIC_INIT(0);
- #endif
- /* for slide QWERTY */
- #if KPD_HAS_SLIDE_QWERTY
- static void kpd_slide_handler(unsigned long data);
- static DECLARE_TASKLET(kpd_slide_tasklet, kpd_slide_handler, 0);
- static u8 kpd_slide_state = !KPD_SLIDE_POLARITY;
- #endif
- /* for Power key using EINT */
- #if KPD_PWRKEY_USE_EINT
- static void kpd_pwrkey_handler(unsigned long data);
- static DECLARE_TASKLET(kpd_pwrkey_tasklet, kpd_pwrkey_handler, 0);
- static u8 kpd_pwrkey_state = !KPD_PWRKEY_POLARITY;
- #endif
- /* for Power key using PMIC */
- /*********************************************************************/
- #if 0//KPD_PWRKEY_USE_PMIC //for 77 chip and earlier version power key bug, has fixed on 89 chip
- static void kpd_pwrkey_handler(struct work_struct *work);
- static DECLARE_WORK(pwrkey_pmic_work, kpd_pwrkey_handler);
- #endif
- /*********************************************************************/
- /* for keymap handling */
- static DEFINE_SPINLOCK(keymap_handler_spinlock);
- static void kpd_keymap_handler(unsigned long data);
- static DECLARE_TASKLET(kpd_keymap_tasklet, kpd_keymap_handler, 0);
- #define KPD_INIT_KEYMAP_FULL() \
- { \
- [0] = KEY_1, \
- [1] = KEY_2, \
- [2] = KEY_3, \
- [3] = KEY_4, \
- [4] = KEY_5, \
- [5] = KEY_6, \
- [6] = KEY_7, \
- [7] = KEY_8, \
- [8] = KEY_9, \
- [9] = KEY_VOLUMEDOWN, \
- [10] = KEY_VOLUMEUP, \
- [11] = KEY_0, \
- [12] = KEY_ENTER, \
- [13] = KEY_TAB, \
- [14] = KEY_BACKSPACE, \
- [15] = KEY_STAR, \
- [16] = KEY_POUND, \
- [17] = KEY_SYM, \
- [18] = KEY_DOT, \
- [19] = KEY_FN, \
- [20] = KEY_F1, \
- [21] = KEY_F2, \
- [22] = KEY_F3, \
- [23] = KEY_F4, \
- [24] = KEY_DEL, \
- [25] = KEY_S, \
- [25] = KEY_OK, \
- }
- //static u16 kpd_keymap[KPD_NUM_KEYS] = KPD_INIT_KEYMAP_FULL(); //KPD_INIT_KEYMAP();
- static u16 kpd_keymap[KPD_NUM_KEYS] = KPD_INIT_KEYMAP();
- static u16 kpd_keymap_state[KPD_NUM_MEMS] = {
- 0xffff, 0xffff, 0xffff, 0xffff, 0x00ff
- };
- /*********************************************************************/
- /*************************kpd function decleare***************************/
- /*********************************************************************/
- static int kpd_pdrv_probe(struct platform_device *pdev);
- static int kpd_pdrv_remove(struct platform_device *pdev);
- #ifndef CONFIG_HAS_EARLYSUSPEND
- static int kpd_pdrv_suspend(struct platform_device *pdev, pm_message_t state);
- static int kpd_pdrv_resume(struct platform_device *pdev);
- #endif
- void mtk_kpd_get_gpio_col(unsigned int COL_REG[], unsigned int GPIO_MODE[]);
- void kpd_auto_test_for_factorymode(void);
- static struct platform_driver kpd_pdrv = {
- .probe = kpd_pdrv_probe,
- .remove = kpd_pdrv_remove,
- #ifndef CONFIG_HAS_EARLYSUSPEND
- .suspend = kpd_pdrv_suspend,
- .resume = kpd_pdrv_resume,
- #endif
- .driver = {
- .name = KPD_NAME,
- .owner = THIS_MODULE,
- },
- };
- /********************************************************************/
- void mtk_kpd_get_gpio_col(unsigned int COL_REG[], unsigned int GPIO_MODE[])
- {
- int i;
- for(i = 0; i< 8; i++)
- {
- COL_REG[i] = 0;
- GPIO_MODE[i] = 0;
- }
- kpd_print("Enter mtk_kpd_get_gpio_col! \n");
- #ifdef GPIO_KPD_KCOL0_PIN
- kpd_print("checking GPIO_KPD_KCOL0_PIN! \n");
- COL_REG[0] = GPIO_KPD_KCOL0_PIN;
- GPIO_MODE[0] |= (GPIO_KPD_KCOL0_PIN_M_KCOL << 4);
- #endif
- #ifdef GPIO_KPD_KCOL1_PIN
- kpd_print("checking GPIO_KPD_KCOL1_PIN! \n");
- COL_REG[1] = GPIO_KPD_KCOL1_PIN;
- GPIO_MODE[1] |= (GPIO_KPD_KCOL1_PIN_M_KCOL << 4);
- #endif
- #ifdef GPIO_KPD_KCOL2_PIN
- kpd_print("checking GPIO_KPD_KCOL2_PIN! \n");
- COL_REG[2] = GPIO_KPD_KCOL2_PIN;
- GPIO_MODE[2] |= (GPIO_KPD_KCOL2_PIN_M_KCOL << 4);
- #endif
- #ifdef GPIO_KPD_KCOL3_PIN
- kpd_print("checking GPIO_KPD_KCOL3_PIN! \n");
- COL_REG[3] = GPIO_KPD_KCOL3_PIN;
- GPIO_MODE[3] |= (GPIO_KPD_KCOL3_PIN_M_KCOL << 4);
- #endif
- #ifdef GPIO_KPD_KCOL4_PIN
- kpd_print("checking GPIO_KPD_KCOL4_PIN! \n");
- COL_REG[4] = GPIO_KPD_KCOL4_PIN;
- GPIO_MODE[4] |= (GPIO_KPD_KCOL4_PIN_M_KCOL << 4);
- #endif
- #ifdef GPIO_KPD_KCOL5_PIN
- kpd_print("checking GPIO_KPD_KCOL5_PIN! \n");
- COL_REG[5] = GPIO_KPD_KCOL5_PIN;
- GPIO_MODE[5] |= (GPIO_KPD_KCOL5_PIN_M_KCOL << 4);
- #endif
- #ifdef GPIO_KPD_KCOL6_PIN
- kpd_print("checking GPIO_KPD_KCOL6_PIN! \n");
- COL_REG[6] = GPIO_KPD_KCOL6_PIN;
- GPIO_MODE[6] |= (GPIO_KPD_KCOL6_PIN_M_KCOL << 4);
- #endif
- #ifdef GPIO_KPD_KCOL7_PIN
- kpd_print("checking GPIO_KPD_KCOL7_PIN! \n");
- COL_REG[7] = GPIO_KPD_KCOL7_PIN;
- GPIO_MODE[7] |= (GPIO_KPD_KCOL7_PIN_M_KCOL << 4);
- #endif
- }
- #ifdef KPD_AUTOTEST_BY_KP
- void kpd_reset_keymap_state(u16 state[])
- {
- int i;
- for(i = 0; i < (KPD_NUM_MEMS - 1); i++)
- state[i] = 0xffff;
- state[(KPD_NUM_MEMS - 1)] = 0x00ff;
- return;
- }
- void kpd_kcol_scan_for_factorymode(void)
- {
- unsigned int COL_REG[8], COL_LAST = 0;
- unsigned int GPIO_MODE[8];
- int i, col_num;
- #if !KPD_USE_EXTEND_TYPE
- kpd_print("Enter kpd_kcol_scan_for_factorymode on single keypad! \n");
- col_num = 8;
- #else
- kpd_print("Enter kpd_kcol_scan_for_factorymode on double keypad! \n");
- col_num = 3;
- #endif
- disable_irq_nosync(MT_KP_IRQ_ID);
- *(volatile u16 *)KP_EN = 0;
- kpd_keymap_handler(1);
- msleep(100);
- mtk_kpd_get_gpio_col(COL_REG, GPIO_MODE);
- for(i = 0; i < col_num; i++)
- {
- if (COL_REG[i] != 0)
- mt_set_gpio_mode(COL_REG[i], GPIO_MODE_GPIO);
- }
- for(i = 0; i < col_num; i++)
- {
- if (COL_REG[i] != 0)
- {
- mt_set_gpio_mode(COL_REG[i], ((GPIO_MODE[i] >> 4) & 0x0f));
- kpd_reset_keymap_state(kpd_keymap_state);
- COL_LAST = COL_REG[i];
- *(volatile u16 *)KP_EN = 0x1;
- kpd_print("kpd_kcol_scan_for_factorymode: KP enable KCOL=%d \n", i);
- }
- msleep(100);
- if(*(volatile u16 *)KP_STA & 0x01)
- kpd_keymap_handler(2);
- if(0 != COL_LAST)
- {
- msleep(100);
- kpd_keymap_handler(1);
- *(volatile u16 *)KP_EN = 0;
- mt_set_gpio_mode(COL_LAST, GPIO_MODE_GPIO);
- kpd_print("kpd_kcol_scan_for_factorymode: KP disable KCOL=%d \n", i);
- COL_LAST = 0;
- }
- }
- for(i = 0; i < col_num; i++)
- {
- if (COL_REG[i] != 0)
- mt_set_gpio_mode(COL_REG[i], ((GPIO_MODE[i] >> 4) & 0x0f));
- }
- kpd_reset_keymap_state(kpd_keymap_state);
- *(volatile u16 *)KP_EN = 0x1;
- if(upmu_get_pwrkey_deb()!=1)
- {
- kpd_pwrkey_pmic_handler(0);
- msleep(100);
- kpd_pwrkey_pmic_handler(1);
- }
- enable_irq(MT_KP_IRQ_ID);
- return;
- }
- #else //KPD_AUTOTEST_BY_KP
- void kpd_auto_test_for_factorymode(void)
- {
- unsigned int COL_REG[8];
- unsigned int GPIO_MODE[8];
- int i;
- kpd_pwrkey_pmic_handler(1);
- msleep(100);
- kpd_pwrkey_pmic_handler(0);
- #ifdef KPD_PMIC_RSTKEY_MAP
- kpd_pmic_rstkey_handler(1);
- msleep(100);
- kpd_pmic_rstkey_handler(0);
- #endif
- kpd_print("Enter kpd_auto_test_for_factorymode! \n");
- mtk_kpd_get_gpio_col(COL_REG, GPIO_MODE);
- for(i = 0; i < 8; i++)
- {
- if (COL_REG[i] != 0)
- {
- msleep(100);
- kpd_print("kpd kcolumn %d pull down!\n", COL_REG[i]);
- mt_set_gpio_pull_select(COL_REG[i], 0);
- msleep(100);
- kpd_print("kpd kcolumn %d pull up!\n", COL_REG[i]);
- mt_set_gpio_pull_select(COL_REG[i], 1);
- }
- }
- return;
- }
- #endif //KPD_AUTOTEST_BY_KP
- /********************************************************************/
- /********************************************************************/
- /*****************for kpd auto set wake up source*************************/
- /********************************************************************/
- static volatile int call_status = 0;
- static ssize_t kpd_store_call_state(struct device_driver *ddri, const char *buf, size_t count)
- {
- if (sscanf(buf, "%u", &call_status) != 1) {
- kpd_print("kpd call state: Invalid values\n");
- return -EINVAL;
- }
- switch(call_status)
- {
- case 1 :
- kpd_print("kpd call state: Idle state!\n");
- break;
- case 2 :
- kpd_print("kpd call state: ringing state!\n");
- break;
- case 3 :
- kpd_print("kpd call state: active or hold state!\n");
- break;
- default:
- kpd_print("kpd call state: Invalid values\n");
- break;
- }
- return count;
- }
- static ssize_t kpd_show_call_state(struct device_driver *ddri, char *buf)
- {
- ssize_t res;
- res = snprintf(buf, PAGE_SIZE, "%d\n", call_status);
- return res;
- }
- static DRIVER_ATTR(kpd_call_state, S_IWUSR | S_IRUGO, kpd_show_call_state, kpd_store_call_state);
- static struct driver_attribute *kpd_attr_list[] = {
- &driver_attr_kpd_call_state,
- };
- /*----------------------------------------------------------------------------*/
- static int kpd_create_attr(struct device_driver *driver)
- {
- int idx, err = 0;
- int num = (int)(sizeof(kpd_attr_list)/sizeof(kpd_attr_list[0]));
- if (driver == NULL)
- {
- return -EINVAL;
- }
- for(idx = 0; idx < num; idx++)
- {
- if((err = driver_create_file(driver, kpd_attr_list[idx])))
- {
- kpd_print("driver_create_file (%s) = %d\n", kpd_attr_list[idx]->attr.name, err);
- break;
- }
- }
- return err;
- }
- /*----------------------------------------------------------------------------*/
- static int kpd_delete_attr(struct device_driver *driver)
- {
- int idx ,err = 0;
- int num = (int)(sizeof(kpd_attr_list)/sizeof(kpd_attr_list[0]));
- if (!driver)
- return -EINVAL;
- for (idx = 0; idx < num; idx++)
- {
- driver_remove_file(driver, kpd_attr_list[idx]);
- }
- return err;
- }
- /*----------------------------------------------------------------------------*/
- /********************************************************************/
- /********************************************************************/
- /********************************************************************/
- /* for autotest */
- #if KPD_AUTOTEST
- static const u16 kpd_auto_keymap[] = {
- KEY_OK, KEY_MENU,
- KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,
- KEY_HOME, KEY_BACK,
- KEY_CALL, KEY_ENDCALL,
- KEY_VOLUMEUP, KEY_VOLUMEDOWN,
- KEY_FOCUS, KEY_CAMERA,
- };
- #endif
- /* for AEE manual dump */
- #define AEE_VOLUMEUP_BIT 0
- #define AEE_VOLUMEDOWN_BIT 1
- #define AEE_DELAY_TIME 15
- /* enable volup + voldown was pressed 5~15 s Trigger aee manual dump */
- #define AEE_ENABLE_5_15 1
- static struct hrtimer aee_timer;
- static unsigned long aee_pressed_keys;
- static bool aee_timer_started;
- #if AEE_ENABLE_5_15
- #define AEE_DELAY_TIME_5S 5
- static struct hrtimer aee_timer_5s;
- static bool aee_timer_5s_started;
- static bool flags_5s;
- #endif
- static inline void kpd_update_aee_state(void) {
- if(aee_pressed_keys == ((1<<AEE_VOLUMEUP_BIT) | (1<<AEE_VOLUMEDOWN_BIT))) {
- /* if volumeup and volumedown was pressed the same time then start the time of ten seconds */
- aee_timer_started = true;
- #if AEE_ENABLE_5_15
- aee_timer_5s_started = true;
- hrtimer_start(&aee_timer_5s,
- ktime_set(AEE_DELAY_TIME_5S, 0),
- HRTIMER_MODE_REL);
- #endif
- hrtimer_start(&aee_timer,
- ktime_set(AEE_DELAY_TIME, 0),
- HRTIMER_MODE_REL);
- kpd_print("aee_timer started\n");
- } else {
- if(aee_timer_started) {
- /*
- * hrtimer_cancel - cancel a timer and wait for the handler to finish.
- * Returns:
- * 0 when the timer was not active.
- * 1 when the timer was active.
- */
- if(hrtimer_cancel(&aee_timer))
- {
- kpd_print("try to cancel hrtimer \n");
- #if AEE_ENABLE_5_15
- if(flags_5s)
- {
- printk("Pressed Volup + Voldown5s~15s then trigger aee manual dump.\n");
- aee_kernel_reminding("manual dump", "Trigger Vol Up +Vol Down 5s");
- }
- #endif
- }
- #if AEE_ENABLE_5_15
- flags_5s = false;
- #endif
- aee_timer_started = false;
- kpd_print("aee_timer canceled\n");
- }
- #if AEE_ENABLE_5_15
- if(aee_timer_5s_started) {
- /*
- * hrtimer_cancel - cancel a timer and wait for the handler to finish.
- * Returns:
- * 0 when the timer was not active.
- * 1 when the timer was active.
- */
- if(hrtimer_cancel(&aee_timer_5s))
- {
- kpd_print("try to cancel hrtimer (5s) \n");
- }
- aee_timer_5s_started = false;
- kpd_print("aee_timer canceled (5s)\n");
- }
- #endif
- }
- }
- static void kpd_aee_handler(u32 keycode, u16 pressed) {
- if(pressed) {
- if(keycode == KEY_VOLUMEUP) {
- __set_bit(AEE_VOLUMEUP_BIT, &aee_pressed_keys);
- } else if(keycode == KEY_VOLUMEDOWN) {
- __set_bit(AEE_VOLUMEDOWN_BIT, &aee_pressed_keys);
- } else {
- return;
- }
- kpd_update_aee_state();
- } else {
- if(keycode == KEY_VOLUMEUP) {
- __clear_bit(AEE_VOLUMEUP_BIT, &aee_pressed_keys);
- } else if(keycode == KEY_VOLUMEDOWN) {
- __clear_bit(AEE_VOLUMEDOWN_BIT, &aee_pressed_keys);
- } else {
- return;
- }
- kpd_update_aee_state();
- }
- }
- static enum hrtimer_restart aee_timer_func(struct hrtimer *timer) {
- //printk("kpd: vol up+vol down AEE manual dump!\n");
- //aee_kernel_reminding("manual dump ", "Triggered by press KEY_VOLUMEUP+KEY_VOLUMEDOWN");
- aee_trigger_kdb();
- return HRTIMER_NORESTART;
- }
- #if AEE_ENABLE_5_15
- static enum hrtimer_restart aee_timer_5s_func(struct hrtimer *timer) {
- //printk("kpd: vol up+vol down AEE manual dump timer 5s !\n");
- flags_5s = true;
- return HRTIMER_NORESTART;
- }
- #endif
- static inline void kpd_get_keymap_state(u16 state[])
- {
- state[0] = *(volatile u16 *)KP_MEM1;
- state[1] = *(volatile u16 *)KP_MEM2;
- state[2] = *(volatile u16 *)KP_MEM3;
- state[3] = *(volatile u16 *)KP_MEM4;
- state[4] = *(volatile u16 *)KP_MEM5;
- if (kpd_show_register) {
- printk(KPD_SAY "register = %x %x %x %x %x\n",
- state[0], state[1], state[2], state[3], state[4]);
- }
- }
- static inline void kpd_set_debounce(u16 val)
- {
- mt65xx_reg_sync_writew((u16)(val & KPD_DEBOUNCE_MASK), KP_DEBOUNCE);
- }
- #if KPD_DRV_CTRL_BACKLIGHT
- static void kpd_switch_backlight(struct work_struct *work)
- {
- if (kpd_backlight_on) {
- kpd_enable_backlight();
- kpd_print("backlight is on\n");
- } else {
- kpd_disable_backlight();
- kpd_print("backlight is off\n");
- }
- }
- static void kpd_backlight_timeout(unsigned long data)
- {
- if (!atomic_read(&kpd_key_pressed)) {
- kpd_backlight_on = !!atomic_read(&kpd_key_pressed);
- schedule_work(&kpd_backlight_work);
- data = 1;
- }
- kpd_print("backlight timeout%s\n",
- data ? ": schedule backlight work" : "");
- }
- void kpd_backlight_handler(bool pressed, u16 linux_keycode)
- {
- if (kpd_suspend && !test_bit(linux_keycode, kpd_wake_keybit)) {
- kpd_print("Linux keycode %u is not WAKE key\n", linux_keycode);
- return;
- }
- /* not in suspend or the key pressed is WAKE key */
- if (pressed) {
- atomic_inc(&kpd_key_pressed);
- kpd_backlight_on = !!atomic_read(&kpd_key_pressed);
- schedule_work(&kpd_backlight_work);
- kpd_print("switch backlight on\n");
- } else {
- atomic_dec(&kpd_key_pressed);
- mod_timer(&kpd_backlight_timer,
- jiffies + KPD_BACKLIGHT_TIME * HZ);
- kpd_print("activate backlight timer\n");
- }
- }
- #endif
- #if KPD_HAS_SLIDE_QWERTY
- static void kpd_slide_handler(unsigned long data)
- {
- bool slid;
- u8 old_state = kpd_slide_state;
- kpd_slide_state = !kpd_slide_state;
- slid = (kpd_slide_state == !!KPD_SLIDE_POLARITY);
- /* for SW_LID, 1: lid open => slid, 0: lid shut => closed */
- input_report_switch(kpd_input_dev, SW_LID, slid);
- input_sync(kpd_input_dev);
- kpd_print("report QWERTY = %s\n", slid ? "slid" : "closed");
- if(old_state) {
- mt_set_gpio_pull_select(GPIO_QWERTYSLIDE_EINT_PIN, 0);
- } else {
- mt_set_gpio_pull_select(GPIO_QWERTYSLIDE_EINT_PIN, 1);
- }
- /* for detecting the return to old_state */
- mt65xx_eint_set_polarity(KPD_SLIDE_EINT, old_state);
- mt65xx_eint_unmask(KPD_SLIDE_EINT);
- }
- static void kpd_slide_eint_handler(void)
- {
- tasklet_schedule(&kpd_slide_tasklet);
- }
- #endif
- #if KPD_PWRKEY_USE_EINT
- static void kpd_pwrkey_handler(unsigned long data)
- {
- bool pressed;
- u8 old_state = kpd_pwrkey_state;
- kpd_pwrkey_state = !kpd_pwrkey_state;
- pressed = (kpd_pwrkey_state == !!KPD_PWRKEY_POLARITY);
- if (kpd_show_hw_keycode) {
- printk(KPD_SAY "(%s) HW keycode = using EINT\n",
- pressed ? "pressed" : "released");
- }
- kpd_backlight_handler(pressed, KPD_PWRKEY_MAP);
- input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
- input_sync(kpd_input_dev);
- kpd_print("report Linux keycode = %u\n", KPD_PWRKEY_MAP);
- /* for detecting the return to old_state */
- mt65xx_eint_set_polarity(KPD_PWRKEY_EINT, old_state);
- mt65xx_eint_unmask(KPD_PWRKEY_EINT);
- }
- static void kpd_pwrkey_eint_handler(void)
- {
- tasklet_schedule(&kpd_pwrkey_tasklet);
- }
- #endif
- /*********************************************************************/
- #if 0//KPD_PWRKEY_USE_PMIC //for 77 chip and earlier version power key bug, has fixed on 89 chip
- static void kpd_pwrkey_handler(struct work_struct *work)
- {
- int pressed = 1;
- /* report Press*/
- input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
- input_sync(kpd_input_dev);
- if (kpd_show_hw_keycode) {
- printk(KPD_SAY "(%s) HW keycode = using PMIC\n",
- pressed ? "pressed" : "released");
- }
- while(1)
- {
- if(upmu_get_pwrkey_deb() == 1)
- {
- pressed = 0;
- /* Report Release */
- input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
- input_sync(kpd_input_dev);
- if (kpd_show_hw_keycode) {
- printk(KPD_SAY "(%s) HW keycode = using PMIC\n",
- pressed ? "pressed" : "released");
- }
- break;
- }
- msleep(10);
- }
- }
- void kpd_pwrkey_pmic_handler(unsigned long pressed)
- {
- printk(KPD_SAY "Power Key generate, pressed=%ld\n", pressed);
- if(!kpd_input_dev) {
- printk("KPD input device not ready\n");
- return;
- }
- if(get_chip_eco_ver() == CHIP_E2) {
- input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
- input_sync(kpd_input_dev);
- if (kpd_show_hw_keycode) {
- printk(KPD_SAY "(%s) HW keycode =%d using PMIC\n",
- pressed ? "pressed" : "released", KPD_PWRKEY_MAP);
- }
- } else {
- schedule_work(&pwrkey_pmic_work);
- }
- }
- #endif
- /*********************************************************************/
- #if KPD_PWRKEY_USE_PMIC
- void kpd_pwrkey_pmic_handler(unsigned long pressed)
- {
- printk(KPD_SAY "Power Key generate, pressed=%ld\n", pressed);
- if(!kpd_input_dev) {
- printk("KPD input device not ready\n");
- return;
- }
- input_report_key(kpd_input_dev, KPD_PWRKEY_MAP, pressed);
- input_sync(kpd_input_dev);
- if (kpd_show_hw_keycode) {
- printk(KPD_SAY "(%s) HW keycode =%d using PMIC\n",
- pressed ? "pressed" : "released", KPD_PWRKEY_MAP);
- }
- }
- #endif
- /*********************************************************************/
- void kpd_pmic_rstkey_handler(unsigned long pressed)
- {
- printk(KPD_SAY "PMIC reset Key generate, pressed=%ld\n", pressed);
- if(!kpd_input_dev) {
- printk("KPD input device not ready\n");
- return;
- }
- #ifdef KPD_PMIC_RSTKEY_MAP
- input_report_key(kpd_input_dev, KPD_PMIC_RSTKEY_MAP, pressed);
- input_sync(kpd_input_dev);
- if (kpd_show_hw_keycode) {
- printk(KPD_SAY "(%s) HW keycode =%d using PMIC\n",
- pressed ? "pressed" : "released", KPD_PMIC_RSTKEY_MAP);
- }
- kpd_aee_handler(KPD_PMIC_RSTKEY_MAP, pressed);
- #endif
- }
- static void kpd_keymap_handler(unsigned long data)
- {
- int i, j;
- bool pressed;
- u16 new_state[KPD_NUM_MEMS], change, mask;
- u16 hw_keycode, linux_keycode;
- spin_lock(&keymap_handler_spinlock);
- kpd_get_keymap_state(new_state);
- #ifdef KPD_AUTOTEST_BY_KP
- if(data == 1)
- kpd_reset_keymap_state(new_state);
- kpd_print("kpd_keymap_handler: data=%d, new_state = %x %x %x %x %x \n",
- data, new_state[0], new_state[1], new_state[2], new_state[3], new_state[4]);
- #endif
- for (i = 0; i < KPD_NUM_MEMS; i++) {
- change = new_state[i] ^ kpd_keymap_state[i];
- if (!change)
- continue;
- for (j = 0; j < 16; j++) {
- mask = 1U << j;
- if (!(change & mask))
- continue;
- hw_keycode = (i << 4) + j;
- /* bit is 1: not pressed, 0: pressed */
- pressed = !(new_state[i] & mask);
- if (kpd_show_hw_keycode) {
- printk(KPD_SAY "(%s) HW keycode = %u\n",
- pressed ? "pressed" : "released",
- hw_keycode);
- }
- BUG_ON(hw_keycode >= KPD_NUM_KEYS);
- linux_keycode = kpd_keymap[hw_keycode];
- if (unlikely(linux_keycode == 0)) {
- kpd_print("Linux keycode = 0\n");
- continue;
- }
- #ifdef KPD_AUTOTEST_BY_KP
- if((get_boot_mode() != FACTORY_BOOT) && (get_boot_mode() != ATE_FACTORY_BOOT))
- #endif
- kpd_aee_handler(linux_keycode, pressed);
- kpd_backlight_handler(pressed, linux_keycode);
- input_report_key(kpd_input_dev, linux_keycode, pressed);
- input_sync(kpd_input_dev);
- kpd_print("report Linux keycode = %u\n", linux_keycode);
- }
- }
- memcpy(kpd_keymap_state, new_state, sizeof(new_state));
- //kpd_print("save new keymap state\n");
- #ifdef KPD_AUTOTEST_BY_KP
- if(data == 0)
- #endif
- enable_irq(MT_KP_IRQ_ID);
- spin_unlock(&keymap_handler_spinlock);
- }
- static irqreturn_t kpd_irq_handler(int irq, void *dev_id)
- {
- /* use _nosync to avoid deadlock */
- disable_irq_nosync(MT_KP_IRQ_ID);
- tasklet_schedule(&kpd_keymap_tasklet);
- return IRQ_HANDLED;
- }
- static long kpd_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
- {
- void __user *uarg = (void __user *)arg;
- struct kpd_ledctl ledctl;
- switch (cmd) {
- #if KPD_AUTOTEST
- case PRESS_OK_KEY://KPD_AUTOTEST disable auto test setting to resolve CR ALPS00464496
- if(test_bit(KEY_OK, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS OK KEY!!\n");
- input_report_key(kpd_input_dev, KEY_OK, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support OK KEY!!\n");
- }
- break;
- case RELEASE_OK_KEY:
- if(test_bit(KEY_OK, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE OK KEY!!\n");
- input_report_key(kpd_input_dev, KEY_OK, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support OK KEY!!\n");
- }
- break;
- case PRESS_MENU_KEY:
- if(test_bit(KEY_MENU, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS MENU KEY!!\n");
- input_report_key(kpd_input_dev, KEY_MENU, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support MENU KEY!!\n");
- }
- break;
- case RELEASE_MENU_KEY:
- if(test_bit(KEY_MENU, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE MENU KEY!!\n");
- input_report_key(kpd_input_dev, KEY_MENU, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support MENU KEY!!\n");
- }
- break;
- case PRESS_UP_KEY:
- if(test_bit(KEY_UP, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS UP KEY!!\n");
- input_report_key(kpd_input_dev, KEY_UP, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support UP KEY!!\n");
- }
- break;
- case RELEASE_UP_KEY:
- if(test_bit(KEY_UP, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE UP KEY!!\n");
- input_report_key(kpd_input_dev, KEY_UP, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support UP KEY!!\n");
- }
- break;
- case PRESS_DOWN_KEY:
- if(test_bit(KEY_DOWN, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS DOWN KEY!!\n");
- input_report_key(kpd_input_dev, KEY_DOWN, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support DOWN KEY!!\n");
- }
- break;
- case RELEASE_DOWN_KEY:
- if(test_bit(KEY_DOWN, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE DOWN KEY!!\n");
- input_report_key(kpd_input_dev, KEY_DOWN, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support DOWN KEY!!\n");
- }
- break;
- case PRESS_LEFT_KEY:
- if(test_bit(KEY_LEFT, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS LEFT KEY!!\n");
- input_report_key(kpd_input_dev, KEY_LEFT, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support LEFT KEY!!\n");
- }
- break;
- case RELEASE_LEFT_KEY:
- if(test_bit(KEY_LEFT, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE LEFT KEY!!\n");
- input_report_key(kpd_input_dev, KEY_LEFT, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support LEFT KEY!!\n");
- }
- break;
- case PRESS_RIGHT_KEY:
- if(test_bit(KEY_RIGHT, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS RIGHT KEY!!\n");
- input_report_key(kpd_input_dev, KEY_RIGHT, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support RIGHT KEY!!\n");
- }
- break;
- case RELEASE_RIGHT_KEY:
- if(test_bit(KEY_RIGHT, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE RIGHT KEY!!\n");
- input_report_key(kpd_input_dev, KEY_RIGHT, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support RIGHT KEY!!\n");
- }
- break;
- case PRESS_HOME_KEY:
- if(test_bit(KEY_HOME, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS HOME KEY!!\n");
- input_report_key(kpd_input_dev, KEY_HOME, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support HOME KEY!!\n");
- }
- break;
- case RELEASE_HOME_KEY:
- if(test_bit(KEY_HOME, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE HOME KEY!!\n");
- input_report_key(kpd_input_dev, KEY_HOME, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support HOME KEY!!\n");
- }
- break;
- case PRESS_BACK_KEY:
- if(test_bit(KEY_BACK, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS BACK KEY!!\n");
- input_report_key(kpd_input_dev, KEY_BACK, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support BACK KEY!!\n");
- }
- break;
- case RELEASE_BACK_KEY:
- if(test_bit(KEY_BACK, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE BACK KEY!!\n");
- input_report_key(kpd_input_dev, KEY_BACK, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support BACK KEY!!\n");
- }
- break;
- case PRESS_CALL_KEY:
- if(test_bit(KEY_CALL, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS CALL KEY!!\n");
- input_report_key(kpd_input_dev, KEY_CALL, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support CALL KEY!!\n");
- }
- break;
- case RELEASE_CALL_KEY:
- if(test_bit(KEY_CALL, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE CALL KEY!!\n");
- input_report_key(kpd_input_dev, KEY_CALL, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support CALL KEY!!\n");
- }
- break;
- case PRESS_ENDCALL_KEY:
- if(test_bit(KEY_ENDCALL, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS ENDCALL KEY!!\n");
- input_report_key(kpd_input_dev, KEY_ENDCALL, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support ENDCALL KEY!!\n");
- }
- break;
- case RELEASE_ENDCALL_KEY:
- if(test_bit(KEY_ENDCALL, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE ENDCALL KEY!!\n");
- input_report_key(kpd_input_dev, KEY_ENDCALL, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support ENDCALL KEY!!\n");
- }
- break;
- case PRESS_VLUP_KEY:
- if(test_bit(KEY_VOLUMEUP, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS VOLUMEUP KEY!!\n");
- input_report_key(kpd_input_dev, KEY_VOLUMEUP, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support VOLUMEUP KEY!!\n");
- }
- break;
- case RELEASE_VLUP_KEY:
- if(test_bit(KEY_VOLUMEUP, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE VOLUMEUP KEY!!\n");
- input_report_key(kpd_input_dev, KEY_VOLUMEUP, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support VOLUMEUP KEY!!\n");
- }
- break;
- case PRESS_VLDOWN_KEY:
- if(test_bit(KEY_VOLUMEDOWN, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS VOLUMEDOWN KEY!!\n");
- input_report_key(kpd_input_dev, KEY_VOLUMEDOWN, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support VOLUMEDOWN KEY!!\n");
- }
- break;
- case RELEASE_VLDOWN_KEY:
- if(test_bit(KEY_VOLUMEDOWN, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE VOLUMEDOWN KEY!!\n");
- input_report_key(kpd_input_dev, KEY_VOLUMEDOWN, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support VOLUMEDOWN KEY!!\n");
- }
- break;
- case PRESS_FOCUS_KEY:
- if(test_bit(KEY_FOCUS, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS FOCUS KEY!!\n");
- input_report_key(kpd_input_dev, KEY_FOCUS, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support FOCUS KEY!!\n");
- }
- break;
- case RELEASE_FOCUS_KEY:
- if(test_bit(KEY_FOCUS, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE FOCUS KEY!!\n");
- input_report_key(kpd_input_dev, KEY_FOCUS, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support RELEASE KEY!!\n");
- }
- break;
- case PRESS_CAMERA_KEY:
- if(test_bit(KEY_CAMERA, kpd_input_dev->keybit)){
- printk("[AUTOTEST] PRESS CAMERA KEY!!\n");
- input_report_key(kpd_input_dev, KEY_CAMERA, 1);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support CAMERA KEY!!\n");
- }
- break;
- case RELEASE_CAMERA_KEY:
- if(test_bit(KEY_CAMERA, kpd_input_dev->keybit)){
- printk("[AUTOTEST] RELEASE CAMERA KEY!!\n");
- input_report_key(kpd_input_dev, KEY_CAMERA, 0);
- input_sync(kpd_input_dev);
- }else{
- printk("[AUTOTEST] Not Support CAMERA KEY!!\n");
- }
- break;
- #endif
- case SET_KPD_BACKLIGHT:
- if (copy_from_user(&ledctl, uarg, sizeof(struct kpd_ledctl)))
- return -EFAULT;
- //kpd_set_backlight(ledctl.onoff, &ledctl.div, &ledctl.duty);
- break;
- case SET_KPD_KCOL:
- #ifndef KPD_AUTOTEST_BY_KP
- kpd_auto_test_for_factorymode();
- #else
- kpd_kcol_scan_for_factorymode();
- #endif
- printk("[kpd_auto_test_for_factorymode] test performed!!\n");
- break;
- default:
- return -EINVAL;
- }
- return 0;
- }
- static int kpd_dev_open(struct inode *inode, struct file *file)
- {
- return 0;
- }
- static struct file_operations kpd_dev_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = kpd_dev_ioctl,
- .open = kpd_dev_open,
- };
- static struct miscdevice kpd_dev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = KPD_NAME,
- .fops = &kpd_dev_fops,
- };
- static int kpd_open(struct input_dev *dev)
- {
- #if KPD_HAS_SLIDE_QWERTY
- bool evdev_flag=false;
- bool power_op=false;
- struct input_handler *handler;
- struct input_handle *handle;
- handle = rcu_dereference(dev->grab);
- if (handle)
- {
- handler = handle->handler;
- if(strcmp(handler->name, "evdev")==0)
- {
- return -1;
- }
- }
- else
- {
- list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
- handler = handle->handler;
- if(strcmp(handler->name, "evdev")==0)
- {
- evdev_flag=true;
- break;
- }
- }
- if(evdev_flag==false)
- {
- return -1;
- }
- }
- power_op = powerOn_slidePin_interface();
- if(!power_op) {
- printk(KPD_SAY "Qwerty slide pin interface power on fail\n");
- } else {
- kpd_print("Qwerty slide pin interface power on success\n");
- }
- mt65xx_eint_set_sens(KPD_SLIDE_EINT, KPD_SLIDE_SENSITIVE);
- mt65xx_eint_set_hw_debounce(KPD_SLIDE_EINT, KPD_SLIDE_DEBOUNCE);
- mt65xx_eint_registration(KPD_SLIDE_EINT, true, KPD_SLIDE_POLARITY,
- kpd_slide_eint_handler, false);
- power_op = powerOff_slidePin_interface();
- if(!power_op) {
- printk(KPD_SAY "Qwerty slide pin interface power off fail\n");
- } else {
- kpd_print("Qwerty slide pin interface power off success\n");
- }
- #if 0
- /*qwerty slide: GPIO 214. input, mode=EINT, pull enbale, pull select high*/
- mt_set_gpio_mode(214, 2);
- mt_set_gpio_dir(214, 0);
- mt_set_gpio_pull_enable(214, 1);
- mt_set_gpio_pull_select(214, 0);
- #endif
- #endif
- return 0;
- }
- #if 1 // AW9523 扩展键盘IC:
- #define GPIO_SIMULATE_I2C
- #define AW9523_EINT_GPIO GPIO144
- #define AW9523_EINT_NO 5 //CUST_EINT_MHALL_NUM
- #define AW9523_RESET_PIN GPIO128
- #define KPD_AW9523_SWITCH_DEBOUNCE 10 //50 // 30
- #define KPD_AW9523_SWITCH_POLARITY CUST_EINT_MHALL_POLARITY
- #define KPD_AW9523_SWITCH_SENSITIVE CUST_EINT_EDGE_SENSITIVE // CUST_EINT_MHALL_SENSITIVE
- static void kpd_aw9523_handler(unsigned long data);
- static DECLARE_TASKLET(kpd_aw9523_tasklet, kpd_aw9523_handler, 0);
- static u8 kpd_aw9523_state = !CUST_EINT_POLARITY_LOW;
- #define LED_SLAVE_ADDR 0xb0//0xB6
- //#if defined(GPIO_SIMULATE_I2C)
- #define I2C_SDA_GPIO GPIO114 //GPIO111 // ROW1
- #define I2C_SCL_GPIO GPIO113 //GPIO108 // COL1
- typedef enum {
- P0_0=0,
- P0_1,
- P0_2,
- P0_3,
- P0_4,
- P0_5,
- P0_6,
- P0_7
- } P0_Enum;
- typedef enum {
- P1_0=0,
- P1_1,
- P1_2,
- P1_3,
- P1_4,
- P1_5,
- P1_6,
- P1_7
- } P1_Enum;
- #define AW9523_I2C_MAX_LOOP 50
- #define Y_NUM 6
- #define X_NUM 6 // has pullup resistor
- // P0 ---> X_NUM ---> col input
- // P1 ---> Y_NUM ---> line(row) output
- const P0_Enum COL[X_NUM] = {P0_0, P0_1, P0_2, P0_3, P0_4, P0_5};
- //const P1_Enum Line[Y_NUM] = {P1_2, P1_3, P1_4, P1_5, P1_6, P1_7};
- const P1_Enum Line[Y_NUM] = {P1_0, P1_1, P1_2, P1_3, P1_4, P1_5};
- const u8 aw9523_key[Y_NUM][X_NUM]={
- // 1 2 3 4 5 6
- /*
- {KEY_7, KEY_8, KEY_9, KEY_POUND, KEY_OK, KEY_BACK},
- {KEY_4, KEY_5, KEY_6, KEY_STAR ,KEY_1, KEY_2},
- {KEY_LEFT, KEY_UP, KEY_MENU, KEY_RIGHT, KEY_DOWN, KEY_HOME},
- {KEY_A, KEY_0, KEY_B, KEY_C, KEY_D, KEY_S}, //SCAN here
- {KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J},
- {KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P},
- */
- {KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_DEL, KEY_3},
- {KEY_FN, KEY_0, KEY_DOT, KEY_SYM ,KEY_OK, KEY_ENTER},
- {KEY_7, KEY_8, KEY_9, KEY_POUND, KEY_TAB, KEY_BACK},
- {KEY_4, KEY_5, KEY_6, KEY_STAR, KEY_1, KEY_2},
- {KEY_LEFT, KEY_UP, KEY_MENU, KEY_RIGHT, KEY_DOWN, KEY_HOME},
- {KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_S},
- };
- u8 P0_kbd_used[8]={1, 1, 1, 1, 1, 1, 0, 0};
- u8 P1_kbd_used[8]={0, 0, 1, 1, 1, 1, 1, 1};
- typedef enum {
- KEY_STATE_PRESSED=0,
- KEY_STATE_RELEASED,
- KEY_STATE_LONGPRESS,
- KEY_STATE_REPEATED,
- KEY_STATE_NULL
- }TOUCHKEY_STATE;
- u8 P0_INT_STATE=0x0;
- u8 P1_INT_STATE=0x0;
- u8 P0_IN_OUT_STATE=0x0;
- u8 P1_IN_OUT_STATE=0x0;
- u8 P0_kbd_used_temp=0x0;
- u8 pre_x=0x00;
- u8 pre_y=0x00;
- u8 P0_X[X_NUM];
- u8 P1_Y[Y_NUM];
- u8 P1_VALUE=0;
- u8 KeyBoard_Key=0xFF;
- u8 KeyBoard_Key_Previous=0xFF;
- TOUCHKEY_STATE KeyBoardKey_State=KEY_STATE_NULL;
- u8 DELAY_TIMES=2;
- //extern void kpled_ctrl_open(u8 enable);
- #define AW9523_delay_1us(ms) udelay(ms*DELAY_TIMES)
- #define GPIO_ModeSetup(x, y) mt_set_gpio_mode(x, y);
- #define GPIO_InitIO(x, y) mt_set_gpio_dir(y, x)
- #define GPIO_WriteIO(x, y) mt_set_gpio_out(y, x)
- #define GPIO_ReadIO(x) mt_get_gpio_in(x)
- #define I2C_SDA_MODE mt_set_gpio_mode(I2C_SDA_GPIO, GPIO_MODE_GPIO)
- #define I2C_SCL_MODE mt_set_gpio_mode(I2C_SCL_GPIO, GPIO_MODE_GPIO)
- #define I2C_SDA_OUTPUT mt_set_gpio_dir(I2C_SDA_GPIO, GPIO_DIR_OUT)
- #define I2C_SDA_INPUT mt_set_gpio_dir(I2C_SDA_GPIO, GPIO_DIR_IN)
- #define I2C_SCL_OUTPUT mt_set_gpio_dir(I2C_SCL_GPIO, GPIO_DIR_OUT)
- #define I2C_SDA_HIGH mt_set_gpio_out(I2C_SDA_GPIO, GPIO_OUT_ONE)
- #define I2C_SDA_LOW mt_set_gpio_out(I2C_SDA_GPIO, GPIO_OUT_ZERO)
- #define I2C_SCL_HIGH mt_set_gpio_out(I2C_SCL_GPIO, GPIO_OUT_ONE)
- #define I2C_SCL_LOW mt_set_gpio_out(I2C_SCL_GPIO, GPIO_OUT_ZERO)
- #define I2C_SDA_READ mt_get_gpio_in(I2C_SDA_GPIO)
- #define NEW_I2C_TIMING 1
- void AW9523_i2c_initial(void)
- {
- #if NEW_I2C_TIMING
- I2C_SDA_MODE;
- I2C_SCL_MODE;
- I2C_SDA_OUTPUT;
- I2C_SCL_OUTPUT;
- mt_set_gpio_pull_enable(I2C_SDA_GPIO, GPIO_PULL_ENABLE);
- mt_set_gpio_pull_enable(I2C_SCL_GPIO, GPIO_PULL_ENABLE);
- I2C_SDA_HIGH;
- I2C_SCL_HIGH;
- #else
- GPIO_ModeSetup(I2C_SCL_GPIO, 0);
- GPIO_InitIO(1, I2C_SCL_GPIO);
- mt_set_gpio_pull_enable(I2C_SCL_GPIO, GPIO_PULL_ENABLE);
- GPIO_WriteIO(1, I2C_SCL_GPIO);
- GPIO_ModeSetup(I2C_SDA_GPIO, 0);
- GPIO_InitIO(1,I2C_SDA_GPIO);
- mt_set_gpio_pull_enable(I2C_SDA_GPIO, GPIO_PULL_ENABLE);
- GPIO_WriteIO(0, I2C_SDA_GPIO);
- AW9523_delay_1us(5);
- GPIO_WriteIO(1, I2C_SDA_GPIO);//脦陋卤脺脙芒i2c initial 脢卤虏煤脡煤\u017d铆脦贸碌脛脳\u017d脤卢拢卢脧脠路垄脪禄\u017e枚脥拢脰鹿脤玫\u0152镁
- #endif
- }
- void AW9523_Hw_reset(void)
- {
- GPIO_ModeSetup(GPIO74, 0);
- GPIO_InitIO(0, AW9523_RESET_PIN);
- AW9523_delay_1us(50);
- GPIO_ModeSetup(AW9523_RESET_PIN, 0);
- GPIO_InitIO(1, AW9523_RESET_PIN);
- GPIO_WriteIO(0, AW9523_RESET_PIN);
- //kpled_ctrl_open(1); // Kpled on , then reset be pulled down
- AW9523_delay_1us(200); //\u017e\u017d脦禄脨脜潞脜脦陋碌脥碌莽脝\u0153碌脛鲁脰脨酶脢卤\u0152盲卤脴脨毛脰脕脡脵20us虏脜脛脺脮媒鲁拢\u017e\u017d脦禄
- GPIO_WriteIO(1, AW9523_RESET_PIN);
- //kpled_ctrl_open(0); // Kpled off, then reset be pulled up by VIO18
- //AW9523_delay_1us(30);
- mdelay(30);
- }
- static void AW9523_i2c_start(void)
- {
- #if NEW_I2C_TIMING
- I2C_SDA_MODE;
- I2C_SCL_MODE;
- I2C_SDA_OUTPUT;
- I2C_SCL_OUTPUT;
- //spin_lock_irqsave(&gpio_i2c_spinLock, flags_spin);
- I2C_SDA_HIGH;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SCL_HIGH;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SDA_LOW;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- #else
- GPIO_InitIO(1,I2C_SDA_GPIO);
- GPIO_InitIO(1,I2C_SCL_GPIO);
- GPIO_WriteIO(1, I2C_SDA_GPIO);
- GPIO_WriteIO(1, I2C_SCL_GPIO);
- AW9523_delay_1us(2);
- GPIO_WriteIO(0, I2C_SDA_GPIO);
- AW9523_delay_1us(2);
- GPIO_WriteIO(0, I2C_SCL_GPIO);
- AW9523_delay_1us(2);
- #endif
- }
- static void AW9523_i2c_stop(void)
- {
- #if NEW_I2C_TIMING
- I2C_SDA_OUTPUT;
- I2C_SCL_OUTPUT;
- //spin_lock_irqsave(&gpio_i2c_spinLock, flags_spin);
- I2C_SCL_LOW; // test @20131009
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1); // 20131010
- I2C_SDA_LOW;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SCL_HIGH;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SDA_HIGH;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- #else
- GPIO_InitIO(1,I2C_SDA_GPIO);
- GPIO_InitIO(1,I2C_SCL_GPIO);
- GPIO_WriteIO(0, I2C_SCL_GPIO);
- AW9523_delay_1us(2);
- GPIO_WriteIO(0, I2C_SDA_GPIO);
- GPIO_WriteIO(1, I2C_SCL_GPIO);
- AW9523_delay_1us(2);
- GPIO_WriteIO(1, I2C_SDA_GPIO);
- #endif
- }
- static char AW9523_i2c_write_byte(unsigned char data)
- {
- #if NEW_I2C_TIMING
- char i = 0;
- char times = 0;
- //unsigned long flags_spin;
- //spin_lock_irqsave(&gpio_i2c_spinLock, flags_spin);
- I2C_SCL_LOW;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SDA_OUTPUT;
- for(i=0;i<8;i++)
- {
- if((data<<i)&0x80)
- I2C_SDA_HIGH;
- else
- I2C_SDA_LOW;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SCL_HIGH;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SCL_LOW;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- }
- I2C_SDA_INPUT;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SCL_HIGH;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- //spin_unlock_irqrestore(&gpio_i2c_spinLock, flags_spin);
- while (I2C_SDA_READ==1)
- {
- AW9523_delay_1us(5); //udelay(10);//return 1;
- times++;
- if (times==10)
- break;
- }
- I2C_SCL_LOW;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- return 1;
- #else
- u8 i;
- char ack;
- GPIO_InitIO(1,I2C_SDA_GPIO);
- for (i=0; i<8; i++)
- {
- if (data & 0x80)
- GPIO_WriteIO(1,I2C_SDA_GPIO);
- else
- GPIO_WriteIO(0,I2C_SDA_GPIO);
- data <<= 1;
- AW9523_delay_1us(1);
- GPIO_WriteIO(1,I2C_SCL_GPIO);
- AW9523_delay_1us(1);
- GPIO_WriteIO(0,I2C_SCL_GPIO);
- AW9523_delay_1us(1);
- }
- GPIO_InitIO(0,I2C_SDA_GPIO);
- AW9523_delay_1us(6);
- GPIO_WriteIO(1,I2C_SCL_GPIO);
- ack = GPIO_ReadIO(I2C_SDA_GPIO); /// ack
- AW9523_delay_1us(1);
- GPIO_WriteIO(0,I2C_SCL_GPIO);
- return ack;
- #endif
- }
- static u8 AW9523_i2c_read_byte(void)
- {
- #if NEW_I2C_TIMING
- u8 rec_byte = 0x00;
- u8 i = 0;
- //I2C_SCL_LOW;
- //mdelay(1);
- for (i=0; i<8; i++)
- {
- rec_byte <<=1;
- //I2C_SCL_LOW;
- //mdelay(1);
- I2C_SCL_HIGH;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- rec_byte |= I2C_SDA_READ;
- I2C_SCL_LOW;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- }
- I2C_SDA_OUTPUT;
- I2C_SDA_HIGH;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SCL_HIGH;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- I2C_SCL_LOW;
- AW9523_delay_1us(5); //udelay(10); //udelay(100); //mdelay(1);
- return rec_byte;
- #else
- u8 i;
- u8 bData;
- GPIO_InitIO(0, I2C_SDA_GPIO);
- //脢媒\u0178脻露脕鲁枚
- bData = 0x00;
- for (i=0;i<8;i++) {
- bData <<= 1;
- AW9523_delay_1us(4);
- GPIO_WriteIO(1, I2C_SCL_GPIO);
- if (GPIO_ReadIO(I2C_SDA_GPIO)) {
- bData |= 0x01;
- } else {
- bData &= 0xfe;
- }
- AW9523_delay_1us(1);
- GPIO_WriteIO(0, I2C_SCL_GPIO);
- }
- AW9523_delay_1us(1);
- GPIO_WriteIO(1, I2C_SCL_GPIO);
- AW9523_delay_1us(1);
- GPIO_WriteIO(0, I2C_SCL_GPIO);
- return bData;
- #endif
- }
- static char AW9523_i2c_write_reg_org(unsigned char reg,unsigned char data)
- {
- #if NEW_I2C_TIMING
- AW9523_i2c_start();
- AW9523_i2c_write_byte(LED_SLAVE_ADDR);
- AW9523_i2c_write_byte(reg);
- AW9523_i2c_write_byte(data);
- AW9523_i2c_stop();
- return 1;
- #else
- char ack=0;
- AW9523_i2c_start();
- ack|=AW9523_i2c_write_byte(LED_SLAVE_ADDR); //write device address
- ack|=AW9523_i2c_write_byte(reg); // reg address
- ack|= AW9523_i2c_write_byte(data); // data
- AW9523_i2c_stop();
- return ack;
- #endif
- }
- static char AW9523_i2c_write_reg(unsigned char reg,unsigned char data)
- {
- #if NEW_I2C_TIMING
- AW9523_i2c_start();
- AW9523_i2c_write_byte(LED_SLAVE_ADDR);
- AW9523_i2c_write_byte(reg);
- AW9523_i2c_write_byte(data);
- AW9523_i2c_stop();
- return 1;
- #else
- char ack=0;
- char i;
- for (i=0;i<AW9523_I2C_MAX_LOOP;i++)
- {
- ack=AW9523_i2c_write_reg_org(reg,data);
- if(ack==0) // ack success
- break;
- }
- return ack;
- #endif
- }
- u8 AW9523_i2c_read_reg(u8 regaddr)
- {
- #if NEW_I2C_TIMING
- u8 read_byte = 0;
- AW9523_i2c_start();
- AW9523_i2c_write_byte(LED_SLAVE_ADDR);
- AW9523_i2c_write_byte(regaddr);
- AW9523_i2c_stop(); /////////////////////
- AW9523_i2c_start(); //restart signal
- AW9523_i2c_write_byte(LED_SLAVE_ADDR|0x01);
- read_byte = AW9523_i2c_read_byte();
- AW9523_i2c_stop();
- return read_byte;
- #else
- u8 mask,i, bData;
- char ack1,ack2,ack3;
- u8 i2caddr;
- for (i=0;i<AW9523_I2C_MAX_LOOP;i++)
- {
- AW9523_i2c_start();
- ack1=AW9523_i2c_write_byte(LED_SLAVE_ADDR); //write device address
- ack2=AW9523_i2c_write_byte(regaddr); // reg address
- AW9523_i2c_stop();
- AW9523_i2c_start();
- ack3=AW9523_i2c_write_byte((LED_SLAVE_ADDR|0x01)); //write device address
- if((ack1 || ack2 || ack3)==0) // ack success
- break;
- }
- bData=AW9523_i2c_read_byte();
- AW9523_i2c_stop();
- return bData;
- #endif
- }
- static void AW9523_SDA_Change(void)
- {
- u8 SDA_index = 0;
- GPIO_WriteIO(0,I2C_SDA_GPIO);
- AW9523_delay_1us(80);
- for (SDA_index=0;SDA_index<50;SDA_index++)
- {
- GPIO_InitIO(0, I2C_SDA_GPIO);
- AW9523_delay_1us(420); //SDA碌脛脰脺脝脷拢卢\u017e脽碌莽脝\u0153420us拢卢 脭脷\u017e梅脝\u0153脤\u0161脧脗脟毛\u017e霉\u0178脻脰梅脝碌脌\u017d碌梅脮没拢卢卤拢鲁脰脪禄脰脗
- GPIO_InitIO(1, I2C_SDA_GPIO);//SDA碌脛脰脺脝脷拢卢碌脥碌莽脝\u015380us拢卢 脭脷\u017e梅脝\u0153脤\u0161脧脗脟毛\u017e霉\u0178脻脰梅脝碌脌\u017d碌梅脮没拢卢卤拢鲁脰脪禄脰脗
- AW9523_delay_1us(80); //SDA碌脥碌莽脝\u015380us
- }
- GPIO_InitIO(1, I2C_SDA_GPIO);
- GPIO_WriteIO(1,I2C_SDA_GPIO);
- AW9523_delay_1us(420);
- }
- char AW9523_POWER_ON(void)
- { // AW9523 POWER-ON拢卢 脟毛驴脥禄搂虏禄脪陋\u017e脛露炉\u017d脣潞炉脢媒
- // 脭脷aw9523_init()脰脨拢卢脧脠\u0153酶脨脨POWER-ON拢卢脭脵\u0153酶脨脨驴脥禄搂脳脭脡铆碌脛脧脿鹿脴虏脵脳梅
- char ack=0;
- u8 count=0;
- AW9523_i2c_initial();
- AW9523_Hw_reset();
- while(count++ < 120) //
- {
- if(AW9523_i2c_write_reg_org(0x55,0x55)) //脜脨露脧脫\u0160\u017d冒脛拢脢\u0153隆拢0x55脦陋驴脮\u0152脛\u017d忙脝梅拢卢虏禄禄谩露脭驴脥禄搂脫\u0160脫脙虏煤脡煤脫掳脧矛
- {
- AW9523_SDA_Change();
- continue;
- }
- if(AW9523_i2c_write_reg_org(0xaa,0xaa))
- {
- AW9523_SDA_Change();
- continue;
- }
- if(AW9523_i2c_write_reg_org(0x55,0xaa))
- {
- AW9523_SDA_Change();
- continue;
- }
- if(AW9523_i2c_write_reg_org(0xaa,0x55))
- {
- AW9523_SDA_Change();
- continue;
- }
- break;
- }
- ack |= AW9523_i2c_write_reg_org(0x55,0x55);
- ack |= AW9523_i2c_write_reg_org(0xaa,0xaa);
- //SCI_TRACE_LOW("----AW9523 POWER ON -----end =%d\r\n", count);
- return ack;
- }
- /*=======================================i2c driver end =================================*/
- /*===========================aw9523\u0152脛\u017d忙脝梅碌脛虏脵脳梅\u0153脫驴脷 begin ================================*/
- void aw9523_p0_p1_in_out_setting(void) /* 脡猫脰脙 p0 p1 脢盲脠毛脢盲鲁枚脳\u017d脤卢*/
- {
- P0_IN_OUT_STATE=0xFF;
- AW9523_i2c_write_reg(0x04,P0_IN_OUT_STATE);//脡猫脰脙脣霉脫脨P0_\u0153脜脦陋脢盲脠毛脳\u017d脤卢
- P1_IN_OUT_STATE=0x0;
- AW9523_i2c_write_reg(0x05,P1_IN_OUT_STATE);//脡猫脰脙脣霉脫脨P1_\u0153脜脦陋脢盲鲁枚脳\u017d脤卢
- }
- void aw9523_p0_p1_interrupt_setting(void) /* 脡猫脰脙 p0 p1 脭脢脨铆脰脨露脧脳\u017d脤卢*/
- {
- u8 i=0;
- P0_INT_STATE=0x0;
- for (i=0;i<X_NUM;i++) {
- P0_INT_STATE=P0_INT_STATE|(1<<COL[i]);//\u017e霉\u0178脻掳\u017d\u0152眉脜脜虏\u0152脌\u017d脡猫脰脙脰脨露脧
- }
- P0_INT_STATE=~P0_INT_STATE;
- AW9523_i2c_write_reg(0x06,P0_INT_STATE);//潞脥掳\u017d\u0152眉脕脨露脭脫\u0160碌脛P0_\u0153脜脭脢脨铆脰脨露脧
- P1_INT_STATE=0xFF;
- AW9523_i2c_write_reg(0x07,P1_INT_STATE);//p1\u0153脜露\u0152虏禄脛脺脰脨露脧
- }
- void aw9523_p0_int_restore(void)
- {
- AW9523_i2c_write_reg(0x06,P0_INT_STATE);
- }
- void aw9523_P1_int_restore()
- {
- AW9523_i2c_write_reg(0x07,P1_INT_STATE);
- }
- void aw9523_p0_int_disable()
- {
- AW9523_i2c_write_reg(0x06, 0xff);
- }
- void aw9523_p1_int_disable()
- {
- AW9523_i2c_write_reg(0x07, 0xff);
- }
- u8 aw9523_get_p0(void)
- {
- //AW9523_i2c_read_reg(0x01); //just for test 20131129
- return AW9523_i2c_read_reg(0x00);
- }
- u8 aw9523_get_p1(void)
- {
- return AW9523_i2c_read_reg(0x01);
- }
- void aw9523_set_p0(u8 data)
- {
- AW9523_i2c_write_reg(0x02,data);
- }
- void aw9523_set_p1(u8 data)
- {
- AW9523_i2c_write_reg(0x03,data);
- }
- void RE_P0_WRITE(u8 P0,u8 data)
- {
- u8 tmp_value;
- tmp_value = AW9523_i2c_read_reg(0x02);
- if(data==1)
- {
- AW9523_i2c_write_reg(0x02,(tmp_value|(1<<P0)));
- }
- else
- {
- AW9523_i2c_write_reg(0x02,(tmp_value&(~(1<<P0))));
- }
- }
- void RE_P1_WRITE(u8 P1,u8 data)
- {
- u8 tmp_value;
- tmp_value = AW9523_i2c_read_reg(0x03);
- if(data==1)
- {
- AW9523_i2c_write_reg(0x03,(tmp_value|(1<<P1)));
- }
- else
- {
- AW9523_i2c_write_reg(0x03,(tmp_value&(~(1<<P1))));
- }
- }
- void aw9523_keylight_open(u8 enable)
- {
- if (enable)
- {
- AW9523_i2c_write_reg(0x20, 0x40); // led current P1_0
- AW9523_i2c_write_reg(0x21, 0x40); // led current P1_1
- AW9523_i2c_write_reg(0x13, 0xFf); // P1_0, P1_1 working mode
- }
- else
- {
- AW9523_i2c_write_reg(0x20, 0x00); // led current P1_0
- AW9523_i2c_write_reg(0x21, 0x00); // led current P1_1
- AW9523_i2c_write_reg(0x13, 0xFf); // P1_0, P1_1 working mode
- }
- }
- #include <mach/mt_pm_ldo.h>
- #define SCAN_GPIO GPIO30
- #define SCAN_POWER_GPIO GPIO134
- #define SCAN_POWER2_GPIO GPIO110
- void SCAN_init(void)
- {
- /*
- GPIO_ModeSetup(SCAN_POWER_GPIO, 0);
- GPIO_InitIO(1, SCAN_POWER_GPIO);
- GPIO_WriteIO(1, SCAN_POWER_GPIO);
- GPIO_ModeSetup(SCAN_POWER2_GPIO, 0);
- GPIO_InitIO(1, SCAN_POWER2_GPIO);
- GPIO_WriteIO(1, SCAN_POWER2_GPIO);
- hwPowerDown(MT6323_POWER_LDO_VGP2, "TP");
- hwPowerOn(MT6323_POWER_LDO_VGP2, VOL_1800, "TP");
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- hwPowerOn(MT6323_POWER_LDO_VGP1, VOL_3300, "TP");
- GPIO_ModeSetup(SCAN_GPIO, 0);
- GPIO_InitIO(1, SCAN_GPIO);
- GPIO_WriteIO(1, SCAN_GPIO);
- */
- }
- void SCAN_test(void)
- {
- printk("\===== SCAN_test\r\n");
- GPIO_ModeSetup(SCAN_GPIO, 0);
- GPIO_InitIO(1, SCAN_GPIO);
- GPIO_WriteIO(1, SCAN_GPIO);
- mdelay(20);
- GPIO_ModeSetup(SCAN_POWER_GPIO, 0);
- GPIO_InitIO(1, SCAN_POWER_GPIO);
- GPIO_WriteIO(1, SCAN_POWER_GPIO);
- GPIO_ModeSetup(SCAN_POWER2_GPIO, 0);
- GPIO_InitIO(1, SCAN_POWER2_GPIO);
- GPIO_WriteIO(1, SCAN_POWER2_GPIO);
- hwPowerDown(MT6323_POWER_LDO_VGP2, "TP");
- hwPowerOn(MT6323_POWER_LDO_VGP2, VOL_1800, "TP");
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- hwPowerOn(MT6323_POWER_LDO_VGP1, VOL_3300, "TP");
- mdelay(100);
- GPIO_WriteIO(0, SCAN_GPIO);
- mdelay(1500);
- GPIO_WriteIO(1, SCAN_GPIO);
- mdelay(100);
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- //GPIO_WriteIO(1, SCAN_GPIO);
- }
- EXPORT_SYMBOL(SCAN_init);
- EXPORT_SYMBOL(SCAN_test);
- void trig_scan_evel(int level)
- {
- #if 0
- SCAN_test();
- #else
- printk("\===== SCAN_test\r\n");
- GPIO_ModeSetup(SCAN_GPIO, 0);
- GPIO_InitIO(1, SCAN_GPIO);
- GPIO_WriteIO(1, SCAN_GPIO);
- mdelay(20);
- GPIO_ModeSetup(SCAN_POWER_GPIO, 0);
- GPIO_InitIO(1, SCAN_POWER_GPIO);
- GPIO_WriteIO(1, SCAN_POWER_GPIO);
- GPIO_ModeSetup(SCAN_POWER2_GPIO, 0);
- GPIO_InitIO(1, SCAN_POWER2_GPIO);
- GPIO_WriteIO(1, SCAN_POWER2_GPIO);
- if(level > 0)
- {
- hwPowerDown(MT6323_POWER_LDO_VGP2, "TP");
- hwPowerOn(MT6323_POWER_LDO_VGP2, VOL_1800, "TP");
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- hwPowerOn(MT6323_POWER_LDO_VGP1, VOL_3300, "TP");
- mdelay(200);
- GPIO_WriteIO(0, SCAN_GPIO);
- mdelay(100);
- }
- else
- {
- GPIO_WriteIO(1, SCAN_GPIO);
- mdelay(100);
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- hwPowerDown(MT6323_POWER_LDO_VGP1, "TP");
- }
- #endif
- }
- void aw9523_test(void)
- {
- // i2c_initial();
- // AW9523_Hw_reset();
- // AW9523_i2c_initial();
- printk("\===== naw9523_test_entry=\r\n");
- printk("\===== naw9523_i2c_read_reg_0x00=0x%x\r\n",AW9523_i2c_read_reg(0x00));
- printk("\===== naw9523_i2c_read_reg_0x01=0x%x\r\n",AW9523_i2c_read_reg(0x01));
- printk("\===== naw9523_i2c_read_reg_0x02=0x%x\r\n",AW9523_i2c_read_reg(0x02));
- printk("\===== naw9523_i2c_read_reg_0x03=0x%x\r\n",AW9523_i2c_read_reg(0x03));
- printk("\===== naw9523_i2c_read_reg_0x04=0x%x\r\n",AW9523_i2c_read_reg(0x04));
- printk("\===== naw9523_i2c_read_reg_0x05=0x%x\r\n",AW9523_i2c_read_reg(0x05));
- printk("\===== naw9523_i2c_read_reg_0x06=0x%x\r\n",AW9523_i2c_read_reg(0x06));
- printk("\===== naw9523_i2c_read_reg_0x07=0x%x\r\n",AW9523_i2c_read_reg(0x07));
- printk("\===== naw9523_i2c_read_reg_0x10=0x%x\r\n",AW9523_i2c_read_reg(0x10));
- printk("\===== naw9523_i2c_read_reg_0x11=0x%x\r\n",AW9523_i2c_read_reg(0x11));
- printk("\===== naw9523_i2c_read_reg_0x12=0x%x\r\n",AW9523_i2c_read_reg(0x12));
- printk("\===== naw9523_i2c_read_reg_0x13=0x%x\r\n",AW9523_i2c_read_reg(0x13));
- }
- void aw9523_set_p1_gpio_mode(void)
- {
- AW9523_i2c_write_reg(0x13,0xff);
- }
- void aw9523_init()
- {
- //AW9523_POWER_ON(); // test new i2c timing , delete this code
- //GPIO_ModeSetup(GPIO73, 0);
- //GPIO_InitIO(1, GPIO73);
- //GPIO_WriteIO(0, GPIO73);
- printk("======= aw9523_init\n");
- AW9523_i2c_initial();
- AW9523_Hw_reset();
- #if 1
- AW9523_i2c_write_reg(0x7F, 0x00); // sw reset
- mdelay(10);
- aw9523_keylight_open(0); // close P1_0, P1_1 mos fet
- aw9523_p0_int_disable();
- aw9523_set_p1_gpio_mode();
- //liubiao
- aw9523_p0_p1_in_out_setting();
- aw9523_p0_p1_interrupt_setting();
- aw9523_set_p1(P1_VALUE);
- AW9523_i2c_read_reg(0x00);
- AW9523_i2c_read_reg(0x01);
- #endif
- }
- void Set_P0_X_AND_P1_Y(void)
- {
- u8 i=0;
- u8 temp=0;
- for (i=0;i<X_NUM;i++) {
- temp=temp|(1<<COL[i]);
- }
- //SCI_TRACE_LOW("temp=%x\r\n",temp);
- for (i=0;i<X_NUM;i++) {
- P0_X[i]=temp&(~(1<<COL[i]));
- //SCI_TRACE_LOW("P0_X[%d]=%x\r\n",i,P0_X[i]);
- }
- temp=0;
- for (i=0;i<Y_NUM;i++) {
- temp=temp|(1<<Line[i]);
- }
- //SCI_TRACE_LOW("temp=%x\r\n",temp);
- for (i=0;i<Y_NUM;i++) {
- P1_Y[i]=temp&(~(1<<Line[i]));
- //SCI_TRACE_LOW("P1_Y[%d]=%x\r\n",i,P1_Y[i]);
- }
- for(i=0;i<8;i++)
- {
- if(P0_kbd_used[i]==1)
- {
- P0_kbd_used_temp|=1<<i;
- }
- }
- //SCI_TRACE_LOW("P0_kbd_used_temp=%x\r\n",P0_kbd_used_temp);
- }
- u8 keyboard_get_press_key(void)
- {
- u8 x=0xFF,y=0XFF;
- u8 i=0,j=0,k=0;
- u8 get_p0=0xff;
- get_p0=aw9523_get_p0();
- i=(get_p0)|(~(P0_kbd_used_temp)); //脦\u017d脫脙脳枚\u0152眉脜脤脡\u0161脙猫碌脛P0驴脷,脝盲露脕鲁枚碌脛脰碌卤禄脝脕卤脦
- //i=get_p0 & P0_kbd_used_temp; //脦\u017d脫脙脳枚\u0152眉脜脤脡\u0161脙猫碌脛P0驴脷,脝盲露脕鲁枚碌脛脰碌卤禄脝脕卤脦
- //SCI_TRACE_LOW("===aw9523_get_p0()===%x\r\n",get_p0);
- if (i==0xff)
- {
- // SCI_TRACE_LOW("------get_key=0xff----\r\n");
- return 0xFF;
- }
- else
- {
- //SCI_TRACE_LOW("===aw9523_get_p0()===%x\r\n",i);
- if(KeyBoardKey_State==KEY_STATE_PRESSED || KeyBoardKey_State==KEY_STATE_LONGPRESS)
- {
- //脠莽鹿没脰庐脟掳脢脟\u017d\u0160脫脷脫脨掳\u017d\u0152眉碌脛脳\u017d脤卢,脭貌脰卤\u0153脫脠楼\u0152矛虏芒脮芒\u017e枚掳\u017d\u0152眉脢脟路帽脢脥路脜
- //SCI_TRACE_LOW("------press or longpress entry ,pre_x=%d,pre_y=%d ----\r\n",pre_x,pre_y);
- AW9523_i2c_write_reg(0x05,P1_Y[pre_y]);
- get_p0=aw9523_get_p0();
- //i=get_p0 & P0_kbd_used_temp;
- if ((get_p0&(1<<COL[pre_x])) == 0)
- {
- AW9523_i2c_write_reg(0x05,P1_VALUE);
- return aw9523_key[pre_y][pre_x];
- }
- else
- {
- AW9523_i2c_write_reg(0x05,P1_VALUE);
- return 0xFF;
- }
- }
- else
- {
- //\u0152矛虏芒掳\u017d\u0152眉碌脛鲁脤脨貌脠毛驴脷
- for (j=0;j<X_NUM;j++)
- {
- if((i&(1<<COL[j]))==0)
- {
- //if (i==P0_X[j]) {
- //卤\u0178脌媒脰脨P0_X[0:7]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f},
- //脠么露脕鲁枚碌脛P0_脰碌脛鲁脪禄脦禄脦陋0拢卢脭貌脜脨露脧鲁枚掳\u017d脧脗碌脛脢脟脮芒脪禄脕脨
- x=j;
- break;
- }
- }
- if (x==0xFF)
- {
- // SCI_TRACE_LOW("------get_key=0xff----\r\n");
- return 0xFF;
- }
- for (j=0;j<Y_NUM;j++)
- {
- // aw9523_set_p1(P1_Y[j]);
- AW9523_i2c_write_reg(0x05,P1_Y[j]);
- /*脗脰脩炉脡\u0161脙猫隆拢脪脌\u017d脦\u0153芦脛鲁脪禄脨脨P1脰碌脰脙0拢卢脝盲脣没脨脨脰脙1禄貌\u017e脽脳猫拢卢脙驴脡\u0161脙猫脪禄脨脨脢卤拢卢露\u0152露脕脪禄\u017d脦P0脰碌
- 碌卤脡\u0161脙猫碌\u0153脛鲁脪禄脨脨脢卤拢卢脠么露脕鲁枚碌脛P0脰碌脫毛脰庐脟掳脜脨露脧碌\u0153碌脛P0脰碌脧脿碌脠拢卢脭貌脜脨露脧鲁枚掳\u017d脧脗碌脛脢脟脮芒脪禄脨脨 */
- get_p0=aw9523_get_p0();
- k=(get_p0)|(~(P0_kbd_used_temp));
- // if (k==P0_X[x]) {
- if ((k&(1<<COL[x]))==0)
- {
- y=j;
- break;
- }
- }
- //aw9523_set_p1(P1_VALUE);
- AW9523_i2c_write_reg(0x05,P1_VALUE);
- // get_p0=aw9523_get_p0();
- // k=get_p0 & P0_kbd_used_temp;
- //SCI_TRACE_LOW("------get_key: x=%d,y=%d----\r\n",x,y);
- if (x!=0xFF && y!=0xFF )
- {
- pre_x=x;
- pre_y=y;
- return aw9523_key[y][x];
- }
- else
- {
- return 0xFF;
- }
- }}
- }
- static void kpd_aw9523_handler(unsigned long data)
- {
- //bool pressed;
- u8 old_state = kpd_aw9523_state;
- //static u8 flag = 1;
- //mt65xx_eint_set_polarity(AW9523_EINT_NO, old_state);
- aw9523_p0_int_disable();
- disable_irq(MT_KP_IRQ_ID);
- mt_eint_mask(AW9523_EINT_NO); // mt65xx_eint_mask(AW9523_EINT_NO);
- //aw9523_p0_int_disable();
- printk("====== kpd_aw9523_handler state=%d\n", kpd_aw9523_state);
- //printk("\n<<<< xxx==kpd_aw9523_handler state=%d\n", kpd_aw9523_state);
- //mt65xx_eint_unmask(AW9523_EINT_NO);
- kpd_aw9523_state = !kpd_aw9523_state;
- #if 0
- if (kpd_aw9523_state!=KPD_AW9523_SWITCH_POLARITY)
- {
- mt65xx_eint_set_polarity(AW9523_EINT_NO, old_state);
- enable_irq(MT_KP_IRQ_ID);
- mt65xx_eint_unmask(AW9523_EINT_NO);
- aw9523_p0_int_restore();
- return;
- }
- #endif
- printk("\n<<<< ==== key =%d pressed=======\r\n",keyboard_get_press_key());
- KeyBoard_Key=keyboard_get_press_key(); //KEY_HOME;
- printk("\n<<<< === aw9523_handler==key =%d pressed,old_state=%d==\r\n",KeyBoard_Key, old_state);
- /*
- if(KeyBoard_Key==158)
- KeyBoard_Key=KEY_3;
- */
- //if(KeyBoard_Key==232)
- // KeyBoard_Key=KEY_DEL;
- //if(((KeyBoard_Key>1)&&(KeyBoard_Key<12))||(KeyBoard_Key==103)||(KeyBoard_Key==105)||(KeyBoard_Key==106)||(KeyBoard_Key==108))
- //if((KeyBoard_Key>1)&&(KeyBoard_Key<12))
- //if(KeyBoard_Key==KEY_S)
- // SCAN_test();
- //if(KeyBoard_Key==KEY_STAR)
- // trig_scan_evel(1);
- //if(KeyBoard_Key==KEY_POUND)
- // trig_scan_evel(0);
- if (KeyBoardKey_State==KEY_STATE_NULL||KeyBoardKey_State==KEY_STATE_RELEASED)
- {
- if (KeyBoard_Key!=0xFF)
- {
- KeyBoardKey_State=KEY_STATE_PRESSED;
- KeyBoard_Key_Previous=KeyBoard_Key;
- input_report_key(kpd_input_dev, KeyBoard_Key, 1);
- input_sync(kpd_input_dev);
- }
- }
- else if (KeyBoardKey_State==KEY_STATE_PRESSED)
- {
- if (KeyBoard_Key != KeyBoard_Key_Previous)
- {
- KeyBoardKey_State=KEY_STATE_RELEASED;
- //---
- input_report_key(kpd_input_dev, KeyBoard_Key_Previous, 0); //发送键值
- input_sync(kpd_input_dev); //同步
- //-----
- }
- }
- // */
- AW9523_i2c_write_reg(0x05,P1_VALUE);
- enable_irq(MT_KP_IRQ_ID);
- mt_eint_unmask(AW9523_EINT_NO); // mt65xx_eint_unmask(AW9523_EINT_NO);
- aw9523_p0_int_restore();
- AW9523_i2c_read_reg(0x00);
- AW9523_i2c_read_reg(0x01);
- #if 0
- aw9523_test();
- #endif
- //mt65xx_eint_set_polarity(AW9523_EINT_NO, old_state);
- }
- static void kpd_aw9523_eint_handler(void)
- {
- printk("===== kpd_aw9523_eint_handler\n");
- //printk("\nxxx==kpd_halldet_eint_handler===\n");
- tasklet_schedule(&kpd_aw9523_tasklet);
- }
- #endif
- static int kpd_pdrv_probe(struct platform_device *pdev)
- {
- int i, r;
- int err = 0;
- printk("===== kpd_pdrv_probe\n");
- //#ifdef CONFIG_MTK_LDVT
- //unsigned int a, c, j;
- //unsigned int addr[]= {0x0502, 0xc0d8, 0xc0e0, 0xc0e8, 0xc0f0, 0xc048};
- //unsigned int data[]= {0x4000, 0x1249, 0x1249, 0x1249, 0x0009, 0x00ff};
- //
- //for(j = 0; j < 6; j++) {
- // a = pwrap_read(addr[j],&c);
- // if(a != 0)
- // printk("kpd read fail, addr: 0x%x\n", addr[j]);
- // printk("kpd read addr: 0x%x: data:0x%x\n",addr[j], c);
- // a = pwrap_write(addr[j],data[j]);
- // if(a != 0)
- // printk("kpd write fail, addr: 0x%x\n", addr[j]);
- // a = pwrap_read(addr[j],&c);
- // if(a != 0)
- // printk("kpd read fail, addr: 0x%x\n", addr[j]);
- // printk("kpd read addr: 0x%x: data:0x%x\n",addr[j], c);
- //}
- //
- //// *(volatile u16 *)(KP_PMIC) = 0x1;
- //// printk("kpd register for pmic set!\n");
- //#endif
- /* initialize and register input device (/dev/input/eventX) */
- kpd_input_dev = input_allocate_device();
- if (!kpd_input_dev)
- return -ENOMEM;
- kpd_input_dev->name = KPD_NAME;
- kpd_input_dev->id.bustype = BUS_HOST;
- kpd_input_dev->id.vendor = 0x2454;
- kpd_input_dev->id.product = 0x6572;
- kpd_input_dev->id.version = 0x0010;
- kpd_input_dev->open = kpd_open;
- __set_bit(EV_KEY, kpd_input_dev->evbit);
- #if (KPD_PWRKEY_USE_EINT||KPD_PWRKEY_USE_PMIC)
- __set_bit(KPD_PWRKEY_MAP, kpd_input_dev->keybit);
- kpd_keymap[8] = 0;
- #endif
- for (i = 17; i < KPD_NUM_KEYS; i += 9) /* only [8] works for Power key */
- kpd_keymap[i] = 0;
- for (i = 0; i < KPD_NUM_KEYS; i++) {
- if (kpd_keymap[i] != 0)
- __set_bit(kpd_keymap[i], kpd_input_dev->keybit);
- }
- #if KPD_AUTOTEST
- for (i = 0; i < ARRAY_SIZE(kpd_auto_keymap); i++)
- __set_bit(kpd_auto_keymap[i], kpd_input_dev->keybit);
- #endif
- #if KPD_HAS_SLIDE_QWERTY
- __set_bit(EV_SW, kpd_input_dev->evbit);
- __set_bit(SW_LID, kpd_input_dev->swbit);
- #endif
- #ifdef KPD_PMIC_RSTKEY_MAP
- __set_bit(KPD_PMIC_RSTKEY_MAP, kpd_input_dev->keybit);
- #endif
- kpd_input_dev->dev.parent = &pdev->dev;
- r = input_register_device(kpd_input_dev);
- if (r) {
- printk(KPD_SAY "register input device failed (%d)\n", r);
- input_free_device(kpd_input_dev);
- return r;
- }
- /* register misc device (/dev/mtk-kpd) */
- kpd_dev.parent = &pdev->dev;
- r = misc_register(&kpd_dev);
- if (r) {
- printk(KPD_SAY "register device failed (%d)\n", r);
- input_unregister_device(kpd_input_dev);
- return r;
- }
- /* register IRQ and EINT */
- kpd_set_debounce(KPD_KEY_DEBOUNCE);
- r = request_irq(MT_KP_IRQ_ID, kpd_irq_handler, IRQF_TRIGGER_FALLING, KPD_NAME, NULL);
- if (r) {
- printk(KPD_SAY "register IRQ failed (%d)\n", r);
- misc_deregister(&kpd_dev);
- input_unregister_device(kpd_input_dev);
- return r;
- }
- #if 0 //KPD_PWRKEY_USE_EINT
- mt65xx_eint_set_sens(KPD_PWRKEY_EINT, KPD_PWRKEY_SENSITIVE);
- mt65xx_eint_set_hw_debounce(KPD_PWRKEY_EINT, KPD_PWRKEY_DEBOUNCE);
- mt65xx_eint_registration(KPD_PWRKEY_EINT, true, KPD_PWRKEY_POLARITY,
- kpd_pwrkey_eint_handler, false);
- #endif
- #if 1
- printk("===== AW9523 probe\n");
- GPIO_ModeSetup(SCAN_GPIO, 0);
- GPIO_InitIO(1, SCAN_GPIO);
- GPIO_WriteIO(1, SCAN_GPIO);
- mt_set_gpio_mode(AW9523_EINT_GPIO, GPIO_MODE_03);
- mt_set_gpio_dir(AW9523_EINT_GPIO, GPIO_DIR_IN);
- mt_set_gpio_pull_enable(AW9523_EINT_GPIO, GPIO_PULL_ENABLE); //To disable GPIO PULL.
- Set_P0_X_AND_P1_Y();
- aw9523_init();
- mt_eint_set_sens(AW9523_EINT_NO, KPD_AW9523_SWITCH_SENSITIVE);
- mt_eint_set_hw_debounce(AW9523_EINT_NO, KPD_AW9523_SWITCH_DEBOUNCE);
- mt_eint_registration(AW9523_EINT_NO, EINTF_TRIGGER_FALLING, kpd_aw9523_eint_handler, false);
- mt_eint_unmask(AW9523_EINT_NO);
- #endif
- #ifndef KPD_EARLY_PORTING /*add for avoid early porting build err the macro is defined in custom file*/
- /*long press reboot function realize*/
- if(kpd_enable_lprst && get_boot_mode() == NORMAL_BOOT) {
- kpd_print("Normal Boot long press reboot selection\n");
- upmu_set_rg_pwrkey_rst_en(0x00);//pmic package function for long press reboot function setting
- upmu_set_rg_homekey_rst_en(0x00);
- #ifdef CONFIG_ONEKEY_REBOOT_NORMAL_MODE
- kpd_print("Enable ONE KEY normal mode LPRST\n");
- upmu_set_rg_pwrkey_rst_en(0x01);//pmic_config_interface(TOP_RST_MISC, 0x01, PMIC_RG_PWRKEY_RST_EN_MASK, PMIC_RG_PWRKEY_RST_EN_SHIFT);
- upmu_set_rg_pwrkey_rst_td(CONFIG_KPD_PMIC_LPRST_TD);
- #endif
- #ifdef CONFIG_TWOKEY_REBOOT_NORMAL_MODE
- kpd_print("Enable TWO KEY normal mode LPRST\n");
- upmu_set_rg_pwrkey_rst_en(0x01);//pmic package function for long press reboot function setting//pmic_config_interface(TOP_RST_MISC, 0x01, PMIC_RG_PWRKEY_RST_EN_MASK, PMIC_RG_PWRKEY_RST_EN_SHIFT);
- upmu_set_rg_homekey_rst_en(0x01);//pmic_config_interface(TOP_RST_MISC, 0x01, PMIC_RG_HOMEKEY_RST_EN_MASK, PMIC_RG_HOMEKEY_RST_EN_SHIFT);
- //upmu_set_rg_homekey_puen(0x01);//pmic_config_interface(GPIO_SMT_CON3,0x01, PMIC_RG_HOMEKEY_PUEN_MASK, PMIC_RG_HOMEKEY_PUEN_SHIFT);//pull up homekey pin of PMIC for 89 project
- upmu_set_rg_pwrkey_rst_td(CONFIG_KPD_PMIC_LPRST_TD);
- #endif
- }
- else {
- kpd_print("Other Boot Mode long press reboot selection\n");
- upmu_set_rg_pwrkey_rst_en(0x00);//pmic package function for long press reboot function setting
- upmu_set_rg_homekey_rst_en(0x00);
- #ifdef CONFIG_ONEKEY_REBOOT_OTHER_MODE
- kpd_print("Enable ONE KEY other mode LPRST\n");
- upmu_set_rg_pwrkey_rst_en(0x01);//pmic_config_interface(TOP_RST_MISC, 0x01, PMIC_RG_PWRKEY_RST_EN_MASK, PMIC_RG_PWRKEY_RST_EN_SHIFT);
- upmu_set_rg_pwrkey_rst_td(CONFIG_KPD_PMIC_LPRST_TD);
- #endif
- #ifdef CONFIG_TWOKEY_REBOOT_OTHER_MODE
- kpd_print("Enable TWO KEY other mode LPRST\n");
- upmu_set_rg_pwrkey_rst_en(0x01);//pmic package function for long press reboot function setting//pmic_config_interface(TOP_RST_MISC, 0x01, PMIC_RG_PWRKEY_RST_EN_MASK, PMIC_RG_PWRKEY_RST_EN_SHIFT);
- upmu_set_rg_homekey_rst_en(0x01);//pmic_config_interface(TOP_RST_MISC, 0x01, PMIC_RG_HOMEKEY_RST_EN_MASK, PMIC_RG_HOMEKEY_RST_EN_SHIFT);
- //upmu_set_rg_homekey_puen(0x01);//pmic_config_interface(GPIO_SMT_CON3,0x01, PMIC_RG_HOMEKEY_PUEN_MASK, PMIC_RG_HOMEKEY_PUEN_SHIFT);//pull up homekey pin of PMIC for 89 project
- upmu_set_rg_pwrkey_rst_td(CONFIG_KPD_PMIC_LPRST_TD);
- #endif
- }
- /*
- int reg;
- pmic_read_interface(TOP_RST_MISC, ®, PMIC_RG_PWRKEY_RST_TD_MASK, PMIC_RG_PWRKEY_RST_TD_SHIFT);
- kpd_print("long press reboot time value reg = %d\n", reg);
- */
- #endif
- hrtimer_init(&aee_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- aee_timer.function = aee_timer_func;
- #if AEE_ENABLE_5_15
- hrtimer_init(&aee_timer_5s, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- aee_timer_5s.function = aee_timer_5s_func;
- #endif
- if((err = kpd_create_attr(&kpd_pdrv.driver)))
- {
- kpd_print("create attr file fail\n");
- kpd_delete_attr(&kpd_pdrv.driver);
- return err;
- }
- /**********************disable kpd as wake up source operation********************************/
- #ifndef EVB_PLATFORM
- kpd_print("disable kpd as wake up source operation!\n");
- upmu_set_rg_smps_autoff_dis(0x00);
- #endif
- /****************************************************************************************/
- #if 0
- /* KCOL0: GPIO103: KCOL1: GPIO108, KCOL2: GPIO105 input + pull enable + pull up */
- mt_set_gpio_mode(103, 1);
- mt_set_gpio_dir(103, 0);
- mt_set_gpio_pull_enable(103, 1);
- mt_set_gpio_pull_select(103, 1);
- mt_set_gpio_mode(108, 1);
- mt_set_gpio_dir(108, 0);
- mt_set_gpio_pull_enable(108, 1);
- mt_set_gpio_pull_select(108, 1);
- mt_set_gpio_mode(105, 1);
- mt_set_gpio_dir(105, 0);
- mt_set_gpio_pull_enable(105, 1);
- mt_set_gpio_pull_select(105, 1);
- /* KROW0: GPIO98, KROW1: GPIO97: KROW2: GPIO95 output + pull disable + pull down */
- mt_set_gpio_mode(98, 1);
- mt_set_gpio_dir(98, 1);
- mt_set_gpio_pull_enable(98, 0);
- mt_set_gpio_pull_select(98, 0);
- mt_set_gpio_mode(97, 1);
- mt_set_gpio_dir(97, 1);
- mt_set_gpio_pull_enable(97, 0);
- mt_set_gpio_pull_select(97, 0);
- mt_set_gpio_mode(95, 1);
- mt_set_gpio_dir(95, 1);
- mt_set_gpio_pull_enable(95, 0);
- mt_set_gpio_pull_select(95, 0);
- #endif
- return 0;
- }
- /* should never be called */
- static int kpd_pdrv_remove(struct platform_device *pdev)
- {
- return 0;
- }
- #define MTK_KP_WAKESOURCE//this is for auto set wake up source
- static int incall = 0;//this is for whether phone in call state judgement when resume
- #ifndef CONFIG_HAS_EARLYSUSPEND
- static int kpd_pdrv_suspend(struct platform_device *pdev, pm_message_t state)
- {
- kpd_suspend = true;
- #ifdef MTK_KP_WAKESOURCE
- #if 0 // TODO: check whether need to enable in 6572
- if(call_status == 2){
- if(incall == 0){
- kpd_print("kpd_early_suspend wake up source enable!! (%d)\n", kpd_suspend);
- upmu_set_rg_smps_autoff_dis(0x01);
- incall = 1;
- }
- //if(incall == 1){}
- }else{
- //if(incall == 0){}
- if(incall == 1){
- kpd_print("kpd_early_resume wake up source disable!! (%d)\n", kpd_suspend);
- upmu_set_rg_smps_autoff_dis(0x00);
- incall = 0;
- }
- }
- #endif
- #endif
- kpd_disable_backlight();
- kpd_print("suspend!! (%d)\n", kpd_suspend);
- return 0;
- }
- static int kpd_pdrv_resume(struct platform_device *pdev)
- {
- kpd_suspend = false;
- //kpd_enable_backlight();
- kpd_print("resume!! (%d)\n", kpd_suspend);
- return 0;
- }
- #else
- #define kpd_pdrv_suspend NULL
- #define kpd_pdrv_resume NULL
- #endif
- #ifdef CONFIG_HAS_EARLYSUSPEND
- static void kpd_early_suspend(struct early_suspend *h)
- {
- kpd_suspend = true;
- #ifdef MTK_KP_WAKESOURCE
- #if 0 // FIXME: check whether need to enable in 6572
- if(call_status == 2){
- if(incall == 0){
- kpd_print("kpd_early_suspend wake up source enable!! (%d)\n", kpd_suspend);
- upmu_set_rg_smps_autoff_dis(0x01);
- incall = 1;
- }
- //if(incall == 1){}
- }else{
- //if(incall == 0){}
- if(incall == 1){
- kpd_print("kpd_early_resume wake up source disable!! (%d)\n", kpd_suspend);
- upmu_set_rg_smps_autoff_dis(0x00);
- incall = 0;
- }
- }
- #endif
- #endif
- kpd_disable_backlight();
- kpd_print("early suspend!! (%d)\n", kpd_suspend);
- }
- static void kpd_early_resume(struct early_suspend *h)
- {
- kpd_suspend = false;
- //kpd_enable_backlight();
- kpd_print("early resume!! (%d)\n", kpd_suspend);
- }
- static struct early_suspend kpd_early_suspend_desc = {
- .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1,
- .suspend = kpd_early_suspend,
- .resume = kpd_early_resume,
- };
- #endif
- static int __init kpd_mod_init(void)
- {
- int r;
- #if KPD_DRV_CTRL_BACKLIGHT
- for (r = 0; r < ARRAY_SIZE(kpd_wake_key); r++)
- __set_bit(kpd_wake_key[r], kpd_wake_keybit);
- #endif
- r = platform_driver_register(&kpd_pdrv);
- if (r) {
- printk(KPD_SAY "register driver failed (%d)\n", r);
- return r;
- }
- #ifdef CONFIG_HAS_EARLYSUSPEND
- register_early_suspend(&kpd_early_suspend_desc);
- #endif
- return 0;
- }
- /* should never be called */
- static void __exit kpd_mod_exit(void)
- {
- }
- module_init(kpd_mod_init);
- module_exit(kpd_mod_exit);
- module_param(kpd_show_hw_keycode, int, 0644);
- module_param(kpd_show_register, int, 0644);
- module_param(kpd_enable_lprst, int, 0644);
- MODULE_AUTHOR("Terry Chang <[email protected]>");
- MODULE_DESCRIPTION("MTK Keypad (KPD) Driver v0.3");
- MODULE_LICENSE("GPL");