按键没有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-20Intent 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; // 0x80field public static final int META_SYM_ON = 4; // 0x4field public static final int KEYCODE_SCAN = 220; // 0xdcfield public static final int KEYCODE_SCAN_LEFT = 221; // 0xddfield 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 addAKEYCODE_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  FNkey 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 <terry.chang@mediatek.com>** 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)
#endifstatic 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 chipstatic 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);
#endifvoid 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_PINkpd_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_PINkpd_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_PINkpd_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_PINkpd_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_PINkpd_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_PINkpd_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_PINkpd_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_PINkpd_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_TYPEkpd_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_MAPkpd_pmic_rstkey_handler(1);msleep(100);kpd_pmic_rstkey_handler(0);
#endifkpd_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;
#endifstatic 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_15aee_timer_5s_started = true;hrtimer_start(&aee_timer_5s, ktime_set(AEE_DELAY_TIME_5S, 0),HRTIMER_MODE_REL);
#endifhrtimer_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_15if(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_15flags_5s = false;
#endifaee_timer_started = false;kpd_print("aee_timer canceled\n");}#if AEE_ENABLE_5_15if(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;
}
#endifstatic 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_PMICvoid 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_MAPinput_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_KPif(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]);
#endiffor (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_KPif((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_KPif(data == 0)
#endifenable_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_AUTOTESTcase PRESS_OK_KEY://KPD_AUTOTEST disable auto test setting to resolve CR ALPS00464496if(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;
#endifcase 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_KPkpd_auto_test_for_factorymode();
#elsekpd_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_QWERTYbool 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_SENSITIVEstatic 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      // COL1typedef 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              1void AW9523_i2c_initial(void)
{
#if NEW_I2C_TIMINGI2C_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;
#elseGPIO_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 downAW9523_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_TIMINGI2C_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);
#elseGPIO_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_TIMINGI2C_SDA_OUTPUT;I2C_SCL_OUTPUT;//spin_lock_irqsave(&gpio_i2c_spinLock, flags_spin);I2C_SCL_LOW;   // test @20131009AW9523_delay_1us(5);  //udelay(10); //udelay(100); //mdelay(1);     // 20131010I2C_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);
#elseGPIO_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_TIMINGchar  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;elseI2C_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;#elseu8 i;char ack;GPIO_InitIO(1,I2C_SDA_GPIO);for   (i=0; i<8; i++){if (data & 0x80)GPIO_WriteIO(1,I2C_SDA_GPIO);elseGPIO_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_TIMINGu8 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;
#elseu8 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_TIMINGAW9523_i2c_start();AW9523_i2c_write_byte(LED_SLAVE_ADDR);AW9523_i2c_write_byte(reg);AW9523_i2c_write_byte(data);AW9523_i2c_stop();return 1;
#elsechar ack=0;AW9523_i2c_start();    ack|=AW9523_i2c_write_byte(LED_SLAVE_ADDR);    //write device addressack|=AW9523_i2c_write_byte(reg);     // reg addressack|= AW9523_i2c_write_byte(data);   // dataAW9523_i2c_stop();return ack;
#endif}static char AW9523_i2c_write_reg(unsigned char reg,unsigned char data)
{
#if NEW_I2C_TIMINGAW9523_i2c_start();AW9523_i2c_write_byte(LED_SLAVE_ADDR);AW9523_i2c_write_byte(reg);AW9523_i2c_write_byte(data);AW9523_i2c_stop();return 1;
#elsechar 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 successbreak;}return ack;
#endif
}u8 AW9523_i2c_read_reg(u8 regaddr)
{
#if NEW_I2C_TIMINGu8 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 signalAW9523_i2c_write_byte(LED_SLAVE_ADDR|0x01);read_byte = AW9523_i2c_read_byte();AW9523_i2c_stop();return read_byte;
#elseu8 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 addressack2=AW9523_i2c_write_byte(regaddr);     // reg addressAW9523_i2c_stop();AW9523_i2c_start(); ack3=AW9523_i2c_write_byte((LED_SLAVE_ADDR|0x01));     //write device addressif((ack1 || ack2 || ack3)==0) // ack successbreak;}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 20131129return 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_0AW9523_i2c_write_reg(0x21, 0x40);       // led current P1_1AW9523_i2c_write_reg(0x13, 0xFf);       // P1_0, P1_1 working mode}else{AW9523_i2c_write_reg(0x20, 0x00);       // led current P1_0AW9523_i2c_write_reg(0x21, 0x00);       // led current P1_1AW9523_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    GPIO110void 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 0SCAN_test();#elseprintk("\===== 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 1AW9523_i2c_write_reg(0x7F, 0x00);   // sw resetmdelay(10);aw9523_keylight_open(0);        // close P1_0, P1_1 mos fetaw9523_p0_int_disable(); aw9523_set_p1_gpio_mode();//liubiaoaw9523_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 0if (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;}#endifprintk("\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 0aw9523_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);
}#endifstatic 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;
#endiffor (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_AUTOTESTfor (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);
#endifkpd_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_EINTmt65xx_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 1printk("===== 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 settingupmu_set_rg_homekey_rst_en(0x00);        #ifdef CONFIG_ONEKEY_REBOOT_NORMAL_MODEkpd_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_MODEkpd_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 projectupmu_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 settingupmu_set_rg_homekey_rst_en(0x00);      #ifdef CONFIG_ONEKEY_REBOOT_OTHER_MODEkpd_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_MODEkpd_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 projectupmu_set_rg_pwrkey_rst_td(CONFIG_KPD_PMIC_LPRST_TD);#endif}/*int reg;pmic_read_interface(TOP_RST_MISC, &reg, 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_15hrtimer_init(&aee_timer_5s, CLOCK_MONOTONIC, HRTIMER_MODE_REL);aee_timer_5s.function = aee_timer_5s_func;#endifif((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_PLATFORMkpd_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);
#endifreturn 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 6572if(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 6572if(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,
};
#endifstatic int __init kpd_mod_init(void)
{int r;#if KPD_DRV_CTRL_BACKLIGHTfor (r = 0; r < ARRAY_SIZE(kpd_wake_key); r++)__set_bit(kpd_wake_key[r], kpd_wake_keybit);
#endifr = platform_driver_register(&kpd_pdrv);if (r) {printk(KPD_SAY "register driver failed (%d)\n", r);return r;}#ifdef CONFIG_HAS_EARLYSUSPENDregister_early_suspend(&kpd_early_suspend_desc);
#endifreturn 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 <terry.chang@mediatek.com>");
MODULE_DESCRIPTION("MTK Keypad (KPD) Driver v0.3");
MODULE_LICENSE("GPL");

MTK keypad调试,扩张键盘IC AW9523相关推荐

  1. MTK keypad调试,扩张键盘IC AW9523

    FROM:http://blog.csdn.net/aree/article/details/28683741 按键没有hal层 设备中断-------驱动------>内核按键码(SCANCO ...

  2. MTK平台开机初始化时 camera驱动流程|MTK camera调试常见几十种问题处理方法

    转载:https://www.jianshu.com/p/75ab1d82bbd3 mtk的驱动多是以模块加载的方式(module_init():module_exit():)加载到内核中去的:正因为 ...

  3. MTK ISP 调试流程总结 ( 使用工具: ImagiqSimulator FSViewer )

    MTK  ISP 调试流程总结  ( 使用工具: ImagiqSimulator  FSViewer ) 加载选择  134341991-0139-0139-main-imgo-PW4608-PH34 ...

  4. MTK 关机充电时充电IC正常,电池正常充电,但是充电动画一直显示0%

    MTK 关机充电时充电IC正常,电池正常充电,但是充电动画一直显示0% 平台 mt8168+mt6357+chargerIC 问题 MTK 关机充电时充电IC正常,电池正常充电,但是充电动画一直显示0 ...

  5. MTK 开发调试方法

    mtk开发基本调试方法大概就三种模拟器方式,trac方式,串口方式 普通的界面修改,功能行基本都可以通过模拟器完成,但是遇到死机或者与l4c相关的问题是就需要打trac配合cather进行调试了:如果 ...

  6. linux脚本ipddr.sh 是什么,MTK DDR调试

    1. 获取 flash id: 硬件信息:通过这个节点可以知道当前flash的id,上层根据id找到对应的flash名字. cat /sys/block/mmcblk0/device/cid \ker ...

  7. MTK lcm调试总结及解决思路

    一.常见lcm问题 LCD会注意到一下问题: 1.gamma是否超标. 2.刷新率是否合适. 3.flicker现象是否严重或能否轻易察觉. 4.ESD是否合格. 5.背光调节是否存在问题,特别是自动 ...

  8. Android OrangePi 4G IOT(二) - MTK更换调试串口

    一.Debug LOG串口更改 orangepi 4G iot的默认的log调试串口是在板子后面的,使用起来不方便,之前UART0焊接不好导致焊盘弄坏了,没办法,准备修改成插针的40pin引脚的的UA ...

  9. 开发调试指令大全--(MTK开发调试命令)

    MTK无线驱动开发调试手册 1.前言 2.MTK Wifi芯片简介 2.1 单频WIFI芯片信息 2.2 WiFi驱动版本 3.MTK 无线驱动开发调试 3.1 常用命令行 3.1.1 设置WLAN驱 ...

最新文章

  1. Windows7中搭建Android x86_64及armv8-a操作步骤
  2. 3- MySQL数据类型
  3. arial字体可以商用吗_每次做PPT都不知该怎么选字体?6种万能字体搭配组合送你...
  4. Linux交叉编译+粤嵌LCD实现三色图
  5. JVM学习系列之对象访问的两种方式句柄和直接指针
  6. 加速器instagram_“类似Instagram过滤器”标记肿瘤图像中的分子细节
  7. C语言入门130题-OJ
  8. 微信公众号不限次数发送消息
  9. STM32H7B0 HAL库中关于DMA的注意事项以及DCMI调试遇到的问题及解决方法
  10. 关于虚拟机中的HWADDR和MACADDR地址
  11. vb/vb.net开发技巧荟萃(七)
  12. 使用scrapy爬取豆瓣上面《战狼2》影评
  13. 祝贺 弓叶科技总经理莫卓亚荣获“松山湖奋斗之星”
  14. 操作系统第七、八章习题
  15. UOS 在桌面创建网页快捷方式
  16. 【你好,windows】Windows10 x64 18363.628 X64专业工作站纯净版2020.2.13
  17. JaCoCo计算代码覆盖率原理
  18. SQL复杂查询,优化
  19. 造成计算机系统不安全的因素,造成计算机系统不安全的因素包括()。
  20. java 最大矩形_最大矩形面积

热门文章

  1. To display the conditions report re-run your application with ‘debug‘ enabled.
  2. [转载].NET商业软件源码保护
  3. VS2019中C#开发的bottom按钮在哪里?
  4. 硬件工程师成长之路(5)——板子调试
  5. TA游戏推荐:Android益智游戏《戳青蛙》
  6. C# MD5加密 解密
  7. linux有没有处理器漏洞,【图片】为什么linux mint上cpu漏洞直到现在也没完全修复?_linux吧_百度贴吧...
  8. Python爬虫——爬取IEEE论文
  9. 如何将论文图表做得漂亮?
  10. 肿瘤的分型、分级和分期