NvBool Synaptics_OneTouch_EnableInterrupt (NvOdmOneTouchDeviceHandle hDevice, NvOdmOsSemaphoreHandle hIntSema)
{
	Synaptics_OneTouch_Device* hTouch = (Synaptics_OneTouch_Device*)hDevice;

	NV_ASSERT(hIntSema);

	NVODMTOUCH_PRINTF(("[ONETOUCH] Synaptics_OneTouch_EnableInterrupt\n"));

	/* can only be initialized once */
	if (hTouch->hGpioIntr || hTouch->hIntSema)
		return NV_FALSE;

	hTouch->hIntSema = hIntSema;    

	if (NvOdmGpioInterruptRegister(hTouch->hGpio, &hTouch->hGpioIntr,
		hTouch->hPin, NvOdmGpioPinMode_InputInterruptLow, Synaptics_OneTouch_GpioIsr,
		(void*)hTouch, SYNAPTICS_DEBOUNCE_TIME_MS) == NV_FALSE)
	{
		NVODMTOUCH_PRINTF(("[ONETOUCH] cannot register interrupt.\n"));
		return NV_FALSE;
	}

	if (!hTouch->hGpioIntr)
		return NV_FALSE;    

	return NV_TRUE;
}
static NvBool Synaptics_OneTouch_GetSamples (Synaptics_OneTouch_Device* hTouch, NvOdmOneTouchButtonInfo* button)
{
	NVODMTOUCH_PRINTF(("[ONETOUCH] Synaptics_OneTouch_GetSamples [START]\n"));

	if (!Synaptics_OneTouch_ReadRegisterSafe (hTouch, (NvU8*)(&pOneTouchDataRegs), sizeof(pOneTouchDataRegs)))
	{
		NVODMTOUCH_PRINTF(("[Touch Driver] Error read register info using I2C\n"));
		return NV_FALSE;
	}

	printk("[ONETOUCH] pOneTouchDataRegs %d, %d, %d, %d\n", pOneTouchDataRegs[0], pOneTouchDataRegs[1], pOneTouchDataRegs[2], pOneTouchDataRegs[3]);
	if(pOneTouchDataRegs[1] &0x8)
		button->back = NV_TRUE;
	else 
		button->back = NV_FALSE;

	if(pOneTouchDataRegs[1] &0x1)
		button->menu = NV_TRUE; 	
	else
		button->menu = NV_FALSE; 	


//	Synaptics_OneTouch_WriteRegisterMulti(hTouch, pButtonBuffer, 4);
	
	Synaptics_OneTouch_SetReadAddr(hTouch); 

	//NVODMTOUCH_PRINTF(("[Touch Driver] Synaptics_OneTouch_GetSamples [END]\n"));

	return NV_TRUE;
}
static NvBool Synaptics_OneTouch_ReadRegisterOnce (Synaptics_OneTouch_Device* hTouch, NvU8* buffer, NvU32 len)
{
	int i=0;
	NvOdmI2cStatus Error = NvOdmI2cStatus_Timeout;
	NvOdmI2cTransactionInfo TransactionInfo;
        
    TransactionInfo.Address = hTouch->DeviceAddr | 0x1;	//read
    TransactionInfo.Buf = buffer;
    TransactionInfo.Flags = 0;
    TransactionInfo.NumBytes = len;

	for (i = 0; i < SYNAPTICS_I2C_RETRY_COUNT && Error != NvOdmI2cStatus_Success; i++)
	{
    	Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
                                &TransactionInfo,
                                1,		// transactioncnt
                                SYNAPTICS_I2C_SPEED_KHZ,
                                SYNAPTICS_I2C_TIMEOUT);
	}

	if (Error != NvOdmI2cStatus_Success)
	{
		NVODMTOUCH_PRINTF(("[ONETOUCH] I2C Read Failure = %d (addr=0x%x)\n", Error, hTouch->DeviceAddr));
		return NV_FALSE;
	}

	return NV_TRUE;
}
// set register address before read
static NvBool Synaptics_OneTouch_SetReadAddr (Synaptics_OneTouch_Device* hTouch)
{
	int i=0;
	NvOdmI2cStatus Error = NvOdmI2cStatus_Timeout;
	NvOdmI2cTransactionInfo TransactionInfo;

	NvU8 pReg[2];
	
	pReg[0]	=	OT_DATA_REG_START_ADDR_HIGH;
	pReg[1]	=	OT_DATA_REG_START_ADDR_LOW;
	
	// set register address
	TransactionInfo.Address = hTouch->DeviceAddr;
	TransactionInfo.Buf = (NvU8*)&pReg;
    TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
    TransactionInfo.NumBytes = 2;

	for (i = 0; i < SYNAPTICS_I2C_RETRY_COUNT && Error != NvOdmI2cStatus_Success; i++)
	{
		Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
                                    &TransactionInfo,
                                    1,
                                    SYNAPTICS_I2C_SPEED_KHZ,
                                    SYNAPTICS_I2C_TIMEOUT);
	}

	if (Error != NvOdmI2cStatus_Success)
	{
		NVODMTOUCH_PRINTF(("[ONETOUCH] I2C Write Failure = %d (addr=0x%x)\n", Error, hTouch->DeviceAddr));
		return NV_FALSE;
	}

	return NV_TRUE;
}
// setting register
static NvBool Synaptics_OneTouch_WriteRegister (Synaptics_OneTouch_Device* hTouch, NvU8 val)
{
	int i=0;
	NvOdmI2cStatus Error = NvOdmI2cStatus_Timeout;
    NvOdmI2cTransactionInfo TransactionInfo;
    NvU8 arr[1];

    arr[0] = val;		// register address
    
    TransactionInfo.Address = hTouch->DeviceAddr;
    TransactionInfo.Buf = arr;
    TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
    TransactionInfo.NumBytes = 1;
    
	for (i = 0; i < SYNAPTICS_I2C_RETRY_COUNT && Error != NvOdmI2cStatus_Success; i++)
    {
        Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
                                    &TransactionInfo,
                                    1,
                                    SYNAPTICS_I2C_SPEED_KHZ,
                                    SYNAPTICS_I2C_TIMEOUT);
	}

    if (Error != NvOdmI2cStatus_Success)
    {
        NVODMTOUCH_PRINTF(("[ONETOUCH] I2C Write Failure = %d (addr=0x%x, val=0x%0x)\n", Error, hTouch->DeviceAddr, val));
        return NV_FALSE;
    }

    return NV_TRUE;
}
void Synaptics_OneTouch_Close (NvOdmOneTouchDeviceHandle hDevice)
{
    Synaptics_OneTouch_Device* hTouch = (Synaptics_OneTouch_Device*)hDevice;
	NVODMTOUCH_PRINTF(("[Touch Driver] Synaptics_OneTouch_Close\n"));

    if (!hTouch) return;

// 20101120 [email protected] power off when Onetouch close    
#if defined(CONFIG_MACH_STAR_SKT_REV_E) || defined(CONFIG_MACH_STAR_SKT_REV_F)
    Synaptics_OneTouch_PowerOnOff(&hTouch->OdmOneTouch, NV_FALSE);
#endif 

    if (hTouch->hGpio)
    {
        if (hTouch->hPin)
        {
            if (hTouch->hGpioIntr)
                NvOdmGpioInterruptUnregister(hTouch->hGpio, hTouch->hPin, hTouch->hGpioIntr);

            NvOdmGpioReleasePinHandle(hTouch->hGpio, hTouch->hPin);
        }

        NvOdmGpioClose(hTouch->hGpio);
    }

    if (hTouch->hOdmI2c)
        NvOdmI2cClose(hTouch->hOdmI2c);

    NvOdmOsFree(hTouch);
}
static NvBool TPK_WriteRegister (TPK_TouchDevice* hTouch, NvU8 reg, NvU8 val)
{
    NvOdmI2cStatus Error;
    NvOdmI2cTransactionInfo TransactionInfo;
    NvU8 arr[2];
#if TPK_ADL340_WAR    
    // dummy write
    Error = NvAccDummyI2CSetRegs(hTouch);
#endif
    arr[0] = reg;
    arr[1] = val;
    
    TransactionInfo.Address = hTouch->DeviceAddr;
    TransactionInfo.Buf = arr;
    TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
    TransactionInfo.NumBytes = 2;
    
    do
    {
        Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
                                    &TransactionInfo,
                                    1,
                                    hTouch->I2cClockSpeedKHz,
                                    TPK_I2C_TIMEOUT);
    } while (Error == NvOdmI2cStatus_Timeout); 

    if (Error != NvOdmI2cStatus_Success)
    {
        NVODMTOUCH_PRINTF(("I2C Write Failure = %d (addr=0x%x, reg=0x%x, val=0x%0x)\n", Error, 
                           hTouch->DeviceAddr, reg, val));
        return NV_FALSE;
    }
    return NV_TRUE;
}
static NvBool TPK_ReadRegisterOnce (TPK_TouchDevice* hTouch, NvU8 reg, NvU8* buffer, NvU32 len)
{
    NvOdmI2cStatus Error;
    NvOdmI2cTransactionInfo TransactionInfo[2 * TPK_MAX_READS];
    int reads = (len+(TPK_MAX_PACKET_SIZE-1))/TPK_MAX_PACKET_SIZE;
    int left = len;
    int i;
    
    NV_ASSERT(len <= TPK_MAX_READ_BYTES);
#if TPK_ADL340_WAR    
    // dummy write
    Error = NvAccDummyI2CSetRegs(hTouch);
#endif
    ////////////////////////////////////////////////////////////////////////////
    // For multi-byte reads, the TPK panel supports just sending the first
    // address and then keep reading registers (non-standard SMBus operation).
    // The limit for I2C packets is 8 bytes, so we read up to 8 bytes per
    // multi-byte read transaction.
    ////////////////////////////////////////////////////////////////////////////

    for (i = 0; i < reads; i++)
    {
        int ind = i*2;

        TransactionInfo[ind].Address = hTouch->DeviceAddr;
        TransactionInfo[ind].Buf = &reg;
        TransactionInfo[ind].Flags = NVODM_I2C_IS_WRITE;
        TransactionInfo[ind].NumBytes = 1;

        ind++;

        TransactionInfo[ind].Address = hTouch->DeviceAddr | 0x1;
        TransactionInfo[ind].Buf = buffer + i*TPK_MAX_PACKET_SIZE;
        TransactionInfo[ind].Flags = 0;
        TransactionInfo[ind].NumBytes =
            left > TPK_MAX_PACKET_SIZE ? TPK_MAX_PACKET_SIZE : left;
        
        left -= TPK_MAX_PACKET_SIZE;
    }
    
    do
    {
        Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
                                    TransactionInfo,
                                    reads * 2,
                                    hTouch->I2cClockSpeedKHz,
                                    TPK_I2C_TIMEOUT);
    } while (Error == NvOdmI2cStatus_Timeout);

    if (Error != NvOdmI2cStatus_Success)
    {
        NVODMTOUCH_PRINTF(("I2C Read Failure = %d (addr=0x%x, reg=0x%x)\n", Error,
                           hTouch->DeviceAddr, reg));
        return NV_FALSE;
    }

    return NV_TRUE;
}
static void Synaptics_OneTouch_GpioIsr(void *arg)
{
    Synaptics_OneTouch_Device* hTouch = (Synaptics_OneTouch_Device*)arg;
	NVODMTOUCH_PRINTF(("[ONETOUCH] Synaptics_OneTouch_GpioIsr\n"));

    /* Signal the touch thread to read the sample. After it is done reading the
        * sample it should re-enable the interrupt. */
    NvOdmOsSemaphoreSignal(hTouch->hIntSema);
}
NvBool Synaptics_OneTouch_HandleInterrupt(NvOdmOneTouchDeviceHandle hDevice)
{
	Synaptics_OneTouch_Device* hTouch = (Synaptics_OneTouch_Device*)hDevice;

	NVODMTOUCH_PRINTF(("[ONETOUCH] Synaptics_OneTouch_HandleInterrupt\n"));

	NvOdmGpioInterruptDone(hTouch->hGpioIntr);

    return NV_TRUE;
}
static NvBool Synaptics_OneTouch_Init(Synaptics_OneTouch_Device* hTouch)
{
	NvU8 pBuffer[OT_NUM_CONFIG_BYTES];
	NvU8 bTemp;

	NvOdmOsMemset(pBuffer, 0, sizeof(pBuffer));

	if(hTouch == NULL)
	{
		NVODMTOUCH_PRINTF(("[ONETOUCH] Synaptics Driver Initialize Fail\n"));
		return NV_FALSE;
	}

	//	Write the configuration to the OneTouch
	if(!Synaptics_OneTouch_WriteRegisterMulti(hTouch, g_OT_Config, OT_NUM_CONFIG_BYTES))
	{
		NVODMTOUCH_PRINTF(("[ONETOUCH] Fail Write the configuration to the OneTouch\n" ));
		return NV_FALSE;
	}

	// read the entire configuration back from the device	
	if(!Synaptics_OneTouch_ReadRegisterSafe(hTouch, pBuffer, OT_NUM_CONFIG_BYTES -2))
	{
		NVODMTOUCH_PRINTF(("[ONETOUCH] Fail read the entire configuration back from the devicen"));
		return NV_FALSE;	

	}
	// verify the configuration registers are written correctly
	for(bTemp=0; bTemp < (OT_NUM_CONFIG_BYTES-2); bTemp++)
	{
	  NVODMTOUCH_PRINTF(("[ONETOUCH] pBuffer[%d]=%d == g_OT_Config[%d]=%d \n", bTemp, pBuffer[bTemp], bTemp, g_OT_Config[bTemp+2]));
		if(pBuffer[bTemp] != g_OT_Config[bTemp+2])
			return NV_FALSE;
	}
	// set base address
	Synaptics_OneTouch_SetReadAddr(hTouch);

	// read the data register to deassert the attention line
	Synaptics_OneTouch_ReadRegisterSafe(hTouch, pBuffer, 1);
	
	return NV_TRUE;
}
NvBool Synaptics_OneTouch_SleepMode (NvOdmOneTouchDeviceHandle hDevice, NvBool OnOff)
{
//	NvU8 pBuffer[OT_NUM_CONFIG_BYTES];

	Synaptics_OneTouch_Device* hTouch = (Synaptics_OneTouch_Device*)hDevice;

	NvU8 mode_buf[4];
	
	NVODMTOUCH_PRINTF(("[ONETOUCH] Synaptics_OneTouch_SleepMode\n"));
	NVODMTOUCH_PRINTF(("[ONETOUCH] sleep mode [%d]\n", OnOff));	

	mode_buf[0] = OT_DATA_REG_SLEEP_ADDR_HIGH;
	mode_buf[1] = OT_DATA_REG_SLEEP_ADDR_LOW;

  if (OnOff)
  {
		mode_buf[2] = OT_DATA_REG_SLEEP_DATA_HIGH;
		mode_buf[3] = OT_DATA_REG_SLEEP_DATA_LOW;		
	}
	else 
	{
		mode_buf[2] = OT_DATA_REG_ACTIVE_DATA_HIGH;
		mode_buf[3] = OT_DATA_REG_ACTIVE_DATA_LOW;		
	}
	
	if(!Synaptics_OneTouch_WriteRegisterMulti(hTouch, mode_buf, sizeof(mode_buf)))
	{
		NVODMTOUCH_PRINTF(("[ONETOUCH] Error write SleepMode regs\n"));
		return NV_FALSE;
	}
#if 0
	// read the entire configuration back from the device	
	if(!Synaptics_OneTouch_ReadRegisterSafe(hTouch, pBuffer, OT_NUM_CONFIG_BYTES -2))
	{
		NVODMTOUCH_PRINTF(("[ONETOUCH] Fail read the entire configuration back from the devicen"));
		return NV_FALSE;	
	}
#endif
	Synaptics_OneTouch_SetReadAddr(hTouch); 

  return NV_TRUE;
}
NvBool Synaptics_OneTouch_ReadButton (NvOdmOneTouchDeviceHandle hDevice, NvOdmOneTouchButtonInfo* button)
{
	Synaptics_OneTouch_Device* hTouch = (Synaptics_OneTouch_Device*)hDevice;

	NVODMTOUCH_PRINTF(("[ONETOUCH] Synaptics_OneTouch_ReadButton\n"));

	if (Synaptics_OneTouch_GetSamples(hTouch, button)==NV_FALSE)
		return NV_FALSE;

	return NV_TRUE;
}
// setting register
static NvBool Synaptics_OneTouch_WriteRegisterMulti(Synaptics_OneTouch_Device* hTouch, NvU8* buffer, NvU32 len)
{
	int i=0;
	NvOdmI2cStatus Error = NvOdmI2cStatus_Timeout;
    NvOdmI2cTransactionInfo TransactionInfo;
    NvU8 *arr;

    arr = (NvU8*)NvOdmOsAlloc(len);
    if(arr ==NULL)
    {
    	NVODMTOUCH_PRINTF(("[ONETOUCH] cannot alloc memory (len=%d)\n",len));
		return NV_FALSE;
    }

    NvOdmOsMemcpy(&arr[0], buffer, len);// register address
    
    TransactionInfo.Address = hTouch->DeviceAddr;
    TransactionInfo.Buf = arr;
    TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
    TransactionInfo.NumBytes = len;
    
	for (i = 0; i < SYNAPTICS_I2C_RETRY_COUNT && Error != NvOdmI2cStatus_Success; i++)
    {
        Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
                                    &TransactionInfo,
                                    1,
                                    SYNAPTICS_I2C_SPEED_KHZ,
                                    SYNAPTICS_I2C_TIMEOUT);
	}
    
    NvOdmOsFree(arr);
    
    if (Error != NvOdmI2cStatus_Success)
    {
        NVODMTOUCH_PRINTF(("[ONETOUCH] I2C Write Failure = %d (addr=0x%x)\n", Error, hTouch->DeviceAddr));
        return NV_FALSE;
    }
    
    return NV_TRUE;
}
示例#15
0
NvBool EETI_ReadCoordinate (NvOdmTouchDeviceHandle hDevice, NvOdmTouchCoordinateInfo* coord) {
    EETI_TouchDevice* hTouch = (EETI_TouchDevice*)hDevice;

#if EETI_BENCHMARK_SAMPLE    
    NvU32 time = NvOdmOsGetTimeMS();
#endif
    NVODMTOUCH_PRINTF(("GpioIst+\n"));

    EETI_GetSample(hTouch, coord);


#if EETI_BENCHMARK_SAMPLE    
    NvOdmOsDebugPrintf("Touch sample time %d\n", NvOdmOsGetTimeMS() - time);
#endif

    return NV_TRUE;
}
示例#16
0
NvBool EETI_GetCalibrationData(NvOdmTouchDeviceHandle hDevice, NvU32 NumOfCalibrationData, NvS32* pRawCoordBuffer) {
#if EETI_SCREEN_ANGLE
    //Portrait
    static const NvS32 RawCoordBuffer[] = {2054, 3624, 3937, 809, 3832, 6546, 453, 6528, 231, 890};
#else
    //Landscape
    static NvS32 RawCoordBuffer[] = {2054, 3624, 3832, 6546, 453, 6528, 231, 890, 3937, 809};
#endif

    if (NumOfCalibrationData*2 != (sizeof(RawCoordBuffer)/sizeof(NvS32))) {
        NVODMTOUCH_PRINTF(("WARNING: number of calibration data isn't matched\n"));
        return NV_FALSE;
    }

    NvOdmOsMemcpy(pRawCoordBuffer, RawCoordBuffer, sizeof(RawCoordBuffer));

    return NV_TRUE;
}
示例#17
0
NvBool EETI_Open (NvOdmTouchDeviceHandle* hDevice) {
    EETI_TouchDevice* hTouch;
    NvU32 i;
    NvU32 found = 0;
    NvU32 GpioPort = 0;
    NvU32 GpioPin = 0;
    NvU32 I2cInstance = 0;



    const NvOdmPeripheralConnectivity *pConnectivity = NULL;

    hTouch = NvOdmOsAlloc(sizeof(EETI_TouchDevice));
    if (!hTouch) return NV_FALSE;

    NvOdmOsMemset(hTouch, 0, sizeof(EETI_TouchDevice));
    NvOdmOsMemset(tempReport, 0, sizeof(struct fingerReport_s) * 4);

    /* set function pointers */
    InitOdmTouch(&hTouch->OdmTouch);

    pConnectivity = NvOdmPeripheralGetGuid(EETI_TOUCH_DEVICE_GUID);
    if (!pConnectivity) {
        NVODMTOUCH_PRINTF(("NvOdm Touch : pConnectivity is NULL Error \n"));
        goto fail;
    }

    if (pConnectivity->Class != NvOdmPeripheralClass_HCI) {
        NVODMTOUCH_PRINTF(("NvOdm Touch : didn't find any periperal in discovery query for touch device Error \n"));
        goto fail;
    }

    for (i = 0; i < pConnectivity->NumAddress; i++) {
        switch (pConnectivity->AddressList[i].Interface) {
        case NvOdmIoModule_I2c:
            hTouch->DeviceAddr = (pConnectivity->AddressList[i].Address << 1);
            I2cInstance = pConnectivity->AddressList[i].Instance;
            found |= 1;
            break;
        case NvOdmIoModule_Gpio:
            GpioPort = pConnectivity->AddressList[i].Instance;
            GpioPin = pConnectivity->AddressList[i].Address;
            found |= 2;
            break;
        case NvOdmIoModule_Vdd:
            hTouch->VddId = pConnectivity->AddressList[i].Address;
            found |= 4;
            break;
        default:
            break;
        }
    }

    if ((found & 3) != 3) {
        NVODMTOUCH_PRINTF(("NvOdm Touch : peripheral connectivity problem \n"));
        goto fail;
    }

    if ((found & 4) != 0) {
        if (NV_FALSE == EETI_PowerOnOff(&hTouch->OdmTouch, 1))
            goto fail;
    } else {
        hTouch->VddId = 0xFF; 
    }

    hTouch->hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c, I2cInstance);
    if (!hTouch->hOdmI2c) {
        NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmI2cOpen Error \n"));
        goto fail;
    }

    hTouch->hGpio = NvOdmGpioOpen();

    if (!hTouch->hGpio) {
        NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmGpioOpen Error \n"));
        goto fail;
    }

    hTouch->hPin = NvOdmGpioAcquirePinHandle(hTouch->hGpio, GpioPort, GpioPin);
    if (!hTouch->hPin) {
        NVODMTOUCH_PRINTF(("NvOdm Touch : Couldn't get GPIO pin \n"));
        goto fail;
    }

    NvOdmGpioConfig(hTouch->hGpio,
                    hTouch->hPin,
                    NvOdmGpioPinMode_InputData);

    NvOdmGpioGetState(hTouch->hGpio, hTouch->hPin, &i);

    /* set default capabilities */
    NvOdmOsMemcpy(&hTouch->Caps, &EETI_Capabilities, sizeof(NvOdmTouchCapabilities));

    /* set default I2C speed */
    hTouch->I2cClockSpeedKHz = EETI_I2C_SPEED_KHZ;
#if 1
    if (EETI_ProbeTouchDevice (hTouch) != NV_TRUE) {
        NvOdmOsPrintf("NvOdm Touch : Multitouch detection failure \n");
        goto fail;
    }
#endif
    hTouch->Caps.XMaxPosition = 32767;
    hTouch->Caps.YMaxPosition = 32767;

    *hDevice = &hTouch->OdmTouch;
    return NV_TRUE;

    fail:
    EETI_Close(&hTouch->OdmTouch);
    return NV_FALSE;
}
static NvBool TPK_GetSample (TPK_TouchDevice* hTouch, NvOdmTouchCoordinateInfo* coord)
{
    NvU8 Finger0[6] = {0};
    NvU8 Finger1[6] = {0};
    NvU8 Relative[2] = {0};
    int status = 0;

    NVODMTOUCH_PRINTF(("TPK_GetSample+\n"));
    coord->fingerstate = NvOdmTouchSampleIgnore;

    if (!TPK_ReadRegisterOnce(hTouch, TPK_DATA_0, Finger0, 6))
        return NV_FALSE;
    else
        status = (Finger0[0] & 0x7);

    if (!TPK_ReadRegisterOnce(hTouch, TPK_DATA_0+6, Finger1, 6))
        return NV_FALSE;

    if (!TPK_ReadRegisterOnce(hTouch, TPK_DATA_0+12, Relative, 2))
        return NV_FALSE; 

    /* tell windows to ignore transitional finger count samples */
    coord->fingerstate = (status > 2) ? NvOdmTouchSampleIgnore : NvOdmTouchSampleValidFlag;
    coord->additionalInfo.Fingers = status;

    if (Finger0[0] & 0x8)
        // Bit 3 of status indicates a tap. Driver still doesn't expose
        // gesture capabilities. This is added more for testing of the support
        // in the hardware for gesture support.
    {
        coord->additionalInfo.Gesture = NvOdmTouchGesture_Tap;
        // NvOdmOsDebugPrintf("Detected the Tap gesture\n");
    }

    if (status)
    {
        /* always read first finger data, even if transitional */
        coord->fingerstate |= NvOdmTouchSampleDownFlag;

        coord->xcoord =
        coord->additionalInfo.multi_XYCoords[0][0] =
            (((NvU16)Finger0[2] & 0x1f) << 8) | (NvU16)Finger0[3];

        coord->ycoord =
        coord->additionalInfo.multi_XYCoords[0][1] =
            (((NvU16)Finger0[4] & 0x1f) << 8) | (NvU16)Finger0[5];

        coord->additionalInfo.width[0] = Finger0[0] >> 4;
        coord->additionalInfo.Pressure[0] = Finger0[1];

        /* only read second finger data if reported */
        if (status == 2)
        {
            coord->additionalInfo.multi_XYCoords[1][0] =
                (((NvU16)Finger1[2] & 0x1f) << 8) | (NvU16)Finger1[3];

            coord->additionalInfo.multi_XYCoords[1][1] =
            (((NvU16)Finger1[4] & 0x1f) << 8) | (NvU16)Finger1[5];

            /* these are not supported, zero out just in case */
            coord->additionalInfo.width[1] = 0;
            coord->additionalInfo.Pressure[1] = 0;
            if ( coord->additionalInfo.multi_XYCoords[1][0] <= 0 ||
                coord->additionalInfo.multi_XYCoords[1][0] >= hTouch->Caps.XMaxPosition ||
                coord->additionalInfo.multi_XYCoords[1][1] <= 0 || 
                coord->additionalInfo.multi_XYCoords[1][1] >= hTouch->Caps.YMaxPosition)
                coord->fingerstate = NvOdmTouchSampleIgnore;
#if TPK_REPORT_2ND_FINGER_DATA
            else
                NvOdmOsDebugPrintf("catch 2 fingers width=0x%x, X=%d, Y=%d, DeltaX=%d, DeltaY=%d\n",
                                    coord->additionalInfo.width[0],
                                    coord->additionalInfo.multi_XYCoords[1][0],
                                    coord->additionalInfo.multi_XYCoords[1][1],
                                    Relative[0], Relative[1]);
#endif
        }
    }
    else if (!hTouch->PrevFingers)
NvBool Synaptics_OneTouch_Open (NvOdmOneTouchDeviceHandle* hDevice, NvOdmOsSemaphoreHandle* hIntSema)
{
    Synaptics_OneTouch_Device* hTouch = (Synaptics_OneTouch_Device*)0;
    NvU32 i;
    NvU32 found = 0;
    NvU32 I2cInstance = 0;
    const NvOdmPeripheralConnectivity *pConnectivity = NULL;

    NVODMTOUCH_PRINTF(("[Touch Driver] Synaptics_OneTouch_Open\n"));
		
    hTouch = NvOdmOsAlloc(sizeof(Synaptics_OneTouch_Device));

    if (!hTouch) return NV_FALSE;

    NvOdmOsMemset(hTouch, 0, sizeof(Synaptics_OneTouch_Device));

    /* set function pointers */
    Synaptics_OneTouch_InitOdmTouch(&hTouch->OdmOneTouch);

    pConnectivity = NvOdmPeripheralGetGuid(SYNAPTICS_ONETOUCH_DEVICE_GUID);
    if (!pConnectivity)
    {
        NVODMTOUCH_PRINTF(("[ONETOUCH] NvOdm Touch : pConnectivity is NULL Error \n"));
        goto fail;
    }

    if (pConnectivity->Class != NvOdmPeripheralClass_HCI)
    {
        NVODMTOUCH_PRINTF(("[ONETOUCH] NvOdm Touch : didn't find any periperal in discovery query for touch device Error \n"));
        goto fail;
    }

    for (i = 0; i < pConnectivity->NumAddress; i++)
    {
        switch (pConnectivity->AddressList[i].Interface)
        {
            case NvOdmIoModule_I2c:
                hTouch->DeviceAddr = (pConnectivity->AddressList[i].Address << 1);
                hTouch->I2CInstance = pConnectivity->AddressList[i].Instance;
                found |= 1;

                NVODMTOUCH_PRINTF(("[ONETOUCH] i2c address = %x.\n", hTouch->DeviceAddr));
                break;
            case NvOdmIoModule_Gpio:
                hTouch->GpioPort = pConnectivity->AddressList[i].Instance;
                hTouch->GpioPin = pConnectivity->AddressList[i].Address;
                found |= 2;
                break;
            case NvOdmIoModule_Vdd:
                hTouch->VddId = pConnectivity->AddressList[i].Address;
                found |= 4;
                break;
			case NvOdmIoModule_I2c_Pmu:
				hTouch->I2cVddId = pConnectivity->AddressList[i].Address;
				break;
            default:
                break;
        }
    }

    if ((found & 3) != 3)
    {
        NVODMTOUCH_PRINTF(("[ONETOUCH] NvOdm Touch : peripheral connectivity problem \n"));
        goto fail;
    }

    if ((found & 4) != 0)
    {
// 20101120 [email protected] power off when Onetouch close    
#if defined(CONFIG_MACH_STAR_SKT_REV_E) || defined(CONFIG_MACH_STAR_SKT_REV_F)
        if (NV_FALSE == Synaptics_OneTouch_PowerOnOff(&hTouch->OdmOneTouch, 1))
	    	goto fail;   
#endif 
    }
    else
    {
        NVODMTOUCH_PRINTF(("[ONETOUCH] Synaptics Power fail \n"));
        hTouch->VddId = 0xFF; 
    }

    hTouch->hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c, I2cInstance);
    if (!hTouch->hOdmI2c)
    {
        NVODMTOUCH_PRINTF(("[ONETOUCH] NvOdm Touch : NvOdmI2cOpen Error \n"));
        goto fail;
    }

    hTouch->hGpio = NvOdmGpioOpen();

    if (!hTouch->hGpio)
    {        
        NVODMTOUCH_PRINTF(("[ONETOUCH] NvOdm Touch : NvOdmGpioOpen Error \n"));
        goto fail;
    }

    NVODMTOUCH_PRINTF(("[ONETOUCH] gpio port = %d. gpio pin = %d\n", hTouch->GpioPort, hTouch->GpioPin));
    hTouch->hPin = NvOdmGpioAcquirePinHandle(hTouch->hGpio, hTouch->GpioPort, hTouch->GpioPin);
    if (!hTouch->hPin)
    {
        NVODMTOUCH_PRINTF(("[ONETOUCH] NvOdm Touch : Couldn't get GPIO pin \n"));
        goto fail;
    }

    NvOdmGpioConfig(hTouch->hGpio,
                    hTouch->hPin,
                    NvOdmGpioPinMode_InputData);

    /* set default I2C speed */
    hTouch->I2cClockSpeedKHz = SYNAPTICS_I2C_SPEED_KHZ;
    NVODMTOUCH_PRINTF(("[ONETOUCH] i2c speed = %d\n", hTouch->I2cClockSpeedKHz));
	
    /* initialize */
    if(!Synaptics_OneTouch_Init(hTouch))	 goto fail;

    *hDevice = &hTouch->OdmOneTouch;
    if (Synaptics_OneTouch_EnableInterrupt(*hDevice, *hIntSema) == NV_FALSE)
          goto fail;

    return NV_TRUE;

 fail:
    Synaptics_OneTouch_Close(&hTouch->OdmOneTouch);
    return NV_FALSE;
}