Beispiel #1
0
VOID
CyapaBootWorkItem(
	IN WDFWORKITEM  WorkItem
	)
{
	WDFDEVICE Device = (WDFDEVICE)WdfWorkItemGetParentObject(WorkItem);
	PDEVICE_CONTEXT pDevice = GetDeviceContext(Device);

	cyapa_boot_regs boot;

	csgesture_softc *sc = &pDevice->sc;

	if (!sc->infoSetup) {
		struct cyapa_cap cap;
		SpbReadDataSynchronously(&pDevice->I2CContext, CMD_QUERY_CAPABILITIES, &cap, sizeof(cap));
		if (strncmp((const char *)cap.prod_ida, "CYTRA", 5) != 0) {
			CyapaPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "[cyapainit] Product ID \"%5.5s\" mismatch\n",
				cap.prod_ida);
			SpbReadDataSynchronously(&pDevice->I2CContext, CMD_QUERY_CAPABILITIES, &cap, sizeof(cap));
		}

		sc->resx = ((cap.max_abs_xy_high << 4) & 0x0F00) |
			cap.max_abs_x_low;
		sc->resy = ((cap.max_abs_xy_high << 8) & 0x0F00) |
			cap.max_abs_y_low;
		sc->phyx = ((cap.phy_siz_xy_high << 4) & 0x0F00) |
			cap.phy_siz_x_low;
		sc->phyy = ((cap.phy_siz_xy_high << 8) & 0x0F00) |
			cap.phy_siz_y_low;
		CyapaPrint(DEBUG_LEVEL_INFO, DBG_PNP, "[cyapainit] %5.5s-%6.6s-%2.2s buttons=%c%c%c res=%dx%d\n",
			cap.prod_ida, cap.prod_idb, cap.prod_idc,
			((cap.buttons & CYAPA_FNGR_LEFT) ? 'L' : '-'),
			((cap.buttons & CYAPA_FNGR_MIDDLE) ? 'M' : '-'),
			((cap.buttons & CYAPA_FNGR_RIGHT) ? 'R' : '-'),
			sc->resx,
			sc->resy);

		for (int i = 0; i < 5; i++) {
			sc->product_id[i] = cap.prod_ida[i];
		}
		sc->product_id[5] = '-';
		for (int i = 0; i < 6; i++) {
			sc->product_id[i + 6] = cap.prod_idb[i];
		}
		sc->product_id[12] = '-';
		for (int i = 0; i < 2; i++) {
			sc->product_id[i + 13] = cap.prod_idc[i];
		}
		sc->product_id[15] = '\0';

		sprintf(sc->firmware_version, "%d.%d", cap.fw_maj_ver, cap.fw_min_ver);
		sc->infoSetup = true;
	}

	cyapa_set_power_mode(pDevice, CMD_POWER_MODE_FULL);

	SpbReadDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, &boot, sizeof(boot));
	WdfObjectDelete(WorkItem);
}
Beispiel #2
0
void cyapa_set_power_mode(_In_  PDEVICE_CONTEXT  pDevice, _In_ uint8_t power_mode)
{
	int ret;
	uint8_t power;

	SpbReadDataSynchronously(&pDevice->I2CContext, CMD_POWER_MODE, &ret, 1);
	if (ret < 0)
		return;

	power = (ret & ~0xFC);
	power |= power_mode & 0xFc;

	SpbWriteDataSynchronously(&pDevice->I2CContext, CMD_POWER_MODE, &power, 1);
}
Beispiel #3
0
BOOLEAN OnInterruptIsr(
	WDFINTERRUPT Interrupt,
	ULONG MessageID){
	UNREFERENCED_PARAMETER(MessageID);

	WDFDEVICE Device = WdfInterruptGetDevice(Interrupt);
	PDEVICE_CONTEXT pDevice = GetDeviceContext(Device);

	if (!pDevice->ConnectInterrupt)
		return true;

	struct cyapa_regs regs;
	SpbReadDataSynchronously(&pDevice->I2CContext, 0, &regs, sizeof(regs));
	pDevice->lastregs = regs;
	pDevice->RegsSet = true;
	return true;
}
Beispiel #4
0
NTSTATUS BOOTTRACKPAD(
	_In_  PDEVICE_CONTEXT  pDevice
	)
{
	NTSTATUS status = 0;

	static char bl_exit[] = {
		0x00, 0xff, 0xa5, 0x00, 0x01,
		0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };

	static char bl_deactivate[] = {
		0x00, 0xff, 0x3b, 0x00, 0x01,
		0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };

	cyapa_boot_regs boot;

	FuncEntry(TRACE_FLAG_WDFLOADING);

	SpbReadDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, &boot, sizeof(boot));

	if ((boot.stat & CYAPA_STAT_RUNNING) == 0) {
		if (boot.error & CYAPA_ERROR_BOOTLOADER)
			SpbWriteDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, bl_deactivate, sizeof(bl_deactivate));
		else
			SpbWriteDataSynchronously(&pDevice->I2CContext, CMD_BOOT_STATUS, bl_exit, sizeof(bl_exit));
	}

	WDF_TIMER_CONFIG              timerConfig;
	WDFTIMER                      hTimer;
	WDF_OBJECT_ATTRIBUTES         attributes;

	WDF_TIMER_CONFIG_INIT(&timerConfig, CyapaBootTimer);

	WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
	attributes.ParentObject = pDevice->FxDevice;
	status = WdfTimerCreate(&timerConfig, &attributes, &hTimer);

	WdfTimerStart(hTimer, WDF_REL_TIMEOUT_IN_MS(75));

	FuncExit(TRACE_FLAG_WDFLOADING);
	return status;
}
Beispiel #5
0
NTSTATUS
RmiChangeSleepState(
   IN RMI4_CONTROLLER_CONTEXT* ControllerContext,
   IN SPB_CONTEXT *SpbContext,
   IN UCHAR SleepState
   )
/*++

Routine Description:

   Changes the SleepMode bits on the controller as specified

Arguments:

   ControllerContext - Touch controller context
   
   SpbContext - A pointer to the current i2c context

   SleepState - Either RMI4_F11_DEVICE_CONTROL_SLEEP_MODE_OPERATING
                or RMI4_F11_DEVICE_CONTROL_SLEEP_MODE_SLEEPING

Return Value:

   NTSTATUS indicating success or failure

--*/
{
    RMI4_F01_CTRL_REGISTERS* controlF01;
    UCHAR deviceControl;
    int index;
    NTSTATUS status;

    controlF01 = (RMI4_F01_CTRL_REGISTERS*) &deviceControl;

    //
    // Find RMI device control function housing sleep settings
    // 
    index = RmiGetFunctionIndex(
        ControllerContext->Descriptors,
        ControllerContext->FunctionCount,
        RMI4_F01_RMI_DEVICE_CONTROL);

    if (index == ControllerContext->FunctionCount)
    {
        Trace(
            TRACE_LEVEL_ERROR,
            TRACE_FLAG_POWER,
            "Power change failure - RMI Function 01 missing");

        status = STATUS_INVALID_DEVICE_STATE;
        goto exit;
    }

    status = RmiChangePage(
        ControllerContext,
        SpbContext,
        ControllerContext->FunctionOnPage[index]);

    if (!NT_SUCCESS(status))
    {
        Trace(
            TRACE_LEVEL_ERROR,
            TRACE_FLAG_POWER,
            "Could not change register page");

        goto exit;
    }

    //
    // Read Device Control register
    //
    status = SpbReadDataSynchronously(
        SpbContext,
        ControllerContext->Descriptors[index].ControlBase,
        &deviceControl,
        sizeof(deviceControl)
        );

    if (!NT_SUCCESS(status))
    {
        Trace(
            TRACE_LEVEL_ERROR,
            TRACE_FLAG_POWER,
            "Could not read sleep register - %!STATUS!",
            status);

        goto exit;
    }

    //
    // Assign new sleep state
    //
    controlF01->DeviceControl.SleepMode = SleepState;

    //
    // Write setting back to the controller
    //
    status = SpbWriteDataSynchronously(
        SpbContext,
        ControllerContext->Descriptors[index].ControlBase,
        &deviceControl,
        sizeof(deviceControl)
        );

    if (!NT_SUCCESS(status))
    {
        Trace(
            TRACE_LEVEL_ERROR,
            TRACE_FLAG_POWER,
            "Could not write sleep register - %X",
            status);

        goto exit;
    }

exit:

    return status;
}
Beispiel #6
0
NTSTATUS BOOTTRACKPAD(
	_In_  PDEVICE_CONTEXT  pDevice
	)
{
	if (deviceLoaded)
		return 0;

	NTSTATUS status = 0;

	FuncEntry(TRACE_FLAG_WDFLOADING);

	elan_i2c_write_cmd(pDevice, ETP_I2C_STAND_CMD, ETP_I2C_RESET);
	
	uint8_t val[256];
	SpbReadDataSynchronously(&pDevice->I2CContext, 0x00, &val, ETP_I2C_INF_LENGTH);

	SpbReadDataSynchronously16(&pDevice->I2CContext, ETP_I2C_DESC_CMD, &val, ETP_I2C_DESC_LENGTH);

	SpbReadDataSynchronously16(&pDevice->I2CContext, ETP_I2C_REPORT_DESC_CMD, &val, ETP_I2C_REPORT_DESC_LENGTH);

	elan_i2c_write_cmd(pDevice, ETP_I2C_SET_CMD, ETP_ENABLE_ABS);

	elan_i2c_write_cmd(pDevice, ETP_I2C_STAND_CMD, ETP_I2C_WAKE_UP);

	uint8_t val2[3];

	elan_i2c_read_cmd(pDevice, ETP_I2C_UNIQUEID_CMD, val2);
	uint8_t prodid = val2[0];

	elan_i2c_read_cmd(pDevice, ETP_I2C_FW_VERSION_CMD, val2);
	uint8_t version = val2[0];

	elan_i2c_read_cmd(pDevice, ETP_I2C_FW_CHECKSUM_CMD, val2);
	uint16_t csum = *((uint16_t *)val2);

	elan_i2c_read_cmd(pDevice, ETP_I2C_SM_VERSION_CMD, val2);
	uint8_t smvers = val2[0];

	elan_i2c_read_cmd(pDevice, ETP_I2C_IAP_VERSION_CMD, val2);
	uint8_t iapversion = val2[0];

	elan_i2c_read_cmd(pDevice, ETP_I2C_PRESSURE_CMD, val2);

	elan_i2c_read_cmd(pDevice, ETP_I2C_MAX_X_AXIS_CMD, val2);
	uint16_t max_x = (*((uint16_t *)val2)) & 0x0fff;

	elan_i2c_read_cmd(pDevice, ETP_I2C_MAX_Y_AXIS_CMD, val2);
	uint16_t max_y = (*((uint16_t *)val2)) & 0x0fff;

	elan_i2c_read_cmd(pDevice, ETP_I2C_XY_TRACENUM_CMD, val2);

	uint8_t x_traces = val2[0];
	uint8_t y_traces = val2[1];

	pDevice->max_y = max_y;

	csgesture_softc *sc = &pDevice->sc;
	sc->resx = max_x;
	sc->resy = max_y;
	sc->phyx = max_x / x_traces;
	sc->phyy = max_y / y_traces;

	ElanPrint(DEBUG_LEVEL_INFO, DBG_PNP, "[etp] ProdID: %d Vers: %d Csum: %d SmVers: %d IAPVers: %d Max X: %d Max Y: %d\n", prodid, version, csum, smvers, iapversion, max_x, max_y);

	elan_i2c_write_cmd(pDevice, ETP_I2C_SET_CMD, ETP_ENABLE_CALIBRATE | ETP_ENABLE_ABS);

	elan_i2c_write_cmd(pDevice, ETP_I2C_STAND_CMD, ETP_I2C_WAKE_UP);

	elan_i2c_write_cmd(pDevice, ETP_I2C_CALIBRATE_CMD, 1);

	SpbReadDataSynchronously16(&pDevice->I2CContext, ETP_I2C_CALIBRATE_CMD, &val2, 1);

	elan_i2c_write_cmd(pDevice, ETP_I2C_SET_CMD, ETP_ENABLE_ABS);

	deviceLoaded = true;

	FuncExit(TRACE_FLAG_WDFLOADING);
	return status;
}