rk2928: a720: touchscren && camera && sdmmc && usb wifi support
authorkfx <kfx@rock-chips.com>
Mon, 20 Aug 2012 05:16:32 +0000 (13:16 +0800)
committerkfx <kfx@rock-chips.com>
Mon, 20 Aug 2012 05:16:32 +0000 (13:16 +0800)
arch/arm/configs/rk2928_a720_defconfig
arch/arm/mach-rk2928/board-rk2928-a720-camera.c [new file with mode: 0644]
arch/arm/mach-rk2928/board-rk2928-a720.c
arch/arm/mach-rk2928/include/mach/board.h
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/sitronix_ts_a720.c [new file with mode: 0755]
drivers/input/touchscreen/sitronix_ts_a720.h [new file with mode: 0755]

index bb5d2ec4d62387073e105abd7e63e28de5cb7f92..e4af82c036e9f2806ddcd1ae25f32b2874d8cf8d 100644 (file)
@@ -202,6 +202,7 @@ CONFIG_PHYLIB=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WLAN_80211=y
+CONFIG_RTL8188EU=y
 CONFIG_USB_USBNET=y
 CONFIG_PPP=y
 CONFIG_PPP_MULTILINK=y
@@ -221,6 +222,7 @@ CONFIG_INPUT_KEYRESET=y
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TABLET=y
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_SITRONIX_A720=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_KEYCHORD=y
 CONFIG_INPUT_UINPUT=y
@@ -250,6 +252,12 @@ CONFIG_MFD_TPS65090=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_TPS65910=y
 CONFIG_RK30_PWM_REGULATOR=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_OV2659=y
+CONFIG_VIDEO_RK29=y
+CONFIG_VIDEO_RK29_CAMMEM_ION=y
 CONFIG_ION=y
 CONFIG_ION_ROCKCHIP=y
 CONFIG_FB=y
@@ -350,7 +358,6 @@ CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_EMBEDDED_SDIO=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_SDMMC_RK29=y
-# CONFIG_SDMMC0_RK29 is not set
 # CONFIG_SDMMC1_RK29 is not set
 CONFIG_SWITCH=y
 CONFIG_SWITCH_GPIO=y
diff --git a/arch/arm/mach-rk2928/board-rk2928-a720-camera.c b/arch/arm/mach-rk2928/board-rk2928-a720-camera.c
new file mode 100644 (file)
index 0000000..b92e6b2
--- /dev/null
@@ -0,0 +1,448 @@
+#ifdef CONFIG_VIDEO_RK29
+/*---------------- Camera Sensor Macro Define Begin  ------------------------*/
+/*---------------- Camera Sensor Configuration Macro Begin ------------------------*/
+#define CONFIG_SENSOR_0 RK29_CAM_SENSOR_OV5642                                         /* back camera sensor */
+#define CONFIG_SENSOR_IIC_ADDR_0               0
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_0   0
+#define CONFIG_SENSOR_CIF_INDEX_0                    0
+#define CONFIG_SENSOR_ORIENTATION_0      90
+#define CONFIG_SENSOR_POWER_PIN_0                INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_0                INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_0            INVALID_GPIO//RK2928_PIN3_PB3
+#define CONFIG_SENSOR_FALSH_PIN_0                INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_0 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_0 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_0 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_0         15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_0   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_0         15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_0          15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_0          15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_0         15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_0         15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_0         30000
+
+#define CONFIG_SENSOR_01  RK29_CAM_SENSOR_OV5642                   /* back camera sensor 1 */
+#define CONFIG_SENSOR_IIC_ADDR_01          0x00
+#define CONFIG_SENSOR_CIF_INDEX_01                    0
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_01    4
+#define CONFIG_SENSOR_ORIENTATION_01       90
+#define CONFIG_SENSOR_POWER_PIN_01         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_01         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_01       INVALID_GPIO//RK2928_PIN3_PB3
+#define CONFIG_SENSOR_FALSH_PIN_01         INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_01 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_01 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_01 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_01 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_01      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_01   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_01      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_01       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_01       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_01      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_01      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_01     30000
+
+#define CONFIG_SENSOR_02 RK29_CAM_SENSOR_OV5640                      /* back camera sensor 2 */
+#define CONFIG_SENSOR_IIC_ADDR_02          0x00
+#define CONFIG_SENSOR_CIF_INDEX_02                    0
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_02    4
+#define CONFIG_SENSOR_ORIENTATION_02       90
+#define CONFIG_SENSOR_POWER_PIN_02         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_02         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_02       INVALID_GPIO//RK2928_PIN3_PB3
+#define CONFIG_SENSOR_FALSH_PIN_02         INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_02 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_02 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_02 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_02 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_02      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_02   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_02      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_02       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_02       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_02      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_02      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_02      30000
+
+#define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV2659                      /* front camera sensor 0 */
+#define CONFIG_SENSOR_IIC_ADDR_1          0x60
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_1   1
+#define CONFIG_SENSOR_CIF_INDEX_1                                0
+#define CONFIG_SENSOR_ORIENTATION_1       270
+#define CONFIG_SENSOR_POWER_PIN_1         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_1         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_1      RK2928_PIN3_PB3
+#define CONFIG_SENSOR_FALSH_PIN_1         INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_1 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_1 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_1         15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_1   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_1         15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_1          15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_1          15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_1         15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_1         15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_1         30000
+
+#define CONFIG_SENSOR_11 RK29_CAM_SENSOR_OV2659                      /* front camera sensor 1 */
+#define CONFIG_SENSOR_IIC_ADDR_11          0x00
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_11    3
+#define CONFIG_SENSOR_CIF_INDEX_11                               0
+#define CONFIG_SENSOR_ORIENTATION_11       270
+#define CONFIG_SENSOR_POWER_PIN_11         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_11         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_11       INVALID_GPIO
+#define CONFIG_SENSOR_FALSH_PIN_11         INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_11 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_11 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_11 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_11 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_11      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_11   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_11      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_11       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_11       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_11      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_11      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_11      30000
+
+#define CONFIG_SENSOR_12 RK29_CAM_SENSOR_OV2659//RK29_CAM_SENSOR_OV2655                      /* front camera sensor 2 */
+#define CONFIG_SENSOR_IIC_ADDR_12         0x00
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_12    3
+#define CONFIG_SENSOR_CIF_INDEX_12                               0
+#define CONFIG_SENSOR_ORIENTATION_12       270
+#define CONFIG_SENSOR_POWER_PIN_12         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_12         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_12       INVALID_GPIO
+#define CONFIG_SENSOR_FALSH_PIN_12         INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_12 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_12 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_12 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_12 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_12      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_12   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_12      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_12       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_12       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_12      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_12      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_12      30000
+
+
+#endif  //#ifdef CONFIG_VIDEO_RK29
+/*---------------- Camera Sensor Configuration Macro End------------------------*/
+#include "../../../drivers/media/video/rk2928_camera.c"
+/*---------------- Camera Sensor Macro Define End  ---------*/
+
+#define PMEM_CAM_SIZE PMEM_CAM_NECESSARY
+/*****************************************************************************************
+ * camera  devices
+ * author: ddl@rock-chips.com
+ *****************************************************************************************/
+#ifdef CONFIG_VIDEO_RK29
+#define CONFIG_SENSOR_POWER_IOCTL_USR     0 //define this refer to your board layout
+#define CONFIG_SENSOR_RESET_IOCTL_USR     0
+#define CONFIG_SENSOR_POWERDOWN_IOCTL_USR         0
+#define CONFIG_SENSOR_FLASH_IOCTL_USR     0
+
+static void rk_cif_power(int on)
+{
+    struct regulator *ldo_18,*ldo_28;
+       ldo_28 = regulator_get(NULL, "ldo7");   // vcc28_cif
+       ldo_18 = regulator_get(NULL, "ldo1");   // vcc18_cif
+       if (ldo_28 == NULL || IS_ERR(ldo_28) || ldo_18 == NULL || IS_ERR(ldo_18)){
+        printk("get cif ldo failed!\n");
+               return;
+           }
+    if(on == 0){       
+       regulator_disable(ldo_28);
+       regulator_put(ldo_28);
+       regulator_disable(ldo_18);
+       regulator_put(ldo_18);
+       mdelay(500);
+        }
+    else{
+       regulator_set_voltage(ldo_28, 2800000, 2800000);
+       regulator_enable(ldo_28);
+   //  printk("%s set ldo7 vcc28_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_28));
+       regulator_put(ldo_28);
+
+       regulator_set_voltage(ldo_18, 1800000, 1800000);
+    // regulator_set_suspend_voltage(ldo, 1800000);
+       regulator_enable(ldo_18);
+    // printk("%s set ldo1 vcc18_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_18));
+       regulator_put(ldo_18);
+        }
+}
+
+#if CONFIG_SENSOR_POWER_IOCTL_USR
+static int sensor_power_usr_cb (struct rk29camera_gpio_res *res,int on)
+{
+       //#error "CONFIG_SENSOR_POWER_IOCTL_USR is 1, sensor_power_usr_cb function must be writed!!";
+    rk_cif_power(on);
+}
+#endif
+
+#if CONFIG_SENSOR_RESET_IOCTL_USR
+static int sensor_reset_usr_cb (struct rk29camera_gpio_res *res,int on)
+{
+       #error "CONFIG_SENSOR_RESET_IOCTL_USR is 1, sensor_reset_usr_cb function must be writed!!";
+}
+#endif
+
+#if CONFIG_SENSOR_POWERDOWN_IOCTL_USR
+static int sensor_powerdown_usr_cb (struct rk29camera_gpio_res *res,int on)
+{
+       #error "CONFIG_SENSOR_POWERDOWN_IOCTL_USR is 1, sensor_powerdown_usr_cb function must be writed!!";
+}
+#endif
+
+#if CONFIG_SENSOR_FLASH_IOCTL_USR
+static int sensor_flash_usr_cb (struct rk29camera_gpio_res *res,int on)
+{
+       #error "CONFIG_SENSOR_FLASH_IOCTL_USR is 1, sensor_flash_usr_cb function must be writed!!";
+}
+#endif
+
+static struct rk29camera_platform_ioctl_cb     sensor_ioctl_cb = {
+       #if CONFIG_SENSOR_POWER_IOCTL_USR
+       .sensor_power_cb = sensor_power_usr_cb,
+       #else
+       .sensor_power_cb = NULL,
+       #endif
+
+       #if CONFIG_SENSOR_RESET_IOCTL_USR
+       .sensor_reset_cb = sensor_reset_usr_cb,
+       #else
+       .sensor_reset_cb = NULL,
+       #endif
+
+       #if CONFIG_SENSOR_POWERDOWN_IOCTL_USR
+       .sensor_powerdown_cb = sensor_powerdown_usr_cb,
+       #else
+       .sensor_powerdown_cb = NULL,
+       #endif
+
+       #if CONFIG_SENSOR_FLASH_IOCTL_USR
+       .sensor_flash_cb = sensor_flash_usr_cb,
+       #else
+       .sensor_flash_cb = NULL,
+       #endif
+};
+
+#if CONFIG_SENSOR_IIC_ADDR_0
+static struct reginfo_t rk_init_data_sensor_reg_0[] =
+{
+               {0x0000, 0x00,0,0}
+       };
+static struct reginfo_t rk_init_data_sensor_winseqreg_0[] ={
+       {0x0000, 0x00,0,0}
+       };
+#endif
+
+#if CONFIG_SENSOR_IIC_ADDR_1
+static struct reginfo_t rk_init_data_sensor_reg_1[] =
+{
+    {0x0000, 0x00,0,0}
+};
+static struct reginfo_t rk_init_data_sensor_winseqreg_1[] =
+{
+       {0x0000, 0x00,0,0}
+};
+#endif
+#if CONFIG_SENSOR_IIC_ADDR_01
+static struct reginfo_t rk_init_data_sensor_reg_01[] =
+{
+    {0x0000, 0x00,0,0}
+};
+static struct reginfo_t rk_init_data_sensor_winseqreg_01[] =
+{
+       {0x0000, 0x00,0,0}
+};
+#endif
+#if CONFIG_SENSOR_IIC_ADDR_02
+static struct reginfo_t rk_init_data_sensor_reg_02[] =
+{
+    {0x0000, 0x00,0,0}
+};
+static struct reginfo_t rk_init_data_sensor_winseqreg_02[] =
+{
+       {0x0000, 0x00,0,0}
+};
+#endif
+#if CONFIG_SENSOR_IIC_ADDR_11
+static struct reginfo_t rk_init_data_sensor_reg_11[] =
+{
+    {0x0000, 0x00,0,0}
+};
+static struct reginfo_t rk_init_data_sensor_winseqreg_11[] =
+{
+       {0x0000, 0x00,0,0}
+};
+#endif
+#if CONFIG_SENSOR_IIC_ADDR_12
+static struct reginfo_t rk_init_data_sensor_reg_12[] =
+{
+    {0x0000, 0x00,0,0}
+};
+static struct reginfo_t rk_init_data_sensor_winseqreg_12[] =
+{
+       {0x0000, 0x00,0,0}
+};
+#endif
+static rk_sensor_user_init_data_s rk_init_data_sensor[RK_CAM_NUM] = 
+{
+    #if CONFIG_SENSOR_IIC_ADDR_0
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = rk_init_data_sensor_reg_0,
+       .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_0,
+       .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_0) / sizeof(struct reginfo_t),
+       .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_0) / sizeof(struct reginfo_t),
+    },
+    #else
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = NULL,
+       .rk_sensor_init_winseq = NULL,
+       .rk_sensor_winseq_size = 0,
+       .rk_sensor_init_data_size = 0,
+    },
+    #endif
+    #if CONFIG_SENSOR_IIC_ADDR_1
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = rk_init_data_sensor_reg_1,
+       .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_1,
+       .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_1) / sizeof(struct reginfo_t),
+       .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_1) / sizeof(struct reginfo_t),
+    },
+    #else
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = NULL,
+       .rk_sensor_init_winseq = NULL,
+       .rk_sensor_winseq_size = 0,
+       .rk_sensor_init_data_size = 0,
+    },
+    #endif
+    #if CONFIG_SENSOR_IIC_ADDR_01
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = rk_init_data_sensor_reg_01,
+       .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_01,
+       .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_01) / sizeof(struct reginfo_t),
+       .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_01) / sizeof(struct reginfo_t),
+    },
+    #else
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = NULL,
+       .rk_sensor_init_winseq = NULL,
+       .rk_sensor_winseq_size = 0,
+       .rk_sensor_init_data_size = 0,
+    },
+    #endif
+    #if CONFIG_SENSOR_IIC_ADDR_02
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = rk_init_data_sensor_reg_02,
+       .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_02,
+       .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_02) / sizeof(struct reginfo_t),
+       .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_02) / sizeof(struct reginfo_t),
+    },
+    #else
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = NULL,
+       .rk_sensor_init_winseq = NULL,
+       .rk_sensor_winseq_size = 0,
+       .rk_sensor_init_data_size = 0,
+    },
+    #endif
+    #if CONFIG_SENSOR_IIC_ADDR_11
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = rk_init_data_sensor_reg_11,
+       .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_11,
+       .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_11) / sizeof(struct reginfo_t),
+       .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_11) / sizeof(struct reginfo_t),
+    },
+    #else
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = NULL,
+       .rk_sensor_init_winseq = NULL,
+       .rk_sensor_winseq_size = 0,
+       .rk_sensor_init_data_size = 0,
+    },
+    #endif
+    #if CONFIG_SENSOR_IIC_ADDR_12
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = rk_init_data_sensor_reg_12,
+       .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_12,
+       .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_12) / sizeof(struct reginfo_t),
+       .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_12) / sizeof(struct reginfo_t),
+    },
+    #else
+    {
+       .rk_sensor_init_width = INVALID_VALUE,
+       .rk_sensor_init_height = INVALID_VALUE,
+       .rk_sensor_init_bus_param = INVALID_VALUE,
+       .rk_sensor_init_pixelcode = INVALID_VALUE,
+       .rk_sensor_init_data = NULL,
+       .rk_sensor_init_winseq = NULL,
+       .rk_sensor_winseq_size = 0,
+       .rk_sensor_init_data_size = 0,
+    },
+    #endif
+
+ };
+#include "../../../drivers/media/video/rk2928_camera.c"
+
+#endif /* CONFIG_VIDEO_RK29 */
index 5808b81359cb48a595296f217be194275e44c440..0bc1895fc61b7baa76352b07dd64914b62c143cf 100755 (executable)
@@ -54,6 +54,7 @@
 #include "../../../drivers/spi/rk29_spim.h"
 #endif
 
+#include "board-rk2928-a720-camera.c" 
 #include "board-rk2928-a720-key.c"
 
 #ifdef  CONFIG_THREE_FB_BUFFER
@@ -259,13 +260,51 @@ static struct platform_device device_ion = {
 };
 #endif
 
+
+#if defined(CONFIG_TOUCHSCREEN_SITRONIX_A720)
+
+#define TOUCH_RESET_PIN         RK2928_PIN1_PA3
+#define TOUCH_INT_PIN   RK2928_PIN1_PB3
+int ft5306_init_platform_hw(void)
+{
+
+        //printk("ft5306_init_platform_hw\n");
+        if(gpio_request(TOUCH_RESET_PIN,NULL) != 0){
+                gpio_free(TOUCH_RESET_PIN);
+                printk("ft5306_init_platform_hw gpio_request error\n");
+                return -EIO;
+        }
+
+        if(gpio_request(TOUCH_INT_PIN,NULL) != 0){
+                gpio_free(TOUCH_INT_PIN);
+                printk("ift5306_init_platform_hw gpio_request error\n");
+                return -EIO;
+        }
+        gpio_direction_output(TOUCH_RESET_PIN, GPIO_HIGH);
+        mdelay(10);
+        gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
+        mdelay(10);
+        gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
+        msleep(300);
+        return 0;
+
+}
+
+struct ft5x0x_platform_data sitronix_info = {
+        .model = 5007,
+        .init_platform_hw= ft5306_init_platform_hw,
+};
+
+#endif
+
+
 /*MMA7660 gsensor*/
 #if defined (CONFIG_GS_MMA7660)
 #define MMA7660_INT_PIN   RK2928_PIN1_PB1
 
 static int mma7660_init_platform_hw(void)
 {
-       rk30_mux_api_set(GPIO4C0_SMCDATA0_TRACEDATA0_NAME, GPIO4C_GPIO4C0);
+       rk30_mux_api_set(GPIO1B1_SPI_TXD_UART1_SOUT_NAME, GPIO1B_GPIO1B1);
 
        return 0;
 }
@@ -332,8 +371,70 @@ struct platform_device pwm_regulator_device[1] = {
                }
        },
 };
+#endif
+/**************************************************************************************************
+ * SDMMC devices,  include the module of SD,MMC,and sdio.noted by xbw at 2012-03-05
+**************************************************************************************************/
+#ifdef CONFIG_SDMMC_RK29
+#include "board-rk2928-sdk-sdmmc.c"
+
+#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT)
+#define SDMMC0_WRITE_PROTECT_PIN       RK2928_PIN1_PA7 //According to your own project to set the value of write-protect-pin.
+#endif
+
+#if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
+#define SDMMC1_WRITE_PROTECT_PIN       RK2928_PIN0_PD5 //According to your own project to set the value of write-protect-pin.
+#endif
+
+#define RK29SDK_WIFI_SDIO_CARD_DETECT_N    RK2928_PIN0_PB2
+
+#endif //endif ---#ifdef CONFIG_SDMMC_RK29
+
+#ifdef CONFIG_SDMMC0_RK29
+static int rk29_sdmmc0_cfg_gpio(void)
+{
+       rk29_sdmmc_set_iomux(0, 0xFFFF);
+
+       rk30_mux_api_set(GPIO1C1_MMC0_DETN_NAME, GPIO1C_MMC0_DETN);
+
+#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT)
+       gpio_request(SDMMC0_WRITE_PROTECT_PIN, "sdmmc-wp");
+       gpio_direction_input(SDMMC0_WRITE_PROTECT_PIN);
 #endif
 
+       return 0;
+}
+
+#define CONFIG_SDMMC0_USE_DMA
+struct rk29_sdmmc_platform_data default_sdmmc0_data = {
+       .host_ocr_avail =
+           (MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 | MMC_VDD_28_29 |
+            MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
+            MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36),
+       .host_caps =
+           (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+       .io_init = rk29_sdmmc0_cfg_gpio,
+
+#if !defined(CONFIG_SDMMC_RK29_OLD)
+       .set_iomux = rk29_sdmmc_set_iomux,
+#endif
+
+       .dma_name = "sd_mmc",
+#ifdef CONFIG_SDMMC0_USE_DMA
+       .use_dma = 1,
+#else
+       .use_dma = 0,
+#endif
+       .detect_irq = RK2928_PIN1_PC1,  // INVALID_GPIO
+       .enable_sd_wakeup = 0,
+
+#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT)
+       .write_prt = SDMMC0_WRITE_PROTECT_PIN,
+#else
+       .write_prt = INVALID_GPIO,
+#endif
+};
+#endif // CONFIG_SDMMC0_RK29
 
 static struct platform_device *devices[] __initdata = {
 #ifdef CONFIG_BACKLIGHT_RK29_BL
@@ -380,6 +481,15 @@ static struct i2c_board_info __initdata i2c1_info[] = {
 #endif
 #ifdef CONFIG_I2C2_RK30
 static struct i2c_board_info __initdata i2c2_info[] = {
+#if defined (CONFIG_TOUCHSCREEN_SITRONIX_A720)
+{
+        .type          ="sitronix",
+       .addr           = 0x38,
+       .flags          = 0,
+       .irq            = TOUCH_INT_PIN,
+       .platform_data = &sitronix_info,
+},
+#endif
 };
 #endif
 #ifdef CONFIG_I2C3_RK30
@@ -426,7 +536,7 @@ static void __init rk30_i2c_register_board_info(void)
 }
 //end of i2c
 
-#define POWER_ON_PIN RK2928_PIN1_PA4   //power_hold
+#define POWER_ON_PIN RK2928_PIN1_PA2   //power_hold
 static void rk2928_pm_power_off(void)
 {
        printk(KERN_ERR "rk2928_pm_power_off start...\n");
@@ -481,8 +591,8 @@ static struct dvfs_arm_table dvfs_cpu_logic_table[] = {
        {.frequency = 600 * 1000,       .cpu_volt = 1200 * 1000,        .logic_volt = 1200 * 1000},//1.025V/1.050V
        {.frequency = 696 * 1000,       .cpu_volt = 1400 * 1000,        .logic_volt = 1200 * 1000},//1.000V/1.025V
        {.frequency = 816 * 1000,       .cpu_volt = 1400 * 1000,        .logic_volt = 1200 * 1000},//1.100V/1.050V
-       {.frequency = 912 * 1000,       .cpu_volt = 1400 * 1000,        .logic_volt = 1200 * 1000},//1.100V/1.050V
-       {.frequency = 1008 * 1000,      .cpu_volt = 1400 * 1000,        .logic_volt = 1200 * 1000},//1.100V/1.050V
+       //{.frequency = 912 * 1000,     .cpu_volt = 1400 * 1000,        .logic_volt = 1200 * 1000},//1.100V/1.050V
+       //{.frequency = 1008 * 1000,    .cpu_volt = 1400 * 1000,        .logic_volt = 1200 * 1000},//1.100V/1.050V
 #if 0
        {.frequency = 1104 * 1000,      .cpu_volt = 1400 * 1000,        .logic_volt = 1200 * 1000},//1.100V/1.050V
        {.frequency = 1200 * 1000,      .cpu_volt = 1400 * 1000,        .logic_volt = 1200 * 1000},//1.100V/1.050V
index 9292adca4591153a6bd3aae4a66bd2787745d356..f6d6e99b2bddfc9aa0b3534f690bff28460faaac 100644 (file)
@@ -57,6 +57,16 @@ struct eeti_egalax_platform_data{
  
 };
 #endif
+#if defined (CONFIG_TOUCHSCREEN_SITRONIX_A720)
+struct ft5x0x_platform_data{
+         u16     model;
+    int     (*get_pendown_state)(void);
+    int     (*init_platform_hw)(void);
+    int     (*ft5x0x_platform_sleep)(void);
+    int     (*ft5x0x_platform_wakeup)(void);
+    void    (*exit_platform_hw)(void);
+};
+#endif
 enum _periph_pll {
        periph_pll_1485mhz = 148500000,
        periph_pll_297mhz = 297000000,
index 6e95e50980398fd4c0e25018c29674c9a03f7728..50d915718bcc39ba1024aad59ac3dfe0f5637e22 100755 (executable)
@@ -969,9 +969,6 @@ config LAIBAO_TS
 config TOUCHSCREEN_GT801_IIC
        tristate "GT801_IIC based touchscreens"
        depends on I2C2_RK29
-config TOUCHSCREEN_GT82X_IIC
-       tristate "GT82x_IIC based touchscreens"
-       depends on I2C2_RK30
 
 config TOUCHSCREEN_GT818_IIC
        tristate "GT818_IIC based touchscreens"
@@ -1002,6 +999,10 @@ config TOUCHSCREEN_FT5306
        tristate "FT5306 based touchscreens: FT5306 Interface"
        depends on I2C2_RK29 || I2C2_RK30
 
+config TOUCHSCREEN_SITRONIX_A720
+       tristate "SITRONIX based touchscreens: SITRONIX Interface for a720"
+       depends on I2C2_RK29 || I2C2_RK30 
+
 config TOUCHSCREEN_FT5306_WPX2
         tristate "FT5306 based touchscreens: FT5306 Interface,only used for umeox wpx2 board"
         depends on I2C2_RK29 || I2C2_RK30
index d64b4a9063f539f52fe5e65d444e7c13f299a995..7b28f1998469016e9e2fd7378bfc31da68cb8146 100644 (file)
@@ -82,6 +82,7 @@ obj-$(CONFIG_D70_L3188A)              += goodix_touch.o
 obj-$(CONFIG_TOUCHSCREEN_GT8XX)                += rk29_i2c_goodix.o
 obj-$(CONFIG_TOUCHSCREEN_FT5406)       += ft5406_ts.o
 obj-$(CONFIG_TOUCHSCREEN_FT5306)       += ft5306_ts.o
+obj-$(CONFIG_TOUCHSCREEN_SITRONIX_A720)        += sitronix_ts_a720.o
 obj-$(CONFIG_TOUCHSCREEN_FT5306_WPX2)        += ft5306_ts_wpx2.o
 obj-$(CONFIG_TOUCHSCREEN_GT819)                += gt819.o
 obj-$(CONFIG_TOUCHSCREEN_NAS)          += nas_ts.o
diff --git a/drivers/input/touchscreen/sitronix_ts_a720.c b/drivers/input/touchscreen/sitronix_ts_a720.c
new file mode 100755 (executable)
index 0000000..7e8922d
--- /dev/null
@@ -0,0 +1,1233 @@
+/*
+ * drivers/input/touchscreen/sitronix_i2c_touch.c
+ *
+ * Touchscreen driver for Sitronix (I2C bus)
+ *
+ * Copyright (C) 2011 Sitronix Technology Co., Ltd.
+ *     Rudy Huang <rudy_huang@sitronix.com.tw>
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif // CONFIG_HAS_EARLYSUSPEND
+#include "sitronix_ts_a720.h"
+#ifdef SITRONIX_FW_UPGRADE_FEATURE
+#include <linux/cdev.h>
+#include <asm/uaccess.h>
+#endif // SITRONIX_FW_UPGRADE_FEATURE
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h> // to be compatible with linux kernel 3.2.15
+#include <linux/gpio.h>
+#include <mach/board.h>
+#include <linux/input/mt.h>
+
+#ifdef SITRONIX_MONITOR_THREAD
+#include <linux/kthread.h>
+//#include <mach/gpio.h>
+#endif // SITRONIX_MONITOR_THREAD
+
+#define DRIVER_AUTHOR           "Sitronix, Inc."
+#define DRIVER_NAME             "sitronix"
+#define DRIVER_DESC             "Sitronix I2C touch"
+#define DRIVER_DATE             "20120507"
+#define DRIVER_MAJOR            2
+#define DRIVER_MINOR           9
+#define DRIVER_PATCHLEVEL       1
+
+MODULE_AUTHOR("Rudy Huang <rudy_huang@sitronix.com.tw>");
+MODULE_DESCRIPTION("Sitronix I2C multitouch panels");
+MODULE_LICENSE("GPL");
+
+#ifdef SITRONIX_SENSOR_KEY
+#define SITRONIX_NUMBER_SENSOR_KEY 3
+int sitronix_sensor_key[SITRONIX_NUMBER_SENSOR_KEY] = {
+       KEY_BACK, // bit 0
+       KEY_HOMEPAGE,//KEY_HOME, // bit 1
+       KEY_MENU, // bit 2
+};
+#endif // SITRONIX_SENSOR_KEY
+
+#ifdef SITRONIX_TOUCH_KEY
+#define SITRONIX_NUMBER_TOUCH_KEY 4
+
+#ifdef SITRONIX_KEY_BOUNDARY_MANUAL_SPECIFY
+#define SITRONIX_TOUCH_RESOLUTION_X 480 /* max of X value in display area */
+#define SITRONIX_TOUCH_RESOLUTION_Y 854 /* max of Y value in display area */
+#define SITRONIX_TOUCH_GAP_Y   10  /* Gap between bottom of display and top of touch key */
+#define SITRONIX_TOUCH_MAX_Y 915  /* resolution of y axis of touch ic */
+struct sitronix_AA_key sitronix_key_array[SITRONIX_NUMBER_TOUCH_KEY] = {
+       {15, 105, SITRONIX_TOUCH_RESOLUTION_Y + SITRONIX_TOUCH_GAP_Y, SITRONIX_TOUCH_MAX_Y, KEY_MENU}, /* MENU */
+       {135, 225, SITRONIX_TOUCH_RESOLUTION_Y + SITRONIX_TOUCH_GAP_Y, SITRONIX_TOUCH_MAX_Y, KEY_HOME},
+       {255, 345, SITRONIX_TOUCH_RESOLUTION_Y + SITRONIX_TOUCH_GAP_Y, SITRONIX_TOUCH_MAX_Y, KEY_BACK}, /* KEY_EXIT */
+       {375, 465, SITRONIX_TOUCH_RESOLUTION_Y + SITRONIX_TOUCH_GAP_Y, SITRONIX_TOUCH_MAX_Y, KEY_SEARCH},
+};
+#else
+#define SCALE_KEY_HIGH_Y 15
+struct sitronix_AA_key sitronix_key_array[SITRONIX_NUMBER_TOUCH_KEY] = {
+       {0, 0, 0, 0, KEY_MENU}, /* MENU */
+       {0, 0, 0, 0, KEY_HOME},
+       {0, 0, 0, 0, KEY_BACK}, /* KEY_EXIT */
+       {0, 0, 0, 0, KEY_SEARCH},
+};
+
+#endif // SITRONIX_KEY_BOUNDARY_MANUAL_SPECIFY
+#endif // SITRONIX_TOUCH_KEY
+struct sitronix_ts_data {
+       uint16_t addr;
+       struct i2c_client *client;
+       struct input_dev *input_dev;
+#if defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+       struct input_dev *keyevent_input;
+#endif // defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+       int use_irq;
+       struct hrtimer timer;
+#ifndef SITRONIX_INT_POLLING_MODE
+       struct work_struct  work;
+#else
+       struct delayed_work work;
+#endif // SITRONIX_INT_POLLING_MODE
+       void (*reset_ic)(void);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       struct early_suspend early_suspend;
+#endif // CONFIG_HAS_EARLYSUSPEND
+       uint8_t fw_revision[4];
+       int resolution_x;
+       int resolution_y;
+       uint8_t max_touches;
+       uint8_t touch_protocol_type;
+       uint8_t pixel_length;
+       int suspend_state;
+};
+
+static unsigned char initkey_code[] =
+{
+    KEY_BACK,  KEY_HOMEPAGE, KEY_MENU
+};
+
+static int i2cErrorCount = 0;
+
+#ifdef SITRONIX_MONITOR_THREAD
+static struct task_struct * SitronixMonitorThread = NULL;
+static int gMonitorThreadSleepInterval = 300; // 0.3 sec
+static atomic_t iMonitorThreadPostpone = ATOMIC_INIT(0);
+
+static uint8_t PreCheckData[4] ;
+static int StatusCheckCount = 0;
+static int sitronix_ts_monitor_thread(void *data);
+static int sitronix_ts_delay_monitor_thread_start = DELAY_MONITOR_THREAD_START_PROBE; 
+#endif // SITRONIX_MONITOR_THREAD
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void sitronix_ts_early_suspend(struct early_suspend *h);
+static void sitronix_ts_late_resume(struct early_suspend *h);
+#endif // CONFIG_HAS_EARLYSUSPEND
+
+static MTD_STRUCTURE sitronix_ts_gMTDPreStructure[SITRONIX_MAX_SUPPORTED_POINT]={{0}};
+
+static struct sitronix_ts_data *sitronix_ts_gpts = NULL;
+static int sitronix_ts_irq_on = 0;
+
+#ifdef SITRONIX_FW_UPGRADE_FEATURE
+int      sitronix_release(struct inode *, struct file *);
+int      sitronix_open(struct inode *, struct file *);
+ssize_t  sitronix_write(struct file *file, const char *buf, size_t count, loff_t *ppos);
+ssize_t  sitronix_read(struct file *file, char *buf, size_t count, loff_t *ppos);
+long    sitronix_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+static struct cdev sitronix_cdev;
+static struct class *sitronix_class;
+static int sitronix_major = 0;
+
+int  sitronix_open(struct inode *inode, struct file *filp)
+{
+       return 0;
+}
+EXPORT_SYMBOL(sitronix_open);
+
+int  sitronix_release(struct inode *inode, struct file *filp)
+{
+       return 0;
+}
+EXPORT_SYMBOL(sitronix_release);
+
+ssize_t  sitronix_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+       int ret;
+       char *tmp;
+
+       if (count > 8192)
+               count = 8192;
+
+       tmp = (char *)kmalloc(count,GFP_KERNEL);
+       if (tmp==NULL)
+               return -ENOMEM;
+       if (copy_from_user(tmp,buf,count)) {
+               kfree(tmp);
+               return -EFAULT;
+       }
+       UpgradeMsg("writing %zu bytes.\n", count);
+
+       ret = i2c_master_send(sitronix_ts_gpts->client, tmp, count);
+       kfree(tmp);
+       return ret;
+}
+EXPORT_SYMBOL(sitronix_write);
+
+ssize_t  sitronix_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+       char *tmp;
+       int ret;
+
+       if (count > 8192)
+               count = 8192;
+
+       tmp = (char *)kmalloc(count,GFP_KERNEL);
+       if (tmp==NULL)
+               return -ENOMEM;
+
+       UpgradeMsg("reading %zu bytes.\n", count);
+
+       ret = i2c_master_recv(sitronix_ts_gpts->client, tmp, count);
+       if (ret >= 0)
+               ret = copy_to_user(buf,tmp,count)?-EFAULT:ret;
+       kfree(tmp);
+       return ret;
+}
+EXPORT_SYMBOL(sitronix_read);
+
+static int sitronix_ts_resume(struct i2c_client *client);
+static int sitronix_ts_suspend(struct i2c_client *client, pm_message_t mesg);
+long    sitronix_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+       int err = 0;
+       int retval = 0;
+       uint8_t temp[4];
+
+       if (_IOC_TYPE(cmd) != SMT_IOC_MAGIC) return -ENOTTY;
+       if (_IOC_NR(cmd) > SMT_IOC_MAXNR) return -ENOTTY;
+       if (_IOC_DIR(cmd) & _IOC_READ)
+               err = !access_ok(VERIFY_WRITE,(void __user *)arg,\
+                                _IOC_SIZE(cmd));
+       else if (_IOC_DIR(cmd) & _IOC_WRITE)
+               err =  !access_ok(VERIFY_READ,(void __user *)arg,\
+                                 _IOC_SIZE(cmd));
+       if (err) return -EFAULT;
+
+       switch(cmd) {
+               case IOCTL_SMT_GET_DRIVER_REVISION:
+                       UpgradeMsg("IOCTL_SMT_GET_DRIVER_REVISION\n");
+                       temp[0] = SITRONIX_TOUCH_DRIVER_VERSION;
+                       if(copy_to_user((uint8_t __user *)arg, &temp[0], 1)){
+                               UpgradeMsg("fail to get driver version\n");
+                               retval = -EFAULT;
+                       }
+                       break;
+               case IOCTL_SMT_GET_FW_REVISION:
+                       UpgradeMsg("IOCTL_SMT_GET_FW_REVISION\n");
+                       if(copy_to_user((uint8_t __user *)arg, &sitronix_ts_gpts->fw_revision[0], 4))
+                                       retval = -EFAULT;
+                       break;
+               case IOCTL_SMT_ENABLE_IRQ:
+                       UpgradeMsg("IOCTL_SMT_ENABLE_IRQ\n");
+                       if(!sitronix_ts_irq_on){
+                               sitronix_ts_irq_on = 1;
+                               enable_irq(sitronix_ts_gpts->client->irq);
+#ifdef SITRONIX_MONITOR_THREAD
+                               atomic_set(&iMonitorThreadPostpone,1);
+                               SitronixMonitorThread = kthread_run(sitronix_ts_monitor_thread,"Sitronix","Monitorthread");
+                               if(IS_ERR(SitronixMonitorThread))
+                                       SitronixMonitorThread = NULL;
+#endif // SITRONIX_MONITOR_THREAD
+                       }
+                       break;
+               case IOCTL_SMT_DISABLE_IRQ:
+                       UpgradeMsg("IOCTL_SMT_DISABLE_IRQ\n");
+                       if(sitronix_ts_irq_on){
+                               sitronix_ts_irq_on = 0;
+                               disable_irq_nosync(sitronix_ts_gpts->client->irq);
+#ifdef SITRONIX_MONITOR_THREAD
+                               if(SitronixMonitorThread){
+                                       kthread_stop(SitronixMonitorThread);
+                                       SitronixMonitorThread = NULL;
+                               }
+#endif // SITRONIX_MONITOR_THREAD
+                       }
+                       break;
+               case IOCTL_SMT_RESUME:
+                       UpgradeMsg("IOCTL_SMT_RESUME\n");
+                       sitronix_ts_resume(sitronix_ts_gpts->client);
+                       break;
+               case IOCTL_SMT_SUSPEND:
+                       UpgradeMsg("IOCTL_SMT_SUSPEND\n");
+                       sitronix_ts_suspend(sitronix_ts_gpts->client, PMSG_SUSPEND);
+                       break;
+               case IOCTL_SMT_HW_RESET:
+                       UpgradeMsg("IOCTL_SMT_HW_RESET\n");
+                       if(sitronix_ts_gpts->reset_ic)
+                               sitronix_ts_gpts->reset_ic();
+                       break;
+               default:
+                       retval = -ENOTTY;
+       }
+
+       return retval;
+}
+EXPORT_SYMBOL(sitronix_ioctl);
+#endif // SITRONIX_FW_UPGRADE_FEATURE
+
+static int sitronix_get_fw_revision(struct sitronix_ts_data *ts)
+{
+       int ret = 0;
+       uint8_t buffer[4];
+
+       buffer[0] = FIRMWARE_REVISION_3;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("send fw revision command error (%d)\n", ret);
+               return ret;
+       }
+       ret = i2c_master_recv(ts->client, buffer, 4);
+       if (ret < 0){
+               printk("read fw revision error (%d)\n", ret);
+               return ret;
+       }else{
+               memcpy(ts->fw_revision, buffer, 4);
+               printk("fw revision (hex) = %x %x %x %x\n", buffer[0], buffer[1], buffer[2], buffer[3]);
+       }
+       return 0;
+}
+
+static int sitronix_get_max_touches(struct sitronix_ts_data *ts)
+{
+       int ret = 0;
+       uint8_t buffer[1];
+
+       buffer[0] = MAX_NUM_TOUCHES;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("send max touches command error (%d)\n", ret);
+               return ret;
+       }
+       ret = i2c_master_recv(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("read max touches error (%d)\n", ret);
+               return ret;
+       }else{
+               ts->max_touches = buffer[0];
+               printk("max touches = %d \n",ts->max_touches);
+       }
+       return 0;
+}
+
+static int sitronix_get_protocol_type(struct sitronix_ts_data *ts)
+{
+       int ret = 0;
+       uint8_t buffer[1];
+
+       buffer[0] = I2C_PROTOCOL;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("send i2c protocol command error (%d)\n", ret);
+               return ret;
+       }
+       ret = i2c_master_recv(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("read i2c protocol error (%d)\n", ret);
+               return ret;
+       }else{
+               ts->touch_protocol_type = buffer[0] & I2C_PROTOCOL_BMSK;
+               if(ts->touch_protocol_type == SITRONIX_A_TYPE)
+                       ts->pixel_length = PIXEL_DATA_LENGTH_A;
+               else if(ts->touch_protocol_type == SITRONIX_B_TYPE)
+                       ts->pixel_length = PIXEL_DATA_LENGTH_B;
+               else
+                       ts->pixel_length = PIXEL_DATA_LENGTH_A;
+               printk("i2c protocol = %d \n", ts->touch_protocol_type);
+       }
+       return 0;
+}
+
+static int sitronix_get_resolution(struct sitronix_ts_data *ts)
+{
+       int ret = 0;
+       uint8_t buffer[3];
+
+       buffer[0] = XY_RESOLUTION_HIGH;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("send resolution command error (%d)\n", ret);
+               return ret;
+       }
+       ret = i2c_master_recv(ts->client, buffer, 3);
+       if (ret < 0){
+               printk("read resolution error (%d)\n", ret);
+               return ret;
+       }else{
+               ts->resolution_x = ((buffer[0] & (X_RES_H_BMSK << X_RES_H_SHFT)) << 4) | buffer[1];
+               ts->resolution_y = ((buffer[0] & Y_RES_H_BMSK) << 8) | buffer[2];
+               printk("resolution = %d x %d\n", ts->resolution_x, ts->resolution_y);
+       }
+       return 0;
+}
+
+static int sitronix_ts_set_powerdown_bit(struct sitronix_ts_data *ts, int value)
+{
+       int ret = 0;
+       uint8_t buffer[2];
+
+       DbgMsg("%s, value = %d\n", __FUNCTION__, value);
+       buffer[0] = DEVICE_CONTROL_REG;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("send device control command error (%d)\n", ret);
+               return ret;
+       }
+
+       ret = i2c_master_recv(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("read device control status error (%d)\n", ret);
+               return ret;
+       }else{
+               DbgMsg("dev status = %d \n", buffer[0]);
+       }
+
+       if(value == 0)
+               buffer[1] = buffer[0] & 0xfd;
+       else
+               buffer[1] = buffer[0] | 0x2;
+
+       buffer[0] = DEVICE_CONTROL_REG;
+       ret = i2c_master_send(ts->client, buffer, 2);
+       if (ret < 0){
+               printk("write power down error (%d)\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int sitronix_ts_get_touch_info(struct sitronix_ts_data *ts)
+{
+       int ret = 0;
+       ret = sitronix_get_resolution(ts);
+       if(ret < 0)
+               return ret;
+       ret = sitronix_get_fw_revision(ts);
+       if(ret < 0)
+               return ret;
+       if((ts->fw_revision[0] == 0) && (ts->fw_revision[1] == 0)){
+               ts->touch_protocol_type = SITRONIX_B_TYPE;
+               ts->pixel_length = PIXEL_DATA_LENGTH_B;
+               ts->max_touches = 2;
+               printk("i2c protocol = %d \n", ts->touch_protocol_type);
+               printk("max touches = %d \n",ts->max_touches);
+       }else{
+               ret = sitronix_get_protocol_type(ts);
+               if(ret < 0)
+                       return ret;
+               if(ts->touch_protocol_type == SITRONIX_B_TYPE){
+                       ts->max_touches = 2;
+                       printk("max touches = %d \n",ts->max_touches);
+               }else{
+                       ret = sitronix_get_max_touches(ts);
+                       if(ret < 0)
+                               return ret;
+               }
+       }
+       return 0;
+}
+
+static int sitronix_ts_get_device_status(struct sitronix_ts_data *ts, uint8_t *dev_status)
+{
+       int ret = 0;
+       uint8_t buffer[8];
+
+       DbgMsg("%s\n", __FUNCTION__);
+       buffer[0] = STATUS_REG;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("send status reg command error (%d)\n", ret);
+               return ret;
+       }
+
+       ret = i2c_master_recv(ts->client, buffer, 8);
+       if (ret < 0){
+               printk("read status reg error (%d)\n", ret);
+               return ret;
+       }else{
+               DbgMsg("status reg = %d \n", buffer[0]);
+       }
+
+       *dev_status = buffer[0] & 0xf;
+
+       return 0;
+}
+
+static int sitronix_ts_Enhance_Function_control(struct sitronix_ts_data *ts, uint8_t *value)
+{
+       int ret = 0;
+       uint8_t buffer[4];
+
+       DbgMsg("%s\n", __FUNCTION__);
+       buffer[0] = 0xF0;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("send Enhance Function command error (%d)\n", ret);
+               return ret;
+       }
+
+       ret = i2c_master_recv(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("read Enhance Functions status error (%d)\n", ret);
+               return ret;
+       }else{
+               DbgMsg("Enhance Functions status = %d \n", buffer[0]);
+       }
+
+       *value = buffer[0] & 0x4;
+
+       return 0;
+}
+
+static int sitronix_ts_FW_Bank_Select(struct sitronix_ts_data *ts, uint8_t value)
+{
+       int ret = 0;
+       uint8_t buffer[1];
+
+       DbgMsg("%s\n", __FUNCTION__);
+       buffer[0] = 0xF1;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("send FW Bank Select command error (%d)\n", ret);
+               return ret;
+       }
+
+       ret = i2c_master_recv(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("read FW Bank Select status error (%d)\n", ret);
+               return ret;
+       }else{
+               DbgMsg("FW Bank Select status = %d \n", buffer[0]);
+       }
+
+       buffer[1] = ((buffer[0] & 0xfc) | value);
+       buffer[0] = 0xF1;
+       ret = i2c_master_send(ts->client, buffer, 2);
+       if (ret < 0){
+               printk("send FW Bank Select command error (%d)\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int sitronix_get_id_info(struct sitronix_ts_data *ts, uint8_t *id_info)
+{
+       int ret = 0;
+       uint8_t buffer[4];
+
+       buffer[0] = 0x0C;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0){
+               printk("send id info command error (%d)\n", ret);
+               return ret;
+       }
+       ret = i2c_master_recv(ts->client, buffer, 4);
+       if (ret < 0){
+               printk("read id info error (%d)\n", ret);
+               return ret;
+       }else{
+               memcpy(id_info, buffer, 4);
+       }
+       return 0;
+}
+
+static int sitronix_ts_identify(struct sitronix_ts_data *ts)
+{
+       int ret = 0;
+       uint8_t id[4];
+       uint8_t Enhance_Function = 0;
+
+       ret = sitronix_ts_FW_Bank_Select(ts, 1);
+       if(ret < 0)
+               return ret;
+       ret = sitronix_ts_Enhance_Function_control(ts, &Enhance_Function);
+       if(ret < 0)
+               return ret;
+       if(Enhance_Function == 0x4){
+               ret = sitronix_get_id_info(ts, &id[0]);
+               if(ret < 0)
+                       return ret;
+               printk("id (hex) = %x %x %x %x\n", id[0], id[1], id[2], id[3]);
+               if((id[0] == 1)&&(id[1] == 2)&&(id[2] == 0xb)&&(id[3] == 1)){
+                       return 0;
+               }else{
+                       printk("Error: It is not Sitronix IC\n");
+                       return -1;
+               }
+       }else{
+               printk("Error: Can not get ID of Sitronix IC\n");
+               return -1;
+       }
+}
+
+#ifdef SITRONIX_MONITOR_THREAD
+static int sitronix_ts_monitor_thread(void *data)
+{
+       int ret = 0;
+       uint8_t buffer[4];
+       int result = 0;
+       int once = 1;
+       DbgMsg("%s:\n", __FUNCTION__);
+
+       printk("delay %d ms\n", sitronix_ts_delay_monitor_thread_start);
+       msleep(sitronix_ts_delay_monitor_thread_start);
+       while(!kthread_should_stop()){
+               DbgMsg("%s:\n", "Sitronix_ts_monitoring");
+               if(atomic_read(&iMonitorThreadPostpone)){
+                               atomic_set(&iMonitorThreadPostpone,0);
+               }else{
+                       if(once == 1){
+                               buffer[0] = DEVICE_CONTROL_REG;
+                               ret = i2c_master_send(sitronix_ts_gpts->client, buffer, 1);
+                               if (ret < 0){
+                                       DbgMsg("send device control command error (%d)\n", ret);
+                                       goto exit_i2c_invalid;
+                               }
+                               ret = i2c_master_recv(sitronix_ts_gpts->client, buffer, 1);
+                               if (ret < 0){
+                                       DbgMsg("read device control status error (%d)\n", ret);
+                                       goto exit_i2c_invalid;
+                               }else{
+                                       DbgMsg("read DEVICE_CONTROL_REG status = %d \n", buffer[0]);
+                               }
+                               buffer[0] &= 0xf3;
+                               ret = i2c_master_send(sitronix_ts_gpts->client, buffer, 1);
+                               if (ret < 0){
+                                       DbgMsg("write power down error (%d)\n", ret);
+                                       goto exit_i2c_invalid;
+                               }
+                               once = 0;
+                       }
+                       buffer[0] = 0x40;
+                       ret = i2c_master_send(sitronix_ts_gpts->client, buffer, 1);
+                       if (ret < 0){
+                               DbgMsg("send device control command error (%d)\n", ret);
+                               goto exit_i2c_invalid;
+                       }
+                       ret = i2c_master_recv(sitronix_ts_gpts->client, buffer, 4);
+                       if (ret < 0){
+                               DbgMsg("read device 1D data error (%d)\n", ret);
+                               goto exit_i2c_invalid;
+                       }else{
+                               DbgMsg("1D data h40-43 = %d, %d, %d, %d \n", buffer[0], buffer[1], buffer[2], buffer[3]);
+                               result = 1;
+                               if ((PreCheckData[0] == buffer[0]) && (PreCheckData[1] == buffer[1]) && 
+                               (PreCheckData[2] == buffer[2]) && (PreCheckData[3] == buffer[3]))
+                                       StatusCheckCount ++;
+                               else
+                                       StatusCheckCount =0;
+                               PreCheckData[0] = buffer[0];
+                               PreCheckData[1] = buffer[1];
+                               PreCheckData[2] = buffer[2];
+                               PreCheckData[3] = buffer[3];
+                               if (3 <= StatusCheckCount){
+                                       DbgMsg("IC Status doesn't update! \n");
+                                       result = -1;
+                                       StatusCheckCount = 0;
+                               }
+                       }
+                       if (-1 == result){
+                               printk("Chip abnormal, reset it!\n");
+                               if(sitronix_ts_gpts->reset_ic)
+                                       sitronix_ts_gpts->reset_ic();
+                               i2cErrorCount = 0;
+                               StatusCheckCount = 0;
+                       }
+exit_i2c_invalid:
+                       if(0 == result){
+                               i2cErrorCount ++;
+                               if ((2 <= i2cErrorCount)){
+                                       printk("I2C abnormal, reset it!\n");
+                                       if(sitronix_ts_gpts->reset_ic)
+                                               sitronix_ts_gpts->reset_ic();
+                                       i2cErrorCount = 0;
+                                       StatusCheckCount = 0;
+                               }
+                       }else
+                               i2cErrorCount = 0;
+               }
+               msleep(gMonitorThreadSleepInterval);
+       }
+       DbgMsg("%s exit\n", __FUNCTION__);
+       return 0;
+}
+#endif // SITRONIX_MONITOR_THREAD
+
+static void sitronix_ts_work_func(struct work_struct *work)
+{
+       int tmp = 0, i = 0;
+#ifdef SITRONIX_TOUCH_KEY
+       int j;
+#endif // SITRONIX_TOUCH_KEY
+       int ret;
+#ifndef SITRONIX_INT_POLLING_MODE
+       struct sitronix_ts_data *ts = container_of(work, struct sitronix_ts_data, work);
+#else
+       struct sitronix_ts_data *ts = container_of(to_delayed_work(work), struct sitronix_ts_data, work);
+#endif // SITRONIX_INT_POLLING_MODE
+       uint8_t buffer[2+ SITRONIX_MAX_SUPPORTED_POINT * PIXEL_DATA_LENGTH_A];
+       static MTD_STRUCTURE MTDStructure[SITRONIX_MAX_SUPPORTED_POINT]={{0}};
+       uint8_t PixelCount = 0;
+       static uint8_t all_clear = 1;
+
+       DbgMsg("%s\n",  __FUNCTION__);
+       if(ts->suspend_state){
+               goto exit_invalid_data;
+       }
+
+       // get finger count
+       buffer[0] = FINGERS;
+       ret = i2c_master_send(ts->client, buffer, 1);
+       if (ret < 0)
+               printk("send finger command error (%d)\n", ret);
+       ret = i2c_master_recv(ts->client, buffer, 2 + ts->max_touches * ts->pixel_length);
+       if (ret < 0) {
+               printk("read finger error (%d)\n", ret);
+               i2cErrorCount ++;
+               goto exit_invalid_data;
+       }else{
+               i2cErrorCount = 0;
+#ifdef SITRONIX_FINGER_COUNT_REG_ENABLE
+               PixelCount = buffer[0] & FINGERS_BMSK ;
+#else
+               for(i = 0; i < ts->max_touches; i++){
+                       if(buffer[2 + i * ts->pixel_length] >= 0x80)
+                               PixelCount++;
+               }
+#endif // SITRONIX_FINGER_COUNT_REG_ENABLE
+               DbgMsg("fingers = %d\n", PixelCount);
+       }
+       DbgMsg("key buffer[1] = %d\n", buffer[1]);
+#ifdef SITRONIX_SENSOR_KEY
+       if (PixelCount == 0)
+       {
+               for(i = 0; i < SITRONIX_NUMBER_SENSOR_KEY; i++){
+                       if(buffer[1] & (1 << i)){
+                               DbgMsg("key[%d] down\n", i);
+                               input_event(ts->input_dev, EV_KEY, sitronix_sensor_key[i], 1);
+                       }else{
+                               DbgMsg("key[%d] up\n", i);
+                               input_event(ts->input_dev, EV_KEY, sitronix_sensor_key[i], 0);
+                       }
+               }
+       }
+#endif // SITRONIX_SENSOR_KEY
+
+       for(i = 0; i < ts->max_touches; i++){
+#ifndef SITRONIX_TOUCH_KEY
+               if((buffer[2 + ts->pixel_length * i] >> X_COORD_VALID_SHFT) == 1){
+                       MTDStructure[i].Pixel_X = ((buffer[2 + ts->pixel_length * i] & (X_COORD_H_BMSK << X_COORD_H_SHFT)) << 4) |  (buffer[2 + ts->pixel_length * i + X_COORD_L]);
+                       MTDStructure[i].Pixel_Y = ((buffer[2 + ts->pixel_length * i] & Y_COORD_H_BMSK) << 8) |  (buffer[2 + ts->pixel_length * i + Y_COORD_L]);
+                       MTDStructure[i].Current_Pressed_area = AREA_DISPLAY;
+               }else
+                       MTDStructure[i].Current_Pressed_area = AREA_NONE;
+#endif // SITRONIX_TOUCH_KEY
+       }
+       
+       if(PixelCount != 0)
+       {
+               for(i = 0; i < ts->max_touches; i++)
+               {
+#ifndef SITRONIX_TOUCH_KEY
+                       if(MTDStructure[i].Current_Pressed_area == AREA_DISPLAY)
+                       {
+                               tmp = MTDStructure[i].Pixel_X;
+                               MTDStructure[i].Pixel_X = MTDStructure[i].Pixel_Y;
+                               MTDStructure[i].Pixel_Y = tmp;
+                               
+                               MTDStructure[i].Pixel_X = MTDStructure[i].Pixel_X < 50  ? 3 + MTDStructure[i].Pixel_X : MTDStructure[i].Pixel_X*97/100;
+                               MTDStructure[i].Pixel_Y = MTDStructure[i].Pixel_Y < 50  ? 3 + MTDStructure[i].Pixel_Y : MTDStructure[i].Pixel_Y*98/100;
+                               input_mt_slot(ts->input_dev, i);
+                               input_report_abs(ts->input_dev,  ABS_MT_TRACKING_ID, i);
+                               input_report_abs(ts->input_dev,  ABS_MT_TOUCH_MAJOR, 200);
+                               input_report_abs(ts->input_dev,  ABS_MT_POSITION_X, MTDStructure[i].Pixel_X);
+                               input_report_abs(ts->input_dev,  ABS_MT_POSITION_Y, 480 - MTDStructure[i].Pixel_Y);
+                               input_report_abs(ts->input_dev,  ABS_MT_WIDTH_MAJOR, 100);
+                               DbgMsg("lr[%d](%d, %d)+\n", i, MTDStructure[i].Pixel_X, MTDStructure[i].Pixel_Y);
+                       }else if(MTDStructure[i].Current_Pressed_area == AREA_NONE){
+                               DbgMsg("lr[%d](%d, %d)-\n", i, MTDStructure[i].Pixel_X, MTDStructure[i].Pixel_Y);
+                               input_mt_slot(ts->input_dev, i);        
+                               input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);        
+                       }
+                       memcpy(&sitronix_ts_gMTDPreStructure[i], &MTDStructure[i], sizeof(MTD_STRUCTURE));
+#endif // SITRONIX_TOUCH_KEY
+               }
+               all_clear = 0;
+#ifdef SITRONIX_INT_POLLING_MODE
+#ifdef SITRONIX_MONITOR_THREAD
+               atomic_set(&iMonitorThreadPostpone,1);
+#endif // SITRONIX_MONITOR_THREAD
+               schedule_delayed_work(&ts->work, msecs_to_jiffies(INT_POLLING_MODE_INTERVAL));
+#endif // SITRONIX_INT_POLLING_MODE
+       }
+       else
+       {
+               if(all_clear == 0)
+               {
+                       DbgMsg("lr: all_clear\n");
+                       for(i = 0; i < ts->max_touches; i++)
+                       {
+                               input_mt_slot(ts->input_dev, i);        
+                               input_report_abs(ts->input_dev,  ABS_MT_TRACKING_ID, -1);
+                       }
+                       all_clear = 1;
+               }
+               else
+               {
+                       DbgMsg("ignore dummy finger leave\n");
+               }
+#ifdef SITRONIX_INT_POLLING_MODE
+               if (ts->use_irq){
+                       sitronix_ts_irq_on = 1;
+                       enable_irq(ts->client->irq);
+               }
+#endif // SITRONIX_INT_POLLING_MODE
+       }
+       input_sync(ts->input_dev);
+
+exit_invalid_data:
+#if defined(SITRONIX_LEVEL_TRIGGERED)
+       if (ts->use_irq){
+               sitronix_ts_irq_on = 1;
+               enable_irq(ts->client->irq);
+       }
+#endif // defined(SITRONIX_LEVEL_TRIGGERED)
+       if ((2 <= i2cErrorCount)){
+               printk("I2C abnormal in work_func(), reset it!\n");
+               if(sitronix_ts_gpts->reset_ic)
+                       sitronix_ts_gpts->reset_ic();
+               i2cErrorCount = 0;
+#ifdef SITRONIX_MONITOR_THREAD
+               StatusCheckCount = 0;
+#endif // SITRONIX_MONITOR_THREAD
+       }
+}
+
+
+static irqreturn_t sitronix_ts_irq_handler(int irq, void *dev_id)
+{
+       struct sitronix_ts_data *ts = dev_id;
+
+//     DbgMsg("%s\n", __FUNCTION__);
+//     printk("lr:%s\n", __FUNCTION__);
+#if defined(SITRONIX_LEVEL_TRIGGERED) || defined(SITRONIX_INT_POLLING_MODE)
+       sitronix_ts_irq_on = 0;
+       disable_irq_nosync(ts->client->irq);
+#endif // defined(SITRONIX_LEVEL_TRIGGERED) || defined(SITRONIX_INT_POLLING_MODE)
+#ifdef SITRONIX_MONITOR_THREAD
+       atomic_set(&iMonitorThreadPostpone,1);
+#endif // SITRONIX_MONITOR_THREAD
+#ifndef SITRONIX_INT_POLLING_MODE
+       schedule_work(&ts->work);
+#else  
+       schedule_delayed_work(&ts->work, msecs_to_jiffies(0));
+#endif // SITRONIX_INT_POLLING_MODE
+       return IRQ_HANDLED;
+}
+
+static int sitronix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+#if defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+       int i;
+#endif // defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+       struct sitronix_ts_data *ts;
+       int ret = 0;
+       uint16_t max_x = 0, max_y = 0;
+       struct ft5x0x_platform_data *pdata;
+       uint8_t dev_status = 0;
+
+       printk("lr------> %s start ------\n", __FUNCTION__);
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               ret = -ENODEV;
+               goto err_check_functionality_failed;
+       }
+
+       ts = kzalloc(sizeof(*ts), GFP_KERNEL);
+       if (ts == NULL) {
+               ret = -ENOMEM;
+               goto err_alloc_data_failed;
+       }
+#ifndef SITRONIX_INT_POLLING_MODE
+       INIT_WORK(&ts->work, sitronix_ts_work_func);
+#else  
+       INIT_DELAYED_WORK(&ts->work, sitronix_ts_work_func);
+#endif // SITRONIX_INT_POLLING_MODE
+       ts->client = client;
+       i2c_set_clientdata(client, ts);
+       pdata = client->dev.platform_data;
+#if 0
+       if(pdata->reset_ic){
+               ts->reset_ic = pdata->reset_ic;
+               pdata->reset_ic();
+               mdelay(SITRONIX_TS_CHANGE_MODE_DELAY);
+       }
+#endif
+       if(pdata->init_platform_hw)
+               pdata->init_platform_hw();
+
+       sitronix_ts_gpts = ts;
+
+       ret = sitronix_ts_get_device_status(ts, &dev_status);
+       if((ret < 0) || (dev_status == 0x6))
+               goto err_device_info_error;
+
+       ret = sitronix_ts_get_touch_info(ts);
+       if(ret < 0)
+               goto err_device_info_error;
+
+       //ret = sitronix_ts_identify(ts);
+       //if(ret < 0)
+       //      goto err_device_info_error;
+
+#ifdef SITRONIX_MONITOR_THREAD
+       //== Add thread to monitor chip
+       atomic_set(&iMonitorThreadPostpone,1);
+       SitronixMonitorThread = kthread_run(sitronix_ts_monitor_thread,"Sitronix","Monitorthread");
+       if(IS_ERR(SitronixMonitorThread))
+               SitronixMonitorThread = NULL;
+#endif // SITRONIX_MONITOR_THREAD
+
+       ts->input_dev = input_allocate_device();
+       if (ts->input_dev == NULL){
+               printk("Can not allocate memory for input device.");
+               ret = -ENOMEM;
+               goto err_input_dev_alloc_failed;
+       }
+
+       ts->input_dev->name = "sitronix-i2c-touch-mt";
+       //set_bit(EV_KEY, ts->input_dev->evbit);
+       //set_bit(BTN_TOUCH, ts->input_dev->keybit);
+       //set_bit(EV_ABS, ts->input_dev->evbit);
+
+#if defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+       ts->keyevent_input = input_allocate_device();
+       if (ts->keyevent_input == NULL){
+               printk("Can not allocate memory for key input device.");
+               ret = -ENOMEM;
+               goto err_input_dev_alloc_failed;
+       }
+       ts->keyevent_input->name  = "sitronix-i2c-touch-key";
+       //set_bit(EV_KEY, ts->keyevent_input->evbit);
+#endif // defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+#if defined(SITRONIX_SENSOR_KEY)
+       for(i = 0; i < SITRONIX_NUMBER_SENSOR_KEY; i++){
+               //set_bit(sitronix_sensor_key[i], ts->keyevent_input->keybit);
+       }
+#endif // defined(SITRONIX_SENSOR_KEY)
+
+#ifndef SITRONIX_TOUCH_KEY
+       max_x = ts->resolution_x;
+       max_y = ts->resolution_y;
+#else
+#ifdef SITRONIX_KEY_BOUNDARY_MANUAL_SPECIFY
+       for(i = 0; i < SITRONIX_NUMBER_TOUCH_KEY; i++){
+               //set_bit(sitronix_key_array[i].code, ts->keyevent_input->keybit);
+       }
+       max_x = SITRONIX_TOUCH_RESOLUTION_X;
+       max_y = SITRONIX_TOUCH_RESOLUTION_Y;
+#else
+       for(i = 0; i < SITRONIX_NUMBER_TOUCH_KEY; i++){
+               sitronix_key_array[i].x_low = ((ts->resolution_x / SITRONIX_NUMBER_TOUCH_KEY ) * i ) + 15;
+               sitronix_key_array[i].x_high = ((ts->resolution_x / SITRONIX_NUMBER_TOUCH_KEY ) * (i + 1)) - 15;
+               sitronix_key_array[i].y_low = ts->resolution_y - ts->resolution_y / SCALE_KEY_HIGH_Y;
+               sitronix_key_array[i].y_high = ts->resolution_y;
+               DbgMsg("key[%d] %d, %d, %d, %d\n", i, sitronix_key_array[i].x_low, sitronix_key_array[i].x_high, sitronix_key_array[i].y_low, sitronix_key_array[i].y_high);
+               //set_bit(sitronix_key_array[i].code, ts->keyevent_input->keybit);
+
+       }
+       max_x = ts->resolution_x;
+       max_y = ts->resolution_y - ts->resolution_y / SCALE_KEY_HIGH_Y;
+#endif // SITRONIX_KEY_BOUNDARY_MANUAL_SPECIFY
+#endif // SITRONIX_TOUCH_KEY
+#if defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+       ret = input_register_device(ts->keyevent_input);
+       if(ret < 0){
+               printk("Can not register key input device.");
+               goto err_input_register_device_failed;
+       }
+#endif // defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+
+       __set_bit(EV_ABS, ts->input_dev->evbit);
+       __set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
+       set_bit(ABS_MT_POSITION_X, ts->input_dev->absbit);
+       set_bit(ABS_MT_POSITION_Y, ts->input_dev->absbit);
+       set_bit(ABS_MT_TOUCH_MAJOR, ts->input_dev->absbit);
+       set_bit(ABS_MT_WIDTH_MAJOR, ts->input_dev->absbit);
+       ts->max_touches = 5;
+
+       input_mt_init_slots(ts->input_dev, ts->max_touches);
+
+       input_set_abs_params(ts->input_dev,ABS_MT_POSITION_X, 0, 800, 0, 0);
+       input_set_abs_params(ts->input_dev,ABS_MT_POSITION_Y, 0, 480, 0, 0);
+       input_set_abs_params(ts->input_dev,ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+
+       for (i = 0; i < ARRAY_SIZE(initkey_code); i++) {
+               input_set_capability(ts->input_dev, EV_KEY, initkey_code[i]);
+       }
+
+       ret = input_register_device(ts->input_dev);
+       if(ret < 0){
+               printk("Can not register input device.");
+               goto err_input_register_device_failed;
+       }
+
+       ts->suspend_state = 0;
+       if (client->irq){
+#ifdef SITRONIX_LEVEL_TRIGGERED
+               ret = request_irq(client->irq, sitronix_ts_irq_handler, IRQF_TRIGGER_LOW | IRQF_DISABLED, client->name, ts);
+#else
+               ret = request_irq(client->irq, sitronix_ts_irq_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED, client->name, ts);
+#endif // SITRONIX_LEVEL_TRIGGERED
+               if (ret == 0){
+                       sitronix_ts_irq_on = 1;
+                       ts->use_irq = 1;
+               }else
+                       dev_err(&client->dev, "request_irq failed\n");
+       }
+#ifdef CONFIG_HAS_EARLYSUSPEND
+        ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+        ts->early_suspend.suspend = sitronix_ts_early_suspend;
+        ts->early_suspend.resume = sitronix_ts_late_resume;
+        register_early_suspend(&ts->early_suspend);
+#endif // CONFIG_HAS_EARLYSUSPEND
+
+       printk("lr------> %s end ------\n", __FUNCTION__);
+
+       return 0;
+
+err_input_register_device_failed:
+       input_free_device(ts->input_dev);
+#if defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+       input_free_device(ts->keyevent_input);
+#endif // defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+err_input_dev_alloc_failed:
+       kfree(ts);
+err_alloc_data_failed:
+err_check_functionality_failed:
+#ifdef SITRONIX_MONITOR_THREAD
+       if(SitronixMonitorThread){
+             kthread_stop(SitronixMonitorThread);
+             SitronixMonitorThread = NULL;
+       }
+#endif // SITRONIX_MONITOR_THREAD
+err_device_info_error:
+       gpio_free(RK2928_PIN1_PA3);
+       gpio_free(RK2928_PIN1_PB3);
+
+       return ret;
+}
+
+static int sitronix_ts_remove(struct i2c_client *client)
+{
+       struct sitronix_ts_data *ts = i2c_get_clientdata(client);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+       unregister_early_suspend(&ts->early_suspend);
+#endif // CONFIG_HAS_EARLYSUSPEND
+#ifdef SITRONIX_MONITOR_THREAD
+       if(SitronixMonitorThread){
+             kthread_stop(SitronixMonitorThread);
+             SitronixMonitorThread = NULL;
+       }
+#endif // SITRONIX_MONITOR_THREAD
+       if (ts->use_irq)
+               free_irq(client->irq, ts);
+       else
+               hrtimer_cancel(&ts->timer);
+       input_unregister_device(ts->input_dev);
+#if defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+       input_unregister_device(ts->keyevent_input);
+#endif // defined(SITRONIX_SENSOR_KEY) || defined (SITRONIX_TOUCH_KEY)
+       kfree(ts);
+       return 0;
+}
+
+static int sitronix_ts_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+       int ret = 0, i = 0;
+       struct sitronix_ts_data *ts = i2c_get_clientdata(client);
+
+       DbgMsg("%s\n", __FUNCTION__);
+#ifdef SITRONIX_MONITOR_THREAD
+       if(SitronixMonitorThread){
+               kthread_stop(SitronixMonitorThread);
+               SitronixMonitorThread = NULL;
+       }
+       sitronix_ts_delay_monitor_thread_start = DELAY_MONITOR_THREAD_START_RESUME;
+#endif // SITRONIX_MONITOR_THREAD
+       if(ts->use_irq){
+               sitronix_ts_irq_on = 0;
+               disable_irq_nosync(ts->client->irq);
+       }
+       ts->suspend_state = 1;
+
+       ret = sitronix_ts_set_powerdown_bit(ts, 1);
+#ifdef SITRONIX_WAKE_UP_TOUCH_BY_INT
+       gpio_direction_output(irq_to_gpio(client->irq), 1);
+#endif // SITRONIX_WAKE_UP_TOUCH_BY_INT
+       DbgMsg("%s return\n", __FUNCTION__);
+
+       for(i = 0; i < ts->max_touches; i++)
+       {
+               input_mt_slot(ts->input_dev, i);        
+               input_report_abs(ts->input_dev,  ABS_MT_TRACKING_ID, -1);
+       }
+       input_sync(ts->input_dev);
+
+       return 0;
+}
+
+static int sitronix_ts_resume(struct i2c_client *client)
+{
+#ifdef SITRONIX_WAKE_UP_TOUCH_BY_INT
+       unsigned int gpio;
+#else
+       int ret;
+#endif // SITRONIX_WAKE_UP_TOUCH_BY_INT
+       struct sitronix_ts_data *ts = i2c_get_clientdata(client);
+
+       DbgMsg("%s\n", __FUNCTION__);
+
+#ifdef SITRONIX_WAKE_UP_TOUCH_BY_INT
+       gpio = irq_to_gpio(client->irq);
+       gpio_set_value(gpio, 0);
+       gpio_direction_input(gpio);
+#else
+       ret = sitronix_ts_set_powerdown_bit(ts, 0);
+#endif // SITRONIX_WAKE_UP_TOUCH_BY_INT
+
+       ts->suspend_state = 0;
+       if(ts->use_irq){
+               sitronix_ts_irq_on = 1;
+               enable_irq(ts->client->irq);
+       }
+#ifdef SITRONIX_MONITOR_THREAD
+       atomic_set(&iMonitorThreadPostpone,1);
+       SitronixMonitorThread = kthread_run(sitronix_ts_monitor_thread,"Sitronix","Monitorthread");
+       if(IS_ERR(SitronixMonitorThread))
+               SitronixMonitorThread = NULL;
+#endif // SITRONIX_MONITOR_THREAD
+       DbgMsg("%s return\n", __FUNCTION__);
+
+       return 0;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void sitronix_ts_early_suspend(struct early_suspend *h)
+{
+       struct sitronix_ts_data *ts;
+       DbgMsg("%s\n", __FUNCTION__);
+       ts = container_of(h, struct sitronix_ts_data, early_suspend);
+       sitronix_ts_suspend(ts->client, PMSG_SUSPEND);
+}
+
+static void sitronix_ts_late_resume(struct early_suspend *h)
+{
+       struct sitronix_ts_data *ts;
+       DbgMsg("%s\n", __FUNCTION__);
+       ts = container_of(h, struct sitronix_ts_data, early_suspend);
+       sitronix_ts_resume(ts->client);
+}
+#endif // CONFIG_HAS_EARLYSUSPEND
+
+static const struct i2c_device_id sitronix_ts_id[] = {
+       { SITRONIX_I2C_TOUCH_DRV_NAME, 0 },
+       { }
+};
+
+static struct i2c_driver sitronix_ts_driver = {
+       .probe          = sitronix_ts_probe,
+       .remove         = sitronix_ts_remove,
+       .id_table       = sitronix_ts_id,
+       .driver = {
+               .name   = SITRONIX_I2C_TOUCH_DRV_NAME,
+       },
+};
+
+#ifdef SITRONIX_FW_UPGRADE_FEATURE
+static struct file_operations nc_fops = {
+       .owner =        THIS_MODULE,
+       .write          = sitronix_write,
+       .read           = sitronix_read,
+       .open           = sitronix_open,
+       .unlocked_ioctl = sitronix_ioctl,
+       .release        = sitronix_release,
+};
+#endif // SITRONIX_FW_UPGRADE_FEATURE
+
+static int __devinit sitronix_ts_init(void)
+{
+#ifdef SITRONIX_FW_UPGRADE_FEATURE
+       int result;
+       int err = 0;
+#endif // SITRONIX_FW_UPGRADE_FEATURE
+       printk("Sitronix touch driver %d.%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR, DRIVER_PATCHLEVEL);
+       printk("Release date: %s\n", DRIVER_DATE);
+#ifdef SITRONIX_FW_UPGRADE_FEATURE
+       dev_t devno = MKDEV(sitronix_major, 0);
+       result  = alloc_chrdev_region(&devno, 0, 1, SITRONIX_I2C_TOUCH_DEV_NAME);
+       if(result < 0){
+               printk("fail to allocate chrdev (%d) \n", result);
+               return 0;
+       }
+       sitronix_major = MAJOR(devno);
+        cdev_init(&sitronix_cdev, &nc_fops);
+       sitronix_cdev.owner = THIS_MODULE;
+       sitronix_cdev.ops = &nc_fops;
+        err =  cdev_add(&sitronix_cdev, devno, 1);
+       if(err){
+               printk("fail to add cdev (%d) \n", err);
+               return 0;
+       }
+
+       sitronix_class = class_create(THIS_MODULE, SITRONIX_I2C_TOUCH_DEV_NAME);
+       if (IS_ERR(sitronix_class)) {
+               result = PTR_ERR(sitronix_class);
+               unregister_chrdev(sitronix_major, SITRONIX_I2C_TOUCH_DEV_NAME);
+               printk("fail to create class (%d) \n", result);
+               return result;
+       }
+       device_create(sitronix_class, NULL, MKDEV(sitronix_major, 0), NULL, SITRONIX_I2C_TOUCH_DEV_NAME);
+#endif // SITRONIX_FW_UPGRADE_FEATURE
+       return i2c_add_driver(&sitronix_ts_driver);
+}
+
+static void __exit sitronix_ts_exit(void)
+{
+#ifdef SITRONIX_FW_UPGRADE_FEATURE
+       dev_t dev_id = MKDEV(sitronix_major, 0);
+#endif // SITRONIX_FW_UPGRADE_FEATURE
+       i2c_del_driver(&sitronix_ts_driver);
+#ifdef SITRONIX_FW_UPGRADE_FEATURE
+       cdev_del(&sitronix_cdev);
+
+       device_destroy(sitronix_class, dev_id); //delete device node under /dev
+       class_destroy(sitronix_class); //delete class created by us
+       unregister_chrdev_region(dev_id, 1);
+#endif // SITRONIX_FW_UPGRADE_FEATURE
+}
+
+module_init(sitronix_ts_init);
+module_exit(sitronix_ts_exit);
+
+MODULE_DESCRIPTION("Sitronix Multi-Touch Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/sitronix_ts_a720.h b/drivers/input/touchscreen/sitronix_ts_a720.h
new file mode 100755 (executable)
index 0000000..cb651c1
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * drivers/input/touchscreen/sitronix_i2c_touch.h
+ *
+ * Touchscreen driver for Sitronix
+ *
+ * Copyright (C) 2011 Sitronix Technology Co., Ltd.
+ *     Rudy Huang <rudy_huang@sitronix.com.tw>
+ */
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#ifndef __SITRONIX_I2C_TOUCH_h
+#define __SITRONIX_I2C_TOUCH_h
+
+#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
+
+#define SITRONIX_TOUCH_DRIVER_VERSION 0x03
+#define SITRONIX_MAX_SUPPORTED_POINT 5
+#define SITRONIX_I2C_TOUCH_DRV_NAME "sitronix"
+#define SITRONIX_I2C_TOUCH_DEV_NAME "sitronixDev"
+
+//#define SITRONIX_WAKE_UP_TOUCH_BY_INT
+
+//#define SITRONIX_MONITOR_THREAD
+#define DELAY_MONITOR_THREAD_START_PROBE 10000
+#define DELAY_MONITOR_THREAD_START_RESUME 3000
+#define SITRONIX_FW_UPGRADE_FEATURE
+#define SITRONIX_LEVEL_TRIGGERED
+// When enable_irq() is invoked, irq will be sent once while INT is not triggered if CONFIG_HARDIRQS_SW_RESEND is set.
+// This behavior is implemented by linux kernel, it is used to prevent irq from losting when irq is edge-triggered mode.
+#ifndef SITRONIX_LEVEL_TRIGGERED
+#define SITRONIX_INT_POLLING_MODE
+#define INT_POLLING_MODE_INTERVAL 14
+#endif // SITRONIX_LEVEL_TRIGGERED
+#define SITRONIX_FINGER_COUNT_REG_ENABLE
+
+//#define EnableDbgMsg 0
+//#define EnableUpgradeMsg 1
+
+#ifdef EnableDbgMsg
+#define DbgMsg(arg...) printk(arg)
+#else
+#define DbgMsg(arg...)
+#endif
+
+#ifdef EnableUpgradeMsg
+#define UpgradeMsg(arg...) printk(arg)
+#else
+#define UpgradeMsg(arg...)
+#endif
+
+typedef enum{
+       FIRMWARE_VERSION,
+       STATUS_REG,
+       DEVICE_CONTROL_REG,
+       TIMEOUT_TO_IDLE_REG,
+       XY_RESOLUTION_HIGH,
+       X_RESOLUTION_LOW,
+       Y_RESOLUTION_LOW,
+       FIRMWARE_REVISION_3 = 0x0C,
+       FIRMWARE_REVISION_2,
+       FIRMWARE_REVISION_1,
+       FIRMWARE_REVISION_0,
+       FINGERS,
+       KEYS_REG,
+       XY0_COORD_H,
+       X0_COORD_L,
+       Y0_COORD_L,
+       I2C_PROTOCOL = 0x3E,
+       MAX_NUM_TOUCHES,
+       DATA_0_HIGH,
+       DATA_0_LOW,
+
+       PAGE_REG = 0xff,
+}RegisterOffset;
+
+#define SITRONIX_TS_CHANGE_MODE_DELAY 150
+
+typedef enum{
+       XY_COORD_H,
+       X_COORD_L,
+       Y_COORD_L,
+       PIXEL_DATA_LENGTH_B,
+       PIXEL_DATA_LENGTH_A,
+}PIXEL_DATA_FORMAT;
+
+#define X_RES_H_SHFT 4
+#define X_RES_H_BMSK 0xf
+#define Y_RES_H_SHFT 0
+#define Y_RES_H_BMSK 0xf
+#define FINGERS_SHFT 0
+#define FINGERS_BMSK 0xf
+#define X_COORD_VALID_SHFT 7
+#define X_COORD_VALID_BMSK 0x1
+#define X_COORD_H_SHFT 4
+#define X_COORD_H_BMSK 0x7
+#define Y_COORD_H_SHFT 0
+#define Y_COORD_H_BMSK 0x7
+
+typedef enum{
+       SITRONIX_A_TYPE = 1,
+       SITRONIX_B_TYPE,
+}I2C_PROTOCOL_TYPE;
+
+#define I2C_PROTOCOL_SHFT 0x0
+#define I2C_PROTOCOL_BMSK 0x3
+
+#define SMT_IOC_MAGIC   0xf1
+
+enum{
+       SMT_GET_DRIVER_REVISION = 1,
+       SMT_GET_FW_REVISION,
+       SMT_ENABLE_IRQ,
+       SMT_DISABLE_IRQ,
+       SMT_RESUME,
+       SMT_SUSPEND,
+       SMT_HW_RESET,
+       SMT_IOC_MAXNR,
+};
+
+#define IOCTL_SMT_GET_DRIVER_REVISION                          _IOC(_IOC_READ,  SMT_IOC_MAGIC, SMT_GET_DRIVER_REVISION,                        1)
+#define IOCTL_SMT_GET_FW_REVISION                                      _IOC(_IOC_READ,  SMT_IOC_MAGIC, SMT_GET_FW_REVISION,                            4)
+#define IOCTL_SMT_ENABLE_IRQ                                   _IOC(_IOC_NONE, SMT_IOC_MAGIC, SMT_ENABLE_IRQ, 0)
+#define IOCTL_SMT_DISABLE_IRQ                                  _IOC(_IOC_NONE, SMT_IOC_MAGIC, SMT_DISABLE_IRQ, 0)
+#define IOCTL_SMT_RESUME                                       _IOC(_IOC_NONE, SMT_IOC_MAGIC, SMT_RESUME, 0)
+#define IOCTL_SMT_SUSPEND                                      _IOC(_IOC_NONE, SMT_IOC_MAGIC, SMT_SUSPEND, 0)
+#define IOCTL_SMT_HW_RESET                                     _IOC(_IOC_NONE, SMT_IOC_MAGIC, SMT_HW_RESET, 0)
+
+#define SITRONIX_SENSOR_KEY
+//#define SITRONIX_TOUCH_KEY
+//#define SITRONIX_KEY_BOUNDARY_MANUAL_SPECIFY
+
+typedef struct _tag_MTD_STRUCTURE{
+       u16 Pixel_X;
+       u16 Pixel_Y;
+       u8 First_Pressed_area; /* 0: no press; 1: display; 2: touch key */
+       u8 Current_Pressed_area; /* 0: no press; 1: display; 2: touch key */
+       unsigned int First_key_index; 
+       unsigned int Current_key_index; 
+}MTD_STRUCTURE, *PMTD_STRUCTURE;
+
+#ifndef SITRONIX_TOUCH_KEY
+enum{
+       AREA_NONE,
+       AREA_DISPLAY,
+};
+#else
+enum{
+       AREA_NONE,
+       AREA_DISPLAY,
+       AREA_KEY,
+       AREA_INVALID,
+};
+
+struct sitronix_AA_key{
+       int x_low;
+       int x_high;
+       int y_low;
+       int y_high;
+       unsigned int code;
+};
+#endif // SITRONIX_TOUCH_KEY
+
+struct sitronix_i2c_touch_platform_data {
+       uint32_t version;       /* Use this entry for panels with */
+                               /* (major << 8 | minor) version or above. */
+                               /* If non-zero another array entry follows */
+       void (*reset_ic)(void);
+};
+
+#endif // __SITRONIX_I2C_TOUCH_h