NvBool NvOdmMouseEnableInterrupt(
    NvOdmMouseDeviceHandle hDevice, 
    NvOdmOsSemaphoreHandle hInterruptSemaphore)
{
    NvError Status = NvSuccess;
    NvEcEventType EventTypes[] = {
        (NvEcEventType) (NvEcEventType_AuxDevice0 + MOUSE_PS2_PORT_ID_0),
        (NvEcEventType) (NvEcEventType_AuxDevice0 + MOUSE_PS2_PORT_ID_1)
    };

    Status = NvEcRegisterForEvents(
        hDevice->hEc,
        &hDevice->hEcEventRegister,
        (NvOsSemaphoreHandle)hInterruptSemaphore,
        NV_ARRAY_SIZE(EventTypes), // number of EventType's
        EventTypes,                // Auxillary 0 event
        1,                         // One event packet is expected
        // event packet size = packet overhead + size of the mouse sample;
        // max sample size is 4 bytes (for an Intellimouse 5-button mouse)
        NVEC_MIN_EVENT_SIZE+4); 

    if (Status != NvSuccess)
        return NV_FALSE;

    return NV_TRUE;
}
NvBool NvOdmCirInit(void) /*jolen 0701*/
{
    NvError NvStatus = NvError_Success;

    /* get nvec handle */
    NvStatus = NvEcOpen(&s_NvEcHandle, 0 /* instance */);
    if (NvStatus != NvError_Success)
    {
        goto fail;
    }
    /* create semaphore which can be used to send scan codes to the clients */
    s_hCirKeyScanRecvSema = NvOdmOsSemaphoreCreate(0);
    if (!s_hCirKeyScanRecvSema)
    {
        goto cleanup;
    }

    /* register for CIR events */
    NvStatus = NvEcRegisterForEvents(
                    s_NvEcHandle,       // nvec handle
                    &s_hEcEventRegistration,
                    (NvOsSemaphoreHandle)s_hCirKeyScanRecvSema,
                    sizeof(EventTypes)/sizeof(NvEcEventType),
                    EventTypes, // receive Ir remote scan codes
                    1,          // currently buffer only 1 packet from ECI at a time
                    sizeof(NvEcEvent));
    if (NvStatus != NvError_Success)
    {
        goto cleanup;
    }

    /* success */
    return NV_TRUE;

cleanup:
    (void)NvEcUnregisterForEvents(s_hEcEventRegistration);
    s_hEcEventRegistration = NULL;

    NvOdmOsSemaphoreDestroy(s_hCirKeyScanRecvSema);
    s_hCirKeyScanRecvSema = NULL;

    NvEcClose(s_NvEcHandle);
fail:
    s_NvEcHandle = NULL;

    return NV_FALSE;
}
NvBool NvOdmKeyboardInit(void)
{
    NvError NvStatus = NvError_Success;
    NvEcRequest Request = {0};
    NvEcResponse Response = {0};

    /* get nvec handle */
    NvStatus = NvEcOpen(&s_NvEcHandle, 0 /* instance */);
    if (NvStatus != NvError_Success)
    {
        goto fail;
    }

    /* reset the EC to start the keyboard scanning */
    Request.PacketType = NvEcPacketType_Request;
    Request.RequestType = NvEcRequestResponseType_Keyboard;
    Request.RequestSubtype = (NvEcRequestResponseSubtype) NvEcKeyboardSubtype_Enable;
    Request.NumPayloadBytes = 0;

    NvStatus = NvEcSendRequest(s_NvEcHandle, &Request, &Response, sizeof(Request), sizeof(Response));
    if (NvStatus != NvError_Success)
    {
        goto cleanup;
    }

    /* check if command passed */
    if (Response.Status != NvEcStatus_Success)
    {
        goto cleanup;
    }

#if WAKE_FROM_KEYBOARD
	hOdm = NvOdmOsAlloc(sizeof(NvOdmKbdContext));
	if (!hOdm) {
		goto cleanup;
	}

	/* Check the supported GPIOs */
	hOdm->GpioPinInfo = NvOdmQueryGpioPinMap(NvOdmGpioPinGroup_EmbeddedController,
					0, &hOdm->PinCount);

	NvRmGpioAcquirePinHandle(s_hGpioGlobal,
		hOdm->GpioPinInfo->Port,
		hOdm->GpioPinInfo->Pin,
		&hOdm->hPin);
	if (!hOdm->hPin) {
		goto cleanup;
	}

	/* register to receive GPIO events */
	NvStatus = NvRmGpioInterruptRegister(s_hGpioGlobal,
		s_hRmGlobal,
		hOdm->hPin,
		(NvOsInterruptHandler)GpioInterruptHandler,
		NvRmGpioPinMode_InputData,
		hOdm,
		&hOdm->GpioIntrHandle,
		DEBOUNCE_TIME_MS);
	if (NvStatus != NvError_Success) {
		goto cleanup;
	}

	NvStatus = NvRmGpioInterruptEnable(hOdm->GpioIntrHandle);
	if (NvStatus != NvError_Success) {
		goto cleanup;
	}

	/* enable keyboard as wake up source */
	Request.PacketType = NvEcPacketType_Request;
	Request.RequestType = NvEcRequestResponseType_Keyboard;
	Request.RequestSubtype = (NvEcRequestResponseSubtype)
	NvEcKeyboardSubtype_ConfigureWake;
	Request.NumPayloadBytes = 2;
	Request.Payload[0] = NVEC_KEYBOARD_WAKE_ENABLE_0_ACTION_ENABLE;
	Request.Payload[1] = NVEC_KEYBOARD_EVENT_TYPE_0_ANY_KEY_PRESS_ENABLE;

	NvStatus = NvEcSendRequest(s_NvEcHandle,
		&Request,
		&Response,
		sizeof(Request),
		sizeof(Response));
	if (NvStatus != NvError_Success) {
		goto cleanup;
        }

	if (Response.Status != NvEcStatus_Success) {
		goto cleanup;
	}

        /* enable key reporting on wake up */
	Request.PacketType = NvEcPacketType_Request;
	Request.RequestType = NvEcRequestResponseType_Keyboard;
	Request.RequestSubtype = (NvEcRequestResponseSubtype)
	NvEcKeyboardSubtype_ConfigureWakeKeyReport;
	Request.NumPayloadBytes = 1;
	Request.Payload[0] = NVEC_KEYBOARD_REPORT_WAKE_KEY_0_ACTION_ENABLE;

	NvStatus = NvEcSendRequest(s_NvEcHandle,
		&Request,
		&Response,
		sizeof(Request),
		sizeof(Response));
	if (NvStatus != NvError_Success) {
		goto cleanup;
        }

	if (Response.Status != NvEcStatus_Success) {
		goto cleanup;
	}
#endif

    /* create semaphore which can be used to send scan codes to the clients */
    s_hKbcKeyScanRecvSema = NvOdmOsSemaphoreCreate(0);
    if (!s_hKbcKeyScanRecvSema)
    {
        goto cleanup;
    }

    /* register for keyboard events */
    NvStatus = NvEcRegisterForEvents(
                    s_NvEcHandle,       // nvec handle
                    &s_hEcEventRegistration,
                    (NvOsSemaphoreHandle)s_hKbcKeyScanRecvSema,
                    sizeof(EventTypes)/sizeof(NvEcEventType),
                    EventTypes, // receive keyboard scan codes
                    1,          // currently buffer only 1 packet from ECI at a time
                    sizeof(NvEcEvent));
    if (NvStatus != NvError_Success)
    {
        goto cleanup;
    }

    /* success */
    return NV_TRUE;

cleanup:
#if WAKE_FROM_KEYBOARD
	NvRmGpioInterruptUnregister(s_hGpioGlobal, s_hRmGlobal, hOdm->GpioIntrHandle);
	hOdm->GpioIntrHandle = NULL;
	NvRmGpioReleasePinHandles(s_hGpioGlobal, &hOdm->hPin, hOdm->PinCount);
	NvOdmOsFree(hOdm);
	hOdm = NULL;
#endif
    (void)NvEcUnregisterForEvents(s_hEcEventRegistration);
    s_hEcEventRegistration = NULL;

    NvOdmOsSemaphoreDestroy(s_hKbcKeyScanRecvSema);
    s_hKbcKeyScanRecvSema = NULL;

    NvEcClose(s_NvEcHandle);
fail:
    s_NvEcHandle = NULL;

    return NV_FALSE;
}