static s32 io_iic_read(u8 * data, void __user * arg) { s32 err = ERROR; s32 data_length = 0; u16 addr = 0; err = copy_from_user(data, arg, CMD_HEAD_LENGTH); if (err) { GTP_DEBUG("Can't access the memory."); return ERROR_MEM; } addr = data[0] << 8 | data[1]; data_length = data[2] << 8 | data[3]; err = gt1x_i2c_read(addr, &data[CMD_HEAD_LENGTH], data_length); if (!err) { err = copy_to_user(&((u8 __user *) arg)[CMD_HEAD_LENGTH], &data[CMD_HEAD_LENGTH], data_length); if (err) { GTP_ERROR("ERROR when copy to user.[addr: %04x], [read length:%d]", addr, data_length); return ERROR_MEM; } err = CMD_HEAD_LENGTH + data_length; } GTP_DEBUG("IIC_READ.addr:0x%4x, length:%d, ret:%d", addr, data_length, err); GTP_DEBUG_ARRAY((&data[CMD_HEAD_LENGTH]), data_length); return err; }
static s32 hotknot_enter_transfer_mode(void) { int ret = 0; u8 buffer[5] = { 0 }; hotknot_transfer_mode = 1; #if GTP_ESD_PROTECT gt1x_esd_switch(SWITCH_OFF); #endif gt1x_irq_disable(); gt1x_send_cmd(GTP_CMD_HN_TRANSFER, 0); msleep(100); gt1x_irq_enable(); ret = gt1x_i2c_read(0x8140, buffer, sizeof(buffer)); if (ret) { hotknot_transfer_mode = 0; return ret; } buffer[4] = 0; GTP_DEBUG("enter transfer mode: %s ", buffer); if (strcmp(buffer, "GHot")) { hotknot_transfer_mode = 0; return ERROR_HN_VER; } return 0; }
static s32 tool_i2c_read(u8 * buf, u16 len) { u16 addr = (buf[0] << 8) + buf[1]; if (!gt1x_i2c_read(addr, &buf[2], len)) { return 1; } return -1; }
static s32 hotknot_load_authentication_subsystem(void) { s32 ret = 0; u8 buffer[5] = { 0 }; ret = gt1x_hold_ss51_dsp_no_reset(); if (ret < 0) { GTP_ERROR("Hold ss51 fail!"); return ERROR; } if (gt1x_chip_type == CHIP_TYPE_GT1X) { GTP_INFO("hotknot load jump code."); ret = gt1x_load_patch(gt1x_patch_jump_fw, 4096, 0, 1024 * 8); if (ret < 0) { GTP_ERROR("Load jump code fail!"); return ret; } GTP_INFO("hotknot load auth code."); ret = gt1x_load_patch(hotknot_auth_fw, 4096, 4096, 1024 * 8); if (ret < 0) { GTP_ERROR("Load auth system fail!"); return ret; } } else { GTP_INFO("hotknot load auth code."); ret = gt1x_load_patch(hotknot_auth_fw, 4096, 0, 1024 * 6); if (ret < 0) { GTP_ERROR("load auth system fail!"); return ret; } } ret = gt1x_startup_patch(); if (ret < 0) { GTP_ERROR("Startup auth system fail!"); return ret; } ret = gt1x_i2c_read(GTP_REG_VERSION, buffer, 4); if (ret < 0) { GTP_ERROR("i2c read error!"); return ERROR_IIC; } buffer[4] = 0; GTP_INFO("Current System version: %s", buffer); return 0; }
s32 hotknot_event_handler(u8 * data) { u8 hn_pxy_state = 0; u8 hn_pxy_state_bak = 0; static u8 hn_paired_cnt = 0; u8 hn_state_buf[10] = { 0 }; u8 finger = data[0]; u8 id = 0; if (block_enable && !hotknot_paired_flag && (finger & 0x0F)) { id = data[1]; hn_pxy_state = data[2] & 0x80; hn_pxy_state_bak = data[3] & 0x80; if ((32 == id) && (0x80 == hn_pxy_state) && (0x80 == hn_pxy_state_bak)) { #ifdef HN_DBLCFM_PAIRED if (hn_paired_cnt++ < 2) { return 0; } #endif GTP_DEBUG("HotKnot paired!"); if (wait_hotknot_state & HN_DEVICE_PAIRED) { GTP_DEBUG("INT wakeup HN_DEVICE_PAIRED block polling waiter"); got_hotknot_state |= HN_DEVICE_PAIRED; wake_up_interruptible(&bp_waiter); } block_enable = 0; hotknot_paired_flag = 1; return 0; } else { got_hotknot_state &= (~HN_DEVICE_PAIRED); hn_paired_cnt = 0; } } if (hotknot_paired_flag) { s32 ret = -1; ret = gt1x_i2c_read(GTP_REG_HN_STATE, hn_state_buf, 6); if (ret < 0) { GTP_ERROR("I2C transfer error. errno:%d\n ", ret); return 0; } got_hotknot_state = 0; GTP_DEBUG("wait_hotknot_state:%x", wait_hotknot_state); GTP_DEBUG("[0x8800~0x8803]=0x%x,0x%x,0x%x,0x%x", hn_state_buf[0], hn_state_buf[1], hn_state_buf[2], hn_state_buf[3]); if (wait_hotknot_state & HN_MASTER_SEND) { if ((0x03 == hn_state_buf[0]) || (0x04 == hn_state_buf[0]) || (0x07 == hn_state_buf[0])) { GTP_DEBUG("Wakeup HN_MASTER_SEND block polling waiter"); got_hotknot_state |= HN_MASTER_SEND; got_hotknot_extra_state = hn_state_buf[0]; wake_up_interruptible(&bp_waiter); } } else if (wait_hotknot_state & HN_SLAVE_RECEIVED) { if ((0x03 == hn_state_buf[1]) || (0x04 == hn_state_buf[1]) || (0x07 == hn_state_buf[1])) { GTP_DEBUG("Wakeup HN_SLAVE_RECEIVED block polling waiter:0x%x", hn_state_buf[1]); got_hotknot_state |= HN_SLAVE_RECEIVED; got_hotknot_extra_state = hn_state_buf[1]; wake_up_interruptible(&bp_waiter); } } else if (wait_hotknot_state & HN_MASTER_DEPARTED) { if (0x07 == hn_state_buf[0]) { GTP_DEBUG("Wakeup HN_MASTER_DEPARTED block polling waiter"); got_hotknot_state |= HN_MASTER_DEPARTED; wake_up_interruptible(&bp_waiter); } } else if (wait_hotknot_state & HN_SLAVE_DEPARTED) { if (0x07 == hn_state_buf[1]) { GTP_DEBUG("Wakeup HN_SLAVE_DEPARTED block polling waiter"); got_hotknot_state |= HN_SLAVE_DEPARTED; wake_up_interruptible(&bp_waiter); } } return 0; } return -1; }
s32 gesture_event_handler(struct input_dev * dev) { u8 doze_buf[4] = { 0 }; s32 ret = -1; int len, extra_len; if (DOZE_ENABLED == gesture_doze_status) { ret = gt1x_i2c_read(GTP_REG_WAKEUP_GESTURE, doze_buf, 4); GTP_DEBUG("0x%x = 0x%02X,0x%02X,0x%02X,0x%02X", GTP_REG_WAKEUP_GESTURE, doze_buf[0], doze_buf[1], doze_buf[2], doze_buf[3]); if (ret == 0 && doze_buf[0] != 0) { if (!QUERYBIT(gestures_flag, doze_buf[0])) { GTP_INFO("Sorry, this gesture has been disabled."); doze_buf[0] = 0x00; gt1x_i2c_write(GTP_REG_WAKEUP_GESTURE, doze_buf, 1); return 0; } mutex_lock(&gesture_data_mutex); len = doze_buf[1]; if (len > GESTURE_MAX_POINT_COUNT) { GTP_ERROR("Gesture contain too many points!(%d)", len); len = GESTURE_MAX_POINT_COUNT; } if (len > 0) { ret = gt1x_i2c_read(GTP_REG_WAKEUP_GESTURE_DETAIL, &gesture_data.data[4], len * 4); if (ret < 0) { GTP_DEBUG("Read gesture data failed."); mutex_unlock(&gesture_data_mutex); return 0; } } extra_len = doze_buf[3]; if (extra_len > 80) { GTP_ERROR("Gesture contain too many extra data!(%d)", extra_len); extra_len = 80; } if (extra_len > 0) { ret = gt1x_i2c_read(GTP_REG_WAKEUP_GESTURE + 4, &gesture_data.data[4 + len * 4], extra_len); if (ret < 0) { GTP_DEBUG("Read extra gesture data failed."); mutex_unlock(&gesture_data_mutex); return 0; } } gesture_data.data[0] = doze_buf[0]; // gesture type gesture_data.data[1] = len; // gesture points number gesture_data.data[2] = doze_buf[2]; gesture_data.data[3] = extra_len; mutex_unlock(&gesture_data_mutex); GTP_DEBUG("Gesture: 0x%02X, points: %d", doze_buf[0], doze_buf[1]); doze_buf[0] = 0; gt1x_i2c_write(GTP_REG_WAKEUP_GESTURE, doze_buf, 1); input_report_key(dev, KEY_GESTURE, 1); input_sync(dev); input_report_key(dev, KEY_GESTURE, 0); input_sync(dev); return 1; } return 0; } return -1; }