int wait_for_keypress(ulong msec) { ulong kv; ulong ini, end; int ret = 0; int handled = 0; pressed_key = 0;/* Reset KEY press */ ulong usec = msec * 1000;/* milli sec to micro sec */ /* scan for key at one first */ keypad_scan(); /* set bit 1 in KEYPAD_IRQ_EN register to enable IRQ */ writel(0x01, KEYPAD_IRQ_EN); /* For delays mor than 10 sec we need loop for every chunks of 10 sec */ do { kv = usec > PERIOD ? PERIOD : usec; ini = get_curr_timer(); end = ini + (ulong)usec2ticks(kv); while ((signed)(end - get_curr_timer()) > 0) { if (readl(KEYPAD_IRQ_STATUS)) keypad_scan(); } usec -= kv; } while (usec); /* set bit 1 in KEYPAD_IRQ_CLEAR register to clear IRQ */ writel(0x01, KEYPAD_IRQ_CLEAR); /* set bit 0 in KEYPAD_IRQ_EN register to disable IRQ */ writel(0x00, KEYPAD_IRQ_EN); look_up_key_comb(pressed_key, &handled); return ret; }
static ssize_t keyshort_test(struct device *dev, struct device_attribute *attr, char *buf) { struct s3c_keypad * s3c_keypad = dev_get_drvdata(dev); KEYGPIO_INFO * info_tbl = (KEYGPIO_INFO *)&s3c_keypad->keygpio_info_tbl[0]; int count; int mask=0; u32 col=0;//,cval=0,rval=0; int i; int rval; u32 press_mask; /* check gpio keys */ mask = !gpio_get_value(GPIO_KBR0) | !gpio_get_value(GPIO_nPOWER); //VOL_UP, nPOWER /* for(i=0; i < KEYGPIO_MAX; i++) { if( !gpio_get_value(info_tbl[i].gpio) ) mask |= (1 << i); } */ #if defined(CONFIG_MACH_CHIEF) && !defined(CONFIG_TIKAL_MPCS) rval = ~readl(key_base+S3C_KEYIFROW) & 0x01/*0x007F*/ ; /* SENSE[0-6] ---> SENSE[0] for chief*/ writel(KEYIFCOL_CLEAR, key_base+S3C_KEYIFCOL) ; if (rval) { mask |= 0x100 ; } #else /* check key scan */ keypad_scan(); for(col=0; col < KEYPAD_COLUMNS; col++) { press_mask = keymask[col]; printk("[%d] press_mask (0x%x) \n", col, press_mask); i = col * KEYPAD_ROWS; while (press_mask) { if (press_mask & 1) { mask |= (1 << (i + KEYGPIO_MAX)); } press_mask >>= 1; i++; } } #endif if(mask) { count = sprintf(buf,"PRESS\n"); printk("keyshort_test: PRESS 0x%x\n", mask); } else { count = sprintf(buf,"RELEASE\n"); printk("keyshort_test: RELEASE 0x%x\n", mask); } return count; }
static void keypad_timer_handler(unsigned long data) { struct s3c_keypad *s3c_keypad = (struct s3c_keypad *)data; u32 keymask_low = 0, keymask_high = 0; keypad_scan(&keymask_low, &keymask_high); process_special_key(s3c_keypad, keymask_low, keymask_high); if (keymask_low != prevmask_low) { process_input_report (s3c_keypad, prevmask_low, keymask_low, 0); prevmask_low = keymask_low; } #if (KEYPAD_COLUMNS>4) if (keymask_high != prevmask_high) { process_input_report (s3c_keypad, prevmask_high, keymask_high, 32); prevmask_high = keymask_high; } #endif if (keymask_low | keymask_high) { mod_timer(&keypad_timer,jiffies + SCAN_INTERVAL); } else { writel(KEYIFCON_INIT, key_base+S3C_KEYIFCON); is_timer_on = FALSE; } }
int wait_for_keypress_forever(void) { int handled = 0; int ret = 0; ulong ini, end; /* Reset KEY press */ pressed_key = 0; /* set bit 1 in KEYPAD_IRQ_EN register to enable IRQ */ writel(0x01, KEYPAD_IRQ_EN); do { ini = get_curr_timer(); end = ini + (ulong)usec2ticks(PERIOD); while ((signed)(end - get_curr_timer()) > 0) { if (readl(KEYPAD_IRQ_STATUS)) keypad_scan(); } ret = look_up_key_comb(pressed_key, &handled); if (handled == 1) break; } while (1); /* set bit 1 in KEYPAD_IRQ_CLEAR register to clear IRQ */ writel(0x01, KEYPAD_IRQ_CLEAR); /* set bit 0 in KEYPAD_IRQ_EN register to disable IRQ */ writel(0x00, KEYPAD_IRQ_EN); return ret; }
static void keypad_timer_handler(unsigned long data) { u32 press_mask; u32 release_mask; u32 restart_timer = 0; int i,col; struct s3c_keypad *pdata = (struct s3c_keypad *)data; struct input_dev *dev = pdata->dev; keypad_scan(); for(col=0; col < KEYPAD_COLUMNS; col++) { press_mask = ((keymask[col] ^ prevmask[col]) & keymask[col]); release_mask = ((keymask[col] ^ prevmask[col]) & prevmask[col]); #ifdef CONFIG_CPU_FREQ #if USE_PERF_LEVEL_KEYPAD if (press_mask || release_mask) set_dvfs_perf_level(); #endif #endif i = col * KEYPAD_ROWS; while (press_mask) { if (press_mask & 1) { input_report_key(dev,pdata->keycodes[i],1); pr_err("[key_press] keycode=%d\n", i+1); //DPRINTK("\nkey Pressed : key %d map %d\n",i, pdata->keycodes[i]); } press_mask >>= 1; i++; } i = col * KEYPAD_ROWS; while (release_mask) { if (release_mask & 1) { input_report_key(dev,pdata->keycodes[i],0); pr_err("[key_release] keycode=%d\n", i+1); //DPRINTK("\nkey Released : %d map %d\n",i,pdata->keycodes[i]); } release_mask >>= 1; i++; } prevmask[col] = keymask[col]; restart_timer |= keymask[col]; } if (restart_timer) { mod_timer(&keypad_timer,jiffies + HZ/10); } else { writel(KEYIFCON_INIT, key_base+S3C_KEYIFCON); is_timer_on = FALSE; } }
/**************************************************************************** * * Interrupt handler, called whenever a keypress/release occurs * ***************************************************************************/ static irqreturn_t keypad_gpio_irq(int irq, void *dev_id) { struct CBLK *bcm_kp = dev_id; int gpio_pin = IRQ_TO_GPIO(irq); disable_irq(irq); reg_gpio_set_debounce_disable( gpio_pin ); keypad_scan( gpio_pin, bcm_kp ); reg_gpio_set_debounce_enable( gpio_pin ); reg_gpio_clear_interrupt( gpio_pin ); enable_irq(irq); return IRQ_HANDLED; }
static void keypad_timer_handler(unsigned long data) { u32 press_mask; u32 release_mask; u32 restart_timer = 0; int i, col; struct s3c_keypad *pdata = (struct s3c_keypad *)data; struct input_dev *dev = pdata->dev; keypad_scan(); for (col = 0; col < KEYPAD_COLUMNS; col++) { press_mask = ((keymask[col] ^ prevmask[col]) & keymask[col]); release_mask = ((keymask[col] ^ prevmask[col]) & prevmask[col]); i = col * KEYPAD_ROWS; while (press_mask) { if (press_mask & 1) { input_report_key(dev, pdata->keycodes[i], 1); pr_debug("key Pressed : key %d map %d\n", i, pdata->keycodes[i]); } press_mask >>= 1; i++; } i = col * KEYPAD_ROWS; while (release_mask) { if (release_mask & 1) { input_report_key(dev, pdata->keycodes[i], 0); pr_debug("key Released : %d map %d\n", i, pdata->keycodes[i]); } release_mask >>= 1; i++; } prevmask[col] = keymask[col]; restart_timer |= keymask[col]; } if (restart_timer) { mod_timer(&keypad_timer, jiffies + HZ/10); } else { writel(KEYIFCON_INIT, key_base + S3C_KEYIFCON); is_timer_on = false; } }
/******************************************************************************* * @brief scan keypad to get key id * @author zhanggaoxin * @date 2013-03-18 * @param T_VOID * @return T_eKEY_ID * @retval the key id *******************************************************************************/ T_eKEY_ID Fwl_KeypadScan(T_VOID) { T_KEY_ID keyIdx; //对平台来说,驱动库返回的并不是真正的KeyId, //只是相应KeyId的索引值,这里需要转换成真正的KeyId keyIdx = keypad_scan(); if (INVALID_KEY_ID == keyIdx) { return kbNULL; } else { return keyIdx; } }
static void keypad_timer_handler(unsigned long data) { u32 keymask[KEYPAD_COLUMNS]; u32 press_mask; u32 release_mask; u32 detect_press = 0; int k, j; int i; struct s3c_keypad *pdata = (struct s3c_keypad *)data; struct input_dev *dev = pdata->dev; keypad_scan(keymask); for (k = 0, i = 0; k < KEYPAD_COLUMNS; k++) { i = k*KEYPAD_ROWS; if (keymask[k] != prevmask[k]) { press_mask = ((keymask[k] ^ prevmask[k]) & keymask[k]); release_mask = ((keymask[k] ^ prevmask[k]) & prevmask[k]); for (j = 0 ; j < KEYPAD_ROWS ; j++) { if (press_mask & 1) { input_report_key(dev, pdata->keycodes[i+j], 1); DPRINTK("key pressed: c=%d,r=%d,index=%d,keycode=%d\n", i, j, i+j, pdata->keycodes[i+j]); } press_mask >>= 1; if (release_mask & 1) { input_report_key(dev, pdata->keycodes[i+j], 0); DPRINTK("key released: c=%d,r=%d,index=%d,keycode=%d\n", i, j, i+j, pdata->keycodes[i+j]); } release_mask >>= 1; } } prevmask[k] = keymask[k]; detect_press |= keymask[k]; }
static void s3c_keypad_timer_handler(unsigned long data) { u32 press_mask; u32 release_mask; u32 restart_timer = 0; int i,col; struct s3c_keypad *pdata = (struct s3c_keypad *)data; struct input_dev *dev = pdata->dev; struct timer_list * timer = &pdata->keypad_timer; #if defined(CONFIG_MACH_CHIEF) && !defined(CONFIG_TIKAL_MPCS) && !defined(CONFIG_MACH_TREBON) int skipcol=0; #endif keypad_scan(); for(col=0; col < KEYPAD_COLUMNS; col++) { press_mask = ((keymask[col] ^ prevmask[col]) & keymask[col]); release_mask = ((keymask[col] ^ prevmask[col]) & prevmask[col]); #ifdef CONFIG_CPU_FREQ #if USE_PERF_LEVEL_KEYPAD // if (press_mask || release_mask) // set_dvfs_target_level(LEV_400MHZ); #endif #endif i = col * KEYPAD_ROWS; while (press_mask) { if (press_mask & 1) { #if defined(CONFIG_MACH_CHIEF) && !defined(CONFIG_TIKAL_MPCS) && !defined(CONFIG_MACH_TREBON) /* * when camera & focus key press is detected simultaneously, * report focus first and camera second, so that platform * detects camera key repeat event (for key long press) */ if ( col==2 && ((keymask[3] ^ prevmask[3]) & keymask[3])) { input_report_key(dev,pdata->keycodes[3],1); #ifdef DEBUG_LOG_ENABLE printk(KERN_DEBUG"[KEYPAD] key Pressed : key %d map %d\n",3, pdata->keycodes[3]); #else printk(KERN_DEBUG"[KEYPAD] key Pressed\n"); #endif skipcol = 1; } #endif input_report_key(dev,pdata->keycodes[i],1); #if defined(CONFIG_MACH_CHIEF) && !defined(CONFIG_TIKAL_MPCS) && !defined(CONFIG_MACH_TREBON) keyled_timer_start(); /* keypad_led */ #endif /* #ifdef CONFIG_KERNEL_DEBUG_SEC */ #ifdef DEBUG_LOG_ENABLE printk(KERN_DEBUG"[KEYPAD] key Pressed : key %d map %d\n",i, pdata->keycodes[i]); #else printk(KERN_DEBUG"[KEYPAD] key Pressed\n"); #endif } press_mask >>= 1; i++; #if defined(CONFIG_MACH_CHIEF) && !defined(CONFIG_TIKAL_MPCS) && !defined(CONFIG_MACH_TREBON) if (skipcol) { press_mask >>= 1; i++; } #endif } i = col * KEYPAD_ROWS; while (release_mask) { if (release_mask & 1) { input_report_key(dev,pdata->keycodes[i],0); #if defined(CONFIG_MACH_CHIEF) && !defined(CONFIG_TIKAL_MPCS) && !defined(CONFIG_MACH_TREBON) keyled_timer_start(); /* keypad_led */ #endif /* #ifdef CONFIG_KERNEL_DEBUG_SEC */ #ifdef DEBUG_LOG_ENABLE printk(KERN_DEBUG"[KEYPAD] key Released : %d map %d\n",i,pdata->keycodes[i]); #else printk(KERN_DEBUG"[KEYPAD] key Released\n"); #endif } release_mask >>= 1; i++; } prevmask[col] = keymask[col]; restart_timer |= keymask[col]; #if defined(CONFIG_MACH_CHIEF) && !defined(CONFIG_TIKAL_MPCS) && !defined(CONFIG_MACH_TREBON) /* skip next column, we've already proccessed this*/ if (skipcol) { col++; skipcol = 0; } #endif } if (restart_timer) { #if defined(CONFIG_MACH_CHIEF) mod_timer(timer,jiffies + (5*HZ/100)); #else mod_timer(timer, timer->expires); #endif } else { writel(KEYIFCON_INIT, key_base+S3C_KEYIFCON); pdata->keypad_timer_on = FALSE; } }
static void s3c_keypad_timer_handler(unsigned long data) { u32 press_mask; u32 release_mask; u32 restart_timer = 0; int i,col; struct s3c_keypad *pdata = (struct s3c_keypad *)data; struct input_dev *dev = pdata->dev; struct timer_list * timer = &pdata->keypad_timer; keypad_scan(); for(col=0; col < KEYPAD_COLUMNS; col++) { press_mask = ((keymask[col] ^ prevmask[col]) & keymask[col]); release_mask = ((keymask[col] ^ prevmask[col]) & prevmask[col]); #ifdef CONFIG_CPU_FREQ #if USE_PERF_LEVEL_KEYPAD // if (press_mask || release_mask) // set_dvfs_target_level(LEV_400MHZ); #endif #endif i = col * KEYPAD_ROWS; while (press_mask) { if (press_mask & 1) { input_report_key(dev,pdata->keycodes[i],1); #ifdef CONFIG_MACH_CHIEF keyled_timer_start(); /* keypad_led */ #endif /* #ifdef CONFIG_KERNEL_DEBUG_SEC */ #ifdef DEBUG_LOG_ENABLE printk(KERN_DEBUG"[KEYPAD] key Pressed : key %d map %d\n",i, pdata->keycodes[i]); #else printk(KERN_DEBUG"[KEYPAD] key Pressed\n"); #endif } press_mask >>= 1; i++; } i = col * KEYPAD_ROWS; while (release_mask) { if (release_mask & 1) { input_report_key(dev,pdata->keycodes[i],0); #ifdef CONFIG_MACH_CHIEF keyled_timer_start(); /* keypad_led */ #endif /* #ifdef CONFIG_KERNEL_DEBUG_SEC */ #ifdef DEBUG_LOG_ENABLE printk(KERN_DEBUG"[KEYPAD] key Released : %d map %d\n",i,pdata->keycodes[i]); #else printk(KERN_DEBUG"[KEYPAD] key Released\n"); #endif } release_mask >>= 1; i++; } prevmask[col] = keymask[col]; restart_timer |= keymask[col]; } if (restart_timer) { mod_timer(timer, timer->expires); } else { writel(KEYIFCON_INIT, key_base+S3C_KEYIFCON); pdata->keypad_timer_on = FALSE; } }
static void keypad_timer_handler(unsigned long data) { u32 press_mask; u32 release_mask; u32 restart_timer = 0; int i,col; struct s3c_keypad *pdata = (struct s3c_keypad *)data; struct input_dev *dev = pdata->dev; keypad_scan(); for(col=0; col < KEYPAD_COLUMNS; col++) { press_mask = ((keymask[col] ^ prevmask[col]) & keymask[col]); release_mask = ((keymask[col] ^ prevmask[col]) & prevmask[col]); #ifdef CONFIG_CPU_FREQ #if USE_PERF_LEVEL_KEYPAD if (press_mask || release_mask) set_dvfs_target_level(LEV_400MHZ); #endif #endif i = col * KEYPAD_ROWS; while (press_mask) { if (press_mask & 1) { if(s3ckeypad_evt_enable_status){ //NAGSM_Android_SEL_Kernel_Aakash_20100319 #if defined(CONFIG_KEPLER_VER_B2) || defined(CONFIG_KEPLER_VER_B4) || defined(CONFIG_T959_VER_B5)|| defined (CONFIG_S5PC110_VIBRANTPLUS_BOARD) if((i != 1) && (i !=2)){ input_report_key(dev,pdata->keycodes[i],1); printk("\nkey Pressed : key %d map %d\n",i, pdata->keycodes[i]); } #elif defined(CONFIG_HAWK_VER_B0) if((i != 0) && (i !=1) && (i != 2) && (i !=3) ){ input_report_key(dev,pdata->keycodes[i],1); printk("\nkey Pressed : key %d map %d\n",i, pdata->keycodes[i]); } #else input_report_key(dev,pdata->keycodes[i],1); printk("\nkey Pressed : key %d map %d\n",i, pdata->keycodes[i]); #endif } } press_mask >>= 1; i++; } i = col * KEYPAD_ROWS; while (release_mask) { if (release_mask & 1) { if(s3ckeypad_evt_enable_status){ //NAGSM_Android_SEL_Kernel_Aakash_20100319 #if defined(CONFIG_KEPLER_VER_B2) || defined(CONFIG_KEPLER_VER_B4) || defined(CONFIG_T959_VER_B5) || defined(CONFIG_HAWK_VER_B0)|| defined (CONFIG_S5PC110_VIBRANTPLUS_BOARD) if((i != 1) && (i !=2)){ input_report_key(dev,pdata->keycodes[i],0); printk("\nkey Released : %d map %d\n",i,pdata->keycodes[i]); } #else input_report_key(dev,pdata->keycodes[i],0); printk("\nkey Released : %d map %d\n",i,pdata->keycodes[i]); #endif } #ifdef CONFIG_KERNEL_DEBUG_SEC #if defined(CONFIG_S5PC110_KEPLER_BOARD) || defined(CONFIG_S5PC110_FLEMING_BOARD) || defined(CONFIG_T959_VER_B5) || defined(CONFIG_HAWK_VER_B0) || defined (CONFIG_S5PC110_VIBRANTPLUS_BOARD) #if defined(CONFIG_KEPLER_VER_B2) || defined(CONFIG_KEPLER_VER_B4) || defined(CONFIG_T959_VER_B5) || defined(CONFIG_HAWK_VER_B0) || defined (CONFIG_S5PC110_VIBRANTPLUS_BOARD) if((i != 1) && (i !=2)){ dump_mode_key_sequence[dump_mode_key_count%DUMP_SEQUENCE_COUNT] = i; dump_mode_key_count++; } #endif #if defined(CONFIG_KEPLER_VER_B0) dump_mode_key_sequence[dump_mode_key_count%DUMP_SEQUENCE_COUNT] = i; dump_mode_key_count++; #endif { // check time inverval between force upload key sequence input int this_cpu; this_cpu = smp_processor_id(); unsigned long nanosec_rem; dump_mode_key_pressed = cpu_clock(this_cpu); nanosec_rem = do_div(dump_mode_key_pressed, 1000000000); if ((dump_mode_key_pressed-dump_mode_key_pressed_prev>=2) && dump_mode_key_pressed_prev!=0) { forced_dump_time_limit=1; printk("force upload long time : %ul\n ", dump_mode_key_pressed-dump_mode_key_pressed_prev); } dump_mode_key_pressed_prev=dump_mode_key_pressed; } if(i == PRESSED_DOWN){ if(is_first_key_down == 1) { // when down key is pressed twice, will check whether pressed keys are same as dump seqence is_dump_sequence = 0; //for(dump_compare_count=0; dump_compare_count<DUMP_SEQUENCE_COUNT; dump_compare_count++) //printk("dump_mode_key_sequence[%d] : %d\n",(dump_mode_key_count + dump_compare_count)%DUMP_SEQUENCE_COUNT, dump_mode_key_sequence[(dump_mode_key_count + dump_compare_count)%DUMP_SEQUENCE_COUNT]); for(dump_compare_count=0; dump_compare_count<DUMP_SEQUENCE_COUNT; dump_compare_count++) { //printk("forced_dump_sequence[%d] : %d, dump_mode_key_sequence[%d] : %d\n",dump_compare_count, forced_dump_sequence[dump_compare_count],(dump_mode_key_count + dump_compare_count)%DUMP_SEQUENCE_COUNT, dump_mode_key_sequence[(dump_mode_key_count + dump_compare_count)%DUMP_SEQUENCE_COUNT]); if(forced_dump_sequence[dump_compare_count] == dump_mode_key_sequence[((dump_mode_key_count + dump_compare_count) % DUMP_SEQUENCE_COUNT)]){ is_dump_sequence++; continue; }else { //printk("This is not dump sequence.\n"); is_dump_sequence = 0; break; } } if(is_dump_sequence == DUMP_SEQUENCE_COUNT) { if (forced_dump_time_limit==1) { // case of long time between force upload key sequence forced_dump_time_limit=0; is_dump_sequence=0; dump_mode_key_pressed_prev=0; printk("Dump Mode Fail\n"); } else { if( (KERNEL_SEC_DEBUG_LEVEL_MID == kernel_sec_get_debug_level()) || (KERNEL_SEC_DEBUG_LEVEL_HIGH == kernel_sec_get_debug_level()) ) { printk("Now going to Dump Mode\n"); if (kernel_sec_viraddr_wdt_reset_reg) { kernel_sec_set_cp_upload(); kernel_sec_save_final_context(); // Save theh final context. kernel_sec_set_upload_cause(UPLOAD_CAUSE_FORCED_UPLOAD); kernel_sec_hw_reset(FALSE); // Reboot. } } } } }else{ is_first_key_down = 1; } }else{ #if defined(CONFIG_KEPLER_VER_B2) || defined(CONFIG_KEPLER_VER_B4) || defined(CONFIG_T959_VER_B5) || defined(CONFIG_HAWK_VER_B0)|| defined (CONFIG_S5PC110_VIBRANTPLUS_BOARD) if((i != 1) && (i !=2)){ is_first_key_down = 0; } #endif #if defined(CONFIG_KEPLER_VER_B0) is_first_key_down = 0; #endif } #endif #endif } release_mask >>= 1; i++; } prevmask[col] = keymask[col]; restart_timer |= keymask[col]; } if (restart_timer) { mod_timer(&keypad_timer,jiffies + HZ/10); } else { writel(KEYIFCON_INIT, key_base+S3C_KEYIFCON); is_timer_on = FALSE; } }
static void keypad_timer_handler(unsigned long data) { u32 press_mask; u32 release_mask; u32 restart_timer = 0; int i,col; struct s3c_keypad *pdata = (struct s3c_keypad *)data; struct input_dev *dev = pdata->dev; keypad_scan(); #if defined (CONFIG_S5PC110_SIDEKICK_BOARD) checking_ghostkey_pressing(); #endif for(col=0; col < KEYPAD_COLUMNS; col++) { press_mask = ((keymask[col] ^ prevmask[col]) & keymask[col]); release_mask = ((keymask[col] ^ prevmask[col]) & prevmask[col]); #ifdef CONFIG_CPU_FREQ #if USE_PERF_LEVEL_KEYPAD if (press_mask || release_mask) set_dvfs_target_level(LEV_400MHZ); #endif #endif i = col * KEYPAD_ROWS; while (press_mask) { if (press_mask & 1) { if(s3ckeypad_evt_enable_status){ //NAGSM_Android_SEL_Kernel_Aakash_20100319 if(i == 41){ abnomal_key_combination = 1; } if((abnomal_key_combination == 1) && (i == 51)){ }else{ input_report_key(dev,pdata->keycodes[i],1); printk("\nkey Pressed : key %d map %d\n",i, pdata->keycodes[i]); } } } press_mask >>= 1; i++; } i = col * KEYPAD_ROWS; while (release_mask) { if (release_mask & 1) { if(s3ckeypad_evt_enable_status){ //NAGSM_Android_SEL_Kernel_Aakash_20100319 if(i == 41){ abnomal_key_combination = 0; } if((abnomal_key_combination == 1) && (i == 51)){ // for T839. if @ is pressed, p is also pressed, then lock up occurs(UI issue...). temporary, block p key when @ is pressed. }else{ input_report_key(dev,pdata->keycodes[i],0); printk("\nkey Released : %d map %d\n",i,pdata->keycodes[i]); } } } release_mask >>= 1; i++; } prevmask[col] = keymask[col]; restart_timer |= keymask[col]; } if (restart_timer) { mod_timer(&keypad_timer,jiffies + HZ/100); } else { writel(KEYIFCON_INIT, key_base+S3C_KEYIFCON); is_timer_on = FALSE; } }
static void keypad_timer_handler(unsigned long data) { struct s3c_keypad *s3c_keypad = (struct s3c_keypad *)data; u32 keymask_low = 0, keymask_high = 0; keypad_scan(&keymask_low, &keymask_high); process_special_key(s3c_keypad, keymask_low, keymask_high); #ifdef CONFIG_KERNEL_DEBUG_SEC // DPRINTK("%s L(0x%x) H(0x%x)\n", __func__, keymask_low, keymask_high); #if defined (CONFIG_MACH_MAX) if(keymask_low == 0x10202) // vol down key + ok key + camera Key #elif defined (CONFIG_MACH_VITAL) if(keymask_high == 0x1000100) // vol down key (0x1000000) + voice key (0x100) #else /* CONFIG_MACH_VINSQ */ if((keymask_low == 0x1) && (keymask_high == 0x100)) // vol down key + ok key #endif { #if defined (DEVELOPE_RELEASE) if (kernel_sec_viraddr_wdt_reset_reg) { kernel_sec_save_final_context(); // Save the final context. kernel_sec_set_upload_cause(UPLOAD_CAUSE_FORCED_UPLOAD); kernel_sec_hw_reset(FALSE); // Reboot. } #endif } else #endif #if defined (CONFIG_MACH_MAX) // Requested by QA // CAM_FULL : keymask_low = 0x30000 // VOLUME_UP : keymask_low = 0x100 // VOLUME_DOWN : keymask_low = 0x200 if((keymask_low == 0x30300) && power_key_pressed) #elif defined (CONFIG_MACH_VITAL) // CAM_FULL : keymask_low = 0x1010000 // VOLUME_UP : keymask_low = 0x1 if((keymask_low == 0x1010001) && power_key_pressed) #else /* CONFIG_MACH_VINSQ */ // CAM_FULL : keymask_low = 0x1010000 // VOLUME_UP : keymask_high = 0x1000000 if((keymask_low == 0x1010000) && (keymask_high == 0x1000000) && power_key_pressed) #endif { kernel_sec_set_upload_cause(UPLOAD_CAUSE_INIT); kernel_sec_hw_reset(FALSE); // Reboot. } if (keymask_low != prevmask_low) { process_input_report (s3c_keypad, prevmask_low, keymask_low, 0); prevmask_low = keymask_low; } #if (KEYPAD_COLUMNS>4) if (keymask_high != prevmask_high) { process_input_report (s3c_keypad, prevmask_high, keymask_high, 32); prevmask_high = keymask_high; } #endif if (keymask_low | keymask_high) { mod_timer(&keypad_timer,jiffies + SCAN_INTERVAL); } else { writel(KEYIFCON_INIT, key_base+S3C_KEYIFCON); } }