unsigned char key_cmd(unsigned char cmd, int *val) { unsigned char ret = 1; KEY_LOG_PRINT("%s: %d\n", __func__, cmd); switch (cmd) { case KEY_DM_CHECK_COMMAND: KEY_LOG_PRINT("key_cmd check:%x val0:%x val1:%x \n", g_kdm_check, val[0], val[1]); if (val[0]) { g_kdm_check = 1; } else { g_kdm_check = 0; } ret = 0; break; case KEY_DM_KEY_GET_EVENT_COOMAND: KEY_LOG_PRINT("key_cmd code:%x\n", g_kdm_keycode ); *val = g_kdm_keycode; g_kdm_keycode = 0x00; ret = 0; break; default: printk(KERN_ERR "%s: %d\n", __func__, cmd); break; } return ret; }
static void gpio_keys_set_stateoff(unsigned int code) { unsigned int pos; pos = gpio_keys_get_chattering_pos(code); if (pos != 0xFFFFFFFF) { KEY_LOG_PRINT("gpio key 0x%x off\n", code); gpio_keys_chattering_data[pos].is_on = false; } else { KEY_LOG_PRINT("gpio keyoff pos invalid\n"); } }
void key_dm_driver_set_port(unsigned char in_swmode) { KEY_LOG_PRINT( "%s: sw:%x \n", __func__, in_swmode); if( g_key_dm_port_check ) { unsigned char i = 0; for(i = 0; i < ARRAY_SIZE(changer2port); i++) { if( changer2port[i].cgr == in_swmode ) { g_key_dm_port_data[g_key_dm_port_data_idx] = changer2port[i].scan; g_key_dm_port_data_idx++; if( ARRAY_SIZE(g_key_dm_port_data) <= g_key_dm_port_data_idx ) { g_key_dm_port_data_idx = 0; } } } g_key_dm_ic_data[g_key_dm_ic_data_idx] = in_swmode; g_key_dm_ic_data_idx++; if( ARRAY_SIZE(g_key_dm_ic_data) <= g_key_dm_ic_data_idx ) { g_key_dm_ic_data_idx = 0; } } }
static void gpio_keys_report_event(struct gpio_button_data *bdata) { struct gpio_keys_button *button = bdata->button; struct input_dev *input = bdata->input; unsigned int type = button->type ?: EV_KEY; #ifdef CONFIG_FEATURE_KCC_00 int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low; #else int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; #endif #ifdef CONFIG_FEATURE_KCC_00 if( g_kdm_check ) { key_set_code( button->code ); }else{ KEY_LOG_PRINT("gpio_keys type:%x code:%x state:%x \n", type, button->code, state); if( state ){ KEY_LOG_PRINT("gpio_keys active_cnt:%x \n", button->active_cnt ); if( button->active_cnt ){ button->active_cnt--; mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(button->debounce_interval)); }else{ button->active_cnt = ACTIVE_STATE_CNT; input_event(input, type, button->code, !!state); input_sync(input); } }else{ button->active_cnt = ACTIVE_STATE_CNT; input_event(input, type, button->code, !!state); input_sync(input); } } #else if (type == EV_ABS) { if (state) input_event(input, type, button->code, button->value); } else { input_event(input, type, button->code, !!state); } input_sync(input); #endif }
static unsigned int gpio_keys_get_chattering_pos(unsigned int code) { unsigned int i; unsigned int size; size = sizeof(gpio_keys_chattering_data) / sizeof(struct gpio_keys_chattering_state); KEY_LOG_PRINT("key off chattering table size=%d \n",size); for (i = 0 ; i < size; i++) { if (gpio_keys_chattering_data[i].code == code) { KEY_LOG_PRINT("find keycode=0x%x,table pos=%d\n", code, i); return i; } } KEY_LOG_PRINT("Can't find keycode=0x%x\n", code); return 0xFFFFFFFF; }
static bool gpio_keys_is_stateon(unsigned int code) { unsigned int pos; pos = gpio_keys_get_chattering_pos(code); if (pos != 0xFFFFFFFF) { KEY_LOG_PRINT("gpio key0x%x state ", code); if (gpio_keys_chattering_data[pos].is_on == true) { KEY_LOG_PRINT("on\n"); return true; } else { KEY_LOG_PRINT("off\n"); return false; } } KEY_LOG_PRINT("gpio keystate pos invalid\n"); return false; }
static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) { struct gpio_keys_button *button = bdata->button; struct input_dev *input = bdata->input; unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low; #ifdef QUALCOMM_ORIGINAL_FEATURE if (type == EV_ABS) { if (state) input_event(input, type, button->code, button->value); } else { input_event(input, type, button->code, !!state); } input_sync(input); #else bool is_on; if (g_kdm_check) { key_set_code(button->code); } else { KEY_LOG_PRINT("gpio_keys type:%x code:%x state:%x \n", type, button->code, state); if (state) { KEY_LOG_PRINT("gpio_keys active_cnt:%x \n", button->active_cnt); if (button->active_cnt) { KEY_LOG_PRINT("gpio_keys active_cnt-- \n"); button->active_cnt--; mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(button->debounce_interval)); } else { KEY_LOG_PRINT("gpio_keys set on \n"); button->active_cnt = ACTIVE_STATE_CNT; gpio_keys_set_stateon(button->code); KEY_LOG_PRINT("send on event \n"); wake_lock_timeout(&gpio_wake_lock,HZ); input_event(input, type, button->code, !!state); input_sync(input); } } else { KEY_LOG_PRINT("gpio_keys set off \n"); button->active_cnt = ACTIVE_STATE_CNT; is_on = gpio_keys_is_stateon(button->code); gpio_keys_set_stateoff(button->code); if (is_on) { KEY_LOG_PRINT("send off event \n"); input_event(input, type, button->code, !!state); input_sync(input); } } } #endif }
static long key_dm_driver_ioctl(struct file* filp, unsigned int cmd, unsigned long data) { int ret = KEY_DM_DRIVER_OK; int *the_v = NULL; int the_vsize = sizeof(int) * 2; the_v = (int*)kmalloc(the_vsize, GFP_KERNEL); if( !the_v ) { return -ENOMEM; } KEY_LOG_PRINT( "%s: cmd:%d \n", __func__, cmd ); memset(the_v, 0x00, the_vsize); switch(cmd){ case KEY_DM_DRIVER_IOCTL_02: if (copy_from_user(the_v, (void *) data, the_vsize)) { ret = -EFAULT; break; } key_cmd(KEY_DM_CHECK_COMMAND, the_v); pwrkey_cmd(KEY_DM_CHECK_COMMAND, the_v); break; case KEY_DM_DRIVER_IOCTL_03: key_cmd(KEY_DM_KEY_GET_EVENT_COOMAND, the_v); if (copy_to_user((void *)data, the_v, the_vsize)) { ret = -EFAULT; } break; case KEY_DM_DRIVER_IOCTL_04: if( g_key_dm_port_check ) { ret = -EFAULT; }else{ g_key_dm_port_check = 1; } break; case KEY_DM_DRIVER_IOCTL_05: if( g_key_dm_port_check ) { if (copy_to_user((void *)data, &g_key_dm_port_data, ARRAY_SIZE(g_key_dm_port_data))) { ret = -EFAULT; } g_key_dm_port_data_idx = 0; memset( &g_key_dm_port_data, 0xff, ARRAY_SIZE(g_key_dm_port_data) ); memset( &g_key_dm_ic_data, 0x00, ARRAY_SIZE(g_key_dm_ic_data) ); }else{ ret = -EFAULT; } break; case KEY_DM_DRIVER_IOCTL_06: if( g_key_dm_port_check ) { g_key_dm_port_check = 0; }else{ ret = -EFAULT; } break; default: ret = KEY_DM_DRIVER_NG; break; } kfree(the_v); return ret; }
static int key_dm_driver_open(struct inode *inode, struct file *file) { KEY_LOG_PRINT( "key_dm_driver_open\n"); return 0; }
static void __exit key_dm_driver_exit(void) { KEY_LOG_PRINT( "%s: \n", __func__); misc_deregister(&kdm); }
static int __init key_dm_driver_init(void) { KEY_LOG_PRINT( "%s: \n", __func__); return misc_register(&kdm); }
void key_set_code(unsigned int code ) { KEY_LOG_PRINT("key_set_code code:%d \n", code); g_kdm_keycode = code; }