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;
}
예제 #3
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;
}