static irqreturn_t msm_ts_irq(int irq, void *dev_id) { struct msm_ts *ts = dev_id; struct msm_ts_platform_data *pdata = ts->pdata; uint32_t tssc_avg12, tssc_avg34, tssc_status, tssc_ctl; int x, y, z1, z2; int was_down; int down; tssc_ctl = tssc_readl(ts, TSSC_CTL); tssc_status = tssc_readl(ts, TSSC_STATUS); tssc_avg12 = tssc_readl(ts, TSSC_AVG_12); tssc_avg34 = tssc_readl(ts, TSSC_AVG_34); setup_next_sample(ts); x = tssc_avg12 & 0xffff; y = tssc_avg12 >> 16; z1 = tssc_avg34 & 0xffff; z2 = tssc_avg34 >> 16; /* invert the inputs if necessary */ if (pdata->inv_x) x = pdata->inv_x - x; if (pdata->inv_y) y = pdata->inv_y - y; if (x < 0) x = 0; if (y < 0) y = 0; down = !(tssc_ctl & TSSC_CTL_PENUP_IRQ); was_down = ts->ts_down; ts->ts_down = down; /* no valid data */ if (down && !(tssc_ctl & TSSC_CTL_DATA_FLAG)) return IRQ_HANDLED; if (msm_tsdebug & 2) printk("%s: down=%d, x=%d, y=%d, z1=%d, z2=%d, status %x\n", __func__, down, x, y, z1, z2, tssc_status); if (!was_down && down) { struct ts_virt_key *vkey = NULL; if (pdata->vkeys_y && (y > pdata->virt_y_start)) vkey = find_virt_key(ts, pdata->vkeys_y, x); if (!vkey && ts->pdata->vkeys_x && (x > pdata->virt_x_start)) vkey = find_virt_key(ts, pdata->vkeys_x, y); if (vkey) { WARN_ON(ts->vkey_down != NULL); if(msm_tsdebug) printk("%s: virtual key down %d\n", __func__, vkey->key); ts->vkey_down = vkey; input_report_key(ts->input_dev, vkey->key, 1); input_sync(ts->input_dev); return IRQ_HANDLED; } } else if (ts->vkey_down != NULL) { if (!down) { if(msm_tsdebug) printk("%s: virtual key up %d\n", __func__, ts->vkey_down->key); input_report_key(ts->input_dev, ts->vkey_down->key, 0); input_sync(ts->input_dev); ts->vkey_down = NULL; } return IRQ_HANDLED; } if (down) { input_report_abs(ts->input_dev, ABS_X, x); input_report_abs(ts->input_dev, ABS_Y, y); input_report_abs(ts->input_dev, ABS_PRESSURE, z1); } input_report_key(ts->input_dev, BTN_TOUCH, down); input_sync(ts->input_dev); return IRQ_HANDLED; }
/****************************************************************************f * * Scan the matrix, and generate event for changes. * ***************************************************************************/ static void keypad_scan( int gpio_pin, struct CBLK *bcm_kp ) { unsigned int stat; int r, gpio_c, value; int c = 0; r = elementExistInArray( gpio_pin, bcm_kp->row_count , bcm_kp->keyRowArray ); stat = gpio_get_value(gpio_pin); if(stat) { /* At this point we know that the some key was released. So no point in scanning the Matrix. Just report the last pressed key on same GPIO as released. */ /* Handle if its a Direct key release*/ if(( bcm_kp->direct_key_col_index != -1 ) && ( bcm_kp->keycode[SCANCODE(r,bcm_kp->direct_key_col_index)] )) { input_report_key(bcm_kp->input_dev, bcm_kp->keycode[SCANCODE(r,bcm_kp->direct_key_col_index)], !stat); input_sync( bcm_kp->input_dev ); } /* Handle Matrix Key Release */ else { for(c=0;c< bcm_kp->col_count;c++) { if( test_bit( SCANCODE(r,c), bcm_kp->prevDown ) ) { input_report_key(bcm_kp->input_dev, bcm_kp->keycode[SCANCODE(r,c)], !stat); input_sync( bcm_kp->input_dev ); change_bit( SCANCODE(r,c), bcm_kp->prevDown ); BCMKP_DBG(KERN_DEBUG "Key released r=%d c=%d..\n", r, c); } } } } else { /* The Key is presses, so scan the Matrix */ //Now we have the GPIO row that cause the interrupt if(( bcm_kp->direct_key_col_index != -1 ) && ( bcm_kp->keycode[SCANCODE(r,bcm_kp->direct_key_col_index)] )) { /* The Key is a Direct Key */ input_report_key(bcm_kp->input_dev, bcm_kp->keycode[SCANCODE(r,bcm_kp->direct_key_col_index)], !stat); BCMKP_DBG(KERN_DEBUG "GPIO %d row press found Direct Key..\n", gpio_pin); } else{ //Now set all Col as High for(c=0;c< bcm_kp->col_count;c++) { gpio_c = bcm_kp->keyColArray[c]; if( gpio_c != BCM_NO_COLUMN ) gpio_set_value( gpio_c, 1 ); } for(c=0;c< bcm_kp->col_count;c++) { gpio_c = bcm_kp->keyColArray[c]; if( gpio_c == BCM_NO_COLUMN ) continue; gpio_set_value( gpio_c, 0 ); value = gpio_get_value(gpio_pin); gpio_set_value( gpio_c, 1 ); if( !value ) //Found the Key { if( bcm_kp->keycode[SCANCODE(r,c)] && !test_bit( SCANCODE(r,c), bcm_kp->prevDown ) ) { /* report status to input-subsystem */ input_report_key(bcm_kp->input_dev, bcm_kp->keycode[SCANCODE(r,c)], !value); input_sync( bcm_kp->input_dev ); change_bit( SCANCODE(r,c), bcm_kp->prevDown ); BCMKP_DBG(KERN_DEBUG "Key Pressed r=%d c=%d..\n", r, c); break; } } } //Now restore all the Col as Low for next interrupt for(c=0;c< bcm_kp->col_count;c++) { gpio_c = bcm_kp->keyColArray[c]; if( gpio_c != BCM_NO_COLUMN ) gpio_set_value( gpio_c, 0 ); } } } return; }
static irqreturn_t touchkey_interrupt(int irq, void *dev_id) { struct touchkey_i2c *tkey_i2c = dev_id; u8 data[18]; int ret; int retry = 10; int keycode_type = 0; int pressed; #if 0 if (gpio_get_value(_3_GPIO_TOUCH_INT)) { pr_debug("[TouchKey] Unknown state.\n", __func__); return IRQ_HANDLED; } #endif set_touchkey_debug('a'); #ifdef CONFIG_CPU_FREQ /* set_dvfs_target_level(LEV_800MHZ); */ #endif retry = 3; while (retry--) { #if defined(CONFIG_TARGET_LOCALE_NA) || defined(CONFIG_MACH_Q1_BD)\ || defined(CONFIG_MACH_C1) ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 18); #else ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 10); #endif if (!ret) break; else { pr_debug("[TouchKey] i2c read failed, ret:%d, retry: %d\n", ret, retry); continue; } } if (ret < 0) return IRQ_HANDLED; #if defined(CONFIG_TARGET_LOCALE_NA) #if defined(CONFIG_MACH_C1_NA_SPR_EPIC2_REV00) menu_sensitivity = data[11]; home_sensitivity = data[13]; search_sensitivity = data[15]; back_sensitivity = data[17]; #else if (tkey_i2c->module_ver >= 8) { menu_sensitivity = data[17]; home_sensitivity = data[15]; search_sensitivity = data[11]; back_sensitivity = data[13]; } else { menu_sensitivity = data[6]; home_sensitivity = data[7]; search_sensitivity = data[8]; back_sensitivity = data[9]; } #endif #elif defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_C1) menu_sensitivity = data[13]; back_sensitivity = data[11]; #else menu_sensitivity = data[7]; back_sensitivity = data[9]; #endif /* CONFIG_TARGET_LOCALE_NA */ set_touchkey_debug(data[0]); keycode_type = (data[0] & TK_BIT_KEYCODE); pressed = !(data[0] & TK_BIT_PRESS_EV); if (keycode_type <= 0 || keycode_type >= touchkey_count) { pr_debug("[Touchkey] keycode_type err\n"); return IRQ_HANDLED; } if (pressed) { set_touchkey_debug('P'); } if (get_tsp_status() && pressed) pr_debug("[TouchKey] touchkey pressed" " but don't send event because touch is pressed.\n"); else { input_report_key(touchkey_driver->input_dev, touchkey_keycode[keycode_type], pressed); input_sync(touchkey_driver->input_dev); /* printk(KERN_DEBUG "[TouchKey] keycode:%d pressed:%d\n", touchkey_keycode[keycode_index], pressed); */ } if (keycode_type == 1) printk(KERN_DEBUG "search key sensitivity = %d\n", search_sensitivity); if (keycode_type == 2) pr_debug("back key sensitivity = %d\n", back_sensitivity); #ifdef CONFIG_TARGET_LOCALE_NA if (keycode_type == 3) pr_debug("home key sensitivity = %d\n", home_sensitivity); if (keycode_type == 4) pr_debug("menu key sensitivity = %d\n", menu_sensitivity); #endif set_touchkey_debug('A'); return IRQ_HANDLED; }
void scan_key(void) { int i, j; u32 key_data = 0; unsigned char key_buf[5]; memset(key_buf, 0, sizeof(key_buf)); command(0x42); /*command2 read key data to Display increment mode*/ stpio_set_pin(kfront->data, 1); for (i = 0; i < 5; i++) { for (j = 0; j < 8; j++) { stpio_set_pin(kfront->clk, 1); delay(1); stpio_set_pin(kfront->clk, 0); delay(1); if (stpio_get_pin(kfront->data)) { key_buf[i] |= (1 << j); } } } #if 0 for (i = 0; i < 5; i++) { for (j = 0; j < 8; j++) { dprintk("%d ", (key_buf[i] >> j) & 0x01); } dprintk("\n"); } dprintk("\n"); #endif stpio_set_pin(kfront->clk, 1); /* parse key */ if (key_buf[0] & 0x01) /* exit */ key_data = FRONT_EXIT; else if (key_buf[0] & 0x08) /* ok */ key_data = FRONT_OK; else if (key_buf[1] & 0x01) /* vol+ */ key_data = FRONT_VolUp; else if (key_buf[1] & 0x08) /* vol- */ key_data = FRONT_VolDn; else if (key_buf[2] & 0x01) /* power */ key_data = FRONT_STBY; else if (key_buf[2] & 0x08) /* ch- */ key_data = FRONT_PgDn; else if (key_buf[3] & 0x01) /* menu */ key_data = FRONT_Menu; else if (key_buf[3] & 0x08) /* ch+ */ key_data = FRONT_PgUp; if (key_data) { int key; #ifdef REPEAT_KEY_SUPPORT #ifdef REPEAT_DEACCEL_SUPPORT if (prev_key_data != key_data) repeat_key_count = 0; repeat_key_count++; #endif if (is_repeat_key(key_data)) { #ifdef REPEAT_DEACCEL_SUPPORT if (repeat_key_count > 1 && repeat_key_count <= MSEC_TO_LOOP_CNT(500)) return; #endif } else { if (prev_key_data == key_data) return; } prev_key_data = key_data; prev_loop_count = cur_loop_count; #endif // event subsystem passing key = translate_fp_key(key_data, 5); if (key) { input_report_key(fp_button_dev, key, 1); input_sync(fp_button_dev); msleep(100); input_report_key(fp_button_dev, key, 0); input_sync(fp_button_dev); //FIXME: Add delay to not report one key press ducplicated } DVB_RINGBUFFER_WRITE_BYTE(&ci_rbuffer, key_data); wake_up_interruptible(&ci_rbuffer.queue); } else { #ifdef REPEAT_KEY_SUPPORT /* delete chattering */ if ((prev_loop_count + MSEC_TO_LOOP_CNT(200)) <= cur_loop_count) { prev_key_data = 0; #ifdef REPEAT_DEACCEL_SUPPORT repeat_key_count = 0; #endif } #endif } }
/* report trackpad data as logical trackpad state */ static int report_tp_state(struct bcm5974 *dev, int size) { const struct bcm5974_config *c = &dev->cfg; const struct tp_finger *f; struct input_dev *input = dev->input; int raw_p, raw_w, raw_x, raw_y, raw_n, i; int ptest, origin, ibt = 0, nmin = 0, nmax = 0; int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) return -EIO; /* finger data, le16-aligned */ f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); raw_n = (size - c->tp_offset) / SIZEOF_FINGER; /* always track the first finger; when detached, start over */ if (raw_n) { /* report raw trackpad data */ for (i = 0; i < raw_n; i++) report_finger_data(input, c, &f[i]); raw_p = raw2int(f->force_major); raw_w = raw2int(f->size_major); raw_x = raw2int(f->abs_x); raw_y = raw2int(f->abs_y); dprintk(9, "bcm5974: " "raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n", raw_p, raw_w, raw_x, raw_y, raw_n); ptest = int2bound(&c->p, raw_p); origin = raw2int(f->origin); /* while tracking finger still valid, count all fingers */ if (ptest > PRESSURE_LOW && origin) { abs_p = ptest; abs_w = int2bound(&c->w, raw_w); abs_x = int2bound(&c->x, raw_x - c->x.devmin); abs_y = int2bound(&c->y, c->y.devmax - raw_y); while (raw_n--) { ptest = int2bound(&c->p, raw2int(f->force_major)); if (ptest > PRESSURE_LOW) nmax++; if (ptest > PRESSURE_HIGH) nmin++; f++; } } } /* set the integrated button if applicable */ if (c->tp_type == TYPE2) ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); if (dev->fingers < nmin) dev->fingers = nmin; if (dev->fingers > nmax) dev->fingers = nmax; input_report_key(input, BTN_TOUCH, dev->fingers > 0); input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1); input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2); input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3); input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3); input_report_abs(input, ABS_PRESSURE, abs_p); input_report_abs(input, ABS_TOOL_WIDTH, abs_w); if (abs_p) { input_report_abs(input, ABS_X, abs_x); input_report_abs(input, ABS_Y, abs_y); dprintk(8, "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d " "nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w, abs_x, abs_y, nmin, nmax, dev->fingers, ibt); } /* type 2 reports button events via ibt only */ if (c->tp_type == TYPE2) input_report_key(input, BTN_LEFT, ibt); input_sync(input); return 0; }
int wacom_i2c_coord(struct wacom_i2c *wac_i2c) { bool prox = false; int ret = 0; u8 *data; int rubber, stylus; static u16 x, y, pressure; static u16 tmp; int rdy = 0; data = wac_i2c->wac_feature->data; ret = i2c_master_recv(wac_i2c->client, data, COM_COORD_NUM); if (ret >= 0) { #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) pr_debug("[E-PEN] %x, %x, %x, %x, %x, %x, %x\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6]); #endif if (data[0] & 0x80) { /* enable emr device */ if (!wac_i2c->pen_prox) { wac_i2c->pen_prox = 1; if (data[0] & 0x40) wac_i2c->tool = BTN_TOOL_RUBBER; else wac_i2c->tool = BTN_TOOL_PEN; #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) pr_debug("[E-PEN] is in(%d)\n", wac_i2c->tool); #endif } prox = !!(data[0] & 0x10); stylus = !!(data[0] & 0x20); rubber = !!(data[0] & 0x40); rdy = !!(data[0] & 0x80); x = ((u16) data[1] << 8) + (u16) data[2]; y = ((u16) data[3] << 8) + (u16) data[4]; pressure = ((u16) data[5] << 8) + (u16) data[6]; #ifdef WACOM_IMPORT_FW_ALGO /* Change Position to Active Area */ if (x <= origin_offset[0]) x = 0; else x = x - origin_offset[0]; if (y <= origin_offset[1]) y = 0; else y = y - origin_offset[1]; #ifdef COOR_WORK_AROUND wacom_i2c_coord_offset(&x, &y); wacom_i2c_coord_average(&x, &y, rdy); #endif #endif if (wac_i2c->wac_pdata->x_invert) x = wac_i2c->wac_feature->x_max - x; if (wac_i2c->wac_pdata->y_invert) y = wac_i2c->wac_feature->y_max - y; if (wac_i2c->wac_pdata->xy_switch) { tmp = x; x = y; y = tmp; } #ifdef COOR_WORK_AROUND /* Add offset */ x = x + tilt_offsetX[user_hand][screen_rotate]; y = y + tilt_offsetY[user_hand][screen_rotate]; #endif if (wacom_i2c_coord_range(&x, &y)) { input_report_abs(wac_i2c->input_dev, ABS_X, x); input_report_abs(wac_i2c->input_dev, ABS_Y, y); input_report_abs(wac_i2c->input_dev, ABS_PRESSURE, pressure); input_report_key(wac_i2c->input_dev, BTN_STYLUS, stylus); input_report_key(wac_i2c->input_dev, BTN_TOUCH, prox); input_report_key(wac_i2c->input_dev, wac_i2c->tool, 1); input_sync(wac_i2c->input_dev); if (prox && !wac_i2c->pen_pressed) { #ifdef SEC_DVFS_LOCK set_dvfs_lock(wac_i2c, true); #endif #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) printk(KERN_DEBUG "[E-PEN] is pressed(%d,%d,%d)(%d)\n", x, y, pressure, wac_i2c->tool); #else printk(KERN_DEBUG "[E-PEN] pressed\n"); #endif } else if (!prox && wac_i2c->pen_pressed) { #ifdef SEC_DVFS_LOCK set_dvfs_lock(wac_i2c, false); #endif #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) printk(KERN_DEBUG "[E-PEN] is released(%d,%d,%d)(%d)\n", x, y, pressure, wac_i2c->tool); #else printk(KERN_DEBUG "[E-PEN] released\n"); #endif } wac_i2c->pen_pressed = prox; #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) if (stylus && !wac_i2c->side_pressed) printk(KERN_DEBUG "[E-PEN] side on"); else if (!stylus && wac_i2c->side_pressed) printk(KERN_DEBUG "[E-PEN] side off"); #endif wac_i2c->side_pressed = stylus; } #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) else printk("[E-PEN] raw data x=0x%x, y=0x%x\n", x, y); #endif } else { #ifdef COOR_WORK_AROUND /* enable emr device */ wacom_i2c_coord_average(0, 0, 0); #endif if (wac_i2c->pen_prox) { /* input_report_abs(wac->input_dev, ABS_X, x); */ /* input_report_abs(wac->input_dev, ABS_Y, y); */ input_report_abs(wac_i2c->input_dev, ABS_PRESSURE, 0); input_report_key(wac_i2c->input_dev, BTN_STYLUS, 0); input_report_key(wac_i2c->input_dev, BTN_TOUCH, 0); input_report_key(wac_i2c->input_dev, wac_i2c->tool, 0); input_sync(wac_i2c->input_dev); #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) if (wac_i2c->pen_pressed || wac_i2c->side_pressed) printk(KERN_DEBUG "[E-PEN] is out"); else printk(KERN_DEBUG "[E-PEN] is out"); #endif } wac_i2c->pen_prox = 0; wac_i2c->pen_pressed = 0; wac_i2c->side_pressed = 0; #ifdef SEC_DVFS_LOCK set_dvfs_lock(wac_i2c, false); #endif } } else { printk(KERN_ERR "[E-PEN]: failed to read i2c\n"); return -1; } return 0; }
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 irqreturn_t touchkey_interrupt_thread(int irq, void *touchkey_devdata) { u8 data; int i; int ret; int scancode; struct cypress_touchkey_devdata *devdata = touchkey_devdata; ret = i2c_touchkey_read_byte(devdata, &data); if (ret || (data & ESD_STATE_MASK)) { ret = recovery_routine(devdata); if (ret) { dev_err(&devdata->client->dev, "%s: touchkey recovery " "failed!\n", __func__); goto err; } } if (devdata->has_legacy_keycode) { scancode = (data & SCANCODE_MASK) - 1; if (scancode < 0 || scancode >= devdata->pdata->keycode_cnt) { dev_err(&devdata->client->dev, "%s: scancode is out of " "range\n", __func__); goto err; } #ifdef CONFIG_TOUCH_WAKE if (!device_is_suspended()) #endif { input_report_key(devdata->input_dev, devdata->pdata->keycode[scancode], !(data & UPDOWN_EVENT_MASK)); } #if defined(CONFIG_TOUCH_WAKE) || defined(CONFIG_BLD) if (!(data & UPDOWN_EVENT_MASK)) { #ifdef CONFIG_BLD touchkey_pressed(); #endif #ifdef CONFIG_TOUCH_WAKE touch_press(); #endif } #endif } else { #ifdef CONFIG_TOUCH_WAKE if (!device_is_suspended()) #endif { for (i = 0; i < devdata->pdata->keycode_cnt; i++) input_report_key(devdata->input_dev, devdata->pdata->keycode[i], !!(data & (1U << i))); } #if defined(CONFIG_TOUCH_WAKE) || defined(CONFIG_BLD) for (i = 0; i < devdata->pdata->keycode_cnt; i++) { if(!!(data & (1U << i))) { #ifdef CONFIG_BLD touchkey_pressed(); #endif #ifdef CONFIG_TOUCH_WAKE touch_press(); #endif break; } } #endif } input_sync(devdata->input_dev); err: return IRQ_HANDLED; }
static irqreturn_t touchkey_interrupt(int irq, void *dev_id) { struct touchkey_i2c *tkey_i2c = dev_id; u8 data[3]; int ret; int retry = 10; int keycode_type = 0; int pressed; set_touchkey_debug('a'); retry = 3; while (retry--) { ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3); if (!ret) { keycode_type = (data[0] & TK_BIT_KEYCODE); if (keycode_type <= 0 || keycode_type >= touchkey_count) { printk(KERN_DEBUG "[Touchkey] keycode_type err" " ret:%d, retry: %d\n", keycode_type, retry); continue; } break; } else { printk(KERN_DEBUG "[TouchKey] i2c read failed, ret:%d, retry: %d\n", ret, retry); continue; } } if (ret < 0) return IRQ_HANDLED; set_touchkey_debug(data[0]); keycode_type = (data[0] & TK_BIT_KEYCODE); pressed = !(data[0] & TK_BIT_PRESS_EV); if (keycode_type <= 0 || keycode_type >= touchkey_count) { int i; printk(KERN_DEBUG "[Touchkey] keycode_type err %d." " Release all keys\n", keycode_type); /* release keys */ for (i = 1; i < touchkey_count; ++i) { input_report_key(tkey_i2c->input_dev, touchkey_keycode[i], 0); } input_sync(tkey_i2c->input_dev); return IRQ_HANDLED; } if (pressed) set_touchkey_debug('P'); if (get_tsp_status() && pressed) printk(KERN_DEBUG "[TouchKey] touch is pressed. Pass touchkey event\n"); else { input_report_key(tkey_i2c->input_dev, touchkey_keycode[keycode_type], pressed); input_sync(tkey_i2c->input_dev); #if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) printk(KERN_DEBUG "[TouchKey] keycode:%d pressed:%d\n", touchkey_keycode[keycode_type], pressed); #else printk(KERN_DEBUG "[TouchKey] pressed:%d\n", pressed); #endif #if defined(CONFIG_TARGET_LOCALE_KOR) if (g_debug_tkey == true) { printk(KERN_DEBUG "[TouchKey] keycode[%d]=%d pressed:%d\n", keycode_type, touchkey_keycode[keycode_type], pressed); } else { printk(KERN_DEBUG "[TouchKey] pressed:%d\n", pressed); } #endif } set_touchkey_debug('A'); return IRQ_HANDLED; }
static int hkey_poll_kthread(void *data) { unsigned long t = 0; int offset, level; unsigned int keycode; u8 scancode; mutex_lock(&hkey_poll_mutex); offset = hkey_ec_get_offset(); if (offset < 0) { vdbg_printk(LENSL_WARNING, "Failed to read hotkey register offset from EC\n"); hkey_ec_prev_offset = 0; } else hkey_ec_prev_offset = offset; while (!kthread_should_stop() && hkey_poll_hz) { if (t == 0) t = 1000/hkey_poll_hz; t = msleep_interruptible(t); if (unlikely(kthread_should_stop())) break; try_to_freeze(); if (t > 0) continue; offset = hkey_ec_get_offset(); if (offset < 0) { vdbg_printk(LENSL_WARNING, "Failed to read hotkey register offset from EC\n"); continue; } if (offset == hkey_ec_prev_offset) continue; if (ec_read(0x0A + offset, &scancode)) { vdbg_printk(LENSL_WARNING, "Failed to read hotkey code from EC\n"); continue; } keycode = ec_scancode_to_keycode(scancode); vdbg_printk(LENSL_DEBUG, "Got hotkey keycode %d (scancode %d)\n", keycode, scancode); /* Special handling for brightness keys. We do it here and not via an ACPI notifier in order to prevent possible conflicts with video.c */ if (keycode == KEY_BRIGHTNESSDOWN) { if (control_backlight && backlight) { level = lensl_bd_get_brightness(backlight); if (0 <= --level) lensl_bd_set_brightness_int(level); } else keycode = KEY_RESERVED; } else if (keycode == KEY_BRIGHTNESSUP) { if (control_backlight && backlight) { level = lensl_bd_get_brightness(backlight); if (backlight_levels.count > ++level) lensl_bd_set_brightness_int(level); } else keycode = KEY_RESERVED; } if (keycode != KEY_RESERVED) { input_report_key(hkey_inputdev, keycode, 1); input_sync(hkey_inputdev); input_report_key(hkey_inputdev, keycode, 0); input_sync(hkey_inputdev); } hkey_ec_prev_offset = offset; } mutex_unlock(&hkey_poll_mutex); return 0; }
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; } }
void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) { input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); }
static irqreturn_t sci_keypad_isr(int irq, void *dev_id) { unsigned short key = 0; unsigned long value; struct sci_keypad_t *sci_kpd = dev_id; unsigned long int_status = __raw_readl(KPD_INT_MASK_STATUS); unsigned long key_status = __raw_readl(KPD_KEY_STATUS); unsigned short *keycodes = sci_kpd->input_dev->keycode; unsigned int row_shift = get_count_order(sci_kpd->cols); int col, row; value = __raw_readl(KPD_INT_CLR); value |= KPD_INT_ALL; __raw_writel(value, KPD_INT_CLR); if ((int_status & KPD_PRESS_INT0)) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03dD\n", key); #endif input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); } if (int_status & KPD_RELEASE_INT0) { col = KPD_INT0_COL(key_status); row = KPD_INT0_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03dU\n", key); #endif input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); } if ((int_status & KPD_PRESS_INT1)) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03dD\n", key); #endif input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); } if (int_status & KPD_RELEASE_INT1) { col = KPD_INT1_COL(key_status); row = KPD_INT1_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03dU\n", key); #endif input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); } if ((int_status & KPD_PRESS_INT2)) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03d\n", key); #endif input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); } if (int_status & KPD_RELEASE_INT2) { col = KPD_INT2_COL(key_status); row = KPD_INT2_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03d\n", key); #endif input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); } if (int_status & KPD_PRESS_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03d\n", key); #endif input_report_key(sci_kpd->input_dev, key, 1); input_sync(sci_kpd->input_dev); } if (int_status & KPD_RELEASE_INT3) { col = KPD_INT3_COL(key_status); row = KPD_INT3_ROW(key_status); key = keycodes[MATRIX_SCAN_CODE(row, col, row_shift)]; #if PRINT_KEY_LOG printk("%03d\n", key); #endif input_report_key(sci_kpd->input_dev, key, 0); input_sync(sci_kpd->input_dev); } return IRQ_HANDLED; }
static void hil_dev_handle_ptr_events(struct hil_dev *ptr) { struct input_dev *dev = ptr->dev; int idx = ptr->idx4 / 4; hil_packet p = ptr->data[idx - 1]; int i, cnt, laxis; bool absdev, ax16; if ((p & HIL_CMDCT_POL) != idx - 1) { printk(KERN_WARNING PREFIX "Malformed poll packet %x (idx = %i)\n", p, idx); return; } i = (p & HIL_POL_AXIS_ALT) ? 3 : 0; laxis = (p & HIL_POL_NUM_AXES_MASK) + i; ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; for (cnt = 1; i < laxis; i++) { unsigned int lo, hi, val; lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK; hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0; if (absdev) { val = lo + (hi << 8); #ifdef TABLET_AUTOADJUST if (val < input_abs_get_min(dev, ABS_X + i)) input_abs_set_min(dev, ABS_X + i, val); if (val > input_abs_get_max(dev, ABS_X + i)) input_abs_set_max(dev, ABS_X + i, val); #endif if (i % 3) val = input_abs_get_max(dev, ABS_X + i) - val; input_report_abs(dev, ABS_X + i, val); } else { val = (int) (((int8_t) lo) | ((int8_t) hi << 8)); if (i % 3) val *= -1; input_report_rel(dev, REL_X + i, val); } } while (cnt < idx - 1) { unsigned int btn = ptr->data[cnt++]; int up = btn & 1; btn &= 0xfe; if (btn == 0x8e) continue; /* TODO: proximity == touch? */ if (btn > 0x8c || btn < 0x80) continue; btn = (btn - 0x80) >> 1; btn = ptr->btnmap[btn]; input_report_key(dev, btn, !up); } input_sync(dev); }
static irqreturn_t ig_input_interrupt(int irq, void *dev_id) { struct stream_packet *packet; uintptr_t next; int i; int data = 0; int kick = 0; // packet = ig_input->rx_complete; packet = memsect_to_vaddr(ig_input, ig_input->control->rx); while(packet) { int new_q = 0; uint16_t *keys; next = packet->next; if ((packet->status & COMPLETED) == 0) { break; } packet->status = 0; ig_input->control->rx = next; /* Append to free list */ data = 1; keys = (uint16_t*)packet->data; for (i=0; i < (packet->xferred/2); i++) { if (keys[i] & 0x4000) { //printk("Mouse %x, %d\n", keys[i] & 0xff, (keys[i] & 0x100) ? -1 : 1); if (keys[i] & 0x8000) { input_report_rel(ig_input->input_dev, keys[i] & 0x0ff, (keys[i] & 0x100) ? -1 : 1); } } else { //printk("Key %s: %x\n", (keys[i] & 0x8000) ? "down" : "up", keys[i] & 0x01ff); input_report_key(ig_input->input_dev, keys[i] & 0x01ff, ((keys[i] & 0x8000) != 0)); } } packet->next = ~0; packet->size = PACKET_SIZE; packet->xferred = 0; if (ig_input->rx_last != NULL) { ig_input->rx_last->next = vaddr_to_memsect(ig_input, packet); if (ig_input->rx_last->status & TERMINATED) { new_q = 1; } } else { new_q = 1; } if (new_q) { ig_input->control->rx = vaddr_to_memsect(ig_input, packet); kick = 1; } ig_input->rx_last = packet; if (next == ~0) { packet = NULL; } else { packet = memsect_to_vaddr(ig_input, next); } } if (data) { input_sync(ig_input->input_dev); } if (kick) { L4_Notify(ig_input->server, 0x1); } return IRQ_HANDLED; }
static void tps6507x_ts_handler(struct work_struct *work) { struct tps6507x_ts *tsc = container_of(work, struct tps6507x_ts, work.work); struct input_dev *input_dev = tsc->input_dev; int pendown; int schd; int poll = 0; s32 ret; ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, &tsc->tc.pressure); if (ret) goto done; pendown = tsc->tc.pressure > tsc->min_pressure; if (unlikely(!pendown && tsc->pendown)) { dev_dbg(tsc->dev, "UP\n"); input_report_key(input_dev, BTN_TOUCH, 0); input_report_abs(input_dev, ABS_PRESSURE, 0); input_sync(input_dev); tsc->pendown = 0; } if (pendown) { if (!tsc->pendown) { dev_dbg(tsc->dev, "DOWN\n"); input_report_key(input_dev, BTN_TOUCH, 1); } else dev_dbg(tsc->dev, "still down\n"); ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_X_POSITION, &tsc->tc.x); if (ret) goto done; ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_Y_POSITION, &tsc->tc.y); if (ret) goto done; input_report_abs(input_dev, ABS_X, tsc->tc.x); input_report_abs(input_dev, ABS_Y, tsc->tc.y); input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure); input_sync(input_dev); tsc->pendown = 1; poll = 1; } done: /* always poll if not using interrupts */ poll = 1; if (poll) { schd = schedule_delayed_work(&tsc->work, msecs_to_jiffies(tsc->poll_period)); if (schd) tsc->polling = 1; else { tsc->polling = 0; dev_err(tsc->dev, "re-schedule failed"); } } else tsc->polling = 0; ret = tps6507x_adc_standby(tsc); }
long kpd_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { /* void __user *uarg = (void __user *)arg; */ switch (cmd) { #if KPD_AUTOTEST case PRESS_OK_KEY: /* KPD_AUTOTEST disable auto test setting to resolve CR ALPS00464496 */ if (test_bit(KEY_OK, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS OK KEY!!\n"); input_report_key(kpd_input_dev, KEY_OK, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support OK KEY!!\n"); } break; case RELEASE_OK_KEY: if (test_bit(KEY_OK, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE OK KEY!!\n"); input_report_key(kpd_input_dev, KEY_OK, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support OK KEY!!\n"); } break; case PRESS_MENU_KEY: if (test_bit(KEY_MENU, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS MENU KEY!!\n"); input_report_key(kpd_input_dev, KEY_MENU, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support MENU KEY!!\n"); } break; case RELEASE_MENU_KEY: if (test_bit(KEY_MENU, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE MENU KEY!!\n"); input_report_key(kpd_input_dev, KEY_MENU, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support MENU KEY!!\n"); } break; case PRESS_UP_KEY: if (test_bit(KEY_UP, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS UP KEY!!\n"); input_report_key(kpd_input_dev, KEY_UP, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support UP KEY!!\n"); } break; case RELEASE_UP_KEY: if (test_bit(KEY_UP, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE UP KEY!!\n"); input_report_key(kpd_input_dev, KEY_UP, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support UP KEY!!\n"); } break; case PRESS_DOWN_KEY: if (test_bit(KEY_DOWN, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS DOWN KEY!!\n"); input_report_key(kpd_input_dev, KEY_DOWN, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support DOWN KEY!!\n"); } break; case RELEASE_DOWN_KEY: if (test_bit(KEY_DOWN, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE DOWN KEY!!\n"); input_report_key(kpd_input_dev, KEY_DOWN, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support DOWN KEY!!\n"); } break; case PRESS_LEFT_KEY: if (test_bit(KEY_LEFT, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS LEFT KEY!!\n"); input_report_key(kpd_input_dev, KEY_LEFT, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support LEFT KEY!!\n"); } break; case RELEASE_LEFT_KEY: if (test_bit(KEY_LEFT, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE LEFT KEY!!\n"); input_report_key(kpd_input_dev, KEY_LEFT, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support LEFT KEY!!\n"); } break; case PRESS_RIGHT_KEY: if (test_bit(KEY_RIGHT, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS RIGHT KEY!!\n"); input_report_key(kpd_input_dev, KEY_RIGHT, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support RIGHT KEY!!\n"); } break; case RELEASE_RIGHT_KEY: if (test_bit(KEY_RIGHT, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE RIGHT KEY!!\n"); input_report_key(kpd_input_dev, KEY_RIGHT, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support RIGHT KEY!!\n"); } break; case PRESS_HOME_KEY: if (test_bit(KEY_HOME, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS HOME KEY!!\n"); input_report_key(kpd_input_dev, KEY_HOME, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support HOME KEY!!\n"); } break; case RELEASE_HOME_KEY: if (test_bit(KEY_HOME, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE HOME KEY!!\n"); input_report_key(kpd_input_dev, KEY_HOME, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support HOME KEY!!\n"); } break; case PRESS_BACK_KEY: if (test_bit(KEY_BACK, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS BACK KEY!!\n"); input_report_key(kpd_input_dev, KEY_BACK, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support BACK KEY!!\n"); } break; case RELEASE_BACK_KEY: if (test_bit(KEY_BACK, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE BACK KEY!!\n"); input_report_key(kpd_input_dev, KEY_BACK, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support BACK KEY!!\n"); } break; case PRESS_CALL_KEY: if (test_bit(KEY_CALL, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS CALL KEY!!\n"); input_report_key(kpd_input_dev, KEY_CALL, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support CALL KEY!!\n"); } break; case RELEASE_CALL_KEY: if (test_bit(KEY_CALL, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE CALL KEY!!\n"); input_report_key(kpd_input_dev, KEY_CALL, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support CALL KEY!!\n"); } break; case PRESS_ENDCALL_KEY: if (test_bit(KEY_ENDCALL, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS ENDCALL KEY!!\n"); input_report_key(kpd_input_dev, KEY_ENDCALL, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support ENDCALL KEY!!\n"); } break; case RELEASE_ENDCALL_KEY: if (test_bit(KEY_ENDCALL, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE ENDCALL KEY!!\n"); input_report_key(kpd_input_dev, KEY_ENDCALL, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support ENDCALL KEY!!\n"); } break; case PRESS_VLUP_KEY: if (test_bit(KEY_VOLUMEUP, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS VOLUMEUP KEY!!\n"); input_report_key(kpd_input_dev, KEY_VOLUMEUP, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support VOLUMEUP KEY!!\n"); } break; case RELEASE_VLUP_KEY: if (test_bit(KEY_VOLUMEUP, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE VOLUMEUP KEY!!\n"); input_report_key(kpd_input_dev, KEY_VOLUMEUP, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support VOLUMEUP KEY!!\n"); } break; case PRESS_VLDOWN_KEY: if (test_bit(KEY_VOLUMEDOWN, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS VOLUMEDOWN KEY!!\n"); input_report_key(kpd_input_dev, KEY_VOLUMEDOWN, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support VOLUMEDOWN KEY!!\n"); } break; case RELEASE_VLDOWN_KEY: if (test_bit(KEY_VOLUMEDOWN, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE VOLUMEDOWN KEY!!\n"); input_report_key(kpd_input_dev, KEY_VOLUMEDOWN, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support VOLUMEDOWN KEY!!\n"); } break; case PRESS_FOCUS_KEY: if (test_bit(KEY_FOCUS, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS FOCUS KEY!!\n"); input_report_key(kpd_input_dev, KEY_FOCUS, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support FOCUS KEY!!\n"); } break; case RELEASE_FOCUS_KEY: if (test_bit(KEY_FOCUS, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE FOCUS KEY!!\n"); input_report_key(kpd_input_dev, KEY_FOCUS, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support RELEASE KEY!!\n"); } break; case PRESS_CAMERA_KEY: if (test_bit(KEY_CAMERA, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS CAMERA KEY!!\n"); input_report_key(kpd_input_dev, KEY_CAMERA, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support CAMERA KEY!!\n"); } break; case RELEASE_CAMERA_KEY: if (test_bit(KEY_CAMERA, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE CAMERA KEY!!\n"); input_report_key(kpd_input_dev, KEY_CAMERA, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support CAMERA KEY!!\n"); } break; case PRESS_POWER_KEY: if (test_bit(KEY_POWER, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] PRESS POWER KEY!!\n"); input_report_key(kpd_input_dev, KEY_POWER, 1); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support POWER KEY!!\n"); } break; case RELEASE_POWER_KEY: if (test_bit(KEY_POWER, kpd_input_dev->keybit)) { kpd_print("[AUTOTEST] RELEASE POWER KEY!!\n"); input_report_key(kpd_input_dev, KEY_POWER, 0); input_sync(kpd_input_dev); } else { kpd_print("[AUTOTEST] Not Support POWER KEY!!\n"); } break; #endif case SET_KPD_KCOL: kpd_auto_test_for_factorymode(); /* API 3 for kpd factory mode auto-test */ kpd_print("[kpd_auto_test_for_factorymode] test performed!!\n"); break; default: return -EINVAL; } return 0; }
static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev) { struct input_dev *pwr; int key_release_irq = platform_get_irq(pdev, 0); int key_press_irq = platform_get_irq(pdev, 1); int err; unsigned int delay; u8 pon_cntl; struct pmic8xxx_pwrkey *pwrkey; const struct pm8xxx_pwrkey_platform_data *pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "power key platform data not supplied\n"); return -EINVAL; } /* Valid range of pwr key trigger delay is 1/64 sec to 2 seconds. */ if (pdata->kpd_trigger_delay_us > USEC_PER_SEC * 2 || pdata->kpd_trigger_delay_us < USEC_PER_SEC / 64) { dev_err(&pdev->dev, "invalid power key trigger delay\n"); return -EINVAL; } pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL); if (!pwrkey) return -ENOMEM; pwrkey->pdata = pdata; pwr = input_allocate_device(); if (!pwr) { dev_dbg(&pdev->dev, "Can't allocate power button\n"); err = -ENOMEM; goto free_pwrkey; } input_set_capability(pwr, EV_KEY, KEY_POWER); pwr->name = "pmic8xxx_pwrkey"; pwr->phys = "pmic8xxx_pwrkey/input0"; pwr->dev.parent = &pdev->dev; delay = (pdata->kpd_trigger_delay_us << 6) / USEC_PER_SEC; delay = ilog2(delay); err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err); goto free_input_dev; } pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK; pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK); if (pdata->pull_up) pon_cntl |= PON_CNTL_PULL_UP; else pon_cntl &= ~PON_CNTL_PULL_UP; err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err); goto free_input_dev; } err = input_register_device(pwr); if (err) { dev_dbg(&pdev->dev, "Can't register power key: %d\n", err); goto free_input_dev; } //zte jiangfeng add init_timer(&pwrkey->timer); pwrkey->timer.data = (unsigned long)pwrkey; pwrkey->timer.function = pwrkey_timer; //zte jiangfeng added pwrkey->key_press_irq = key_press_irq; pwrkey->key_release_irq = key_release_irq; pwrkey->pwr = pwr; INIT_WORK(&pwrkey->pwrkey_poweroff_work, pwrkey_poweroff); platform_set_drvdata(pdev, pwrkey); /* check power key status during boot */ err = pm8xxx_read_irq_stat(pdev->dev.parent, key_press_irq); if (err < 0) { dev_err(&pdev->dev, "reading irq status failed\n"); goto unreg_input_dev; } pwrkey->press = !!err; if (pwrkey->press) { input_report_key(pwrkey->pwr, KEY_POWER, 1); input_sync(pwrkey->pwr); } err = request_any_context_irq(key_press_irq, pwrkey_press_irq, IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey); if (err < 0) { dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", key_press_irq, err); goto unreg_input_dev; } err = request_any_context_irq(key_release_irq, pwrkey_release_irq, IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwrkey); if (err < 0) { dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", key_release_irq, err); goto free_press_irq; } device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; free_press_irq: free_irq(key_press_irq, NULL); unreg_input_dev: platform_set_drvdata(pdev, NULL); input_unregister_device(pwr); pwr = NULL; free_input_dev: input_free_device(pwr); free_pwrkey: kfree(pwrkey); return err; }
static irqreturn_t hisi_powerkey_handler(int irq, void *data) { struct hisi_powerkey_info *info = (struct hisi_powerkey_info *)data; wake_lock_timeout(&info->pwr_wake_lock, HZ); if (info->irq[0] == irq) { pr_info("[%s]response press interrupt!\n", __FUNCTION__); power_key_ps=true; #if defined (CONFIG_HUAWEI_DSM) powerkey_press_count++; if ((jiffies - powerkey_last_press_time) < msecs_to_jiffies(PRESS_KEY_INTERVAL)) { if (!dsm_client_ocuppy(power_key_dclient)) { dsm_client_record(power_key_dclient, "power key trigger on the abnormal style.\n"); dsm_client_notify(power_key_dclient, DSM_POWER_KEY_ERROR_NO); } } powerkey_last_press_time = jiffies; #endif /* modify by songliangliang for dmd_log> */ #if defined (CONFIG_FB_HI6220_CLCD) lcd_dcm_pwr_add_timer(); #endif input_report_key(info->idev, KEY_POWER, POWER_KEY_PRESS); input_sync(info->idev); } else if (info->irq[1] == irq) { pr_info("[%s]response release interrupt!\n", __FUNCTION__); #if defined(CONFIG_HISILICON_PLATFORM_MAINTAIN) #ifdef CONFIG_ARCH_HI6XXX if (check_himntn(HIMNTN_PRESS_KEY_TO_FASTBOOT)) { if ((VOL_UPDOWN_PRESS & gpio_key_vol_updown_press_get()) == VOL_UPDOWN_PRESS) { gpio_key_vol_updown_press_set_zero(); if(is_gpio_key_vol_updown_pressed()) { systemError(0x25, EXCH_S_LOGDUMP, 0,0,0); } } } #elif defined(CONFIG_HISI_3635) if(is_fastboot_dumpmem_enable()) if ((VOL_UPDOWN_PRESS & gpio_key_vol_updown_press_get()) == VOL_UPDOWN_PRESS) { gpio_key_vol_updown_press_set_zero(); if(is_gpio_key_vol_updown_pressed()) { pr_info("[%s]Powerkey+VolUp_key+VolDn_key\n", __FUNCTION__); #ifdef CONFIG_HISI_REBOOT_TYPE set_watchdog_resetflag(); #endif emergency_restart(); } } #endif #endif input_report_key(info->idev, KEY_POWER, POWER_KEY_RELEASE); input_sync(info->idev); } else if (info->irq[2] == irq) { pr_info("[%s]response long press 1s interrupt!\n", __FUNCTION__); input_report_key(info->idev, KEY_POWER, POWER_KEY_PRESS); input_sync(info->idev); } else if (irq == info->irq[3]) { pr_info("[%s]response long press 8s interrupt!\n", __FUNCTION__); } else if (irq == info->irq[4]) { pr_info("[%s]response long press 10s interrupt!\n", __FUNCTION__); } else { pr_err("[%s]invalid irq %d!\n", __FUNCTION__, irq); } return IRQ_HANDLED; }
static irqreturn_t button_interrupt(int irq, void *dummy) { input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1); input_sync(button_dev); return IRQ_HANDLED; }
static void adp5588_work_func( struct work_struct *work) { int rc,i; uint8_t reg=ADP5588_REG_KEY_EVENTA; struct adp5588_keypad_data *kp = container_of(work, struct adp5588_keypad_data, work); struct i2c_client *client=kp->client; uint8_t scan_code; /* set read address */ I2C_MUTEX_LOCK; if ((rc = i2c_master_send(client, ®, 1)) <0) { dev_err(&client->dev," %s(%s):i2c_master_send error %d\n", __FILE__, __FUNCTION__, rc); /* I2c Write error . exit now , enable IRQ and read again if IRQ pin still low */ } else { /* read scancodes until queue is empty */ i=0; do { scan_code =ADP5588_KEY_FIFO_EMPTY; if ((rc = i2c_master_recv(client, &scan_code,1 )) < 0 ) { dev_err(&client->dev," %s(%s):i2c_master_recv error %d\n", __FILE__, __FUNCTION__, rc); break; } if( scan_code != ADP5588_KEY_FIFO_EMPTY ) { kp->last_key = ADP5588_KEY_CODE & scan_code ; kp->last_key_state = !!(ADP5588_KEY_RELEASE & scan_code); dev_dbg(&client->dev,"ADP5588 got scancode %d ,keycode 0x%x ( %d ) state %d \n", scan_code, kp->last_key, kp->last_key,kp->last_key_state ); if( kp->last_key == ADP5588_GPIO_KEY ) { /* got RINGER/SILENCE switch event */ adp5588_data.ringer_switch = kp->last_key_state; switch_set_state(&adp5588_data.sw_mute_dev, !adp5588_data.ringer_switch); } else { /* got regular key event */ input_report_key(kp->input_dev, kp->last_key, kp->last_key_state); } // Sync is removed. It does not required for key event // input_sync(kp->input_dev); } else if( i == 0 ) { /*IRQ without the code ? , must be key release HW problem , Wait 5ms */ clk_busy_wait(5000); } } while( scan_code && (i++ <10) ); } I2C_MUTEX_UNLOCK; /* Clear IRQ and enable it */ if (kp->use_irq) { if ( adp5588_clear_irq(client)<0) { /* I2c Problem , do not enable IRQ but wait 1 sec */ hrtimer_start(&kp->timer, ktime_set(1,0), HRTIMER_MODE_REL); } else enable_irq(client->irq); } }
static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) { struct input_dev *dev = xpad->dev; if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04); input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08); input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01); input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02); } else { input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); } input_report_key(dev, BTN_START, data[2] & 0x10); input_report_key(dev, BTN_SELECT, data[2] & 0x20); input_report_key(dev, BTN_THUMBL, data[2] & 0x40); input_report_key(dev, BTN_THUMBR, data[2] & 0x80); input_report_key(dev, BTN_A, data[3] & 0x10); input_report_key(dev, BTN_B, data[3] & 0x20); input_report_key(dev, BTN_X, data[3] & 0x40); input_report_key(dev, BTN_Y, data[3] & 0x80); input_report_key(dev, BTN_TL, data[3] & 0x01); input_report_key(dev, BTN_TR, data[3] & 0x02); input_report_key(dev, BTN_MODE, data[3] & 0x04); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { input_report_abs(dev, ABS_X, (__s16) le16_to_cpup((__le16 *)(data + 6))); input_report_abs(dev, ABS_Y, ~(__s16) le16_to_cpup((__le16 *)(data + 8))); input_report_abs(dev, ABS_RX, (__s16) le16_to_cpup((__le16 *)(data + 10))); input_report_abs(dev, ABS_RY, ~(__s16) le16_to_cpup((__le16 *)(data + 12))); } if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { input_report_key(dev, BTN_TL2, data[4]); input_report_key(dev, BTN_TR2, data[5]); } else { input_report_abs(dev, ABS_Z, data[4]); input_report_abs(dev, ABS_RZ, data[5]); } input_sync(dev); }
void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) { struct input_dev *dev = iforce->dev; int i; static int being_used = 0; if (being_used) dev_warn(&iforce->dev->dev, "re-entrant call to iforce_process %d\n", being_used); being_used++; #ifdef CONFIG_JOYSTICK_IFORCE_232 if (HI(iforce->expect_packet) == HI(cmd)) { iforce->expect_packet = 0; iforce->ecmd = cmd; memcpy(iforce->edata, data, IFORCE_MAX_LENGTH); } #endif wake_up(&iforce->wait); if (!iforce->type) { being_used--; return; } switch (HI(cmd)) { case 0x01: /* joystick position data */ case 0x03: /* wheel position data */ if (HI(cmd) == 1) { input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0])); input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2])); input_report_abs(dev, ABS_THROTTLE, 255 - data[4]); if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit)) input_report_abs(dev, ABS_RUDDER, (__s8)data[7]); } else { input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0])); input_report_abs(dev, ABS_GAS, 255 - data[2]); input_report_abs(dev, ABS_BRAKE, 255 - data[3]); } input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x); input_report_abs(dev, ABS_HAT0Y, iforce_hat_to_axis[data[6] >> 4].y); for (i = 0; iforce->type->btn[i] >= 0; i++) input_report_key(dev, iforce->type->btn[i], data[(i >> 3) + 5] & (1 << (i & 7))); /* If there are untouched bits left, interpret them as the second hat */ if (i <= 8) { int btns = data[6]; if (test_bit(ABS_HAT1X, dev->absbit)) { if (btns & 8) input_report_abs(dev, ABS_HAT1X, -1); else if (btns & 2) input_report_abs(dev, ABS_HAT1X, 1); else input_report_abs(dev, ABS_HAT1X, 0); } if (test_bit(ABS_HAT1Y, dev->absbit)) { if (btns & 1) input_report_abs(dev, ABS_HAT1Y, -1); else if (btns & 4) input_report_abs(dev, ABS_HAT1Y, 1); else input_report_abs(dev, ABS_HAT1Y, 0); } } input_sync(dev); break; case 0x02: /* status report */ input_report_key(dev, BTN_DEAD, data[0] & 0x02); input_sync(dev); /* Check if an effect was just started or stopped */ i = data[1] & 0x7f; if (data[1] & 0x80) { if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { /* Report play event */ input_report_ff_status(dev, i, FF_STATUS_PLAYING); } } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { /* Report stop event */ input_report_ff_status(dev, i, FF_STATUS_STOPPED); } if (LO(cmd) > 3) { int j; for (j = 3; j < LO(cmd); j += 2) mark_core_as_ready(iforce, data[j] | (data[j+1]<<8)); } break; } being_used--; }
static void rk28_adkeyscan_timer(unsigned long data) { unsigned int ADKEY1,code = 0,i; /*Enable AD controller to sample */ prockAD_button->timer.expires = jiffies+msecs_to_jiffies(10); add_timer(&prockAD_button->timer); RockAdcScanning(); if (ADSampleTimes < 4) { ADSampleTimes ++; goto scan_io_key; /* scan gpio button event*/ } ADSampleTimes = 0; /*Get button value*/ ADKEY1=get_rock_adc1(); if(ADKEY1<EmptyADValue) printk("\n ADC1 value=%d \n",ADKEY1); #if 1 //ffhh if((ADKEY1>EmptyADValue)&&(ADKEY1<=InvalidADValue)) goto scan_io_key1; #endif valuecount++; if(valuecount < 2) goto scan_code; code=find_rock_adkeycode(ADKEY1,ad1valuetab); valuecount = 2; goto scan_code; ///scan_code; scan_io_key1: valuecount = 0; scan_code: if((g_code == 0) && (code == 0)){ goto scan_io_key; } ///DBG("\n key button PE2 == %d \n",GPIOGetPinLevel(GPIOPortE_Pin2)); if(code != 0){ if(valuecount<2) goto scan_io_key; if(g_code == 0){ g_code = code; DBG("\n %s::%d rock adc1 key scan ,find press down a key=%d \n",__func__,__LINE__,g_code); input_report_key(prockAD_button->input_dev,g_code,1); input_sync(prockAD_button->input_dev); goto scan_io_key; }else{ if(g_code != code){ DBG("\n %s::%d rock adc1 key scan ,find press up a key=%d \n",__func__,__LINE__,g_code); input_report_key(prockAD_button->input_dev,g_code,0); input_sync(prockAD_button->input_dev); DBG("\n %s::%d rock adc1 key scan ,find press down a key=%d \n",__func__,__LINE__,code); input_report_key(prockAD_button->input_dev,code,1); input_sync(prockAD_button->input_dev); g_code = code; goto scan_io_key; } } } if((g_code != 0)&&(code == 0)&&(ADSampleTimes == 0)){ DBG("\n %s::%d rock adc1 key scan ,find press up a key=%d \n",__func__,__LINE__,g_code); input_report_key(prockAD_button->input_dev,g_code,0); input_sync(prockAD_button->input_dev); valuecount = 0; g_code = 0; goto scan_io_key; } scan_io_key : if(g_wake_press) { pwrscantimes = 0; g_wake_press = !GPIOGetPinLevel(WAKEUP_KEY_PORT); if(g_wake_press) return; } if(!GPIOGetPinLevel(GPIOPortE_Pin2)) { pwrscantimes += 1; if(pwrscantimes == (SEC_NUM * ONESEC_TIMES)) { input_report_key(prockAD_button->input_dev,ENDCALL,1); input_sync(prockAD_button->input_dev); DBG("the kernel come to power down!!!\n"); } if(pwrscantimes ==( (SEC_NUM + 1)* ONESEC_TIMES)) { pwrscantimes = 0; input_report_key(prockAD_button->input_dev,ENDCALL,0); input_sync(prockAD_button->input_dev); DBG("the kernel come to power up!!!\n"); } return ; } if( pwrscantimes > SLEEP_TIME) { pwrscantimes = 0; printk("========== %s: g_enable_sleep=%d\n", __FUNCTION__, g_enable_sleep); if(g_enable_sleep) { input_report_key(prockAD_button->input_dev,AD1KEY5,1); input_sync(prockAD_button->input_dev); input_report_key(prockAD_button->input_dev,AD1KEY5,0); input_sync(prockAD_button->input_dev); } rk28printk("\n%s^^^^Wake Up ^^^^^!!\n",__FUNCTION__); } }
static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) { struct input_dev *dev = xpad->dev; /* digital pad */ if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { /* dpad as buttons (left, right, up, down) */ input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04); input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08); input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01); input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02); } else { input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); } /* start/back buttons */ input_report_key(dev, BTN_START, data[2] & 0x10); input_report_key(dev, BTN_SELECT, data[2] & 0x20); /* stick press left/right */ input_report_key(dev, BTN_THUMBL, data[2] & 0x40); input_report_key(dev, BTN_THUMBR, data[2] & 0x80); /* buttons A,B,X,Y,TL,TR and MODE */ input_report_key(dev, BTN_A, data[3] & 0x10); input_report_key(dev, BTN_B, data[3] & 0x20); input_report_key(dev, BTN_X, data[3] & 0x40); input_report_key(dev, BTN_Y, data[3] & 0x80); input_report_key(dev, BTN_TL, data[3] & 0x01); input_report_key(dev, BTN_TR, data[3] & 0x02); input_report_key(dev, BTN_MODE, data[3] & 0x04); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { /* left stick */ input_report_abs(dev, ABS_X, (__s16) le16_to_cpup((__le16 *)(data + 6))); input_report_abs(dev, ABS_Y, ~(__s16) le16_to_cpup((__le16 *)(data + 8))); /* right stick */ input_report_abs(dev, ABS_RX, (__s16) le16_to_cpup((__le16 *)(data + 10))); input_report_abs(dev, ABS_RY, ~(__s16) le16_to_cpup((__le16 *)(data + 12))); } /* triggers left/right */ if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { input_report_key(dev, BTN_TL2, data[4]); input_report_key(dev, BTN_TR2, data[5]); } else { input_report_abs(dev, ABS_Z, data[4]); input_report_abs(dev, ABS_RZ, data[5]); } input_sync(dev); }
//input key conversion void input_report_rcp_key(uint8_t rcp_keycode, int up_down) { rcp_keycode &= 0x7F; TX_DEBUG_PRINT( ("\nupdown = %d " , up_down)); switch ( rcp_keycode ) { case MHL_RCP_CMD_SELECT:// error input_report_key(kpd_input_dev, KEY_SELECT, up_down); TX_DEBUG_PRINT(( "\nSelect received\n\n" )); break; case MHL_RCP_CMD_UP: input_report_key(kpd_input_dev, KEY_UP, up_down); TX_DEBUG_PRINT(( "\nUp received\n\n" )); break; case MHL_RCP_CMD_DOWN: input_report_key(kpd_input_dev, KEY_DOWN, up_down); TX_DEBUG_PRINT(( "\nDown received\n\n" )); break; case MHL_RCP_CMD_LEFT: input_report_key(kpd_input_dev, KEY_LEFT, up_down); TX_DEBUG_PRINT(( "\nLeft received\n\n" )); break; case MHL_RCP_CMD_RIGHT: input_report_key(kpd_input_dev, KEY_RIGHT, up_down); TX_DEBUG_PRINT(( "\nRight received\n\n" )); break; case MHL_RCP_CMD_ROOT_MENU: input_report_key(kpd_input_dev, KEY_MENU, up_down); TX_DEBUG_PRINT(( "\nRoot Menu received\n\n" )); break; case MHL_RCP_CMD_EXIT: input_report_key(kpd_input_dev, KEY_BACK, up_down); TX_DEBUG_PRINT(( "\nExit received\n\n" )); break; case MHL_RCP_CMD_NUM_0: input_report_key(kpd_input_dev, KEY_0, up_down); TX_DEBUG_PRINT(( "\nNumber 0 received\n\n" )); break; case MHL_RCP_CMD_NUM_1: input_report_key(kpd_input_dev, KEY_1, up_down); TX_DEBUG_PRINT(( "\nNumber 1 received\n\n" )); break; case MHL_RCP_CMD_NUM_2: input_report_key(kpd_input_dev, KEY_2, up_down); TX_DEBUG_PRINT(( "\nNumber 2 received\n\n" )); break; case MHL_RCP_CMD_NUM_3: input_report_key(kpd_input_dev, KEY_3, up_down); TX_DEBUG_PRINT(( "\nNumber 3 received\n\n" )); break; case MHL_RCP_CMD_NUM_4: input_report_key(kpd_input_dev, KEY_4, up_down); TX_DEBUG_PRINT(( "\nNumber 4 received\n\n" )); break; case MHL_RCP_CMD_NUM_5: input_report_key(kpd_input_dev, KEY_5, up_down); TX_DEBUG_PRINT(( "\nNumber 5 received\n\n" )); break; case MHL_RCP_CMD_NUM_6: input_report_key(kpd_input_dev, KEY_6, up_down); TX_DEBUG_PRINT(( "\nNumber 6 received\n\n" )); break; case MHL_RCP_CMD_NUM_7: input_report_key(kpd_input_dev, KEY_7, up_down); TX_DEBUG_PRINT(( "\nNumber 7 received\n\n" )); break; case MHL_RCP_CMD_NUM_8: input_report_key(kpd_input_dev, KEY_8, up_down); TX_DEBUG_PRINT(( "\nNumber 8 received\n\n" )); break; case MHL_RCP_CMD_NUM_9: input_report_key(kpd_input_dev, KEY_9, up_down); TX_DEBUG_PRINT(( "\nNumber 9 received\n\n" )); break; case MHL_RCP_CMD_DOT: input_report_key(kpd_input_dev, KEY_DOT, up_down); TX_DEBUG_PRINT(( "\nDot received\n\n" )); break; case MHL_RCP_CMD_ENTER: input_report_key(kpd_input_dev, KEY_ENTER, up_down); TX_DEBUG_PRINT(( "\nEnter received\n\n" )); break; case MHL_RCP_CMD_CLEAR: input_report_key(kpd_input_dev, KEY_CLEAR, up_down); TX_DEBUG_PRINT(( "\nClear received\n\n" )); break; case MHL_RCP_CMD_SOUND_SELECT: input_report_key(kpd_input_dev, KEY_SOUND, up_down); TX_DEBUG_PRINT(( "\nSound Select received\n\n" )); break; case MHL_RCP_CMD_PLAY: input_report_key(kpd_input_dev, KEY_PLAY, up_down); TX_DEBUG_PRINT(( "\nPlay received\n\n" )); break; case MHL_RCP_CMD_PAUSE: //input_report_key(kpd_input_dev, KEY_PAUSE, up_down); input_report_key(kpd_input_dev, KEY_PAUSECD, up_down); TX_DEBUG_PRINT(( "\nPause received\n\n" )); break; case MHL_RCP_CMD_STOP: input_report_key(kpd_input_dev, KEY_STOP, up_down); TX_DEBUG_PRINT(( "\nStop received\n\n" )); break; case MHL_RCP_CMD_FAST_FWD: input_report_key(kpd_input_dev, KEY_FASTFORWARD, up_down); input_report_key(kpd_input_dev, KEY_FASTFORWARD, up_down); TX_DEBUG_PRINT(( "\nFastfwd received\n\n" )); break; case MHL_RCP_CMD_REWIND: input_report_key(kpd_input_dev, KEY_REWIND, up_down); TX_DEBUG_PRINT(( "\nRewind received\n\n" )); break; case MHL_RCP_CMD_EJECT: input_report_key(kpd_input_dev, KEY_EJECTCD, up_down); TX_DEBUG_PRINT(( "\nEject received\n\n" )); break; case MHL_RCP_CMD_FWD: //input_report_key(kpd_input_dev, KEY_FORWARD, up_down);//next song input_report_key(kpd_input_dev, KEY_NEXTSONG, up_down); TX_DEBUG_PRINT(( "\nNext song received\n\n" )); break; case MHL_RCP_CMD_BKWD: //input_report_key(kpd_input_dev, KEY_BACK, up_down);//previous song input_report_key(kpd_input_dev, KEY_PREVIOUSSONG, up_down); TX_DEBUG_PRINT(( "\nPrevious song received\n\n" )); break; case MHL_RCP_CMD_PLAY_FUNC: //input_report_key(kpd_input_dev, KEY_PL, up_down); input_report_key(kpd_input_dev, KEY_PLAY, up_down); TX_DEBUG_PRINT(( "\nPlay Function received\n\n" )); break; case MHL_RCP_CMD_PAUSE_PLAY_FUNC: input_report_key(kpd_input_dev, KEY_PLAYPAUSE, up_down); TX_DEBUG_PRINT(( "\nPause_Play Function received\n\n" )); break; case MHL_RCP_CMD_STOP_FUNC: input_report_key(kpd_input_dev, KEY_STOP, up_down); TX_DEBUG_PRINT(( "\nStop Function received\n\n" )); break; case MHL_RCP_CMD_F1: input_report_key(kpd_input_dev, KEY_F1, up_down); TX_DEBUG_PRINT(( "\nF1 received\n\n" )); break; case MHL_RCP_CMD_F2: input_report_key(kpd_input_dev, KEY_F2, up_down); TX_DEBUG_PRINT(( "\nF2 received\n\n" )); break; case MHL_RCP_CMD_F3: input_report_key(kpd_input_dev, KEY_F3, up_down); TX_DEBUG_PRINT(( "\nF3 received\n\n" )); break; case MHL_RCP_CMD_F4: input_report_key(kpd_input_dev, KEY_F4, up_down); TX_DEBUG_PRINT(( "\nF4 received\n\n" )); break; case MHL_RCP_CMD_F5: input_report_key(kpd_input_dev, KEY_F5, up_down); TX_DEBUG_PRINT(( "\nF5 received\n\n" )); break; default: break; } //added for improving mhl RCP start input_sync(kpd_input_dev); //added for improving mhl RCP end }
static irqreturn_t touchkey_interrupt(int irq, void *dev_id) { struct touchkey_i2c *tkey_i2c = dev_id; static const int ledCmd[] = {TK_CMD_LED_ON, TK_CMD_LED_OFF}; u8 data[3]; int ret; int retry = 10; int keycode_type = 0; int pressed; set_touchkey_debug('a'); retry = 3; while (retry--) { ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3); if (!ret) break; else { pr_debug("[TouchKey] i2c read failed, ret:%d, retry: %d\n", ret, retry); continue; } } if (ret < 0) return IRQ_HANDLED; set_touchkey_debug(data[0]); keycode_type = (data[0] & TK_BIT_KEYCODE); pressed = !(data[0] & TK_BIT_PRESS_EV); if (keycode_type <= 0 || keycode_type >= touchkey_count) { pr_debug("[Touchkey] keycode_type err\n"); return IRQ_HANDLED; } if (pressed) { set_touchkey_debug('P'); // enable lights on keydown if (touch_led_disabled == 0) { if (touchkey_led_status == TK_CMD_LED_OFF) { pr_debug("[Touchkey] %s: keydown - LED ON\n", __func__); i2c_touchkey_write(tkey_i2c->client, (u8 *) &ledCmd[0], 1); touchkey_led_status = TK_CMD_LED_ON; } if (timer_pending(&touch_led_timer) == 1) { mod_timer(&touch_led_timer, jiffies + (HZ * touch_led_timeout)); } } } else { // touch led timeout on keyup if (touch_led_disabled == 0) { if (timer_pending(&touch_led_timer) == 0) { pr_debug("[Touchkey] %s: keyup - add_timer\n", __func__); touch_led_timer.expires = jiffies + (HZ * touch_led_timeout); add_timer(&touch_led_timer); } else { mod_timer(&touch_led_timer, jiffies + (HZ * touch_led_timeout)); } } } if (get_tsp_status() && pressed) pr_debug("[TouchKey] touchkey pressed but don't send event because touch is pressed.\n"); else { input_report_key(tkey_i2c->input_dev, touchkey_keycode[keycode_type], pressed); input_sync(tkey_i2c->input_dev); /* pr_debug("[TouchKey] keycode:%d pressed:%d\n", touchkey_keycode[keycode_index], pressed); */ #if defined(CONFIG_TARGET_LOCALE_KOR) if (g_debug_tkey == true) { pr_debug("[TouchKey] keycode[%d]=%d pressed:%d\n", keycode_type, touchkey_keycode[keycode_type], pressed); } else { pr_debug("[TouchKey] pressed:%d\n", pressed); } #endif } set_touchkey_debug('A'); return IRQ_HANDLED; }
void touchkey_work_func(struct work_struct * p) { u8 data[3]; int ret; int retry = 10; set_touchkey_debug('a'); if (!gpio_get_value(_3_GPIO_TOUCH_INT)) { #ifdef CONFIG_CPU_FREQ set_dvfs_target_level(LEV_800MHZ); #endif ret = i2c_touchkey_read(KEYCODE_REG, data, 1); set_touchkey_debug(data[0]); if ((data[0] & ESD_STATE_BIT) || (ret != 0)) { printk ("ESD_STATE_BIT set or I2C fail: data: %d, retry: %d\n", data[0], retry); //releae key input_report_key(touchkey_driver->input_dev, touchkey_keycode[1], 0); input_report_key(touchkey_driver->input_dev, touchkey_keycode[2], 0); retry = 10; while (retry--) { gpio_direction_output(_3_GPIO_TOUCH_EN, 0); mdelay(300); init_hw(); if (i2c_touchkey_read(KEYCODE_REG, data, 3) >= 0) { printk("%s touchkey init success\n", __func__); set_touchkey_debug('O'); enable_irq(IRQ_TOUCH_INT); return; } printk("%s %d i2c transfer error retry = %d\n", __func__, __LINE__, retry); } //touchkey die , do not enable touchkey //enable_irq(IRQ_TOUCH_INT); touchkey_enable = -1; gpio_direction_output(_3_GPIO_TOUCH_EN, 0); #if !(defined(CONFIG_ARIES_NTT) || defined(CONFIG_S5PC110_CELOX_BOARD)) gpio_direction_output(_3_GPIO_TOUCH_CE, 0); #endif gpio_direction_output(_3_TOUCH_SDA_28V, 0); gpio_direction_output(_3_TOUCH_SCL_28V, 0); printk("%s touchkey died\n", __func__); set_touchkey_debug('D'); return; } if (data[0] & UPDOWN_EVENT_BIT) { input_report_key(touchkey_driver->input_dev, touchkey_keycode[data[0] & KEYCODE_BIT], 0); input_sync(touchkey_driver->input_dev); //printk(" touchkey release keycode: %d\n", touchkey_keycode[data[0] & KEYCODE_BIT]); printk(KERN_DEBUG "touchkey release keycode:%d \n", touchkey_keycode[data[0] & KEYCODE_BIT]); } else { if (touch_state_val == 1) { printk(KERN_DEBUG "touchkey pressed but don't send event because touch is pressed. \n"); set_touchkey_debug('P'); } else { if ((data[0] & KEYCODE_BIT) == 2) { // if back key is pressed, release multitouch //printk("touchkey release tsp input. \n"); TSP_forced_release(); } input_report_key(touchkey_driver->input_dev, touchkey_keycode[data[0] & KEYCODE_BIT], 1); input_sync(touchkey_driver->input_dev); //printk(" touchkey press keycode: %d\n", touchkey_keycode[data[0] & KEYCODE_BIT]); printk(KERN_DEBUG "touchkey press keycode:%d \n", touchkey_keycode[data[0] & KEYCODE_BIT]); } } } //clear interrupt #if defined(CONFIG_S5PC110_CELOX_BOARD) if (readl(gpio_pend_mask_mem) & (0x1 << 5)) writel(readl(gpio_pend_mask_mem) | (0x1 << 5), gpio_pend_mask_mem); #else if (readl(gpio_pend_mask_mem) & (0x1 << 1)) writel(readl(gpio_pend_mask_mem) | (0x1 << 1), gpio_pend_mask_mem); #endif set_touchkey_debug('A'); enable_irq(IRQ_TOUCH_INT); }
void stm401_irq_wake_work_func(struct work_struct *work) { int err; unsigned short irq_status; u32 irq2_status; uint8_t irq3_status; struct stm401_data *ps_stm401 = container_of(work, struct stm401_data, irq_wake_work); dev_dbg(&ps_stm401->client->dev, "stm401_irq_wake_work_func\n"); mutex_lock(&ps_stm401->lock); if (ps_stm401->mode == BOOTMODE) goto EXIT_NO_WAKE; /* This is to handle the case of receiving an interrupt after suspend_late, but before interrupts were globally disabled. If this is the case, interrupts might be disabled now, so we cannot handle this at this time. suspend_noirq will return BUSY if this happens so that we can handle these interrupts. */ if (ps_stm401->ignore_wakeable_interrupts) { dev_info(&ps_stm401->client->dev, "Deferring interrupt work\n"); ps_stm401->ignored_interrupts++; goto EXIT_NO_WAKE; } stm401_wake(ps_stm401); /* read interrupt mask register */ stm401_cmdbuff[0] = WAKESENSOR_STATUS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading from stm401 failed\n"); goto EXIT; } irq_status = (stm401_readbuff[IRQ_WAKE_MED] << 8) | stm401_readbuff[IRQ_WAKE_LO]; /* read algorithm interrupt status register */ stm401_cmdbuff[0] = ALGO_INT_STATUS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 3); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading from stm401 failed\n"); goto EXIT; } irq2_status = (stm401_readbuff[IRQ_WAKE_HI] << 16) | (stm401_readbuff[IRQ_WAKE_MED] << 8) | stm401_readbuff[IRQ_WAKE_LO]; /* read generic interrupt register */ stm401_cmdbuff[0] = GENERIC_INT_STATUS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading from stm failed\n"); goto EXIT; } irq3_status = stm401_readbuff[0]; if (ps_stm401->qw_irq_status) { irq_status |= ps_stm401->qw_irq_status; ps_stm401->qw_irq_status = 0; } /* First, check for error messages */ if (irq_status & M_LOG_MSG) { stm401_cmdbuff[0] = ERROR_STATUS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, ESR_SIZE); if (err >= 0) { memcpy(stat_string, stm401_readbuff, ESR_SIZE); stat_string[ESR_SIZE] = 0; dev_err(&ps_stm401->client->dev, "STM401 Error: %s\n", stat_string); } else dev_err(&ps_stm401->client->dev, "Failed to read error message %d\n", err); } /* Second, check for a reset request */ if (irq_status & M_HUB_RESET) { unsigned char status; if (strnstr(stat_string, "modality", ESR_SIZE)) status = 0x01; else if (strnstr(stat_string, "Algo", ESR_SIZE)) status = 0x02; else if (strnstr(stat_string, "Watchdog", ESR_SIZE)) status = 0x03; else status = 0x04; stm401_as_data_buffer_write(ps_stm401, DT_RESET, &status, 1, 0); stm401_reset_and_init(); dev_err(&ps_stm401->client->dev, "STM401 requested a reset\n"); goto EXIT; } /* Check all other status bits */ if (irq_status & M_DOCK) { int state; dev_err(&ps_stm401->client->dev, "Invalid M_DOCK bit set. irq_status = 0x%06x\n", irq_status); stm401_cmdbuff[0] = DOCK_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Dock state failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_DOCK, stm401_readbuff, 1, 0); state = stm401_readbuff[DOCK_STATE]; if (ps_stm401->dsdev.dev != NULL) switch_set_state(&ps_stm401->dsdev, state); if (ps_stm401->edsdev.dev != NULL) switch_set_state(&ps_stm401->edsdev, state); dev_dbg(&ps_stm401->client->dev, "Dock status:%d\n", state); } if (irq_status & M_PROXIMITY) { stm401_cmdbuff[0] = PROXIMITY; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading prox from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_PROX, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending Proximity distance %d\n", stm401_readbuff[PROX_DISTANCE]); } if (irq_status & M_TOUCH) { if (stm401_display_handle_touch_locked(ps_stm401) < 0) goto EXIT; } if (irq_status & M_COVER) { int state; stm401_cmdbuff[0] = COVER_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Cover state failed\n"); goto EXIT; } state = stm401_readbuff[COVER_STATE]; if (state > 0) state = 1; input_report_switch(ps_stm401->input_dev, SW_LID, state); input_sync(ps_stm401->input_dev); dev_dbg(&ps_stm401->client->dev, "Cover status: %d\n", state); } if (irq_status & M_QUICKPEEK) { if (stm401_display_handle_quickpeek_locked(ps_stm401, irq_status == M_QUICKPEEK) < 0) goto EXIT; } if (irq_status & M_FLATUP) { stm401_cmdbuff[0] = FLAT_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading flat data from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_FLAT_UP, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending Flat up %d\n", stm401_readbuff[FLAT_UP]); } if (irq_status & M_FLATDOWN) { stm401_cmdbuff[0] = FLAT_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading flat data from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_FLAT_DOWN, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending Flat down %d\n", stm401_readbuff[FLAT_DOWN]); } if (irq_status & M_STOWED) { stm401_cmdbuff[0] = STOWED; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading stowed from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_STOWED, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending Stowed status %d\n", stm401_readbuff[STOWED]); } if (irq_status & M_CAMERA_ACT) { stm401_cmdbuff[0] = CAMERA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading camera data from stm failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_CAMERA_ACT, stm401_readbuff, 2, 0); dev_dbg(&ps_stm401->client->dev, "Sending Camera: %d\n", STM16_TO_HOST(CAMERA_VALUE)); input_report_key(ps_stm401->input_dev, KEY_CAMERA, 1); input_report_key(ps_stm401->input_dev, KEY_CAMERA, 0); input_sync(ps_stm401->input_dev); dev_dbg(&ps_stm401->client->dev, "Report camkey toggle\n"); } if (irq_status & M_NFC) { stm401_cmdbuff[0] = NFC; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading nfc data from stm failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_NFC, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending NFC value: %d\n", stm401_readbuff[NFC_VALUE]); } if (irq_status & M_SIM) { stm401_cmdbuff[0] = SIM; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading sig_motion data from stm failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_SIM, stm401_readbuff, 2, 0); /* This is one shot sensor */ stm401_g_wake_sensor_state &= (~M_SIM); dev_dbg(&ps_stm401->client->dev, "Sending SIM Value=%d\n", STM16_TO_HOST(SIM_DATA)); } if (irq_status & M_CHOPCHOP) { stm401_cmdbuff[0] = CHOPCHOP; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading chopchop data from stm failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_CHOPCHOP, stm401_readbuff, 2, 0); dev_dbg(&ps_stm401->client->dev, "ChopChop triggered. Gyro aborts=%d\n", STM16_TO_HOST(CHOPCHOP_DATA)); } if (irq2_status & M_MMOVEME) { unsigned char status; /* Client recieving action will be upper 2 most significant */ /* bits of the least significant byte of status. */ status = (irq2_status & STM401_CLIENT_MASK) | M_MMOVEME; stm401_ms_data_buffer_write(ps_stm401, DT_MMMOVE, &status, 1); dev_dbg(&ps_stm401->client->dev, "Sending meaningful movement event\n"); } if (irq2_status & M_NOMMOVE) { unsigned char status; /* Client recieving action will be upper 2 most significant */ /* bits of the least significant byte of status. */ status = (irq2_status & STM401_CLIENT_MASK) | M_NOMMOVE; stm401_ms_data_buffer_write(ps_stm401, DT_NOMOVE, &status, 1); dev_dbg(&ps_stm401->client->dev, "Sending no meaningful movement event\n"); } if (irq2_status & M_ALGO_MODALITY) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_MODALITY].evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_TRANSITION); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading modality event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_MODALITY; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending modality event\n"); } if (irq2_status & M_ALGO_ORIENTATION) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_ORIENTATION].evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_TRANSITION); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading orientation event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_ORIENTATION; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending orientation event\n"); } if (irq2_status & M_ALGO_STOWED) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_STOWED].evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_TRANSITION); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading stowed event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_STOWED; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending stowed event\n"); } if (irq2_status & M_ALGO_ACCUM_MODALITY) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_ACCUM_MODALITY] .evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_ACCUM_STATE); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading accum modality event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_ACCUM_MODALITY; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending accum modality event\n"); } if (irq2_status & M_ALGO_ACCUM_MVMT) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_ACCUM_MVMT].evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_ACCUM_MVMT); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading accum mvmt event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_ACCUM_MVMT; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending accum mvmt event\n"); } if (irq2_status & M_IR_WAKE_GESTURE) { err = stm401_process_ir_gesture(ps_stm401); if (err < 0) goto EXIT; } if (irq3_status & M_GENERIC_INTRPT) { dev_err(&ps_stm401->client->dev, "Invalid M_GENERIC_INTRPT bit set. irq_status = 0x%06x\n", irq_status); /* x (data1) : irq3_status */ stm401_ms_data_buffer_write(ps_stm401, DT_GENERIC_INT, &irq3_status, 1); dev_dbg(&ps_stm401->client->dev, "Sending generic interrupt event:%d\n", irq3_status); } EXIT: stm401_sleep(ps_stm401); EXIT_NO_WAKE: mutex_unlock(&ps_stm401->lock); }
static void st1232_ts_update_pen_state(struct st1232_ts_data *ts, int x, int y, int pressure) { int i=0;/* if(NULL!=msm_7k_handset_get_input_dev()) kpdev =(struct input_dev *) msm_7k_handset_get_input_dev(); else { printk("[bing]msm_7k_handset_get_input_dev=NULL \r\n"); goto err; }*/ //printk("[Bing][%s] x=%d, y=%d, p=%d keyregister=%d ,tpversion=%d \r\n", __func__, x, y, pressure,keyregister,tpversion); //printk("[bing]kpdev=%d ,KEY_HOME=%d KEY_SEARCH=%d KEY_BACK=%d KEY_MENU=%d ,pressure=%d\r\n",kpdev,KEY_HOME,KEY_SEARCH,KEY_BACK,KEY_MENU,pressure); if(y<=480) { for (i = 0; i < st1232_ts->prev_touches; i++) { input_report_abs(st1232_ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(st1232_ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); input_mt_sync(st1232_ts->input_dev); } st1232_ts->prev_touches = 0; input_sync(st1232_ts->input_dev); } if(tpversion>=1) //Herman { if(keyregister==1) { input_report_key(st1232_ts->input_dev, KEY_HOME, pressure); //printk("[bing]KEY_HOME,keyregister=%d \r\n",keyregister); } else if(keyregister==2) { input_report_key(st1232_ts->input_dev, KEY_SEARCH, pressure); //printk("[bing]KEY_SEARCH,keyregister=%d \r\n",keyregister); } else if(keyregister==4) { input_report_key(st1232_ts->input_dev, KEY_BACK, pressure); //printk("[bing]KEY_BACK,keyregister=%d \r\n",keyregister); } else if(keyregister==8) { input_report_key(st1232_ts->input_dev, KEY_MENU, pressure); //printk("[bing]KEY_MENU,keyregister=%d \r\n",keyregister); } input_sync(st1232_ts->input_dev); } else if(tpversion==0) { if(y>490) { if(x>0&&x<=80) { input_report_key(st1232_ts->input_dev, KEY_HOME, pressure); //printk("[bing]KEY_HOME \r\n"); } else if(x>80&&x<=150) { input_report_key(st1232_ts->input_dev, KEY_SEARCH, pressure); //printk("[bing]KEY_SEARCH \r\n"); } else if(x>150&&x<=260) { input_report_key(st1232_ts->input_dev, KEY_BACK, pressure); //printk("[bing]KEY_BACK \r\n"); } else if(x>260) { input_report_key(st1232_ts->input_dev, KEY_MENU, pressure); //printk("[bing]KEY_MENU \r\n"); } } input_sync(st1232_ts->input_dev); } //err: //printk("st1232_ts_update_pen_state\r\n"); }