static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) { struct egalax_ts *data = dev_id; struct i2c_client *client = data->client; u8 buf[MAX_I2C_DATA_LEN]; int id, ret, x, y, z; int tries = 0; bool down, valid; u8 state; memset(buf, 0, MAX_I2C_DATA_LEN); do { ret = i2c_master_recv(client, buf, MAX_I2C_DATA_LEN); } while (ret == -EAGAIN && tries++ < EGALAX_MAX_TRIES); if (ret < 0) return IRQ_HANDLED; if (buf[0] != REPORT_MODE_MTTOUCH) { /* ignore mouse events and vendor events */ return IRQ_HANDLED; } state = buf[1]; x = (buf[3] << 8) | buf[2]; y = (buf[5] << 8) | buf[4]; z = (buf[7] << 8) | buf[6]; valid = state & EVENT_VALID_MASK; id = (state & EVENT_ID_MASK) >> EVENT_ID_OFFSET; down = state & EVENT_DOWN_UP; if (!valid || id >= MAX_SUPPORT_POINTS) { dev_dbg(&client->dev, "point invalid\n"); return IRQ_HANDLED; } if (data->finger_mask & (1U << id)) report_input_data(data); if (!down) { data->fingers[id].z = -1; data->finger_mask |= 1U << id; } else { data->fingers[id].x = x; data->fingers[id].y = y; data->fingers[id].z = z; data->finger_mask |= 1U << id; } dev_dbg(&client->dev, "%s id:%d x:%d y:%d z:%d\n", (down ? "down" : "up"), id, x, y, z); if (data->finger_mask) report_input_data(data); return IRQ_HANDLED; }
static irqreturn_t ist30xx_irq_thread(int irq, void *ptr) { int i, ret; int key_cnt, finger_cnt, read_cnt; struct ist30xx_data *data = ptr; u32 msg[IST30XX_MAX_MT_FINGERS]; bool unknown_idle = false; #if IST30XX_TRACKING_MODE u32 ms; #endif if (!data->irq_enabled) return IRQ_HANDLED; memset(msg, 0, sizeof(msg)); ret = ist30xx_get_position(data->client, msg, 1); if (ret) goto irq_err; tsp_verb("intr msg: 0x%08x\n", *msg); if (msg[0] == 0) return IRQ_HANDLED; #if IST30XX_EVENT_MODE if ((data->status.update != 1) && (data->status.calib != 1)) ktime_get_ts(&t_event); #endif #if IST30XX_TRACKING_MODE ms = t_event.tv_sec * 1000 + t_event.tv_nsec / 1000000; ist30xx_put_track(ms, msg[0]); #endif #if IST30XX_NOISE_MODE if (get_event_mode) { if ((msg[0] & 0xFFFF0000) == IST30XX_IDLE_STATUS) { if (msg[0] & IDLE_ALGORITHM_MODE) return IRQ_HANDLED; for (i = 0; i < IST30XX_MAX_MT_FINGERS; i++) { if (data->prev_fingers[i].bit_field.id == 0) continue; if (data->prev_fingers[i].bit_field.udmg & PRESS_MSG_MASK) { tsp_warn("prev_fingers: %08x\n", data->prev_fingers[i].full_field); release_finger(&data->prev_fingers[i]); unknown_idle = true; } } for (i = 0; i < data->num_keys; i++) { if (data->prev_keys[i].bit_field.id == 0) continue; if (data->prev_keys[i].bit_field.w == PRESS_MSG_KEY) { tsp_warn("prev_keys: %08x\n", data->prev_keys[i].full_field); release_key(&data->prev_keys[i], RELEASE_KEY); unknown_idle = true; } } if (unknown_idle) { schedule_delayed_work(&work_reset_check, 0); tsp_warn("Find unknown pressure\n"); } return IRQ_HANDLED; } } #endif // IST30XX_NOISE_MODE if ((msg[0] & CALIB_MSG_MASK) == CALIB_MSG_VALID) { data->status.calib_msg = msg[0]; tsp_info("calib status: 0x%08x\n", data->status.calib_msg); return IRQ_HANDLED; } for (i = 0; i < IST30XX_MAX_MT_FINGERS; i++) data->fingers[i].full_field = 0; key_cnt = 0; finger_cnt = 1; read_cnt = 1; data->fingers[0].full_field = msg[0]; if (data->fingers[0].bit_field.udmg & MULTI_MSG_MASK) { key_cnt = data->fingers[0].bit_field.x; finger_cnt = data->fingers[0].bit_field.y; read_cnt = finger_cnt + key_cnt; if (finger_cnt > ist30xx_tsp_info.finger_num || key_cnt > ist30xx_tkey_info.key_num) { tsp_warn("Invalid touch count - finger: %d(%d), key: %d(%d)\n", finger_cnt, ist30xx_tsp_info.finger_num, key_cnt, ist30xx_tkey_info.key_num); goto irq_err; } #if I2C_BURST_MODE ret = ist30xx_get_position(data->client, msg, read_cnt); if (ret) goto irq_err; for (i = 0; i < read_cnt; i++) data->fingers[i].full_field = msg[i]; #else for (i = 0; i < read_cnt; i++) { ret = ist30xx_get_position(data->client, &msg[i], 1); if (ret) goto irq_err; data->fingers[i].full_field = msg[i]; } #endif // I2C_BURST_MODE for (i = 0; i < read_cnt; i++) tsp_verb("intr msg[%d]: 0x%08x\n", i, msg[i]); #if IST30XX_TRACKING_MODE for (i = 0; i < read_cnt; i++) ist30xx_put_track(ms, msg[i]); #endif } if (check_report_data(data, finger_cnt, key_cnt)) return IRQ_HANDLED; if (read_cnt > 0) report_input_data(data, finger_cnt, key_cnt); return IRQ_HANDLED; irq_err: tsp_err("intr msg[0]: 0x%08x, ret: %d\n", msg[0], ret); ist30xx_request_reset(); return IRQ_HANDLED; }