/******************************************************* Function: Touch down report function. Input: ts:private data. id:tracking id. x:input x. y:input y. w:input weight. Output: None. *******************************************************/ static void gtp_touch_down(struct goodix_ts_data* ts,s32 id,s32 x,s32 y,s32 w) { #if GTP_CHANGE_X2Y GTP_SWAP(x, y); #endif #if GTP_ICS_SLOT_REPORT input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1); //input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(ts->input_dev, ABS_MT_PRESSURE, w); #else input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); //input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); //input_mt_sync(ts->input_dev); #endif GTP_DEBUG("======ID:%d, X:%d, Y:%d, W:%d======", id, x, y, w); }
static void ct360_ts_work_func(struct work_struct *work) { //struct timespec now; //now = current_kernel_time();//(&now); //printk("now %lu:%lu\n",now.tv_sec,now.tv_nsec); unsigned short x = 0; unsigned short y = 0; int i,ret,syn_flag = 0; char toatl_num = 0; int bufLen = 0; unsigned char buf[TOUCH_REG_NUM*TOUCH_NUMBER+1] = {0}; int point_status; int point_id; int touch_state_index=0; int pendown = 0; struct ct360_ts_data *ts = container_of(work, struct ct360_ts_data, work); ret= ct360_read_regs(ts->client, buf, TOUCH_REG_NUM*TOUCH_NUMBER);//only one data represent the current touch num if (ret < 0) { printk("%s:i2c_transfer fail =%d..tmp\n", __FUNCTION__, toatl_num); //enable_irq(ts->irq); return; } for (i = 0; i < 20; i += TOUCH_REG_NUM) { point_status = buf[i+3] & 0x0F; point_id = buf[i+3] >> 4; //printk("point_status:0x%02x, point_id:0x%02x i = %d\n", point_status, point_id, i); //printk("buf: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", buf[i], buf[i+1], buf[i+2], buf[i+3]); //if (point_status != 0) { if((point_status == 1) || (point_status == 2)) { x = (((s16)buf[i+0] << 4)|((s16)buf[i+2] >> 4)); y = (((s16)buf[i+1] << 4)|((s16)buf[i+2] & 0x0f)); //printk("x=%d,y=%d\n",x,y); input_mt_slot(ts->input_dev, point_id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, point_id); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 100); //Finger Size input_report_abs(ts->input_dev, ABS_MT_POSITION_X, (480-y)); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, (800-x)); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 100); //Touch Size syn_flag = 1; } else if(point_status == 3 || point_status == 0) { input_mt_slot(ts->input_dev, point_id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); syn_flag = 1; touch_state[touch_state_index] = TOUCH_UP; } }
void Send_Touch(unsigned int x, unsigned int y) { /* Press */ input_mt_slot(ts_data->input_dev, 0); input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, true); input_report_abs(ts_data->input_dev, ABS_MT_POSITION_X, x); input_report_abs(ts_data->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(ts_data->input_dev, ABS_MT_TOUCH_MAJOR, 1); input_sync(ts_data->input_dev); /* Release */ input_mt_slot(ts_data->input_dev, 0); input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, false); input_sync(ts_data->input_dev); }
/* * this function is called when a whole packet has been received and processed, * so that it can decide what to send to the input layer. */ static void mt_emit_event(struct mt_device *td, struct input_dev *input) { int i; for (i = 0; i < td->maxcontacts; ++i) { struct mt_slot *s = &(td->slots[i]); if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && !s->seen_in_this_frame) { s->touch_state = false; } input_mt_slot(input, i); input_mt_report_slot_state(input, MT_TOOL_FINGER, s->touch_state); if (s->touch_state) { /* this finger is on the screen */ int wide = (s->w > s->h); /* divided by two to match visual scale of touch */ int major = max(s->w, s->h) >> 1; int minor = min(s->w, s->h) >> 1; input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); } s->seen_in_this_frame = false; }
static void ektf2127_report_event(struct ektf2127_ts *ts, const u8 *buf) { struct input_mt_pos touches[EKTF2127_MAX_TOUCHES]; int slots[EKTF2127_MAX_TOUCHES]; unsigned int touch_count, i; touch_count = buf[1] & 0x07; if (touch_count > EKTF2127_MAX_TOUCHES) { dev_err(&ts->client->dev, "Too many touches %d > %d\n", touch_count, EKTF2127_MAX_TOUCHES); touch_count = EKTF2127_MAX_TOUCHES; } ektf2127_parse_coordinates(buf, touch_count, touches); input_mt_assign_slots(ts->input, slots, touches, touch_count, 0); for (i = 0; i < touch_count; i++) { input_mt_slot(ts->input, slots[i]); input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true); touchscreen_report_pos(ts->input, &ts->prop, touches[i].x, touches[i].y, true); } input_mt_sync_frame(ts->input); input_sync(ts->input); }
int ct36x_ts_suspend(struct i2c_client *client, pm_message_t mesg) { struct ct36x_ts_info *ts; unsigned char iter; if (CT36X_TS_CORE_DEBUG) printk(">>>>> %s() called <<<<< \n", __FUNCTION__); ts = (struct ct36x_ts_info *)i2c_get_clientdata(client); if ( ts->state == CT36X_STATE_NORMAL ) { disable_irq(ts->irq); cancel_work_sync(&ts->event_work); ct36x_chip_go_sleep(client, ts->data.buf); ts->state = CT36X_STATE_SLEEP; } for ( iter = 0; iter < CT36X_TS_POINT_NUM; iter++ ) { input_mt_slot(ts->input,iter); input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false); } input_sync(ts->input); return 0; }
/******************************************************* Function: Touch up report function. Input: ts:private data. Output: None. *******************************************************/ static void gtp_touch_up(struct goodix_ts_data* ts, s32 id) { #if GTP_ICS_SLOT_REPORT input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); // input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); GTP_DEBUG("Touch id[%2d] release!", id); #else input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); //input_mt_sync(ts->input_dev); #endif }
/******************************************************* Function: Touch down report function. Input: ts:private data. id:tracking id. x:input x. y:input y. w:input weight. Output: None. *******************************************************/ static void gtp_touch_down(struct goodix_ts_data* ts,s32 id,s32 x,s32 y,s32 w) { dprintk(DEBUG_X_Y_INFO, "source data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); if(1 == exchange_x_y_flag){ swap(x, y); } if(1 == revert_x_flag){ x = SCREEN_MAX_X - x; } if(1 == revert_y_flag){ y = SCREEN_MAX_Y - y; } dprintk(DEBUG_X_Y_INFO,"report data:ID:%d, X:%d, Y:%d, W:%d\n", id, x, y, w); #if GTP_ICS_SLOT_REPORT input_mt_slot(ts->input_dev, id); input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); #else input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id); input_mt_sync(ts->input_dev); #endif }
/** * Handler for multitouch touch events. * * @param info The device information structure for the relevant PV input * device. * @param event The touch event to be handled. */ static void __handle_touch_up(struct openxt_kbd_info *info, union oxtkbd_in_event *event) { //Send an indication that the given finger has been pressed... input_mt_slot(info->absolute_pointer, event->touch_move.id); input_mt_report_slot_state(info->absolute_pointer, MT_TOOL_FINGER, 0); }
/* * this function is called when a whole packet has been received and processed, * so that it can decide what to send to the input layer. */ static void mt_emit_event(struct mt_device *td, struct input_dev *input) { int i; for (i = 0; i < td->mtclass->maxcontacts; ++i) { struct mt_slot *s = &(td->slots[i]); if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && !s->seen_in_this_frame) { s->touch_state = false; } input_mt_slot(input, i); input_mt_report_slot_state(input, MT_TOOL_FINGER, s->touch_state); if (s->touch_state) { input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w); input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h); } s->seen_in_this_frame = false; } input_mt_report_pointer_emulation(input, true); input_sync(input); td->num_received = 0; }
int amba_vtouch_mt_slot(int slot) { if((amba_vtouch_dev==NULL) || (amba_vtouch_dev->input_dev==NULL)){ return -1; } dbgmsg("===> %s, %d\n",__func__, slot); input_mt_slot(amba_vtouch_dev->input_dev, slot); return 0; }
static void silead_ts_report_touch(struct silead_ts_data *data, u16 x, u16 y, u8 id) { input_mt_slot(data->input_dev, id); input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, true); input_report_abs(data->input_dev, ABS_MT_POSITION_X, x); input_report_abs(data->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, data->pressure); input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); }
static void cyttsp4_input_report(struct input_dev *input, int sig, int t, int type) { input_mt_slot(input, t); if (type == CY_OBJ_STANDARD_FINGER || type == CY_OBJ_GLOVE) input_mt_report_slot_state(input, MT_TOOL_FINGER, true); else if (type == CY_OBJ_STYLUS) input_mt_report_slot_state(input, MT_TOOL_PEN, true); }
/* * this function is called when a whole finger has been parsed, * so that it can decide what to send to the input layer. */ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) { input_mt_slot(input, td->slot); input_mt_report_slot_state(input, MT_TOOL_FINGER, td->touch); if (td->touch) { input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); } input_mt_report_pointer_emulation(input, true); }
static void __input_mt_drop_unused(struct input_dev *dev, struct input_mt *mt) { int i; for (i = 0; i < mt->num_slots; i++) { if (!input_mt_is_used(mt, &mt->slots[i])) { input_mt_slot(dev, i); input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); } } }
void vinput_multi_tc_event_report(void *data) { struct multi_touch_info *info = NULL; int i = 0; info = (struct multi_touch_info *)data; if (info->fingernr > 0) { if (info->fingernr > MAX_FINGER_NUM) info->fingernr = MAX_FINGER_NUM; for (i = 0; i < info->fingernr; i++) { input_mt_slot(vinput_multi_tc_dev, i); if (1 == info->finger[i].press) { input_mt_report_slot_state(vinput_multi_tc_dev, MT_TOOL_FINGER, true); input_report_key(vinput_multi_tc_dev, ABS_MT_TRACKING_ID, i); input_report_abs(vinput_multi_tc_dev, ABS_MT_POSITION_X, info->finger[i].x); input_report_abs(vinput_multi_tc_dev, ABS_MT_POSITION_Y, info->finger[i].y); } else { input_mt_report_slot_state(vinput_multi_tc_dev, MT_TOOL_FINGER, false); } } if (1 == info->fingernr) { input_mt_slot(vinput_multi_tc_dev, 1); input_mt_report_slot_state(vinput_multi_tc_dev, MT_TOOL_FINGER, false); } input_mt_report_pointer_emulation(vinput_multi_tc_dev, true); input_sync(vinput_multi_tc_dev); } }
/******************************************************* Function: Touch up report function. Input: ts:private data. Output: None. *******************************************************/ static void gtp_touch_up(struct goodix_ts_data* ts, s32 id) { #if GTP_ICS_SLOT_REPORT input_mt_slot(ts->input_dev, id); input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1); dprintk(DEBUG_X_Y_INFO, "Touch id[%2d] release!", id); #else input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); input_mt_sync(ts->input_dev); #endif }
static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts, struct pixcir_report_data *report) { struct input_mt_pos pos[PIXCIR_MAX_SLOTS]; int slots[PIXCIR_MAX_SLOTS]; struct pixcir_touch *touch; int n, i, slot; struct device *dev = &ts->client->dev; const struct pixcir_i2c_chip_data *chip = &ts->pdata->chip; n = report->num_touches; if (n > PIXCIR_MAX_SLOTS) n = PIXCIR_MAX_SLOTS; if (!chip->has_hw_ids) { for (i = 0; i < n; i++) { touch = &report->touches[i]; pos[i].x = touch->x; pos[i].y = touch->y; } input_mt_assign_slots(ts->input, slots, pos, n); } for (i = 0; i < n; i++) { touch = &report->touches[i]; if (chip->has_hw_ids) { slot = input_mt_get_slot_by_key(ts->input, touch->id); if (slot < 0) { dev_dbg(dev, "no free slot for id 0x%x\n", touch->id); continue; } } else { slot = slots[i]; } input_mt_slot(ts->input, slot); input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true); input_event(ts->input, EV_ABS, ABS_MT_POSITION_X, touch->x); input_event(ts->input, EV_ABS, ABS_MT_POSITION_Y, touch->y); dev_dbg(dev, "%d: slot %d, x %d, y %d\n", i, slot, touch->x, touch->y); } input_mt_sync_frame(ts->input); input_sync(ts->input); }
static void aps_clear_input_data(struct aps_ts_info *info) { int i; dev_dbg(&info->client->dev, "%s\n", __func__); for (i = 0; i < MAX_FINGER_NUM; i++) { input_mt_slot(info->input_dev, i); input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, false); } input_sync(info->input_dev); return; }
/* * this function is called when a whole packet has been received and processed, * so that it can decide what to send to the input layer. */ static void mt_emit_event(struct mt_device *td, struct input_dev *input) { struct mt_slot *oldest = 0; /* touchscreen emulation: oldest touch */ int i; #ifdef MT_DBG if (trace) printk(KERN_ERR "++++++++++++++++++++ count=%d expected=%d\n", td->num_received, td->num_expected); #endif /* MT_DBG */ for (i = 0; i < td->maxcontacts; ++i) { struct mt_slot *s = &(td->slots[i]); if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && !s->seen_in_this_frame) { s->touch_state = false; } input_mt_slot(input, i); if (s->touch_state) { if (s->trkid == 0) s->trkid = td->lasttrkid++; input_event(input, EV_ABS, ABS_MT_TRACKING_ID, s->trkid); input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w); input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h); /* touchscreen emulation: is this the oldest contact? */ if (!oldest || ((s->trkid - oldest->trkid) & (SHRT_MAX + 1))) oldest = s; } else { input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1); s->trkid = 0; } s->seen_in_this_frame = false; } /* touchscreen emulation */ if (oldest) { input_event(input, EV_KEY, BTN_TOUCH, 1); input_event(input, EV_ABS, ABS_X, oldest->x); input_event(input, EV_ABS, ABS_Y, oldest->y); } else { input_event(input, EV_KEY, BTN_TOUCH, 0); } input_sync(input); td->num_received = 0; }
static void cyttsp5_report_slot_liftoff(struct cyttsp5_mt_data *md, int max_slots) { int t; if (md->num_prv_rec == 0) return; for (t = 0; t < max_slots; t++) { input_mt_slot(md->input, t); input_mt_report_slot_state(md->input, MT_TOOL_FINGER, false); } }
static void cyttsp4_report_slot_liftoff(struct cyttsp4_mt_data *md) { struct cyttsp4_sysinfo *si = md->si; int t; if (md->num_prv_tch == 0) return; for (t = 0; t < si->si_ofs.max_tchs + 1; t++) { input_mt_slot(md->input, t); input_mt_report_slot_state(md->input, MT_TOOL_FINGER, false); } }
static void cyttsp4_final_sync(struct input_dev *input, int max_tchs, int mt_sync_count, int *ids) { int t; for (t = 0; t < max_tchs + 1; t++) { if (ids[t]) continue; input_mt_slot(input, t); input_mt_report_slot_state(input, MT_TOOL_FINGER, false); } input_sync(input); }
static int sis_ts_report_contact(struct sis_ts_data *ts, const u8 *data, u8 id) { struct input_dev *input = ts->input; int slot; u8 status = data[SIS_CONTACT_STATUS_OFFSET]; u8 pressure; u8 height, width; u16 x, y; if (status != SIS_STATUS_DOWN && status != SIS_STATUS_UP) { dev_err(&ts->client->dev, "Unexpected touch status: %#02x\n", data[SIS_CONTACT_STATUS_OFFSET]); return -EINVAL; } slot = input_mt_get_slot_by_key(input, data[SIS_CONTACT_ID_OFFSET]); if (slot < 0) return -ENOENT; input_mt_slot(input, slot); input_mt_report_slot_state(input, MT_TOOL_FINGER, status == SIS_STATUS_DOWN); if (status == SIS_STATUS_DOWN) { pressure = height = width = 1; if (id != SIS_ALL_IN_ONE_PACKAGE) { if (SIS_PKT_HAS_AREA(id)) { width = data[SIS_CONTACT_WIDTH_OFFSET]; height = data[SIS_CONTACT_HEIGHT_OFFSET]; } if (SIS_PKT_HAS_PRESSURE(id)) pressure = data[SIS_CONTACT_PRESSURE_OFFSET(id)]; } x = get_unaligned_le16(&data[SIS_CONTACT_X_OFFSET]); y = get_unaligned_le16(&data[SIS_CONTACT_Y_OFFSET]); input_report_abs(input, ABS_MT_TOUCH_MAJOR, width * SIS_AREA_UNIT); input_report_abs(input, ABS_MT_TOUCH_MINOR, height * SIS_AREA_UNIT); input_report_abs(input, ABS_MT_PRESSURE, pressure); input_report_abs(input, ABS_MT_POSITION_X, x); input_report_abs(input, ABS_MT_POSITION_Y, y); } return 0; }
static void gtp_touch_down(struct goodix_ts_data *ts, int id, int x, int y, int w) { #if GTP_CHANGE_X2Y swap(x, y); #endif input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); }
static void cyttsp5_final_sync(struct input_dev *input, int max_slots, int mt_sync_count, unsigned long *ids) { int t; for (t = 0; t < max_slots; t++) { if (test_bit(t, ids)) continue; input_mt_slot(input, t); input_mt_report_slot_state(input, MT_TOOL_FINGER, false); } input_sync(input); }
static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) { int id = coor_data[0] & 0x0F; int input_x = get_unaligned_le16(&coor_data[1]); int input_y = get_unaligned_le16(&coor_data[3]); int input_w = get_unaligned_le16(&coor_data[5]); input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); }
/* * this function is called when a whole contact has been processed, * so that it can assign it to a slot and store the data there */ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) { if ((td->mtclass.quirks & MT_QUIRK_CONTACT_CNT_ACCURATE) && td->num_received >= td->num_expected) return; if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) { int active; int slotnum = mt_compute_slot(td, input); struct mt_slot *s = &td->curdata; struct input_mt *mt = input->mt; if (slotnum < 0 || slotnum >= td->maxcontacts) return; if ((td->mtclass.quirks & MT_QUIRK_IGNORE_DUPLICATES) && mt) { struct input_mt_slot *slot = &mt->slots[slotnum]; if (input_mt_is_active(slot) && input_mt_is_used(mt, slot)) return; } if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE)) s->confidence_state = 1; active = (s->touch_state || s->inrange_state) && s->confidence_state; input_mt_slot(input, slotnum); input_mt_report_slot_state(input, MT_TOOL_FINGER, active); if (active) { /* this finger is in proximity of the sensor */ int wide = (s->w > s->h); /* divided by two to match visual scale of touch */ int major = max(s->w, s->h) >> 1; int minor = min(s->w, s->h) >> 1; input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx); input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy); input_event(input, EV_ABS, ABS_MT_DISTANCE, !s->touch_state); input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); } }
static int ct363_resume(struct ct36x_data *ts) { int i; /* Hardware reset */ ct363_reset_hw(ts); msleep(3); for(i = 0; i < ts->point_num; i++){ input_mt_slot(ts->input, i); input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false); } input_sync(ts->input); return 0; }
static void silead_ts_read_data(struct i2c_client *client) { struct silead_ts_data *data = i2c_get_clientdata(client); struct input_dev *input = data->input; struct device *dev = &client->dev; u8 *bufp, buf[SILEAD_TS_DATA_LEN]; int touch_nr, error, i; error = i2c_smbus_read_i2c_block_data(client, SILEAD_REG_DATA, SILEAD_TS_DATA_LEN, buf); if (error < 0) { dev_err(dev, "Data read error %d\n", error); return; } touch_nr = buf[0]; if (touch_nr > data->max_fingers) { dev_warn(dev, "More touches reported then supported %d > %d\n", touch_nr, data->max_fingers); touch_nr = data->max_fingers; } bufp = buf + SILEAD_POINT_DATA_LEN; for (i = 0; i < touch_nr; i++, bufp += SILEAD_POINT_DATA_LEN) { /* Bits 4-7 are the touch id */ data->id[i] = (bufp[SILEAD_POINT_X_MSB_OFF] & SILEAD_TOUCH_ID_MASK) >> 4; touchscreen_set_mt_pos(&data->pos[i], &data->prop, get_unaligned_le16(&bufp[SILEAD_POINT_X_OFF]) & 0xfff, get_unaligned_le16(&bufp[SILEAD_POINT_Y_OFF]) & 0xfff); } input_mt_assign_slots(input, data->slots, data->pos, touch_nr, 0); for (i = 0; i < touch_nr; i++) { input_mt_slot(input, data->slots[i]); input_mt_report_slot_state(input, MT_TOOL_FINGER, true); input_report_abs(input, ABS_MT_POSITION_X, data->pos[i].x); input_report_abs(input, ABS_MT_POSITION_Y, data->pos[i].y); dev_dbg(dev, "x=%d y=%d hw_id=%d sw_id=%d\n", data->pos[i].x, data->pos[i].y, data->id[i], data->slots[i]); } input_mt_sync_frame(input); input_sync(input); }