/* Copyright Statement:
*
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
* Without the prior written permission of MediaTek inc. and/or its licensors,
* any reproduction, modification, use or disclosure of MediaTek Software,
* and information contained herein, in whole or in part, shall be strictly prohibited.
*/
/* MediaTek Inc. (C) 2010. All rights reserved.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
* THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
* CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
* SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* The following software/firmware and/or related documentation ("MediaTek Software")
* have been modified by MediaTek Inc. All revisions are subject to any receiver's
* applicable license agreements with MediaTek Inc.
*/
#include <linux/i2c.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include "tpd.h"
#include <cust_eint.h>
#include <linux/rtpm_prio.h>
#include <linux/wakelock.h>
#include <asm/uaccess.h>
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
#include "cust_gpio_usage.h"
#include "tpd_custom_ft5306.h"
#ifdef MT6575
#include <mach/mt6575_boot.h>
#include <mach/mt6575_pm_ldo.h>
#endif
#ifdef MT6577
#include <mach/mt6577_pm_ldo.h>
#include <mach/mt6577_typedefs.h>
#include <mach/mt6577_boot.h>
#endif
#define TPD_SLAVE_ADDR 0x72 //ES980=0x72 //ES970=0x7E //default = 0x70
#define CONFIG_TOUCHSCREEN_FT5X05_SUPPORT_ISP
static int isUpgrade = 0; // 1:show that TP is upgrading ...edit by Magnum 2012-7-19
#define TPIO_RESET GPIO_CTP_RST_PIN //GPIO184
#define TPIO_WAKEUP GPIO_CTP_EN_PIN //GPIO187
#define TPIO_EINT GPIO_CTP_EINT_PIN
static const int TPD_KEYSFACTORY[TPD_KEY_COUNT] = {KEY_F1, KEY_F2, KEY_F3};
#ifdef TPD_HAVE_BUTTON
static int tpd_keys_local[TPD_KEY_COUNT] = TPD_KEYS;
static int tpd_keys_dim_local[TPD_KEY_COUNT][4] = TPD_KEYS_DIM;
extern void tpd_button(unsigned int x, unsigned int y, unsigned int down);
#endif
#if (defined(TPD_WARP_START) && defined(TPD_WARP_END))
static int tpd_wb_start_local[TPD_WARP_CNT] = TPD_WARP_START;
static int tpd_wb_end_local[TPD_WARP_CNT] = TPD_WARP_END;
#endif
#if (defined(TPD_HAVE_CALIBRATION) && !defined(TPD_CUSTOM_CALIBRATION))
static int tpd_calmat_local[8] = TPD_CALIBRATION_MATRIX;
static int tpd_def_calmat_local[8] = TPD_CALIBRATION_MATRIX;
#endif
typedef struct _tinno_ts_point{
int x, y, z, id;
} tinno_ts_point;
struct touch_info {
tinno_ts_point pt[2];
int p, count, pending;
};
struct touch_elapse {
int t1, t2, i;
int buf[5];
};
extern struct tpd_device *tpd;
extern int tpd_firmware_version[2];
extern BOOL bPMIC_Init_finish;
//end edit
static void tpd_eint_interrupt_handler(void);
static int tpd_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
static int tpd_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info);
static int tpd_i2c_remove(struct i2c_client *client);
static int __devexit tpd_remove(struct i2c_client *client);
// TODO: should be moved into mach/xxx.h
#ifdef MT6575
extern void mt65xx_eint_unmask(unsigned int line);
extern void mt65xx_eint_mask(unsigned int line);
extern void mt65xx_eint_set_hw_debounce(kal_uint8 eintno, kal_uint32 ms);
extern kal_uint32 mt65xx_eint_set_sens(kal_uint8 eintno, kal_bool sens);
extern void mt65xx_eint_registration(kal_uint8 eintno, kal_bool Dbounce_En,
kal_bool ACT_Polarity, void (EINT_FUNC_PTR)(void),
kal_bool auto_umask);
#endif
#ifdef MT6577
extern void mt65xx_eint_unmask(unsigned int line);
extern void mt65xx_eint_mask(unsigned int line);
extern void mt65xx_eint_set_hw_debounce(unsigned int eint_num, unsigned int ms);
extern unsigned int mt65xx_eint_set_sens(unsigned int eint_num, unsigned int sens);
extern void mt65xx_eint_registration(unsigned int eint_num, unsigned int is_deb_en, unsigned int pol, void (EINT_FUNC_PTR)(void), unsigned int is_auto_umask);
#endif
static struct i2c_client *i2c_client = NULL;
struct task_struct *thread = NULL;
static DECLARE_WAIT_QUEUE_HEAD(waiter);
static int tpd_flag=0;
extern int tp_boot_mode;
static int touch_event_handler(void *unused);
//static int raw_x1, raw_y1, raw_x2, raw_y2;
static int tpd_status = 0;
static int tpd_dcount = 0;
static const struct i2c_device_id ft5306_i2c_id[] = {{"ft5306",0},{}};
static struct i2c_board_info __initdata ft5206_i2c_tpd={ I2C_BOARD_INFO("ft5306", (TPD_SLAVE_ADDR>>1))};
//unsigned short force[] = {1, TPD_SLAVE_ADDR, I2C_CLIENT_END, I2C_CLIENT_END};
//static const unsigned short * const forces[] = { force, NULL };
//static struct i2c_client_address_data addr_data = { .forces = forces, };
static char panel_version = 0;
//edit by Magnum 2012-7-10
static char vendor_version = 0;
static int tpd_downMode = 0; // 1:touchmode, 2:virtual key in touch mode, 0 : default and up event
static int tpd_init_skip = 0;
#define FTS_PROTOCOL_LEN (sizeof(fts_report_data_t))
#define TINNO_TOUCH_TRACK_IDS (2)
#define FTS_INVALID_DATA (-1)
#define FTS_EF_DOWN (0)
#define FTS_EF_UP (1)
#define FTS_EF_CONTACT (2)
#define FTS_EF_RESERVED (3)
#ifdef CONFIG_TOUCHSCREEN_FT5X05_SUPPORT_ISP
struct tinno_ts_data {
struct wake_lock wake_lock;
atomic_t isp_opened;
uint8_t *isp_pBuffer;
struct i2c_client *client;
};
struct tinno_ts_data *g_pts = NULL;
struct mutex tp_mutex;
#define ISP_FLASH_SIZE 0x8000 //32KB
#define FT5X06_FIRMWAIR_VERSION_D
#define FTS_MODE_OPRATE (0x00)
#define FTS_MODE_UPDATE (0x01)
#define FTS_MODE_SYSTEM (0x02)
#define TOUCH_IO_MAGIC ('F')
#define FT5X05_IOCTL_RESET _IO(TOUCH_IO_MAGIC, 0x00)
#define FT5X05_IOCTL_SWITCH_TO _IOW(TOUCH_IO_MAGIC, 0x01, int)
#define FT5X05_IOCTL_WRITE_PROTECT _IOW(TOUCH_IO_MAGIC, 0x02, int)
#define FT5X05_IOCTL_ERASE _IO(TOUCH_IO_MAGIC, 0x03)
#define FT5X05_IOCTL_GET_STATUS _IOR(TOUCH_IO_MAGIC, 0x04, int)
#define FT5X05_IOCTL_GET_CHECKSUM _IOR(TOUCH_IO_MAGIC, 0x05, int)
#define FT5X05_IOCTL_GET_TPID _IOR(TOUCH_IO_MAGIC, 0x06, int)
#define FT5X05_IOCTL_GET_VENDORID _IOR(TOUCH_IO_MAGIC, 0x07, int)
#define FT5X05_IOC_MAXNR (0x08)
static u8 tpd_down_state=0;
static int down_x=0;
static int down_y=0;
static void fts_isp_register(struct i2c_client *client);
#endif
extern char phonestate;
typedef struct {
uint8_t x_h: 4,
reserved_1: 2,
event_flag: 2;
uint8_t x_l;
uint8_t y_h: 4,
touch_id: 4;
uint8_t y_l;
uint8_t reserved