//
//                  SAMSUNG ELECTRONICS
//                  Copyright(C) 2008
//                  ALL RIGHTS RESERVED
//
// This program is proprietary to Samsung Electronics,and is protected under International
// Copyright Act as an unpublished work.Its use and disclosure is limited by the terms and
// conditions of a license agreement.  It may not  be copied  or  otherwise   reproduced or
// disclosed  to persons  outside  the  licensee's   organization  except  in  accordance with
// the  terms and conditions  of such  an agreement. All copies and  reproductions shall be
// the property of  Samsung  Electronics  and  must bear this  notice in its entirety.
//

//
//  File name : tsp.cpp
//
//  Descriptions : This file contains HW Dependent code for Touch.
//

#ifndef _TSP_H_
#define _TSP_H_


//____________________________________INCLUDE FUNCTION________________________
#define TCH_FUNC 1
#define TCH_DBG 1
#define TCH_XY 1



// Global include
#include <windows.h>
#include <types.h>
#include <ceddk.h>
#include <ddkreg.h>
#include <tchddsi.h>

// BSP include
#include <bsp.h>

//Touch Button
#include <winuserm.h>

// Driver libraries
#include <drvmsg.h>
#include <drvlib_wait.h>
#include <drvlib_mem.h>

// Power management
#include <pm.h>
#include <pmplatform.h>


// TODO : The dual touch support is not implemented yet.
//        Two channels can't be selected at once. Use only one channel.


#if (BSP_TOUCH_TYPE == 0)
	#define TSP_CH0
#elif (BSP_TOUCH_TYPE == 1)
	#define TSP_CH1
#elif (BSP_TOUCH_TYPE == 2)
	#define TSP_QT602240
#else
	#error Unsupported target board!
#endif


//____________________________________DEFINITIONS_____________________________
#define TSPMSG(x, y) DBGMSG(x, (TEXT("[TSP] : "))); DBGMSG(x, y);
#define TSPERR(x, y) ERRMSG((TEXT("[TSP:ERR] : "))); ERRMSG(y);




// Detailed sampling
//#define DETAIL_SAMPLING //lkb del, lkb?

#define TOUCH_DEV                       0x2
#define TIMER_DEV                       0x1


#define PEN_DOWN						0
#define PEN_UP							1

// A/D converter clock = PCLK / (prescaler value + 1)
// Maximum 5Mhz
#define PRSCVL							14

#define BIT_PENDN                       (1<<(PHYIRQ_PENDN - VIC2_BIT_OFFSET))
#define BIT_PENDN1                      (1<<(PHYIRQ_PENDN1 - VIC3_BIT_OFFSET))

#define BIT_TIMER3                      (1<<(PHYIRQ_TIMER3))
#define BIT_TIMER1						(1<<(PHYIRQ_TIMER1))

#ifdef TSP_QT602240
	// TOUCH_INT
    #define TOUCH_INT_NUM               (IRQ_GPJ0_INT5)
#endif


#define TSP_USE_TIMER1		// PWM timer3 is used for the touch driver

#if TSP_USE_TIMER3


// PWM Timer3 Register Bit Descriptions
#define TCONBIT_TIMER3                  16
#define TCONT3_Start                    (0x1 << TCONBIT_TIMER3)
#define TCONT3_Update                   (0x2 << TCONBIT_TIMER3)
#define TCONT3_AutoReload               (0x8 << TCONBIT_TIMER3)

#define BIT_TINT_CSTAT_TIMER3_INT_EN    (1<<3)
#define BIT_TINT_CSTAT_TIMER3_INT_STAT  (1<<8)

#define TSP_TCNTB						(v_pPWMregs->TCNTB3)
#define TSP_TCNTO						(v_pPWMregs->TCNTO3)
#define TSP_TCMPB						(v_pPWMregs->TCNTB3)
#else

// PWM Timer1 Register Bit Descriptions
#define TCONBIT_TIMER1                  8
#define TCONT1_Start                    (0x1 << TCONBIT_TIMER1)
#define TCONT1_Update                   (0x2 << TCONBIT_TIMER1)
#define TCONT1_AutoReload               (0x8 << TCONBIT_TIMER1)

#define BIT_TINT_CSTAT_TIMER1_INT_EN    (1<<1)
#define BIT_TINT_CSTAT_TIMER1_INT_STAT  (1<<6)

#define TSP_TCNTB						(v_pPWMregs->TCNTB1)
#define TSP_TCNTO						(v_pPWMregs->TCNTO1)
#define TSP_TCMPB						(v_pPWMregs->TCNTB1)
#endif


// The touch device driver collects several samples for a point to achieve more accurate value.
#define SAMPLE_DISCARD_THRESHOLD        1000 //lkb? 40   // 40--->60 for test  terry


#ifdef TSP_QT602240
// Actually, no timer is required to use TQ602240 external touch controller.
// These values are just for reporting the sample rate.
#define TSP_SAMPLE_RATE_LOW				100
#define TSP_SAMPLE_RATE_HIGH			100
#else
#define TSP_SAMPLE_RATE_LOW             100     // Samples / seconds
#define TSP_SAMPLE_RATE_HIGH            300     // Samples / seconds
#endif

#ifndef DETAIL_SAMPLING
	#define TSP_SAMPLE_NUM				3
#else
	#define TSP_SAMPLE_NUM				8
#endif


// TSADC clock
//#define FILCLK							24000000
//#define FILCLK_PERIOD_IN_NS				(float)(1000000000 / FILCLK)
#define FILCLK							24
#define FILCLK_PERIOD_IN_NS				(float)(1000 / FILCLK)
#if defined(BSP_HW_ID) && (BSP_HW_ID==0)
#define CONVERSION_DELAY_IN_NS			300000
#define CONVERSION_DELAY_IN_NS_2		300000				// Conversion delay while continuous sample mode (pen down)
#else
#define CONVERSION_DELAY_IN_NS			300000				// Conversion delay on wait for pen down mode
#define CONVERSION_DELAY_IN_NS_2		100000				// Conversion delay while continuous sample mode (pen down)
#endif
#define CONVERSION_DELAY_COUNT			(DWORD)(CONVERSION_DELAY_IN_NS / FILCLK_PERIOD_IN_NS)		// TSDLY
#define CONVERSION_DELAY_COUNT_2		(DWORD)(CONVERSION_DELAY_IN_NS_2 / FILCLK_PERIOD_IN_NS)		// TSDLY


// If the pen is moved faster than the threshold value, the pen up detection is triggered.
// We need to check that the pen movement is a real action or a resistance change caused by the pen up.
#define PEN_UP_CHECK_THRESHOLD_DIFFERENCE	50				// if dx or dy is larger than this value, pen up detection will be triggered

#if defined(BSP_HW_ID) && (BSP_HW_ID==0)
#define PEN_UP_CHECK_TIME_IN_NS				800000			// how long will we check the status of pen
#else
#define PEN_UP_CHECK_TIME_IN_NS				500000			// how long will we check the status of pen
#endif



// Touch pressure
#ifdef LCD_MODULE
#define TOUCH_PRESSURE_DETECTION				// The touch pressure detection is used.
#if (LCD_MODULE == LCD_MODULE_LTE480)
#define PEN_DOWN_PRESSURE_THRESHOLD		(1400)	// The touch device driver will ignore a touch sample whose Rtouch value is larger than this threshold.
#elif (LCD_MODULE == LCD_MODULE_AT070TN92)
#define PEN_DOWN_PRESSURE_THRESHOLD		(5500) //lkb add
#elif (LCD_MODULE == LCD_MODULE_TL2796)

#if (S5PV210_EVT == 0)
#define PEN_DOWN_PRESSURE_THRESHOLD		(1100)	// The touch device driver will ignore a touch sample whose Rtouch value is larger than this threshold.
#elif (S5PV210_EVT == 1)
#define PEN_DOWN_PRESSURE_THRESHOLD		(1500)	// The touch device driver will ignore a touch sample whose Rtouch value is larger than this threshold.
#endif

#else
// Touch pressure detection is not supported for this type of LCD yet.
#undef TOUCH_PRESSURE_DETECTION
#endif
#endif
#define CALC_FLOATING							// Floating point calculation
#define R_XPLATE_VALUE					(1000)	// set X-plate resistance value of each touch panel
#define WEIGHT_VALUE_FOR_POWER_OF_2		(20)
#define RESOLUTION_RANGE				(12)	// resolution = R_XPLATE_VALUE / (2^(WEIGHT_VALUE_FOR_POWER_OF_2-RESOLUTION_RANGE))


// TPDC_SAMPLE_RATE
// CurrentSampleRateSetting : 0 (low sample rate)
//                            1 (high sample rate)
#define TPDC_SAMPLE_RATE_LOW			0
#define TPDC_SAMPLE_RATE_HIGH			1


//____________________________________GLOBAL_VARIABLES________________________


//____________________________________FUNCTION DECLARATION_____________________

// Allocation/Deallocation memory of the TOUCH, ADC, Interrupt registers.
// (NONE)   ->   (True/Fail)
BOOL TSP_VirtualAlloc(VOID);
VOID TSP_VirtualFree(VOID);

// Credit Touch/Timer Interrupt.
// (Touch Intr ID, Timer Intr ID, Array with size 4)   ->   (True/False)
BOOL TSP_GetSysIntrVal(DWORD * TouchIntr, DWORD * TouchIntrChanged, UINT32 * IrqTable);

// Clear/Check/Enable Timer/Touch Interrupt.
// (TOUCH_DEV/TIMER_DEV)   -> (NONE)
VOID TSP_ClearInt(INT type);

// (NONE)  ->  True(PENDN) / False (Timer)
INT TSP_CheckInt(VOID);

// (TOUCH_DEV/TIMER_DEV, True/False)   ->  (NONE)
VOID TSP_EnableInt(INT type, BOOL En);

// Notify HW to detect PENDN interrupt.
VOID TSP_DetectPnDn(VOID);

// Setting timer period for ink sampling.
// (Sample rate)       ->  (NONE)
VOID TSP_SetPollingRate(DWORD RATE);

// Backup/Restore current ADC register value.
VOID TSP_GetDefaultRegs();
VOID TSP_SetDefaultRegs(BOOL bPowerHandler);

// Check stylus state (UP or Down).
// (NONE)      ->      (0 : Down / NonZero : Up)
INT TSP_GetTSPState();

// Trigger/Stop Timer for sampling under down state.
VOID TSP_SampleStart(VOID);
VOID TSP_SampleStop(VOID);

// Initialize/Deinitialize HW (ADC, Timer).
VOID TSP_PowerOn(BOOL bPowerHandler);
VOID TSP_PowerOff(BOOL bPowerHandler);

// Get the Position Conversion Data values.
// (X, Y Position)     -> (NONE)
static VOID TSP_GetPosDATA(int *XP, int *YP);


// Touch pressure
int TSP_GetPressure(DWORD dwWaitTargetStatus);

// Pen history
BOOL TSP_GetPenHistory(DWORD dwUpDown);
void TSP_ClearPenHistory(DWORD dwUpDown);


// Get the point coordinates and filtering.
BOOL TSP_GetXY(int *px, int *py);

// Return the average coordinates.
BOOL TSP_Filtering(int *px, int *py);

// Create/Obtain/Release Mutex for ADC resource.
// (NONE)      ->      (ERROR)
DWORD TSP_CreateADCMutex(void);
DWORD TSP_ADCLock(void);
DWORD TSP_ADCUnlock(void);

void SetPulseEventFunction(TCHAR* szEventName);

#endif // _TSP_H_
