summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/msg2233/mstar_drv_platform_porting_layer.c
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
committerYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
commit8e4bff4cab0ddac6060645b0715210484d02ff40 (patch)
tree3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/input/touchscreen/msg2233/mstar_drv_platform_porting_layer.c
Initial file dump from open source releaseHEADmaster
Diffstat (limited to 'drivers/input/touchscreen/msg2233/mstar_drv_platform_porting_layer.c')
-rw-r--r--drivers/input/touchscreen/msg2233/mstar_drv_platform_porting_layer.c910
1 files changed, 910 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/msg2233/mstar_drv_platform_porting_layer.c b/drivers/input/touchscreen/msg2233/mstar_drv_platform_porting_layer.c
new file mode 100644
index 00000000..d07e81dc
--- /dev/null
+++ b/drivers/input/touchscreen/msg2233/mstar_drv_platform_porting_layer.c
@@ -0,0 +1,910 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2006-2014 MStar Semiconductor, Inc.
+// All rights reserved.
+//
+// Unless otherwise stipulated in writing, any and all information contained
+// herein regardless in any format shall remain the sole proprietary of
+// MStar Semiconductor Inc. and be kept in strict confidence
+// (??MStar Confidential Information??) by the recipient.
+// Any unauthorized act including without limitation unauthorized disclosure,
+// copying, use, reproduction, sale, distribution, modification, disassembling,
+// reverse engineering and compiling of the contents of MStar Confidential
+// Information is unlawful and strictly prohibited. MStar hereby reserves the
+// rights to any and all damages, losses, costs and expenses resulting therefrom.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ *
+ * @file mstar_drv_platform_porting_layer.c
+ *
+ * @brief This file defines the interface of touch screen
+ *
+ *
+ */
+
+/*=============================================================*/
+// INCLUDE FILE
+/*=============================================================*/
+
+#include "mstar_drv_platform_porting_layer.h"
+#include "mstar_drv_ic_fw_porting_layer.h"
+#include "mstar_drv_platform_interface.h"
+#include "mstar_drv_utility_adaption.h"
+#include <linux/wakelock.h>
+
+#ifdef CONFIG_ENABLE_HOTKNOT
+#include "mstar_drv_hotknot_queue.h"
+#endif //CONFIG_ENABLE_HOTKNOT
+
+#ifdef CONFIG_ENABLE_JNI_INTERFACE
+#include "mstar_drv_jni_interface.h"
+#endif //CONFIG_ENABLE_JNI_INTERFACE
+
+/*=============================================================*/
+// EXTREN VARIABLE DECLARATION
+/*=============================================================*/
+
+extern struct kset *g_TouchKSet;
+extern struct kobject *g_TouchKObj;
+extern u8 g_GestureWakeupFlag;
+
+#ifdef CONFIG_ENABLE_PROXIMITY_DETECTION
+extern u8 g_FaceClosingTp;
+#endif //CONFIG_ENABLE_PROXIMITY_DETECTION
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+extern struct tpd_device *tpd;
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+#ifdef CONFIG_ENABLE_REGULATOR_POWER_ON
+extern struct regulator *g_ReguVdd;
+#endif //CONFIG_ENABLE_REGULATOR_POWER_ON
+#endif
+
+#ifdef CONFIG_ENABLE_HOTKNOT
+extern struct miscdevice hotknot_miscdevice;
+extern u8 g_HotKnotState;
+#endif //CONFIG_ENABLE_HOTKNOT
+
+extern u8 IS_FIRMWARE_DATA_LOG_ENABLED;
+/*=============================================================*/
+// LOCAL VARIABLE DEFINITION
+/*=============================================================*/
+
+struct mutex g_Mutex;
+spinlock_t _gIrqLock;
+extern struct wake_lock mstar_irq_lock;
+
+static struct work_struct _gFingerTouchWork;
+static int _gInterruptFlag = 0;
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+#ifdef CONFIG_ENABLE_NOTIFIER_FB
+static struct notifier_block _gFbNotifier;
+#else
+static struct early_suspend _gEarlySuspend;
+#endif //CONFIG_ENABLE_NOTIFIER_FB
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM || CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifndef CONFIG_USE_IRQ_INTERRUPT_FOR_MTK_PLATFORM
+static DECLARE_WAIT_QUEUE_HEAD(_gWaiter);
+static struct task_struct *_gThread = NULL;
+static int _gTpdFlag = 0;
+#endif //CONFIG_USE_IRQ_INTERRUPT_FOR_MTK_PLATFORM
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+/*=============================================================*/
+// GLOBAL VARIABLE DEFINITION
+/*=============================================================*/
+
+#ifdef CONFIG_TP_HAVE_KEY
+const int g_TpVirtualKey[] = {TOUCH_KEY_HOME, TOUCH_KEY_MENU, TOUCH_KEY_BACK, TOUCH_KEY_SEARCH};
+
+#ifdef CONFIG_ENABLE_REPORT_KEY_WITH_COORDINATE
+#define BUTTON_W (100)
+#define BUTTON_H (100)
+
+const int g_TpVirtualKeyDimLocal[MAX_KEY_NUM][4] = {{BUTTON_W/2*1,TOUCH_SCREEN_Y_MAX+BUTTON_H/2,BUTTON_W,BUTTON_H},{BUTTON_W/2*3,TOUCH_SCREEN_Y_MAX+BUTTON_H/2,BUTTON_W,BUTTON_H},{BUTTON_W/2*5,TOUCH_SCREEN_Y_MAX+BUTTON_H/2,BUTTON_W,BUTTON_H},{BUTTON_W/2*7,TOUCH_SCREEN_Y_MAX+BUTTON_H/2,BUTTON_W,BUTTON_H}};
+#endif //CONFIG_ENABLE_REPORT_KEY_WITH_COORDINATE
+#endif //CONFIG_TP_HAVE_KEY
+
+struct input_dev *g_InputDevice = NULL;
+int _gIrq = -1;
+
+/*=============================================================*/
+// LOCAL FUNCTION DEFINITION
+/*=============================================================*/
+
+/* read data through I2C then report data to input sub-system when interrupt occurred */
+static void _DrvPlatformLyrFingerTouchDoWork(struct work_struct *pWork)
+{
+ unsigned long nIrqFlag;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DrvIcFwLyrHandleFingerTouch(NULL, 0);
+
+ DBG("*** %s() _gInterruptFlag = %d ***\n", __func__, _gInterruptFlag); // add for debug
+
+// DBG("*** %s() spin_lock_irqsave() ***\n", __func__); // add for debug
+ spin_lock_irqsave(&_gIrqLock, nIrqFlag);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+
+ if (_gInterruptFlag == 0)
+ {
+ enable_irq(_gIrq);
+// DBG("*** %s() enable_irq(_gIrq) ***\n", __func__); // add for debug
+
+ _gInterruptFlag = 1;
+ }
+
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+
+ if (_gInterruptFlag == 0)
+ {
+ mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
+// DBG("*** %s() mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM) ***\n", __func__); // add for debug
+
+ _gInterruptFlag = 1;
+ }
+
+#endif
+ spin_unlock_irqrestore(&_gIrqLock, nIrqFlag);
+/*
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+ if (g_GestureWakeupFlag == 1)
+ wake_unlock(&mstar_irq_lock);
+#endif*/
+ //wake_unlock(&mstar_irq_lock);
+// DBG("*** %s() spin_unlock_irqrestore() ***\n", __func__); // add for debug
+}
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+/* The interrupt service routine will be triggered when interrupt occurred */
+static irqreturn_t _DrvPlatformLyrFingerTouchInterruptHandler(s32 nIrq, void *pDeviceId)
+{
+ unsigned long nIrqFlag;
+
+ //wake_lock_timeout(&mstar_irq_lock,msecs_to_jiffies(20000));
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("*** %s() _gInterruptFlag = %d ***\n", __func__, _gInterruptFlag); // add for debug
+
+// DBG("*** %s() spin_lock_irqsave() ***\n", __func__); // add for debug
+ spin_lock_irqsave(&_gIrqLock, nIrqFlag);
+
+ if (_gInterruptFlag == 1)
+ {
+ disable_irq_nosync(_gIrq);
+// DBG("*** %s() disable_irq_nosync(_gIrq) ***\n", __func__); // add for debug
+
+ _gInterruptFlag = 0;
+
+ schedule_work(&_gFingerTouchWork);
+ }
+
+ spin_unlock_irqrestore(&_gIrqLock, nIrqFlag);
+// DBG("*** %s() spin_unlock_irqrestore() ***\n", __func__); // add for debug
+ return IRQ_HANDLED;
+}
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+static void _DrvPlatformLyrFingerTouchInterruptHandler(void)
+{
+ unsigned long nIrqFlag;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("*** %s() _gInterruptFlag = %d ***\n", __func__, _gInterruptFlag); // add for debug
+
+// DBG("*** %s() spin_lock_irqsave() ***\n", __func__); // add for debug
+ spin_lock_irqsave(&_gIrqLock, nIrqFlag);
+
+#ifdef CONFIG_USE_IRQ_INTERRUPT_FOR_MTK_PLATFORM
+
+ if (_gInterruptFlag == 1)
+ {
+ mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);
+// DBG("*** %s() mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM) ***\n", __func__); // add for debug
+
+ _gInterruptFlag = 0;
+
+ schedule_work(&_gFingerTouchWork);
+ }
+
+#else
+
+ if (_gInterruptFlag == 1)
+ {
+ mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);
+// DBG("*** %s() mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM) ***\n", __func__); // add for debug
+
+ _gInterruptFlag = 0;
+
+ _gTpdFlag = 1;
+ wake_up_interruptible(&_gWaiter);
+ }
+#endif //CONFIG_USE_IRQ_INTERRUPT_FOR_MTK_PLATFORM
+
+ spin_unlock_irqrestore(&_gIrqLock, nIrqFlag);
+// DBG("*** %s() spin_unlock_irqrestore() ***\n", __func__); // add for debug
+}
+
+#ifndef CONFIG_USE_IRQ_INTERRUPT_FOR_MTK_PLATFORM
+static int _DrvPlatformLyrFingerTouchHandler(void *pUnUsed)
+{
+ unsigned long nIrqFlag;
+ struct sched_param param = { .sched_priority = RTPM_PRIO_TPD };
+ sched_setscheduler(current, SCHED_RR, &param);
+
+ DBG("*** %s() ***\n", __func__);
+
+ do
+ {
+ set_current_state(TASK_INTERRUPTIBLE);
+ wait_event_interruptible(_gWaiter, _gTpdFlag != 0);
+ _gTpdFlag = 0;
+
+ set_current_state(TASK_RUNNING);
+
+ DrvIcFwLyrHandleFingerTouch(NULL, 0);
+
+ DBG("*** %s() _gInterruptFlag = %d ***\n", __func__, _gInterruptFlag); // add for debug
+
+// DBG("*** %s() spin_lock_irqsave() ***\n", __func__); // add for debug
+ spin_lock_irqsave(&_gIrqLock, nIrqFlag);
+
+ if (_gInterruptFlag == 0)
+ {
+ mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
+// DBG("*** %s() mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM) ***\n", __func__); // add for debug
+
+ _gInterruptFlag = 1;
+ }
+
+ spin_unlock_irqrestore(&_gIrqLock, nIrqFlag);
+// DBG("*** %s() spin_unlock_irqrestore() ***\n", __func__); // add for debug
+
+ } while (!kthread_should_stop());
+
+ return 0;
+}
+#endif //CONFIG_USE_IRQ_INTERRUPT_FOR_MTK_PLATFORM
+#endif
+
+/*=============================================================*/
+// GLOBAL FUNCTION DEFINITION
+/*=============================================================*/
+
+#ifdef CONFIG_ENABLE_REGULATOR_POWER_ON
+void DrvPlatformLyrTouchDeviceRegulatorPowerOn(void)
+{
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ s32 nRetVal = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+ nRetVal = regulator_set_voltage(g_ReguVdd, 2800000, 2800000); // For specific SPRD BB chip(ex. SC7715) or QCOM BB chip(ex. MSM8610), need to enable this function call for correctly power on Touch IC.
+
+ if (nRetVal)
+ {
+ DBG("Could not set to 2800mv.\n");
+ }
+ regulator_enable(g_ReguVdd);
+
+ mdelay(20);
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+ //hwPowerOn(MT6323_POWER_LDO_VGP1, VOL_2800, "TP"); // For specific MTK BB chip(ex. MT6582), need to enable this function call for correctly power on Touch IC.
+ hwPowerOn(PMIC_APP_CAP_TOUCH_VDD, VOL_2800, "TP"); // For specific MTK BB chip(ex. MT6735), need to enable this function call for correctly power on Touch IC.
+#endif
+}
+#endif //CONFIG_ENABLE_REGULATOR_POWER_ON
+
+void DrvPlatformLyrTouchDevicePowerOn(void)
+{
+ DBG("*** %s() ***\n", __func__);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ gpio_direction_output(MS_TS_MSG_IC_GPIO_RST, 1);
+// gpio_set_value(MS_TS_MSG_IC_GPIO_RST, 1);
+ udelay(100);
+ gpio_set_value(MS_TS_MSG_IC_GPIO_RST, 0);
+ udelay(100);
+ gpio_set_value(MS_TS_MSG_IC_GPIO_RST, 1);
+ mdelay(25);
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+ mt_set_gpio_mode(MS_TS_MSG_IC_GPIO_RST, GPIO_CTP_RST_PIN_M_GPIO);
+ mt_set_gpio_dir(MS_TS_MSG_IC_GPIO_RST, GPIO_DIR_OUT);
+ mt_set_gpio_out(MS_TS_MSG_IC_GPIO_RST, GPIO_OUT_ONE);
+ udelay(100);
+
+ mt_set_gpio_mode(MS_TS_MSG_IC_GPIO_RST, GPIO_CTP_RST_PIN_M_GPIO);
+ mt_set_gpio_dir(MS_TS_MSG_IC_GPIO_RST, GPIO_DIR_OUT);
+ mt_set_gpio_out(MS_TS_MSG_IC_GPIO_RST, GPIO_OUT_ZERO);
+ udelay(100);
+
+#ifdef TPD_CLOSE_POWER_IN_SLEEP
+ hwPowerDown(TPD_POWER_SOURCE, "TP");
+ mdelay(100);
+ hwPowerOn(TPD_POWER_SOURCE, VOL_2800, "TP");
+ mdelay(10); // reset pulse
+#endif //TPD_CLOSE_POWER_IN_SLEEP
+
+ mt_set_gpio_mode(MS_TS_MSG_IC_GPIO_RST, GPIO_CTP_RST_PIN_M_GPIO);
+ mt_set_gpio_dir(MS_TS_MSG_IC_GPIO_RST, GPIO_DIR_OUT);
+ mt_set_gpio_out(MS_TS_MSG_IC_GPIO_RST, GPIO_OUT_ONE);
+ mdelay(25);
+#endif
+}
+
+void DrvPlatformLyrTouchDevicePowerOff(void)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ DrvIcFwLyrOptimizeCurrentConsumption();
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+// gpio_direction_output(MS_TS_MSG_IC_GPIO_RST, 0);
+ gpio_set_value(MS_TS_MSG_IC_GPIO_RST, 0);
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+ mt_set_gpio_mode(MS_TS_MSG_IC_GPIO_RST, GPIO_CTP_RST_PIN_M_GPIO);
+ mt_set_gpio_dir(MS_TS_MSG_IC_GPIO_RST, GPIO_DIR_OUT);
+ mt_set_gpio_out(MS_TS_MSG_IC_GPIO_RST, GPIO_OUT_ZERO);
+#ifdef TPD_CLOSE_POWER_IN_SLEEP
+ hwPowerDown(TPD_POWER_SOURCE, "TP");
+#endif //TPD_CLOSE_POWER_IN_SLEEP
+#endif
+}
+
+void DrvPlatformLyrTouchDeviceResetHw(void)
+{
+ DBG("*** %s() MS_TS_MSG_IC_GPIO_RST=%d***\n", __func__,MS_TS_MSG_IC_GPIO_RST);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ gpio_direction_output(MS_TS_MSG_IC_GPIO_RST, 1);
+// gpio_set_value(MS_TS_MSG_IC_GPIO_RST, 1);
+ udelay(100);
+ gpio_set_value(MS_TS_MSG_IC_GPIO_RST, 0);
+ udelay(100);
+ gpio_set_value(MS_TS_MSG_IC_GPIO_RST, 1);
+ mdelay(25);
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+ mt_set_gpio_mode(MS_TS_MSG_IC_GPIO_RST, GPIO_CTP_RST_PIN_M_GPIO);
+ mt_set_gpio_dir(MS_TS_MSG_IC_GPIO_RST, GPIO_DIR_OUT);
+ mt_set_gpio_out(MS_TS_MSG_IC_GPIO_RST, GPIO_OUT_ONE);
+ udelay(100);
+ mt_set_gpio_mode(MS_TS_MSG_IC_GPIO_RST, GPIO_CTP_RST_PIN_M_GPIO);
+ mt_set_gpio_dir(MS_TS_MSG_IC_GPIO_RST, GPIO_DIR_OUT);
+ mt_set_gpio_out(MS_TS_MSG_IC_GPIO_RST, GPIO_OUT_ZERO);
+ udelay(100);
+ mt_set_gpio_mode(MS_TS_MSG_IC_GPIO_RST, GPIO_CTP_RST_PIN_M_GPIO);
+ mt_set_gpio_dir(MS_TS_MSG_IC_GPIO_RST, GPIO_DIR_OUT);
+ mt_set_gpio_out(MS_TS_MSG_IC_GPIO_RST, GPIO_OUT_ONE);
+ mdelay(25);
+#endif
+}
+
+void DrvPlatformLyrDisableFingerTouchReport(void)
+{
+ unsigned long nIrqFlag;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("*** %s() _gInterruptFlag = %d ***\n", __func__, _gInterruptFlag); // add for debug
+
+ spin_lock_irqsave(&_gIrqLock, nIrqFlag);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+
+#ifdef CONFIG_ENABLE_HOTKNOT
+ if (g_HotKnotState != HOTKNOT_TRANS_STATE && g_HotKnotState != HOTKNOT_BEFORE_TRANS_STATE)
+#endif //CONFIG_ENABLE_HOTKNOT
+ {
+ if (_gInterruptFlag == 1)
+ {
+ printk("DrvPlatformLyrDisableFingerTouchReport___gIrq=%d\n",_gIrq);
+ disable_irq(_gIrq);
+
+ _gInterruptFlag = 0;
+ }
+ }
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+
+#ifdef CONFIG_ENABLE_HOTKNOT
+ if (g_HotKnotState != HOTKNOT_TRANS_STATE && g_HotKnotState != HOTKNOT_BEFORE_TRANS_STATE)
+#endif //CONFIG_ENABLE_HOTKNOT
+ {
+ if (_gInterruptFlag == 1)
+ {
+ mt_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);
+
+ _gInterruptFlag = 0;
+ }
+ }
+#endif
+
+ spin_unlock_irqrestore(&_gIrqLock, nIrqFlag);
+}
+
+void DrvPlatformLyrEnableFingerTouchReport(void)
+{
+ unsigned long nIrqFlag;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("*** %s() _gInterruptFlag = %d ***\n", __func__, _gInterruptFlag); // add for debug
+
+// DBG("*** %s() spin_lock_irqsave() ***\n", __func__); // add for debug
+ spin_lock_irqsave(&_gIrqLock, nIrqFlag);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+
+ if (_gInterruptFlag == 0)
+ {
+ enable_irq(_gIrq);
+// DBG("*** %s() enable_irq(_gIrq) ***\n", __func__); // add for debug
+
+ _gInterruptFlag = 1;
+ }
+
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+
+ if (_gInterruptFlag == 0)
+ {
+ mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
+// DBG("*** %s() mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM) ***\n", __func__); // add for debug
+
+ _gInterruptFlag = 1;
+ }
+
+#endif
+
+ spin_unlock_irqrestore(&_gIrqLock, nIrqFlag);
+// DBG("*** %s() spin_unlock_irqrestore() ***\n", __func__); // add for debug
+}
+
+void DrvPlatformLyrFingerTouchPressed(s32 nX, s32 nY, s32 nPressure, s32 nId)
+{
+ DBG("*** %s() ***\n", __func__);
+ DBG("point touch pressed\n");
+
+ input_report_key(g_InputDevice, BTN_TOUCH, 1);
+#if defined(CONFIG_ENABLE_TOUCH_DRIVER_FOR_MUTUAL_IC)
+ input_report_abs(g_InputDevice, ABS_MT_TRACKING_ID, nId);
+#endif //CONFIG_ENABLE_TOUCH_DRIVER_FOR_MUTUAL_IC
+ input_report_abs(g_InputDevice, ABS_MT_TOUCH_MAJOR, 1);
+ input_report_abs(g_InputDevice, ABS_MT_WIDTH_MAJOR, 1);
+ input_report_abs(g_InputDevice, ABS_MT_POSITION_X, nX);
+ input_report_abs(g_InputDevice, ABS_MT_POSITION_Y, nY);
+
+ input_mt_sync(g_InputDevice);
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_TP_HAVE_KEY
+ if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode())
+ {
+ tpd_button(nX, nY, 1);
+ }
+#endif //CONFIG_TP_HAVE_KEY
+
+ TPD_EM_PRINT(nX, nY, nX, nY, nId, 1);
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+}
+
+void DrvPlatformLyrFingerTouchReleased(s32 nX, s32 nY)
+{
+ DBG("*** %s() ***\n", __func__);
+ DBG("point touch released\n");
+
+ input_report_key(g_InputDevice, BTN_TOUCH, 0);
+ input_mt_sync(g_InputDevice);
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_TP_HAVE_KEY
+ if (FACTORY_BOOT == get_boot_mode() || RECOVERY_BOOT == get_boot_mode())
+ {
+ tpd_button(nX, nY, 0);
+// tpd_button(0, 0, 0);
+ }
+#endif //CONFIG_TP_HAVE_KEY
+
+ TPD_EM_PRINT(nX, nY, nX, nY, 0, 0);
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+}
+
+s32 DrvPlatformLyrInputDeviceInitialize(struct i2c_client *pClient)
+{
+ s32 nRetVal = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+ mutex_init(&g_Mutex);
+ spin_lock_init(&_gIrqLock);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ /* allocate an input device */
+ g_InputDevice = input_allocate_device();
+ if (g_InputDevice == NULL)
+ {
+ DBG("*** input device allocation failed ***\n");
+ return -ENOMEM;
+ }
+
+ g_InputDevice->name = pClient->name;
+ g_InputDevice->phys = "I2C";
+ g_InputDevice->dev.parent = &pClient->dev;
+ g_InputDevice->id.bustype = BUS_I2C;
+
+ /* set the supported event type for input device */
+ set_bit(EV_ABS, g_InputDevice->evbit);
+ set_bit(EV_SYN, g_InputDevice->evbit);
+ set_bit(EV_KEY, g_InputDevice->evbit);
+ set_bit(BTN_TOUCH, g_InputDevice->keybit);
+ set_bit(INPUT_PROP_DIRECT, g_InputDevice->propbit);
+
+#ifdef CONFIG_TP_HAVE_KEY
+ // Method 1.
+ {
+ u32 i;
+ for (i = 0; i < MAX_KEY_NUM; i ++)
+ {
+ input_set_capability(g_InputDevice, EV_KEY, g_TpVirtualKey[i]);
+ }
+ }
+#endif
+/*
+#ifdef CONFIG_TP_HAVE_KEY
+ // Method 2.
+ set_bit(TOUCH_KEY_MENU, g_InputDevice->keybit); //Menu
+ set_bit(TOUCH_KEY_HOME, g_InputDevice->keybit); //Home
+ set_bit(TOUCH_KEY_BACK, g_InputDevice->keybit); //Back
+ set_bit(TOUCH_KEY_SEARCH, g_InputDevice->keybit); //Search
+#endif
+*/
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+ input_set_capability(g_InputDevice, EV_KEY, KEY_POWER);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_UP);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_DOWN);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_LEFT);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_RIGHT);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_W);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_Z);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_V);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_O);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_M);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_C);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_E);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_S);
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+
+#if defined(CONFIG_ENABLE_TOUCH_DRIVER_FOR_MUTUAL_IC)
+ input_set_abs_params(g_InputDevice, ABS_MT_TRACKING_ID, 0, 255, 0, 0);
+#endif //CONFIG_ENABLE_TOUCH_DRIVER_FOR_MUTUAL_IC
+ input_set_abs_params(g_InputDevice, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+ input_set_abs_params(g_InputDevice, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
+ input_set_abs_params(g_InputDevice, ABS_MT_POSITION_X, TOUCH_SCREEN_X_MIN, TOUCH_SCREEN_X_MAX, 0, 0);
+ input_set_abs_params(g_InputDevice, ABS_MT_POSITION_Y, TOUCH_SCREEN_Y_MIN, TOUCH_SCREEN_Y_MAX, 0, 0);
+
+ /* register the input device to input sub-system */
+ nRetVal = input_register_device(g_InputDevice);
+ if (nRetVal < 0)
+ {
+ DBG("*** Unable to register touch input device ***\n");
+ }
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+ g_InputDevice = tpd->dev;
+/*
+ g_InputDevice->phys = "I2C";
+ g_InputDevice->dev.parent = &pClient->dev;
+ g_InputDevice->id.bustype = BUS_I2C;
+
+ // set the supported event type for input device
+ set_bit(EV_ABS, g_InputDevice->evbit);
+ set_bit(EV_SYN, g_InputDevice->evbit);
+ set_bit(EV_KEY, g_InputDevice->evbit);
+ set_bit(BTN_TOUCH, g_InputDevice->keybit);
+ set_bit(INPUT_PROP_DIRECT, g_InputDevice->propbit);
+*/
+
+#ifdef CONFIG_TP_HAVE_KEY
+ {
+ u32 i;
+ for (i = 0; i < MAX_KEY_NUM; i ++)
+ {
+ input_set_capability(g_InputDevice, EV_KEY, g_TpVirtualKey[i]);
+ }
+ }
+#endif
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+ input_set_capability(g_InputDevice, EV_KEY, KEY_POWER);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_UP);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_DOWN);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_LEFT);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_RIGHT);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_W);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_Z);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_V);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_O);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_M);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_C);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_E);
+ input_set_capability(g_InputDevice, EV_KEY, KEY_S);
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+
+#if defined(CONFIG_ENABLE_TOUCH_DRIVER_FOR_MUTUAL_IC)
+ input_set_abs_params(g_InputDevice, ABS_MT_TRACKING_ID, 0, (MAX_TOUCH_NUM-1), 0, 0);
+#endif //CONFIG_ENABLE_TOUCH_DRIVER_FOR_MUTUAL_IC
+/*
+ input_set_abs_params(g_InputDevice, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+ input_set_abs_params(g_InputDevice, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
+ input_set_abs_params(g_InputDevice, ABS_MT_POSITION_X, TOUCH_SCREEN_X_MIN, TOUCH_SCREEN_X_MAX, 0, 0);
+ input_set_abs_params(g_InputDevice, ABS_MT_POSITION_Y, TOUCH_SCREEN_Y_MIN, TOUCH_SCREEN_Y_MAX, 0, 0);
+*/
+
+#endif
+
+ return nRetVal;
+}
+
+s32 DrvPlatformLyrTouchDeviceRequestGPIO(void)
+{
+ s32 nRetVal = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ nRetVal = gpio_request(MS_TS_MSG_IC_GPIO_RST, "C_TP_RST");
+ if (nRetVal < 0)
+ {
+ DBG("*** Failed to request GPIO %d, error %d ***\n", MS_TS_MSG_IC_GPIO_RST, nRetVal);
+ }
+
+ nRetVal = gpio_request(MS_TS_MSG_IC_GPIO_INT, "C_TP_INT");
+ if (nRetVal < 0)
+ {
+ DBG("*** Failed to request GPIO %d, error %d ***\n", MS_TS_MSG_IC_GPIO_INT, nRetVal);
+ }
+#endif
+
+ return nRetVal;
+}
+
+s32 DrvPlatformLyrTouchDeviceRegisterFingerTouchInterruptHandler(void)
+{
+ s32 nRetVal = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+ if (DrvIcFwLyrIsRegisterFingerTouchInterruptHandler())
+ {
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ /* initialize the finger touch work queue */
+ INIT_WORK(&_gFingerTouchWork, _DrvPlatformLyrFingerTouchDoWork);
+
+ _gIrq = gpio_to_irq(MS_TS_MSG_IC_GPIO_INT);
+
+ /* request an irq and register the isr */
+ nRetVal = request_threaded_irq(_gIrq/*MS_TS_MSG_IC_GPIO_INT*/,NULL, _DrvPlatformLyrFingerTouchInterruptHandler,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT | IRQF_NO_SUSPEND /*//* IRQF_TRIGGER_FALLING */,
+ "msg2xxx", NULL);
+
+// nRetVal = request_irq(_gIrq/*MS_TS_MSG_IC_GPIO_INT*/, _DrvPlatformLyrFingerTouchInterruptHandler,
+// IRQF_TRIGGER_RISING /* | IRQF_NO_SUSPEND *//* IRQF_TRIGGER_FALLING */,
+// "msg2xxx", NULL);
+
+ _gInterruptFlag = 1;
+
+ if (nRetVal != 0)
+ {
+ DBG("*** Unable to claim irq %d; error %d ***\n", MS_TS_MSG_IC_GPIO_INT, nRetVal);
+ }
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+ mt_set_gpio_mode(MS_TS_MSG_IC_GPIO_INT, GPIO_CTP_EINT_PIN_M_EINT);
+ mt_set_gpio_dir(MS_TS_MSG_IC_GPIO_INT, GPIO_DIR_IN);
+ mt_set_gpio_pull_enable(MS_TS_MSG_IC_GPIO_INT, GPIO_PULL_ENABLE);
+ mt_set_gpio_pull_select(MS_TS_MSG_IC_GPIO_INT, GPIO_PULL_UP);
+
+ mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
+ mt_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_TYPE/* EINTF_TRIGGER_RISING */, _DrvPlatformLyrFingerTouchInterruptHandler, 1);
+
+ mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
+
+ _gInterruptFlag = 1;
+
+#ifdef CONFIG_USE_IRQ_INTERRUPT_FOR_MTK_PLATFORM
+ /* initialize the finger touch work queue */
+ INIT_WORK(&_gFingerTouchWork, _DrvPlatformLyrFingerTouchDoWork);
+#else
+ _gThread = kthread_run(_DrvPlatformLyrFingerTouchHandler, 0, TPD_DEVICE);
+ if (IS_ERR(_gThread))
+ {
+ nRetVal = PTR_ERR(_gThread);
+ DBG("Failed to create kernel thread: %d\n", nRetVal);
+ }
+#endif //CONFIG_USE_IRQ_INTERRUPT_FOR_MTK_PLATFORM
+#endif
+ }
+
+ return nRetVal;
+}
+
+void DrvPlatformLyrTouchDeviceRegisterEarlySuspend(void)
+{
+ DBG("*** %s() ***\n", __func__);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+#ifdef CONFIG_ENABLE_NOTIFIER_FB
+ _gFbNotifier.notifier_call = MsDrvInterfaceTouchDeviceFbNotifierCallback;
+ fb_register_client(&_gFbNotifier);
+#else
+ _gEarlySuspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
+ _gEarlySuspend.suspend = MsDrvInterfaceTouchDeviceSuspend;
+ _gEarlySuspend.resume = MsDrvInterfaceTouchDeviceResume;
+ register_early_suspend(&_gEarlySuspend);
+#endif //CONFIG_ENABLE_NOTIFIER_FB
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM || CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM
+}
+
+/* remove function is triggered when the input device is removed from input sub-system */
+s32 DrvPlatformLyrTouchDeviceRemove(struct i2c_client *pClient)
+{
+ DBG("*** %s() ***\n", __func__);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ free_irq(_gIrq, g_InputDevice);
+ gpio_free(MS_TS_MSG_IC_GPIO_INT);
+ gpio_free(MS_TS_MSG_IC_GPIO_RST);
+ input_unregister_device(g_InputDevice);
+#endif
+
+ if (IS_FIRMWARE_DATA_LOG_ENABLED)
+ {
+ kset_unregister(g_TouchKSet);
+ kobject_put(g_TouchKObj);
+ } //IS_FIRMWARE_DATA_LOG_ENABLED
+
+#ifdef CONFIG_ENABLE_HOTKNOT
+ DeleteQueue();
+ DeleteHotKnotMem();
+ DBG("Deregister hotknot misc device.\n");
+ misc_deregister( &hotknot_miscdevice );
+#endif //CONFIG_ENABLE_HOTKNOT
+
+#ifdef CONFIG_ENABLE_JNI_INTERFACE
+ DeleteMsgToolMem();
+#endif //CONFIG_ENABLE_JNI_INTERFACE
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_ENABLE_DMA_IIC
+ DmaFree();
+#endif //CONFIG_ENABLE_DMA_IIC
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+ return 0;
+}
+extern void sprd_i2c_ctl_chg_clk(unsigned int id_nr, unsigned int freq);
+
+void DrvPlatformLyrSetIicDataRate(struct i2c_client *pClient, u32 nIicDataRate)
+{
+ DBG("*** %s() nIicDataRate = %d ***\n", __func__, nIicDataRate);
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM)
+ // TODO : Please FAE colleague to confirm with customer device driver engineer for how to set i2c data rate on SPRD platform
+ sprd_i2c_ctl_chg_clk(pClient->adapter->nr, nIicDataRate);
+ mdelay(100);
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ // TODO : Please FAE colleague to confirm with customer device driver engineer for how to set i2c data rate on QCOM platform
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+ pClient->timing = nIicDataRate/1000;
+#endif
+}
+
+//------------------------------------------------------------------------------//
+
+#ifdef CONFIG_ENABLE_PROXIMITY_DETECTION
+
+int DrvPlatformLyrGetTpPsData(void)
+{
+ DBG("*** %s() g_FaceClosingTp = %d ***\n", __func__, g_FaceClosingTp);
+
+ return g_FaceClosingTp;
+}
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+void DrvPlatformLyrTpPsEnable(int nEnable)
+{
+ DBG("*** %s() nEnable = %d ***\n", __func__, nEnable);
+
+ if (nEnable)
+ {
+ DrvIcFwLyrEnableProximity();
+ }
+ else
+ {
+ DrvIcFwLyrDisableProximity();
+ }
+}
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+int DrvPlatformLyrTpPsOperate(void* pSelf, u32 nCommand, void* pBuffIn, int nSizeIn,
+ void* pBuffOut, int nSizeOut, int* pActualOut)
+{
+ int nErr = 0;
+ int nValue;
+ hwm_sensor_data *pSensorData;
+
+ switch (nCommand)
+ {
+ case SENSOR_DELAY:
+ if ((pBuffIn == NULL) || (nSizeIn < sizeof(int)))
+ {
+ nErr = -EINVAL;
+ }
+ // Do nothing
+ break;
+
+ case SENSOR_ENABLE:
+ if ((pBuffIn == NULL) || (nSizeIn < sizeof(int)))
+ {
+ nErr = -EINVAL;
+ }
+ else
+ {
+ nValue = *(int *)pBuffIn;
+ if (nValue)
+ {
+ if (DrvIcFwLyrEnableProximity() < 0)
+ {
+ DBG("Enable ps fail: %d\n", nErr);
+ return -1;
+ }
+ }
+ else
+ {
+ if (DrvIcFwLyrDisableProximity() < 0)
+ {
+ DBG("Disable ps fail: %d\n", nErr);
+ return -1;
+ }
+ }
+ }
+ break;
+
+ case SENSOR_GET_DATA:
+ if ((pBuffOut == NULL) || (nSizeOut < sizeof(hwm_sensor_data)))
+ {
+ DBG("Get sensor data parameter error!\n");
+ nErr = -EINVAL;
+ }
+ else
+ {
+ pSensorData = (hwm_sensor_data *)pBuffOut;
+
+ pSensorData->values[0] = DrvPlatformLyrGetTpPsData();
+ pSensorData->value_divide = 1;
+ pSensorData->status = SENSOR_STATUS_ACCURACY_MEDIUM;
+ }
+ break;
+
+ default:
+ DBG("Un-recognized parameter %d!\n", nCommand);
+ nErr = -1;
+ break;
+ }
+
+ return nErr;
+}
+#endif
+
+#endif //CONFIG_ENABLE_PROXIMITY_DETECTION
+
+//------------------------------------------------------------------------------//
+