int ist30xx_set_cmcs_cmd(struct i2c_client *client, CMCS_INFO *cmcs) { int ret; u32 val; val = (u32)(cmcs->cmd.base_screen | (cmcs->cmd.mode << 16)); ret = ist30xx_write_cmd(client, cmcs->addr.base_screen, val); if (ret) return ret; tsp_verb("Baseline screen(0x%08x): 0x%08x\n", cmcs->addr.base_screen, val); val = (u32)cmcs->cmd.base_key; ret = ist30xx_write_cmd(client, cmcs->addr.base_key, val); if (ret) return ret; tsp_verb("Baseline key(0x%08x): 0x%08x\n", cmcs->addr.base_key, val); val = cmcs->cmd.start_cp_cm | (cmcs->cmd.start_cp_cs << 16); ret = ist30xx_write_cmd(client, cmcs->addr.start_cp, val); if (ret) return ret; tsp_verb("StartCP(0x%08x): 0x%08x\n", cmcs->addr.start_cp, val); val = cmcs->cmd.vcmp_cm | (cmcs->cmd.vcmp_cs << 16); ret = ist30xx_write_cmd(client, cmcs->addr.vcmp, val); if (ret) return ret; tsp_verb("VCMP(0x%08x): 0x%08x\n", cmcs->addr.vcmp, val); return 0; }
/* sysfs: /sys/class/touch/tracking/track_frame */ ssize_t ist30xx_track_frame_show(struct device *dev, struct device_attribute *attr, char *buf) { int i, buf_cnt = 0; u32 track_cnt = MAX_TRACKING_COUNT; u32 track; char msg[10]; mutex_lock(&ist30xx_mutex); buf[0] = '\0'; if (track_cnt > ist30xx_get_track_cnt()) track_cnt = ist30xx_get_track_cnt(); track_cnt /= sizeof(track); tsp_verb("num: %d of %d\n", track_cnt, ist30xx_get_track_cnt()); for (i = 0; i < track_cnt; i++) { ist30xx_get_track(&track, 1); tsp_verb("%08X\n", track); buf_cnt += sprintf(msg, "%08x", track); strcat(buf, msg); } mutex_unlock(&ist30xx_mutex); return buf_cnt; }
int ist30xx_check_valid_ch(struct ist30xx_data *data, int ch_tx, int ch_rx) { TKEY_INFO *tkey = &data->tkey_info; TSP_INFO *tsp = &data->tsp_info; if (unlikely((ch_tx > tsp->ch_num.tx) || (ch_rx > tsp->ch_num.rx))) return 0; if (tkey->enable) { if (tkey->axis_rx) { tsp_verb("tx: %d, rx: %d\n", ch_tx, ch_rx); if (ch_rx == tsp->ch_num.rx - 1) { tsp_verb("ch_tx: %d\n", ch_tx); if ((ch_tx == tkey->ch_num[0]) || (ch_tx == tkey->ch_num[1]) || (ch_tx == tkey->ch_num[2]) || (ch_tx == tkey->ch_num[3]) || (ch_tx == tkey->ch_num[4])) return TSP_CH_KEY; else return 0; } } else { if (ch_tx == tsp->ch_num.tx - 1) { if ((ch_rx == tkey->ch_num[0]) || (ch_rx == tkey->ch_num[1]) || (ch_rx == tkey->ch_num[2]) || (ch_rx == tkey->ch_num[3]) || (ch_rx == tkey->ch_num[4])) return TSP_CH_KEY; else return 0; } } } return TSP_CH_SCREEN; }
int ist30xx_set_cmcs_sensor(struct i2c_client *client, CMCS_INFO *cmcs, u32 *buf32) { int i, ret; int len; u32 waddr; u32 *tmp32; tsp_verb("%08x %08x %08x %08x\n", buf32[0], buf32[1], buf32[2], buf32[3]); waddr = cmcs->addr.sensor1; len = cmcs->sensor1_size / IST30XX_DATA_LEN; for (i = 0; i < len; i++) { ret = ist30xx_write_cmd(client, waddr, *buf32++); if (ret) return ret; waddr += IST30XX_DATA_LEN; } tmp32 = buf32; tsp_verb("%08x %08x %08x %08x\n", tmp32[0], tmp32[1], tmp32[2], tmp32[3]); waddr = cmcs->addr.sensor2; len = (cmcs->sensor2_size - 0x10) / IST30XX_DATA_LEN; for (i = 0; i < len; i++) { ret = ist30xx_write_cmd(client, waddr, *buf32++); if (ret) return ret; waddr += IST30XX_DATA_LEN; } buf32 += (0x10 / IST30XX_DATA_LEN); tmp32 = buf32; tsp_verb("%08x %08x %08x %08x\n", tmp32[0], tmp32[1], tmp32[2], tmp32[3]); waddr = cmcs->addr.sensor3; len = cmcs->sensor3_size / IST30XX_DATA_LEN; for (i = 0; i < len; i++) { ret = ist30xx_write_cmd(client, waddr, *buf32++); if (ret) return ret; waddr += IST30XX_DATA_LEN; } return 0; }
void timer_handler(unsigned long data) { int event_ms; int curr_ms; if (get_event_mode) { if ((ts_data->status.power == 1) && (ts_data->status.update != 1)) { ktime_get_ts(&t_current); curr_ms = t_current.tv_sec * 1000 + t_current.tv_nsec / 1000000; event_ms = t_event.tv_sec * 1000 + t_event.tv_nsec / 1000000; tsp_verb("event_ms %d, current: %d\n", event_ms, curr_ms); if (ts_data->status.calib == 1) { if (curr_ms - event_ms >= 2000) { // 2second ts_data->status.calib = 0; tsp_debug("calibration timeout over 3sec\n"); schedule_delayed_work(&work_reset_check, 0); ktime_get_ts(&t_event); } } #if IST30XX_NOISE_MODE else if (curr_ms - event_ms >= 5000) { // 5second tsp_warn("idle timeout over 5sec\n"); schedule_delayed_work(&work_reset_check, 0); } #endif // IST30XX_NOISE_MODE } } mod_timer(&idle_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL); }
/* sysfs: /sys/class/touch/cmcs/info */ ssize_t ist30xx_cmcs_info_show(struct device *dev, struct device_attribute *attr, char *buf) { int count; char msg[128]; CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; if (cmcs_ready == CMCS_NOT_READY) return sprintf(buf, "CMCS test is not work!!\n"); if (cmcs == NULL) return sprintf(buf, "Unknown cmcs bin\n"); /* Mode */ count = sprintf(msg, "%d ", cmcs->cmd.mode); strcat(buf, msg); /* Channel */ count += sprintf(msg, "%d %d %d %d %d %d %d %d ", cmcs->ch.tx_num, cmcs->ch.rx_num, cmcs->ch.key_rx, cmcs->ch.key1, cmcs->ch.key2, cmcs->ch.key3, cmcs->ch.key4, cmcs->ch.key5); strcat(buf, msg); /* Slope */ count += sprintf(msg, "%d %d %d %d %d %d", cmcs->slope.x_min, cmcs->slope.x_max, cmcs->slope.y_min, cmcs->slope.y_max, cmcs->slope.key_min, cmcs->slope.key_max); strcat(buf, msg); /* CM */ count += sprintf(msg, "%d %d %d %d ", cmcs->spec_cm.screen_min, cmcs->spec_cm.screen_max, cmcs->spec_cm.key_min, cmcs->spec_cm.key_max); strcat(buf, msg); /* CS0 */ count += sprintf(msg, "%d %d %d %d ", cmcs->spec_cs0.screen_min, cmcs->spec_cs0.screen_max, cmcs->spec_cs0.key_min, cmcs->spec_cs0.key_max); strcat(buf, msg); /* CS1 */ count += sprintf(msg, "%d %d %d %d ", cmcs->spec_cs1.screen_min, cmcs->spec_cs1.screen_max, cmcs->spec_cs1.key_min, cmcs->spec_cs1.key_max); strcat(buf, msg); /* CR */ count += sprintf(msg, "%d %d %d %d ", cmcs->spec_cr.screen_min, cmcs->spec_cr.screen_max, cmcs->spec_cr.key_min, cmcs->spec_cr.key_max); strcat(buf, msg); tsp_verb("%s\n", buf); return count; }
/* sysfs: /sys/class/touch/tracking/track_cnt */ ssize_t ist30xx_track_cnt_show(struct device *dev, struct device_attribute *attr, char *buf) { u32 val = (u32)ist30xx_get_track_cnt(); tsp_verb("tracking cnt: %d\n", val); return sprintf(buf, "%08x", val); }
/* sysfs: /sys/class/touch/cmcs/cs1 */ ssize_t ist30xx_cs1_show(struct device *dev, struct device_attribute *attr, char *buf) { CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; if (cmcs_ready == CMCS_NOT_READY) return sprintf(buf, "CMCS test is not work!!\n"); if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CS)) return 0; tsp_verb("CS1 (%d * %d)\n", cmcs->ch.tx_num, cmcs->ch.rx_num); return print_cmcs(ts_cmcs_buf->cs1, buf); }
/* sysfs: /sys/class/touch/cmcs/cs0 */ ssize_t ist30xx_cs0_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ist30xx_data *data = dev_get_drvdata(dev); CMCS_INFO *cmcs = (CMCS_INFO *)&data->cmcs->cmcs; if (data->cmcs_ready == CMCS_NOT_READY) return sprintf(buf, "CMCS test is not work!!\n"); if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CS)) return 0; tsp_verb("CS0 (%d * %d)\n", cmcs->ch.tx_num, cmcs->ch.rx_num); return print_cmcs(data, data->cmcs_buf->cs0, buf); }
int ist30xx_parse_cmcs_bin(const u8 *buf, const u32 size) { int ret = -EPERM; CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; memcpy(ts_cmcs->magic1, buf, sizeof(ts_cmcs->magic1)); memcpy(ts_cmcs->magic2, &buf[size - sizeof(ts_cmcs->magic2)], sizeof(ts_cmcs->magic2)); memcpy(cmcs, &buf[sizeof(ts_cmcs->magic1)], sizeof(ts_cmcs->cmcs)); if (!strncmp(ts_cmcs->magic1, IST30XX_CMCS_MAGIC, sizeof(ts_cmcs->magic1)) && !strncmp(ts_cmcs->magic2, IST30XX_CMCS_MAGIC, sizeof(ts_cmcs->magic2))) { int idx; idx = sizeof(ts_cmcs->magic1) + sizeof(ts_cmcs->cmcs); ts_cmcs->buf_cmcs = (u8 *)&buf[idx]; idx += cmcs->cmd.cmcs_size; ts_cmcs->buf_sensor = (u32 *)&buf[idx]; idx += (cmcs->sensor1_size + cmcs->sensor2_size + cmcs->sensor3_size); ts_cmcs->buf_node = (u16 *)&buf[idx]; ret = 0; } tsp_verb("Magic1: %s, Magic2: %s\n", ts_cmcs->magic1, ts_cmcs->magic2); tsp_verb(" mode: 0x%x, base(screen: %d, key: %d)\n", cmcs->cmd.mode, cmcs->cmd.base_screen, cmcs->cmd.base_key); tsp_verb(" start_cp (cm: %d, cs: %d), vcmp (cm: %d, cs: %d)\n", cmcs->cmd.start_cp_cm, cmcs->cmd.start_cp_cs, cmcs->cmd.vcmp_cm, cmcs->cmd.vcmp_cs); tsp_verb(" timeout: %d\n", cmcs->timeout); tsp_verb(" baseline scrn: 0x%08x, key: 0x%08x\n", cmcs->addr.base_screen, cmcs->addr.base_key); tsp_verb(" start_cp: 0x%08x, vcmp: 0x%08x\n", cmcs->addr.start_cp, cmcs->addr.vcmp); tsp_verb(" sensor 1: 0x%08x, 2: 0x%08x, 3: 0x%08x\n", cmcs->addr.sensor1, cmcs->addr.sensor2, cmcs->addr.sensor3); tsp_verb(" tx: %d, rx:%d, key rx: %d, num(%d, %d, %d, %d, %d)\n", cmcs->ch.tx_num, cmcs->ch.rx_num, cmcs->ch.key_rx, cmcs->ch.key1, cmcs->ch.key2, cmcs->ch.key3, cmcs->ch.key4, cmcs->ch.key5); tsp_verb(" cr: screen(%4d, %4d), key(%4d, %4d)\n", cmcs->spec_cr.screen_min, cmcs->spec_cr.screen_max, cmcs->spec_cr.key_min, cmcs->spec_cr.key_max); tsp_verb(" cm: screen(%4d, %4d), key(%4d, %4d)\n", cmcs->spec_cm.screen_min, cmcs->spec_cm.screen_max, cmcs->spec_cm.key_min, cmcs->spec_cm.key_max); tsp_verb(" cs0: screen(%4d, %4d), key(%4d, %4d)\n", cmcs->spec_cs0.screen_min, cmcs->spec_cs0.screen_max, cmcs->spec_cs0.key_min, cmcs->spec_cs0.key_max); tsp_verb(" cs1: screen(%4d, %4d), key(%4d, %4d)\n", cmcs->spec_cs1.screen_min, cmcs->spec_cs1.screen_max, cmcs->spec_cs1.key_min, cmcs->spec_cs1.key_max); tsp_verb(" slope - x(%d, %d), y(%d, %d), key(%d, %d)\n", cmcs->slope.x_min, cmcs->slope.x_max, cmcs->slope.y_min, cmcs->slope.y_max, cmcs->slope.key_min, cmcs->slope.key_max); tsp_verb(" size - cmcs(%d), sensor(%d, %d, %d)\n", cmcs->cmd.cmcs_size, cmcs->sensor1_size, cmcs->sensor2_size, cmcs->sensor3_size); tsp_verb(" checksum - cmcs: 0x%08x, sensor: 0x%08x\n", cmcs->cmcs_chksum, cmcs->sensor_chksum); tsp_verb(" cmcs: %x, %x, %x, %x\n", ts_cmcs->buf_cmcs[0], ts_cmcs->buf_cmcs[1], ts_cmcs->buf_cmcs[2], ts_cmcs->buf_cmcs[3]); tsp_verb(" sensor: %x, %x, %x, %x\n", ts_cmcs->buf_sensor[0], ts_cmcs->buf_sensor[1], ts_cmcs->buf_sensor[2], ts_cmcs->buf_sensor[3]); tsp_verb(" node: %x, %x, %x, %x\n", ts_cmcs->buf_node[0], ts_cmcs->buf_node[1], ts_cmcs->buf_node[2], ts_cmcs->buf_node[3]); return ret; }
int ist30xx_cmcs_test(const u8 *buf, int size) { int ret; int len; u32 chksum = 0; u32 *buf32; struct i2c_client *client = (struct i2c_client *)ts_data->client; CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; tsp_info("*** CM/CS test ***\n"); tsp_info(" mode: 0x%x, baseline(screen: %d, key: %d)\n", cmcs->cmd.mode, cmcs->cmd.base_screen, cmcs->cmd.base_key); tsp_info(" start_cp (cm: %d, cs: %d), vcmp (cm: %d, cs: %d)\n", cmcs->cmd.start_cp_cm, cmcs->cmd.start_cp_cs, cmcs->cmd.vcmp_cm, cmcs->cmd.vcmp_cs); ist30xx_disable_irq(ts_data); ist30xx_reset(false); ret = ist30xx_cmd_reg(client, CMD_ENTER_REG_ACCESS); cmcs_next_step(ret); /* Set sensor register */ buf32 = ts_cmcs->buf_sensor; ret = ist30xx_set_cmcs_sensor(client, cmcs, buf32); cmcs_next_step(ret); /* Set command */ ret = ist30xx_set_cmcs_cmd(client, cmcs); cmcs_next_step(ret); ret = ist30xx_cmd_reg(client, CMD_EXIT_REG_ACCESS); cmcs_next_step(ret); /* Load cmcs test code */ ret = ist30xx_write_cmd(client, CMD_EXEC_MEM_CODE, 0); cmcs_next_step(ret); buf32 = (u32 *)ts_cmcs->buf_cmcs; len = cmcs->cmd.cmcs_size / IST30XX_DATA_LEN; tsp_verb("%08x %08x %08x %08x\n", buf32[0], buf32[1], buf32[2], buf32[3]); ret = ist30xx_write_buf(client, len, buf32, len); cmcs_next_step(ret); /* Check checksum */ ret = ist30xx_read_cmd(client, CMD_DEFAULT, &chksum); cmcs_next_step(ret); if (chksum != IST30XX_CMCS_LOAD_END) goto end; tsp_info("CM/CS code ready!!\n"); /* Check checksum */ ret = ist30xx_read_cmd(client, CMD_DEFAULT, &chksum); cmcs_next_step(ret); tsp_info("CM/CS code chksum: %08x, %08x\n", chksum, cmcs->cmcs_chksum); ist30xx_enable_irq(ts_data); /* Wait CMCS test result */ if (ist30xx_calib_wait() == 1) tsp_info("CM/CS test OK.\n"); else tsp_info("CM/CS test fail.\n"); ist30xx_disable_irq(ts_data); /* Read CM/CS data*/ if (ENABLE_CM_MODE(cmcs->cmd.mode)) { /* Read CM data */ memset(ts_cmcs_buf->cm, 0, sizeof(ts_cmcs_buf->cm)); ret = ist30xx_get_cmcs_buf(client, cmcs, ts_cmcs_buf->cm); cmcs_next_step(ret); ret = ist30xx_apply_cmcs_slope(cmcs, ts_cmcs_buf); } if (ENABLE_CS_MODE(cmcs->cmd.mode)) { /* Read CS0 data */ memset(ts_cmcs_buf->cs0, 0, sizeof(ts_cmcs_buf->cs0)); memset(ts_cmcs_buf->cs1, 0, sizeof(ts_cmcs_buf->cs1)); ret = ist30xx_get_cmcs_buf(client, cmcs, ts_cmcs_buf->cs0); cmcs_next_step(ret); /* Read CS1 data */ ret = ist30xx_get_cmcs_buf(client, cmcs, ts_cmcs_buf->cs1); cmcs_next_step(ret); } ist30xx_reset(false); ist30xx_start(ts_data); cmcs_ready = CMCS_READY; end: if (unlikely(ret)) { tsp_warn("CM/CS test Fail!, ret=%d\n", ret); } else if (unlikely(chksum != cmcs->cmcs_chksum)) { tsp_warn("Error CheckSum: %x(%x)\n", chksum, cmcs->cmcs_chksum); ret = -ENOEXEC; } ist30xx_enable_irq(ts_data); return ret; }
int ist30xx_apply_cmcs_slope(CMCS_INFO *cmcs, CMCS_BUF *cmcs_buf) { int i, j; int idx1, idx2; int ch_num = cmcs->ch.tx_num * cmcs->ch.rx_num; int width = cmcs->ch.rx_num; int height = cmcs->ch.tx_num; s16 *pcm = (s16 *)cmcs_buf->cm; s16 *pspec = (s16 *)cmcs_buf->spec; s16 *pslope0 = (s16 *)cmcs_buf->slope0; s16 *pslope1 = (s16 *)cmcs_buf->slope1; if (cmcs->ch.key_rx) width -= 1; else height -= 1; memset(cmcs_buf->slope0, 0, sizeof(cmcs_buf->slope0)); memset(cmcs_buf->slope1, 0, sizeof(cmcs_buf->slope1)); memcpy(cmcs_buf->spec, ts_cmcs->buf_node, (ch_num * sizeof(u16))); idx1 = 0; #if CMCS_PARSING_DEBUG tsp_info("# Node specific\n"); for (i = 0; i < cmcs->ch.tx_num; i++) { tsp_info(" "); for (j = 0; j < cmcs->ch.rx_num; j++) printk("%5d ", cmcs_buf->spec[idx1++]); printk("\n"); } #endif tsp_verb("# Apply slope0_x\n"); for (i = 0; i < height; i++) { for (j = 0; j < width - 1; j++) { idx1 = (i * cmcs->ch.rx_num) + j; idx2 = idx1 + 1; pslope0[idx1] = (pcm[idx2] - pcm[idx1]); pslope0[idx1] += (pspec[idx1] - pspec[idx2]); } } tsp_verb("# Apply slope1_y\n"); for (i = 0; i < height - 1; i++) { for (j = 0; j < width; j++) { idx1 = (i * cmcs->ch.rx_num) + j; idx2 = idx1 + cmcs->ch.rx_num; pslope1[idx1] = (pcm[idx2] - pcm[idx1]); pslope1[idx1] += (pspec[idx1] - pspec[idx2]); } } #if CMCS_PARSING_DEBUG tsp_info("# slope0_x\n"); for (i = 0; i < height; i++) { tsp_info(" "); for (j = 0; j < width; j++) { idx1 = (i * cmcs->ch.rx_num) + j; printk("%5d ", pslope0[idx1]); } printk("\n"); } tsp_info("# slope1_y\n"); for (i = 0; i < height; i++) { tsp_info(" "); for (j = 0; j < width; j++) { idx1 = (i * cmcs->ch.rx_num) + j; printk("%5d ", pslope1[idx1]); } printk("\n"); } #endif return 0; }
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; }