summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/msg2233/mstar_drv_mutual_fw_control.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_mutual_fw_control.c
Initial file dump from open source releaseHEADmaster
Diffstat (limited to 'drivers/input/touchscreen/msg2233/mstar_drv_mutual_fw_control.c')
-rw-r--r--drivers/input/touchscreen/msg2233/mstar_drv_mutual_fw_control.c6412
1 files changed, 6412 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/msg2233/mstar_drv_mutual_fw_control.c b/drivers/input/touchscreen/msg2233/mstar_drv_mutual_fw_control.c
new file mode 100644
index 00000000..0c6458ed
--- /dev/null
+++ b/drivers/input/touchscreen/msg2233/mstar_drv_mutual_fw_control.c
@@ -0,0 +1,6412 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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_mutual_fw_control.c
+ *
+ * @brief This file defines the interface of touch screen
+ *
+ *
+ */
+
+/*=============================================================*/
+// INCLUDE FILE
+/*=============================================================*/
+
+#include "mstar_drv_mutual_fw_control.h"
+#include "mstar_drv_utility_adaption.h"
+#include "mstar_drv_platform_porting_layer.h"
+
+#if defined(CONFIG_ENABLE_TOUCH_DRIVER_FOR_MUTUAL_IC)
+
+/*=============================================================*/
+// EXTERN VARIABLE DECLARATION
+/*=============================================================*/
+
+extern u32 SLAVE_I2C_ID_DBBUS;
+extern u32 SLAVE_I2C_ID_DWI2C;
+
+#ifdef CONFIG_TP_HAVE_KEY
+extern const int g_TpVirtualKey[];
+
+#ifdef CONFIG_ENABLE_REPORT_KEY_WITH_COORDINATE
+extern const int g_TpVirtualKeyDimLocal[][4];
+#endif //CONFIG_ENABLE_REPORT_KEY_WITH_COORDINATE
+#endif //CONFIG_TP_HAVE_KEY
+
+extern struct input_dev *g_InputDevice;
+
+extern u8 g_FwData[MAX_UPDATE_FIRMWARE_BUFFER_SIZE][1024];
+extern u32 g_FwDataCount;
+
+extern struct mutex g_Mutex;
+
+extern u16 FIRMWARE_MODE_UNKNOWN_MODE;
+extern u16 FIRMWARE_MODE_DEMO_MODE;
+extern u16 FIRMWARE_MODE_DEBUG_MODE;
+extern u16 FIRMWARE_MODE_RAW_DATA_MODE;
+
+extern struct kobject *g_TouchKObj;
+extern u8 g_IsSwitchModeByAPK;
+
+extern u8 IS_FIRMWARE_DATA_LOG_ENABLED;
+
+#ifdef CONFIG_ENABLE_SEGMENT_READ_FINGER_TOUCH_DATA
+extern u16 g_FwPacketDataAddress;
+extern u16 g_FwPacketFlagAddress;
+
+extern u8 g_FwSupportSegment;
+#endif //CONFIG_ENABLE_SEGMENT_READ_FINGER_TOUCH_DATA
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+#ifdef CONFIG_ENABLE_GESTURE_DEBUG_MODE
+extern struct kobject *g_GestureKObj;
+#endif //CONFIG_ENABLE_GESTURE_DEBUG_MODE
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+#ifdef CONFIG_ENABLE_COUNT_REPORT_RATE
+extern u32 g_IsEnableReportRate;
+extern u32 g_InterruptCount;
+extern u32 g_ValidTouchCount;
+
+extern struct timeval g_StartTime;
+#endif //CONFIG_ENABLE_COUNT_REPORT_RATE
+
+#ifdef CONFIG_ENABLE_HOTKNOT
+extern u8 g_HotKnotState;
+#endif //CONFIG_ENABLE_HOTKNOT
+
+/*=============================================================*/
+// LOCAL VARIABLE DEFINITION
+/*=============================================================*/
+
+//static u8 _gTpVendorCode[3] = {0}; // used for MSG28XX
+
+static u8 _gOneDimenFwData[MSG28XX_FIRMWARE_WHOLE_SIZE*1024] = {0}; // used for MSG28XX
+
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_SW_ID
+/*
+ * Note.
+ * Please modify the name of the below .h depends on the vendor TP that you are using.
+ */
+#include "msg26xxm_xxxx_update_bin.h" // for MSG26xxM
+#include "msg26xxm_yyyy_update_bin.h"
+
+#include "msg28xx_xxxx_update_bin.h" // for MSG28xx
+#include "msg28xx_yyyy_update_bin.h"
+
+static u32 _gUpdateRetryCount = UPDATE_FIRMWARE_RETRY_COUNT;
+static u32 _gIsUpdateInfoBlockFirst = 0;
+static struct work_struct _gUpdateFirmwareBySwIdWork;
+static struct workqueue_struct *_gUpdateFirmwareBySwIdWorkQueue = NULL;
+static u8 _gTempData[1024];
+#endif //CONFIG_UPDATE_FIRMWARE_BY_SW_ID
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+static u32 _gGestureWakeupValue[2] = {0};
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+#ifdef CONFIG_ENABLE_SEGMENT_READ_FINGER_TOUCH_DATA
+static u8 _gTouchPacketFlag[2] = {0};
+#endif //CONFIG_ENABLE_SEGMENT_READ_FINGER_TOUCH_DATA
+
+static u8 _gIsDisableFinagerTouch = 0;
+
+static u16 _gSFR_ADDR3_BYTE0_1_VALUE = 0x0000;
+static u16 _gSFR_ADDR3_BYTE2_3_VALUE = 0x0000;
+
+
+/*=============================================================*/
+// GLOBAL VARIABLE DEFINITION
+/*=============================================================*/
+
+u8 g_ChipType = 0;
+u8 g_DemoModePacket[DEMO_MODE_PACKET_LENGTH] = {0};
+
+#ifdef CONFIG_ENABLE_HOTKNOT
+u8 g_DemoModeHotKnotSndRetPacket[DEMO_HOTKNOT_SEND_RET_LEN] = {0};
+u8 g_DebugModeHotKnotSndRetPacket[DEBUG_HOTKNOT_SEND_RET_LEN] = {0};
+#endif //CONFIG_ENABLE_HOTKNOT
+
+FirmwareInfo_t g_FirmwareInfo;
+u8 g_LogModePacket[DEBUG_MODE_PACKET_LENGTH] = {0};
+u16 g_FirmwareMode;
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+
+#if defined(CONFIG_ENABLE_GESTURE_DEBUG_MODE)
+u8 _gGestureWakeupPacket[GESTURE_DEBUG_MODE_PACKET_LENGTH] = {0};
+#elif defined(CONFIG_ENABLE_GESTURE_INFORMATION_MODE)
+u8 _gGestureWakeupPacket[GESTURE_WAKEUP_INFORMATION_PACKET_LENGTH] = {0};
+#else
+u8 _gGestureWakeupPacket[GESTURE_WAKEUP_PACKET_LENGTH] = {0};
+#endif //CONFIG_ENABLE_GESTURE_DEBUG_MODE
+
+#ifdef CONFIG_ENABLE_GESTURE_DEBUG_MODE
+u8 g_GestureDebugFlag = 0x00;
+u8 g_GestureDebugMode = 0x00;
+u8 g_LogGestureDebug[GESTURE_DEBUG_MODE_PACKET_LENGTH] = {0};
+#endif //CONFIG_ENABLE_GESTURE_DEBUG_MODE
+
+#ifdef CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+u32 g_LogGestureInfor[GESTURE_WAKEUP_INFORMATION_PACKET_LENGTH] = {0};
+#endif //CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+
+u32 g_GestureWakeupMode[2] = {0xFFFFFFFF, 0xFFFFFFFF};
+u8 g_GestureWakeupFlag = 0;
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+#ifdef CONFIG_ENABLE_PROXIMITY_DETECTION
+u8 g_EnableTpProximity = 0;
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+u8 g_FaceClosingTp = 0; // for QCOM platform -> 1 : close to, 0 : far away
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+u8 g_FaceClosingTp = 1; // for MTK platform -> 0 : close to, 1 : far away
+#endif
+#endif //CONFIG_ENABLE_PROXIMITY_DETECTION
+
+#ifdef CONFIG_ENABLE_GLOVE_MODE
+u8 g_IsGloveModeOpen = 0;
+#endif //CONFIG_ENABLE_GLOVE_MODE
+
+u8 g_IsUpdateFirmware = 0x00;
+
+/*=============================================================*/
+// LOCAL FUNCTION DECLARATION
+/*=============================================================*/
+
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_SW_ID
+static void _DrvFwCtrlUpdateFirmwareBySwIdDoWork(struct work_struct *pWork);
+#endif //CONFIG_UPDATE_FIRMWARE_BY_SW_ID
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+#ifdef CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+static void _DrvFwCtrlCoordinate(u8 *pRawData, u32 *pTranX, u32 *pTranY);
+#endif //CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+/*=============================================================*/
+// LOCAL FUNCTION DEFINITION
+/*=============================================================*/
+
+static s32 _DrvFwCtrlParsePacket(u8 *pPacket, u16 nLength, TouchInfo_t *pInfo)
+{
+ u32 i;
+ u8 nCheckSum = 0;
+ u32 nX = 0, nY = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+#ifdef CONFIG_ENABLE_COUNT_REPORT_RATE
+ if (g_IsEnableReportRate == 1)
+ {
+ if (g_InterruptCount == 4294967296)
+ {
+ g_InterruptCount = 0; // Reset count if overflow
+ DBG("g_InterruptCount reset to 0\n");
+ }
+
+ if (g_InterruptCount == 0)
+ {
+ // Get start time
+ do_gettimeofday(&g_StartTime);
+
+ DBG("Start time : %lu sec, %lu msec\n", g_StartTime.tv_sec, g_StartTime.tv_usec);
+ }
+
+ g_InterruptCount ++;
+
+ DBG("g_InterruptCount = %d\n", g_InterruptCount);
+ }
+#endif //CONFIG_ENABLE_COUNT_REPORT_RATE
+
+ nCheckSum = DrvCommonCalculateCheckSum(&pPacket[0], (nLength-1));
+ DBG("checksum : [%x] == [%x]? \n", pPacket[nLength-1], nCheckSum);
+
+ if (pPacket[nLength-1] != nCheckSum)
+ {
+ DBG("WRONG CHECKSUM\n");
+ return -1;
+ }
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+ if (g_GestureWakeupFlag == 1)
+ {
+ u8 nWakeupMode = 0;
+ u8 bIsCorrectFormat = 0;
+
+ DBG("received raw data from touch panel as following:\n");
+ DBG("pPacket[0]=%x \n pPacket[1]=%x pPacket[2]=%x pPacket[3]=%x pPacket[4]=%x pPacket[5]=%x \n", \
+ pPacket[0], pPacket[1], pPacket[2], pPacket[3], pPacket[4], pPacket[5]);
+
+ if (pPacket[0] == 0xA7 && pPacket[1] == 0x00 && pPacket[2] == 0x06 && pPacket[3] == PACKET_TYPE_GESTURE_WAKEUP)
+ {
+ nWakeupMode = pPacket[4];
+ bIsCorrectFormat = 1;
+ }
+#ifdef CONFIG_ENABLE_GESTURE_DEBUG_MODE
+ else if (pPacket[0] == 0xA7 && pPacket[1] == 0x00 && pPacket[2] == 0x80 && pPacket[3] == PACKET_TYPE_GESTURE_DEBUG)
+ {
+ u32 a = 0;
+
+ nWakeupMode = pPacket[4];
+ bIsCorrectFormat = 1;
+
+ for (a = 0; a < 0x80; a ++)
+ {
+ g_LogGestureDebug[a] = pPacket[a];
+ }
+
+ if (!(pPacket[5] >> 7))// LCM Light Flag = 0
+ {
+ nWakeupMode = 0xFE;
+ DBG("gesture debug mode LCM flag = 0\n");
+ }
+ }
+#endif //CONFIG_ENABLE_GESTURE_DEBUG_MODE
+
+#ifdef CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+ else if (pPacket[0] == 0xA7 && pPacket[1] == 0x00 && pPacket[2] == 0x80 && pPacket[3] == PACKET_TYPE_GESTURE_INFORMATION)
+ {
+ u32 a = 0;
+ u32 nTmpCount = 0;
+
+ nWakeupMode = pPacket[4];
+ bIsCorrectFormat = 1;
+
+ for (a = 0; a < 6; a ++)//header
+ {
+ g_LogGestureInfor[nTmpCount] = pPacket[a];
+ nTmpCount++;
+ }
+
+ for (a = 6; a < 126; a = a+3)//parse packet to coordinate
+ {
+ u32 nTranX = 0;
+ u32 nTranY = 0;
+
+ _DrvFwCtrlCoordinate(&pPacket[a], &nTranX, &nTranY);
+ g_LogGestureInfor[nTmpCount] = nTranX;
+ nTmpCount++;
+ g_LogGestureInfor[nTmpCount] = nTranY;
+ nTmpCount++;
+ }
+
+ g_LogGestureInfor[nTmpCount] = pPacket[126]; //Dummy
+ nTmpCount++;
+ g_LogGestureInfor[nTmpCount] = pPacket[127]; //checksum
+ nTmpCount++;
+ DBG("gesture information mode Count = %d\n", nTmpCount);
+ }
+#endif //CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+
+ if (bIsCorrectFormat)
+ {
+ DBG("nWakeupMode = 0x%x\n", nWakeupMode);
+
+ switch (nWakeupMode)
+ {
+ case 0x58:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_DOUBLE_CLICK_FLAG;
+
+ DBG("Light up screen by DOUBLE_CLICK gesture wakeup.\n");
+
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x60:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_UP_DIRECT_FLAG;
+
+ DBG("Light up screen by UP_DIRECT gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_UP, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_UP, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x61:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_DOWN_DIRECT_FLAG;
+
+ DBG("Light up screen by DOWN_DIRECT gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_DOWN, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_DOWN, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x62:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_LEFT_DIRECT_FLAG;
+
+ DBG("Light up screen by LEFT_DIRECT gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_LEFT, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_LEFT, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x63:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RIGHT_DIRECT_FLAG;
+
+ DBG("Light up screen by RIGHT_DIRECT gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_RIGHT, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_RIGHT, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x64:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_m_CHARACTER_FLAG;
+
+ DBG("Light up screen by m_CHARACTER gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_M, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_M, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x65:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_W_CHARACTER_FLAG;
+
+ DBG("Light up screen by W_CHARACTER gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_W, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_W, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x66:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_C_CHARACTER_FLAG;
+
+ DBG("Light up screen by C_CHARACTER gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_C, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_C, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x67:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_e_CHARACTER_FLAG;
+
+ DBG("Light up screen by e_CHARACTER gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_E, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_E, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x68:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_V_CHARACTER_FLAG;
+
+ DBG("Light up screen by V_CHARACTER gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_V, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_V, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x69:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_O_CHARACTER_FLAG;
+
+ DBG("Light up screen by O_CHARACTER gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_O, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_O, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x6A:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_S_CHARACTER_FLAG;
+
+ DBG("Light up screen by S_CHARACTER gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_S, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_S, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x6B:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_Z_CHARACTER_FLAG;
+
+ DBG("Light up screen by Z_CHARACTER gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, KEY_Z, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, KEY_Z, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x6C:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE1_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE1_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER1, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER1, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x6D:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE2_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE2_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER2, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER2, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x6E:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE3_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE3_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER3, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER3, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+#ifdef CONFIG_SUPPORT_64_TYPES_GESTURE_WAKEUP_MODE
+ case 0x6F:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE4_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE4_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER4, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER4, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x70:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE5_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE5_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER5, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER5, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x71:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE6_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE6_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER6, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER6, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x72:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE7_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE7_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER7, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER7, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x73:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE8_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE8_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER8, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER8, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x74:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE9_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE9_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER9, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER9, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x75:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE10_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE10_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER10, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER10, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x76:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE11_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE11_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER11, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER11, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x77:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE12_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE12_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER12, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER12, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x78:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE13_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE13_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER13, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER13, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x79:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE14_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE14_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER14, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER14, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x7A:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE15_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE15_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER15, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER15, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x7B:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE16_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE16_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER16, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER16, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x7C:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE17_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE17_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER17, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER17, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x7D:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE18_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE18_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER18, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER18, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x7E:
+ _gGestureWakeupValue[0] = GESTURE_WAKEUP_MODE_RESERVE19_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE19_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER19, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER19, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x7F:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE20_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE20_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER20, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER20, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x80:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE21_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE21_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER21, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER21, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x81:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE22_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE22_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER22, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER22, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x82:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE23_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE23_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER23, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER23, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x83:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE24_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE24_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER24, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER24, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x84:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE25_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE25_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER25, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER25, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x85:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE26_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE26_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER26, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER26, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x86:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE27_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE27_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER27, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER27, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x87:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE28_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE28_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER28, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER28, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x88:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE29_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE29_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER29, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER29, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x89:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE30_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE30_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER30, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER30, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x8A:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE31_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE31_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER31, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER31, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x8B:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE32_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE32_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER32, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER32, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x8C:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE33_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE33_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER33, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER33, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x8D:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE34_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE34_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER34, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER34, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x8E:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE35_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE35_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER35, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER35, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x8F:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE36_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE36_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER36, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER36, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x90:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE37_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE37_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER37, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER37, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x91:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE38_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE38_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER38, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER38, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x92:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE39_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE39_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER39, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER39, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x93:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE40_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE40_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER40, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER40, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x94:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE41_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE41_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER41, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER41, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x95:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE42_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE42_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER42, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER42, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x96:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE43_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE43_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER43, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER43, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x97:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE44_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE44_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER44, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER44, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x98:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE45_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE45_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER45, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER45, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x99:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE46_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE46_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER46, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER46, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x9A:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE47_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE47_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER47, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER47, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x9B:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE48_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE48_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER48, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER48, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x9C:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE49_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE49_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER49, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER49, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x9D:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE50_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE50_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER50, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER50, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+ case 0x9E:
+ _gGestureWakeupValue[1] = GESTURE_WAKEUP_MODE_RESERVE51_FLAG;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_RESERVE51_FLAG gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER51, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER51, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+#endif //CONFIG_SUPPORT_64_TYPES_GESTURE_WAKEUP_MODE
+
+#ifdef CONFIG_ENABLE_GESTURE_DEBUG_MODE
+ case 0xFF://Gesture Fail
+ _gGestureWakeupValue[1] = 0xFF;
+
+ DBG("Light up screen by GESTURE_WAKEUP_MODE_FAIL gesture wakeup.\n");
+
+// input_report_key(g_InputDevice, RESERVER51, 1);
+ input_report_key(g_InputDevice, KEY_POWER, 1);
+ input_sync(g_InputDevice);
+// input_report_key(g_InputDevice, RESERVER51, 0);
+ input_report_key(g_InputDevice, KEY_POWER, 0);
+ input_sync(g_InputDevice);
+ break;
+#endif //CONFIG_ENABLE_GESTURE_DEBUG_MODE
+
+ default:
+ _gGestureWakeupValue[0] = 0;
+ _gGestureWakeupValue[1] = 0;
+ DBG("Un-supported gesture wakeup mode. Please check your device driver code.\n");
+ break;
+ }
+
+ DBG("_gGestureWakeupValue = 0x%x, 0x%x\n", _gGestureWakeupValue[0], _gGestureWakeupValue[1]);
+ }
+ else
+ {
+ DBG("gesture wakeup packet format is incorrect.\n");
+ }
+
+#ifdef CONFIG_ENABLE_GESTURE_DEBUG_MODE
+ // Notify android application to retrieve log data mode packet from device driver by sysfs.
+ if (g_GestureKObj != NULL && pPacket[3] == PACKET_TYPE_GESTURE_DEBUG)
+ {
+ char *pEnvp[2];
+ s32 nRetVal = 0;
+
+ pEnvp[0] = "STATUS=GET_GESTURE_DEBUG";
+ pEnvp[1] = NULL;
+
+ nRetVal = kobject_uevent_env(g_GestureKObj, KOBJ_CHANGE, pEnvp);
+ DBG("kobject_uevent_env() nRetVal = %d\n", nRetVal);
+ }
+#endif //CONFIG_ENABLE_GESTURE_DEBUG_MODE
+
+ return -1;
+ }
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+ DBG("received raw data from touch panel as following:\n");
+ DBG("pPacket[0]=%x \n pPacket[1]=%x pPacket[2]=%x pPacket[3]=%x pPacket[4]=%x \n pPacket[5]=%x pPacket[6]=%x pPacket[7]=%x pPacket[8]=%x \n", \
+ pPacket[0], pPacket[1], pPacket[2], pPacket[3], pPacket[4], pPacket[5], pPacket[6], pPacket[7], pPacket[8]);
+
+ if (IS_FIRMWARE_DATA_LOG_ENABLED)
+ {
+ if (g_FirmwareMode == FIRMWARE_MODE_DEMO_MODE && pPacket[0] != 0x5A)
+ {
+#ifdef CONFIG_ENABLE_HOTKNOT
+ if (pPacket[3] != HOTKNOT_PACKET_TYPE && pPacket[3] != HOTKNOT_RECEIVE_PACKET_TYPE)
+#endif //CONFIG_ENABLE_HOTKNOT
+ {
+ DBG("WRONG DEMO MODE HEADER\n");
+ return -1;
+ }
+ }
+ else if (g_FirmwareMode == FIRMWARE_MODE_DEBUG_MODE && pPacket[0] != 0xA5 && pPacket[0] != 0xAB && (pPacket[0] != 0xA7 && pPacket[3] != PACKET_TYPE_TOOTH_PATTERN))
+ {
+ DBG("WRONG DEBUG MODE HEADER\n");
+ return -1;
+ }
+ }
+ else
+ {
+ if (pPacket[0] != 0x5A)
+ {
+#ifdef CONFIG_ENABLE_HOTKNOT
+ if (pPacket[3] != HOTKNOT_PACKET_TYPE && pPacket[3] != HOTKNOT_RECEIVE_PACKET_TYPE)
+#endif //CONFIG_ENABLE_HOTKNOT
+ {
+ DBG("WRONG DEMO MODE HEADER\n");
+ return -1;
+ }
+ }
+ } //IS_FIRMWARE_DATA_LOG_ENABLED
+
+ // Process raw data...
+ if (pPacket[0] == 0x5A)
+ {
+#ifdef CONFIG_ENABLE_HOTKNOT
+ if (((DemoHotKnotCmdRet_t*)pPacket)->nIdentify == DEMO_PD_PACKET_IDENTIFY)
+ {
+ ReportHotKnotCmd(pPacket, nLength);
+ return -1; //return 0 will run key procedure
+ }
+ else
+#endif //CONFIG_ENABLE_HOTKNOT
+ {
+ for (i = 0; i < MAX_TOUCH_NUM; i ++)
+ {
+ if ((pPacket[(4*i)+1] == 0xFF) && (pPacket[(4*i)+2] == 0xFF) && (pPacket[(4*i)+3] == 0xFF))
+ {
+ continue;
+ }
+
+ nX = (((pPacket[(4*i)+1] & 0xF0) << 4) | (pPacket[(4*i)+2]));
+ nY = (((pPacket[(4*i)+1] & 0x0F) << 8) | (pPacket[(4*i)+3]));
+
+ pInfo->tPoint[pInfo->nCount].nX = nX * TOUCH_SCREEN_X_MAX / TPD_WIDTH;
+ pInfo->tPoint[pInfo->nCount].nY = nY * TOUCH_SCREEN_Y_MAX / TPD_HEIGHT;
+ pInfo->tPoint[pInfo->nCount].nP = pPacket[4*(i+1)];
+ pInfo->tPoint[pInfo->nCount].nId = i;
+
+ DBG("[x,y]=[%d,%d]\n", nX, nY);
+ DBG("point[%d] : (%d,%d) = %d\n", pInfo->tPoint[pInfo->nCount].nId, pInfo->tPoint[pInfo->nCount].nX, pInfo->tPoint[pInfo->nCount].nY, pInfo->tPoint[pInfo->nCount].nP);
+
+ pInfo->nCount ++;
+ }
+ }
+ }
+ else if (pPacket[0] == 0xA5 || pPacket[0] == 0xAB)
+ {
+ for (i = 0; i < MAX_TOUCH_NUM; i ++)
+ {
+ if ((pPacket[(3*i)+4] == 0xFF) && (pPacket[(3*i)+5] == 0xFF) && (pPacket[(3*i)+6] == 0xFF))
+ {
+ continue;
+ }
+
+ nX = (((pPacket[(3*i)+4] & 0xF0) << 4) | (pPacket[(3*i)+5]));
+ nY = (((pPacket[(3*i)+4] & 0x0F) << 8) | (pPacket[(3*i)+6]));
+
+ pInfo->tPoint[pInfo->nCount].nX = nX * TOUCH_SCREEN_X_MAX / TPD_WIDTH;
+ pInfo->tPoint[pInfo->nCount].nY = nY * TOUCH_SCREEN_Y_MAX / TPD_HEIGHT;
+ pInfo->tPoint[pInfo->nCount].nP = 1;
+ pInfo->tPoint[pInfo->nCount].nId = i;
+
+ DBG("[x,y]=[%d,%d]\n", nX, nY);
+ DBG("point[%d] : (%d,%d) = %d\n", pInfo->tPoint[pInfo->nCount].nId, pInfo->tPoint[pInfo->nCount].nX, pInfo->tPoint[pInfo->nCount].nY, pInfo->tPoint[pInfo->nCount].nP);
+
+ pInfo->nCount ++;
+ }
+
+ // Notify android application to retrieve debug mode packet from device driver by sysfs.
+ if (g_TouchKObj != NULL)
+ {
+ char *pEnvp[2];
+ s32 nRetVal = 0;
+
+ pEnvp[0] = "STATUS=GET_DEBUG_MODE_PACKET";
+ pEnvp[1] = NULL;
+
+ nRetVal = kobject_uevent_env(g_TouchKObj, KOBJ_CHANGE, pEnvp);
+ DBG("kobject_uevent_env() nRetVal = %d\n", nRetVal);
+ }
+ }
+ else if (pPacket[0] == 0xA7 && pPacket[3] == PACKET_TYPE_TOOTH_PATTERN)
+ {
+ for (i = 0; i < MAX_TOUCH_NUM; i ++)
+ {
+ if ((pPacket[(3*i)+5] == 0xFF) && (pPacket[(3*i)+6] == 0xFF) && (pPacket[(3*i)+7] == 0xFF))
+ {
+ continue;
+ }
+
+ nX = (((pPacket[(3*i)+5] & 0xF0) << 4) | (pPacket[(3*i)+6]));
+ nY = (((pPacket[(3*i)+5] & 0x0F) << 8) | (pPacket[(3*i)+7]));
+
+ pInfo->tPoint[pInfo->nCount].nX = nX * TOUCH_SCREEN_X_MAX / TPD_WIDTH;
+ pInfo->tPoint[pInfo->nCount].nY = nY * TOUCH_SCREEN_Y_MAX / TPD_HEIGHT;
+ pInfo->tPoint[pInfo->nCount].nP = 1;
+ pInfo->tPoint[pInfo->nCount].nId = i;
+
+ DBG("[x,y]=[%d,%d]\n", nX, nY);
+ DBG("point[%d] : (%d,%d) = %d\n", pInfo->tPoint[pInfo->nCount].nId, pInfo->tPoint[pInfo->nCount].nX, pInfo->tPoint[pInfo->nCount].nY, pInfo->tPoint[pInfo->nCount].nP);
+
+ pInfo->nCount ++;
+ }
+
+ // Notify android application to retrieve debug mode packet from device driver by sysfs.
+ if (g_TouchKObj != NULL)
+ {
+ char *pEnvp[2];
+ s32 nRetVal = 0;
+
+ pEnvp[0] = "STATUS=GET_DEBUG_MODE_PACKET";
+ pEnvp[1] = NULL;
+
+ nRetVal = kobject_uevent_env(g_TouchKObj, KOBJ_CHANGE, pEnvp);
+ DBG("kobject_uevent_env() nRetVal = %d\n", nRetVal);
+ }
+ }
+#ifdef CONFIG_ENABLE_HOTKNOT
+ else if (pPacket[0] == 0xA7)
+ {
+ if (pPacket[3] == HOTKNOT_PACKET_TYPE || pPacket[3] == HOTKNOT_RECEIVE_PACKET_TYPE)
+ {
+ ReportHotKnotCmd(pPacket, nLength);
+ return -1; //return 0 will run key procedure
+ }
+ }
+#endif //CONFIG_ENABLE_HOTKNOT
+
+
+#ifdef CONFIG_TP_HAVE_KEY
+ if (pPacket[0] == 0x5A)
+ {
+ u8 nButton = pPacket[nLength-2]; //Since the key value is stored in 0th~3th bit of variable "button", we can only retrieve 0th~3th bit of it.
+
+// if (nButton)
+ if (nButton != 0xFF)
+ {
+ DBG("button = %x\n", nButton);
+
+#ifdef CONFIG_ENABLE_PROXIMITY_DETECTION
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ DBG("g_EnableTpProximity = %d, pPacket[nLength-2] = 0x%x\n", g_EnableTpProximity, pPacket[nLength-2]);
+
+ if (g_EnableTpProximity && ((pPacket[nLength-2] == 0x80) || (pPacket[nLength-2] == 0x40)))
+ {
+ if (pPacket[nLength-2] == 0x80) // close to
+ {
+ g_FaceClosingTp = 1;
+ }
+ else if (pPacket[nLength-2] == 0x40) // far away
+ {
+ g_FaceClosingTp = 0;
+ }
+
+ DBG("g_FaceClosingTp = %d\n", g_FaceClosingTp);
+
+ return -1;
+ }
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+ if (g_EnableTpProximity && ((pPacket[nLength-2] == 0x80) || (pPacket[nLength-2] == 0x40)))
+ {
+ int nErr;
+ hwm_sensor_data tSensorData;
+
+ if (pPacket[nLength-2] == 0x80) // close to
+ {
+ g_FaceClosingTp = 0;
+ }
+ else if (pPacket[nLength-2] == 0x40) // far away
+ {
+ g_FaceClosingTp = 1;
+ }
+
+ DBG("g_FaceClosingTp = %d\n", g_FaceClosingTp);
+
+ // map and store data to hwm_sensor_data
+ tSensorData.values[0] = DrvPlatformLyrGetTpPsData();
+ tSensorData.value_divide = 1;
+ tSensorData.status = SENSOR_STATUS_ACCURACY_MEDIUM;
+ // let up layer to know
+ if ((nErr = hwmsen_get_interrupt_data(ID_PROXIMITY, &tSensorData)))
+ {
+ DBG("call hwmsen_get_interrupt_data() failed = %d\n", nErr);
+ }
+
+ return -1;
+ }
+#endif
+#endif //CONFIG_ENABLE_PROXIMITY_DETECTION
+
+ for (i = 0; i < MAX_KEY_NUM; i ++)
+ {
+ if ((nButton & (1<<i)) == (1<<i))
+ {
+ if (pInfo->nKeyCode == 0)
+ {
+ pInfo->nKeyCode = i;
+
+ DBG("key[%d]=%d ...\n", i, g_TpVirtualKey[i]);
+
+#ifdef CONFIG_ENABLE_REPORT_KEY_WITH_COORDINATE
+ pInfo->nKeyCode = 0xFF;
+ pInfo->nCount = 1;
+ pInfo->tPoint[0].nX = g_TpVirtualKeyDimLocal[i][0];
+ pInfo->tPoint[0].nY = g_TpVirtualKeyDimLocal[i][1];
+ pInfo->tPoint[0].nP = 1;
+ pInfo->tPoint[0].nId = 0;
+#endif //CONFIG_ENABLE_REPORT_KEY_WITH_COORDINATE
+ }
+ else
+ {
+ /// if pressing multi-key => no report
+ pInfo->nKeyCode = 0xFF;
+ }
+ }
+ }
+ }
+ else
+ {
+ pInfo->nKeyCode = 0xFF;
+ }
+ }
+ else if (pPacket[0] == 0xA5 || pPacket[0] == 0xAB || (pPacket[0] == 0xA7 && pPacket[3] == PACKET_TYPE_TOOTH_PATTERN))
+ {
+ // TODO : waiting for firmware define the virtual key
+
+ if (pPacket[0] == 0xA5)
+ {
+ // Do nothing because of 0xA5 not define virtual key in the packet
+ }
+ else if (pPacket[0] == 0xAB || (pPacket[0] == 0xA7 && pPacket[3] == PACKET_TYPE_TOOTH_PATTERN))
+ {
+ u8 nButton = 0xFF;
+
+ if (pPacket[0] == 0xAB)
+ {
+ nButton = pPacket[3]; // The pressed virtual key is stored in 4th byte for debug mode packet 0xAB.
+ }
+ else if (pPacket[0] == 0xA7 && pPacket[3] == PACKET_TYPE_TOOTH_PATTERN)
+ {
+ nButton = pPacket[4]; // The pressed virtual key is stored in 5th byte for debug mode packet 0xA7.
+ }
+
+ if (nButton != 0xFF)
+ {
+ DBG("button = %x\n", nButton);
+
+ for (i = 0; i < MAX_KEY_NUM; i ++)
+ {
+ if ((nButton & (1<<i)) == (1<<i))
+ {
+ if (pInfo->nKeyCode == 0)
+ {
+ pInfo->nKeyCode = i;
+
+ DBG("key[%d]=%d ...\n", i, g_TpVirtualKey[i]);
+
+#ifdef CONFIG_ENABLE_REPORT_KEY_WITH_COORDINATE
+ pInfo->nKeyCode = 0xFF;
+ pInfo->nCount = 1;
+ pInfo->tPoint[0].nX = g_TpVirtualKeyDimLocal[i][0];
+ pInfo->tPoint[0].nY = g_TpVirtualKeyDimLocal[i][1];
+ pInfo->tPoint[0].nP = 1;
+ pInfo->tPoint[0].nId = 0;
+#endif //CONFIG_ENABLE_REPORT_KEY_WITH_COORDINATE
+ }
+ else
+ {
+ /// if pressing multi-key => no report
+ pInfo->nKeyCode = 0xFF;
+ }
+ }
+ }
+ }
+ else
+ {
+ pInfo->nKeyCode = 0xFF;
+ }
+ }
+ }
+#endif //CONFIG_TP_HAVE_KEY
+
+ return 0;
+}
+
+static void _DrvFwCtrlStoreFirmwareData(u8 *pBuf, u32 nSize)
+{
+ u32 nCount = nSize / 1024;
+ u32 nRemainder = nSize % 1024;
+ u32 i;
+
+ DBG("*** %s() ***\n", __func__);
+
+ if (nCount > 0) // nSize >= 1024
+ {
+ for (i = 0; i < nCount; i ++)
+ {
+ memcpy(g_FwData[g_FwDataCount], pBuf+(i*1024), 1024);
+
+ g_FwDataCount ++;
+ }
+
+ if (nRemainder > 0) // Handle special firmware size like MSG22XX(48.5KB)
+ {
+ DBG("nRemainder = %d\n", nRemainder);
+
+ memcpy(g_FwData[g_FwDataCount], pBuf+(i*1024), nRemainder);
+
+ g_FwDataCount ++;
+ }
+ }
+ else // nSize < 1024
+ {
+ if (nSize > 0)
+ {
+ memcpy(g_FwData[g_FwDataCount], pBuf, nSize);
+
+ g_FwDataCount ++;
+ }
+ }
+
+ DBG("*** g_FwDataCount = %d ***\n", g_FwDataCount);
+
+ if (pBuf != NULL)
+ {
+ DBG("*** buf[0] = %c ***\n", pBuf[0]);
+ }
+}
+
+static u16 _DrvFwCtrlMsg26xxmGetSwId(EmemType_e eEmemType)
+{
+ u16 nRetVal = 0;
+ u16 nRegData = 0;
+ u8 szDbBusTxData[5] = {0};
+ u8 szDbBusRxData[4] = {0};
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // cmd
+ RegSet16BitValue(0x3CE4, 0xA4AB); //bank:reg_PIU_MISC_0, addr:h0072
+
+ // TP SW reset
+ RegSet16BitValue(0x1E04, 0x7d60); //bank:chip, addr:h0002
+ RegSet16BitValue(0x1E04, 0x829F);
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+
+ mdelay(100);
+
+ // Polling 0x3CE4 is 0x5B58
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4); //bank:reg_PIU_MISC_0, addr:h0072
+ } while (nRegData != 0x5B58);
+
+ szDbBusTxData[0] = 0x72;
+ if (eEmemType == EMEM_MAIN) // Read SW ID from main block
+ {
+ szDbBusTxData[1] = 0x00;
+ szDbBusTxData[2] = 0x2A;
+ }
+ else if (eEmemType == EMEM_INFO) // Read SW ID from info block
+ {
+ szDbBusTxData[1] = 0x80;
+ szDbBusTxData[2] = 0x04;
+ }
+ szDbBusTxData[3] = 0x00;
+ szDbBusTxData[4] = 0x04;
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 5);
+ IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 4);
+
+ /*
+ Ex. SW ID in Main Block :
+ Major low byte at address 0x002A
+ Major high byte at address 0x002B
+
+ SW ID in Info Block :
+ Major low byte at address 0x8004
+ Major high byte at address 0x8005
+ */
+
+ nRetVal = szDbBusRxData[1];
+ nRetVal = (nRetVal << 8) | szDbBusRxData[0];
+
+ DBG("SW ID = 0x%x\n", nRetVal);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return nRetVal;
+}
+
+static s32 _DrvFwCtrlMsg26xxmUpdateFirmware(u8 szFwData[][1024], EmemType_e eEmemType)
+{
+ u32 i, j;
+ u32 nCrcMain, nCrcMainTp;
+ u32 nCrcInfo, nCrcInfoTp;
+ u16 nRegData = 0;
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_ENABLE_DMA_IIC
+ DmaReset();
+#endif //CONFIG_ENABLE_DMA_IIC
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+ nCrcMain = 0xffffffff;
+ nCrcInfo = 0xffffffff;
+
+ /////////////////////////
+ // Erase
+ /////////////////////////
+
+ DBG("erase 0\n");
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ DBG("erase 1\n");
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // Set PROGRAM password
+ RegSet16BitValue(0x161A, 0xABBA); //bank:emem, addr:h000D
+
+ // Clear pce
+ RegSetLByteValue(0x1618, 0x80); //bank:emem, addr:h000C
+
+ DBG("erase 2\n");
+ // Clear setting
+ RegSetLByteValue(0x1618, 0x40); //bank:emem, addr:h000C
+
+ mdelay(10);
+
+ // Clear pce
+ RegSetLByteValue(0x1618, 0x80); //bank:emem, addr:h000C
+
+ DBG("erase 3\n");
+ // Trigger erase
+ if (eEmemType == EMEM_ALL)
+ {
+ RegSetLByteValue(0x160E, 0x08); //all chip //bank:emem, addr:h0007
+ }
+ else
+ {
+ RegSetLByteValue(0x160E, 0x04); //sector //bank:emem, addr:h0007
+ }
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ mdelay(1000);
+ DBG("erase OK\n");
+
+ /////////////////////////
+ // Program
+ /////////////////////////
+
+ DBG("program 0\n");
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ DBG("program 1\n");
+
+ // Check_Loader_Ready: Polling 0x3CE4 is 0x1C70
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4); //bank:reg_PIU_MISC_0, addr:h0072
+ } while (nRegData != 0x1C70);
+
+ DBG("program 2\n");
+
+ RegSet16BitValue(0x3CE4, 0xE38F); //all chip
+ mdelay(100);
+
+ // Check_Loader_Ready2Program: Polling 0x3CE4 is 0x2F43
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4);
+ } while (nRegData != 0x2F43);
+
+ DBG("program 3\n");
+
+ // prepare CRC & send data
+ DrvCommonCrcInitTable();
+
+ for (i = 0; i < MSG26XXM_FIRMWARE_WHOLE_SIZE; i ++) // Main : 32KB + Info : 8KB
+ {
+ if (i > 31)
+ {
+ for (j = 0; j < 1024; j ++)
+ {
+ nCrcInfo = DrvCommonCrcGetValue(szFwData[i][j], nCrcInfo);
+ }
+ }
+ else if (i < 31)
+ {
+ for (j = 0; j < 1024; j ++)
+ {
+ nCrcMain = DrvCommonCrcGetValue(szFwData[i][j], nCrcMain);
+ }
+ }
+ else ///if (i == 31)
+ {
+ szFwData[i][1014] = 0x5A;
+ szFwData[i][1015] = 0xA5;
+
+ for (j = 0; j < 1016; j ++)
+ {
+ nCrcMain = DrvCommonCrcGetValue(szFwData[i][j], nCrcMain);
+ }
+ }
+
+ for (j = 0; j < 8; j ++)
+ {
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szFwData[i][j*128], 128);
+ }
+ mdelay(100);
+
+ // Check_Program_Done: Polling 0x3CE4 is 0xD0BC
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4);
+ } while (nRegData != 0xD0BC);
+
+ // Continue_Program
+ RegSet16BitValue(0x3CE4, 0x2F43);
+ }
+
+ DBG("program 4\n");
+
+ // Notify_Write_Done
+ RegSet16BitValue(0x3CE4, 0x1380);
+ mdelay(100);
+
+ DBG("program 5\n");
+
+ // Check_CRC_Done: Polling 0x3CE4 is 0x9432
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4);
+ } while (nRegData != 0x9432);
+
+ DBG("program 6\n");
+
+ // check CRC
+ nCrcMain = nCrcMain ^ 0xffffffff;
+ nCrcInfo = nCrcInfo ^ 0xffffffff;
+
+ // read CRC from TP
+ nCrcMainTp = RegGet16BitValue(0x3C80);
+ nCrcMainTp = (nCrcMainTp << 16) | RegGet16BitValue(0x3C82);
+ nCrcInfoTp = RegGet16BitValue(0x3CA0);
+ nCrcInfoTp = (nCrcInfoTp << 16) | RegGet16BitValue(0x3CA2);
+
+ DBG("nCrcMain=0x%x, nCrcInfo=0x%x, nCrcMainTp=0x%x, nCrcInfoTp=0x%x\n",
+ nCrcMain, nCrcInfo, nCrcMainTp, nCrcInfoTp);
+
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after update firmware
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ DrvPlatformLyrTouchDeviceResetHw();
+ mdelay(300);
+
+ if ((nCrcMainTp != nCrcMain) || (nCrcInfoTp != nCrcInfo))
+ {
+ DBG("Update FAILED\n");
+
+ return -1;
+ }
+
+ DBG("Update SUCCESS\n");
+
+ return 0;
+}
+
+static void _DrvFwCtrlMsg28xxConvertFwDataTwoDimenToOneDimen(u8 szTwoDimenFwData[][1024], u8* pOneDimenFwData)
+{
+ u32 i, j;
+
+ DBG("*** %s() ***\n", __func__);
+
+ for (i = 0; i < MSG28XX_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+ for (j = 0; j < 1024; j ++)
+ {
+ pOneDimenFwData[i*1024+j] = szTwoDimenFwData[i][j];
+ }
+ }
+}
+
+static u32 _DrvFwCtrlMsg28xxCalculateCrc(u8 *pFwData, u32 nOffset, u32 nSize)
+{
+ u32 i;
+ u32 nData = 0, nCrc = 0;
+ u32 nCrcRule = 0x0C470C06; // 0000 1100 0100 0111 0000 1100 0000 0110
+
+ for (i = 0; i < nSize; i += 4)
+ {
+ nData = (pFwData[nOffset+i]) | (pFwData[nOffset+i+1] << 8) | (pFwData[nOffset+i+2] << 16) | (pFwData[nOffset+i+3] << 24);
+ nCrc = (nCrc >> 1) ^ (nCrc << 1) ^ (nCrc & nCrcRule) ^ nData;
+ }
+
+ return nCrc;
+}
+
+static void _DrvFwCtrlMsg28xxAccessEFlashInit(void)
+{
+ // Disable watchdog
+ RegSetLByteValue(0x3C60, 0x55);
+ RegSetLByteValue(0x3C61, 0xAA);
+
+ // Disable cpu read flash
+ RegSetLByteValue(0x1606, 0x20);
+ RegSetLByteValue(0x1608, 0x20);
+
+ // Clear PROGRAM erase password
+ RegSet16BitValue(0x1618, 0xA55A);
+}
+
+static void _DrvFwCtrlMsg28xxIspBurstWriteEFlashStart(u16 nStartAddr, u8 *pFirstData, u32 nBlockSize, u16 nPageNum, EmemType_e eEmemType)
+{
+ u16 nWriteAddr = nStartAddr/4;
+ u8 szDbBusTxData[3] = {0};
+
+ DBG("*** %s() nStartAddr = 0x%x, nBlockSize = %d, nPageNum = %d, eEmemType = %d ***\n", __func__, nStartAddr, nBlockSize, nPageNum, eEmemType);
+
+ // Disable cpu read flash
+ RegSetLByteValue(0x1608, 0x20);
+ RegSetLByteValue(0x1606, 0x20);
+
+ // Set e-flash mode to page write mode
+ RegSet16BitValue(0x1606, 0x0080);
+
+ // Set data align
+ RegSetLByteValue(0x1640, 0x01);
+
+ if (eEmemType == EMEM_INFO)
+ {
+ RegSetLByteValue(0x1607, 0x08);
+ }
+
+ // Set double buffer
+ RegSetLByteValue(0x1604, 0x01);
+
+ // Set page write number
+ RegSet16BitValue(0x161A, nPageNum);
+
+ // Set e-flash mode trigger(Trigger write mode)
+ RegSetLByteValue(0x1606, 0x81);
+
+ // Set init data
+ RegSetLByteValue(0x1602, pFirstData[0]);
+ RegSetLByteValue(0x1602, pFirstData[1]);
+ RegSetLByteValue(0x1602, pFirstData[2]);
+ RegSetLByteValue(0x1602, pFirstData[3]);
+
+ // Set initial address(for latch SA, CA)
+ RegSet16BitValue(0x1600, nWriteAddr);
+
+ // Set initial address(for latch PA)
+ RegSet16BitValue(0x1600, nWriteAddr);
+
+ // Enable burst mode
+ RegSetLByteValue(0x1608, 0x21);
+
+ szDbBusTxData[0] = 0x10;
+ szDbBusTxData[1] = 0x16;
+ szDbBusTxData[2] = 0x02;
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 3);
+
+ szDbBusTxData[0] = 0x20;
+// szDbBusTxData[1] = 0x00;
+// szDbBusTxData[2] = 0x00;
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 1);
+}
+
+static void _DrvFwCtrlMsg28xxIspBurstWriteEFlashDoWrite(u8 *pBufferData, u32 nLength)
+{
+ u32 i;
+ u8 szDbBusTxData[3+MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE] = {0};
+
+ DBG("*** %s() nLength = %d ***\n", __func__, nLength);
+
+ szDbBusTxData[0] = 0x10;
+ szDbBusTxData[1] = 0x16;
+ szDbBusTxData[2] = 0x02;
+
+ for (i = 0; i < nLength; i ++)
+ {
+ szDbBusTxData[3+i] = pBufferData[i];
+ }
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 3+nLength);
+}
+
+static void _DrvFwCtrlMsg28xxIspBurstWriteEFlashEnd(void)
+{
+ u8 szDbBusTxData[1] = {0};
+
+ DBG("*** %s() ***\n", __func__);
+
+ szDbBusTxData[0] = 0x21;
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 1);
+
+ szDbBusTxData[0] = 0x7E;
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 1);
+
+ // Clear burst mode
+ RegSetLByteValue(0x1608, 0x20);
+}
+
+static void _DrvFwCtrlMsg28xxWriteEFlashStart(u16 nStartAddr, u8 *pFirstData, EmemType_e eEmemType)
+{
+ u16 nWriteAddr = nStartAddr/4;
+
+ DBG("*** %s() nStartAddr = 0x%x, eEmemType = %d ***\n", __func__, nStartAddr, eEmemType);
+
+ // Disable cpu read flash
+ RegSetLByteValue(0x1608, 0x20);
+ RegSetLByteValue(0x1606, 0x20);
+
+ // Set e-flash mode to write mode
+ RegSet16BitValue(0x1606, 0x0040);
+
+ // Set data align
+ RegSetLByteValue(0x1640, 0x01);
+
+ if (eEmemType == EMEM_INFO)
+ {
+ RegSetLByteValue(0x1607, 0x08);
+ }
+
+ // Set double buffer
+ RegSetLByteValue(0x1604, 0x01);
+
+ // Set e-flash mode trigger(Trigger write mode)
+ RegSetLByteValue(0x1606, 0x81);
+
+ // Set init data
+ RegSetLByteValue(0x1602, pFirstData[0]);
+ RegSetLByteValue(0x1602, pFirstData[1]);
+ RegSetLByteValue(0x1602, pFirstData[2]);
+ RegSetLByteValue(0x1602, pFirstData[3]);
+
+ // Set initial address(for latch SA, CA)
+ RegSet16BitValue(0x1600, nWriteAddr);
+
+ // Set initial address(for latch PA)
+ RegSet16BitValue(0x1600, nWriteAddr);
+}
+
+static void _DrvFwCtrlMsg28xxWriteEFlashDoWrite(u16 nStartAddr, u8 *pBufferData)
+{
+ u16 nWriteAddr = nStartAddr/4;
+
+ DBG("*** %s() nWriteAddr = %d ***\n", __func__, nWriteAddr);
+
+ // Write data
+ RegSetLByteValue(0x1602, pBufferData[0]);
+ RegSetLByteValue(0x1602, pBufferData[1]);
+ RegSetLByteValue(0x1602, pBufferData[2]);
+ RegSetLByteValue(0x1602, pBufferData[3]);
+
+ // Set address
+ RegSet16BitValue(0x1600, nWriteAddr);
+}
+
+static void _DrvFwCtrlMsg28xxWriteEFlashEnd(void)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ // Do nothing
+}
+
+static void _DrvFwCtrlMsg28xxReadEFlashStart(u16 nStartAddr, EmemType_e eEmemType)
+{
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ // Disable cpu read flash
+ RegSetLByteValue(0x1608, 0x20);
+ RegSetLByteValue(0x1606, 0x20);
+
+ RegSetLByteValue(0x1606, 0x02);
+
+ RegSet16BitValue(0x1600, nStartAddr);
+
+ if (eEmemType == EMEM_MAIN)
+ {
+ // Set main block
+ RegSetLByteValue(0x1607, 0x00);
+
+ // Set main double buffer
+ RegSetLByteValue(0x1604, 0x01);
+
+ // Set e-flash mode to read mode for main
+ RegSet16BitValue(0x1606, 0x0001);
+ }
+ else if (eEmemType == EMEM_INFO)
+ {
+ // Set info block
+ RegSetLByteValue(0x1607, 0x08);
+
+ // Set info double buffer
+ RegSetLByteValue(0x1604, 0x01);
+
+ // Set e-flash mode to read mode for info
+ RegSet16BitValue(0x1606, 0x0801);
+ }
+}
+
+static void _DrvFwCtrlMsg28xxReadEFlashDoRead(u16 nReadAddr, u8 *pReadData)
+{
+ u16 nRegData1 = 0, nRegData2 = 0;
+
+ DBG("*** %s() nReadAddr = 0x%x ***\n", __func__, nReadAddr);
+
+ // Set read address
+ RegSet16BitValue(0x1600, nReadAddr);
+
+ // Read 16+16 bits
+ nRegData1 = RegGet16BitValue(0x160A);
+ nRegData2 = RegGet16BitValue(0x160C);
+
+ pReadData[0] = nRegData1 & 0xFF;
+ pReadData[1] = (nRegData1 >> 8) & 0xFF;
+ pReadData[2] = nRegData2 & 0xFF;
+ pReadData[3] = (nRegData2 >> 8) & 0xFF;
+}
+
+static void _DrvFwCtrlMsg28xxReadEFlashEnd(void)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ // Set read done
+ RegSetLByteValue(0x1606, 0x02);
+
+ // Unset info flag
+ RegSetLByteValue(0x1607, 0x00);
+
+ // Clear address
+ RegSet16BitValue(0x1600, 0x0000);
+}
+
+/*
+static void _DrvFwCtrlMsg28xxGetTpVendorCode(u8 *pTpVendorCode)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ u16 nReadAddr = 0;
+ u8 szTmpData[4] = {0};
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01);
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55);
+
+ _DrvFwCtrlMsg28xxReadEFlashStart(0x81FA, EMEM_INFO);
+ nReadAddr = 0x81FA;
+
+ _DrvFwCtrlMsg28xxReadEFlashDoRead(nReadAddr, &szTmpData[0]);
+
+ DBG("szTmpData[0] = 0x%x\n", szTmpData[0]); // add for debug
+ DBG("szTmpData[1] = 0x%x\n", szTmpData[1]); // add for debug
+ DBG("szTmpData[2] = 0x%x\n", szTmpData[2]); // add for debug
+ DBG("szTmpData[3] = 0x%x\n", szTmpData[3]); // add for debug
+
+ _DrvFwCtrlMsg28xxReadEFlashEnd();
+
+ pTpVendorCode[0] = szTmpData[1];
+ pTpVendorCode[1] = szTmpData[2];
+ pTpVendorCode[2] = szTmpData[3];
+
+ DBG("pTpVendorCode[0] = 0x%x , %c \n", pTpVendorCode[0], pTpVendorCode[0]);
+ DBG("pTpVendorCode[1] = 0x%x , %c \n", pTpVendorCode[1], pTpVendorCode[1]);
+ DBG("pTpVendorCode[2] = 0x%x , %c \n", pTpVendorCode[2], pTpVendorCode[2]);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+ }
+}
+*/
+
+static void _DrvFwCtrlMsg28xxGetSfrAddr3Value(void)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ // Disable cpu read flash
+ RegSetLByteValue(0x1608, 0x20);
+ RegSetLByteValue(0x1606, 0x20);
+
+ // Set e-flash mode to read mode
+ RegSetLByteValue(0x1606, 0x01);
+ RegSetLByteValue(0x1610, 0x01);
+ RegSetLByteValue(0x1607, 0x20);
+
+ // Set read address
+ RegSetLByteValue(0x1600, 0x03);
+ RegSetLByteValue(0x1601, 0x00);
+
+ _gSFR_ADDR3_BYTE0_1_VALUE = RegGet16BitValue(0x160A);
+ _gSFR_ADDR3_BYTE2_3_VALUE = RegGet16BitValue(0x160C);
+
+ DBG("_gSFR_ADDR3_BYTE0_1_VALUE = 0x%4X, _gSFR_ADDR3_BYTE2_3_VALUE = 0x%4X\n", _gSFR_ADDR3_BYTE0_1_VALUE, _gSFR_ADDR3_BYTE2_3_VALUE);
+}
+
+static void _DrvFwCtrlMsg28xxUnsetProtectBit(void)
+{
+ u8 nB0, nB1, nB2, nB3;
+
+ DBG("*** %s() ***\n", __func__);
+
+ _DrvFwCtrlMsg28xxGetSfrAddr3Value();
+
+ nB0 = _gSFR_ADDR3_BYTE0_1_VALUE & 0xFF;
+ nB1 = (_gSFR_ADDR3_BYTE0_1_VALUE & 0xFF00) >> 8;
+
+ nB2 = _gSFR_ADDR3_BYTE2_3_VALUE & 0xFF;
+ nB3 = (_gSFR_ADDR3_BYTE2_3_VALUE & 0xFF00) >> 8;
+
+ DBG("nB0 = 0x%2X, nB1 = 0x%2X, nB2 = 0x%2X, nB3 = 0x%2X\n", nB0, nB1, nB2, nB3);
+
+ nB2 = nB2 & 0xBF; // 10111111
+ nB3 = nB3 & 0xFC; // 11111100
+
+ DBG("nB0 = 0x%2X, nB1 = 0x%2X, nB2 = 0x%2X, nB3 = 0x%2X\n", nB0, nB1, nB2, nB3);
+
+ // Disable cpu read flash
+ RegSetLByteValue(0x1608, 0x20);
+ RegSetLByteValue(0x1606, 0x20);
+ RegSetLByteValue(0x1610, 0x80);
+ RegSetLByteValue(0x1607, 0x10);
+
+ // Trigger SFR write
+ RegSetLByteValue(0x1606, 0x01);
+
+ // Set write data
+ RegSetLByteValue(0x1602, nB0);
+ RegSetLByteValue(0x1602, nB1);
+ RegSetLByteValue(0x1602, nB2);
+ RegSetLByteValue(0x1602, nB3);
+
+ // Set write address
+ RegSetLByteValue(0x1600, 0x03);
+ RegSetLByteValue(0x1601, 0x00);
+
+ // Set TM mode = 0
+ RegSetLByteValue(0x1607, 0x00);
+}
+
+static void _DrvFwCtrlMsg28xxSetProtectBit(void)
+{
+ u8 nB0, nB1, nB2, nB3;
+
+ DBG("*** %s() ***\n", __func__);
+
+ nB0 = _gSFR_ADDR3_BYTE0_1_VALUE & 0xFF;
+ nB1 = (_gSFR_ADDR3_BYTE0_1_VALUE & 0xFF00) >> 8;
+
+ nB2 = _gSFR_ADDR3_BYTE2_3_VALUE & 0xFF;
+ nB3 = (_gSFR_ADDR3_BYTE2_3_VALUE & 0xFF00) >> 8;
+
+ DBG("nB0 = 0x%2X, nB1 = 0x%2X, nB2 = 0x%2X, nB3 = 0x%2X\n", nB0, nB1, nB2, nB3);
+
+ // Disable cpu read flash
+ RegSetLByteValue(0x1608, 0x20);
+ RegSetLByteValue(0x1606, 0x20);
+ RegSetLByteValue(0x1610, 0x80);
+ RegSetLByteValue(0x1607, 0x10);
+
+ // Trigger SFR write
+ RegSetLByteValue(0x1606, 0x01);
+
+ // Set write data
+ RegSetLByteValue(0x1602, nB0);
+ RegSetLByteValue(0x1602, nB1);
+ RegSetLByteValue(0x1602, nB2);
+ RegSetLByteValue(0x1602, nB3);
+
+ // Set write address
+ RegSetLByteValue(0x1600, 0x03);
+ RegSetLByteValue(0x1601, 0x00);
+ RegSetLByteValue(0x1606, 0x02);
+}
+
+static void _DrvFwCtrlMsg28xxEraseEmem(EmemType_e eEmemType)
+{
+ u32 nInfoAddr = 0x20;
+ u32 nTimeOut = 0;
+ u8 nRegData = 0;
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ DBG("Erase start\n");
+
+ _DrvFwCtrlMsg28xxAccessEFlashInit();
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01);
+
+ // Set PROGRAM erase password
+ RegSet16BitValue(0x1618, 0x5AA5);
+
+ _DrvFwCtrlMsg28xxUnsetProtectBit();
+
+ if (eEmemType == EMEM_MAIN) // 128KB
+ {
+ DBG("Erase main block\n");
+
+ // Set main block
+ RegSetLByteValue(0x1607, 0x00);
+
+ // Set e-flash mode to erase mode
+ RegSetLByteValue(0x1606, 0xC0);
+
+ // Set page erase main
+ RegSetLByteValue(0x1607, 0x03);
+
+ // e-flash mode trigger
+ RegSetLByteValue(0x1606, 0xC1);
+
+ nTimeOut = 0;
+ while (1) // Wait erase done
+ {
+ nRegData = RegGetLByteValue(0x160E);
+ nRegData = (nRegData & BIT3);
+
+ DBG("Wait erase done flag nRegData = 0x%x\n", nRegData);
+
+ if (nRegData == BIT3)
+ {
+ break;
+ }
+
+ mdelay(10);
+
+ if ((nTimeOut ++) > 10)
+ {
+ DBG("Erase main block failed. Timeout.\n");
+
+ goto EraseEnd;
+ }
+ }
+ }
+ else if (eEmemType == EMEM_INFO) // 2KB
+ {
+ DBG("Erase info block\n");
+
+ // Set info block
+ RegSetLByteValue(0x1607, 0x08);
+
+ // Set info double buffer
+ RegSetLByteValue(0x1604, 0x01);
+
+ // Set e-flash mode to erase mode
+ RegSetLByteValue(0x1606, 0xC0);
+
+ // Set page erase info
+ RegSetLByteValue(0x1607, 0x09);
+
+ for (nInfoAddr = 0x20; nInfoAddr <= MSG28XX_EMEM_INFO_MAX_ADDR; nInfoAddr += 0x20)
+ {
+ DBG("nInfoAddr = 0x%x\n", nInfoAddr); // add for debug
+
+ // Set address
+ RegSet16BitValue(0x1600, nInfoAddr);
+
+ // e-flash mode trigger
+ RegSetLByteValue(0x1606, 0xC1);
+
+ nTimeOut = 0;
+ while (1) // Wait erase done
+ {
+ nRegData = RegGetLByteValue(0x160E);
+ nRegData = (nRegData & BIT3);
+
+ DBG("Wait erase done flag nRegData = 0x%x\n", nRegData);
+
+ if (nRegData == BIT3)
+ {
+ break;
+ }
+
+ mdelay(10);
+
+ if ((nTimeOut ++) > 10)
+ {
+ DBG("Erase info block failed. Timeout.\n");
+
+ // Set main block
+ RegSetLByteValue(0x1607, 0x00);
+
+ goto EraseEnd;
+ }
+ }
+ }
+
+ // Set main block
+ RegSetLByteValue(0x1607, 0x00);
+ }
+
+ EraseEnd:
+
+ _DrvFwCtrlMsg28xxSetProtectBit();
+
+ RegSetLByteValue(0x1606, 0x00);
+ RegSetLByteValue(0x1607, 0x00);
+
+ // Clear PROGRAM erase password
+ RegSet16BitValue(0x1618, 0xA55A);
+
+ DBG("Erase end\n");
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+}
+
+static void _DrvFwCtrlMsg28xxProgramEmem(EmemType_e eEmemType)
+{
+ u32 i, j;
+ u32 nPageNum = 0, nLength = 0, nIndex = 0, nWordNum = 0;
+ u32 nRetryTime = 0;
+ u8 nRegData = 0;
+ u8 szFirstData[MSG28XX_EMEM_SIZE_BYTES_ONE_WORD] = {0};
+ u8 szBufferData[MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE] = {0};
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_ENABLE_DMA_IIC
+ DmaReset();
+#endif //CONFIG_ENABLE_DMA_IIC
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ DBG("Program start\n");
+
+ _DrvFwCtrlMsg28xxAccessEFlashInit();
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01);
+
+ // Set PROGRAM erase password
+ RegSet16BitValue(0x1618, 0x5AA5);
+
+ _DrvFwCtrlMsg28xxUnsetProtectBit();
+
+ if (eEmemType == EMEM_MAIN) // Program main block
+ {
+ DBG("Program main block\n");
+
+ nPageNum = (MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE * 1024) / MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE; // 128*1024/128=1024
+ nIndex = 0;
+
+ for (i = 0; i < nPageNum; i ++)
+ {
+ if (i == 0)
+ {
+ // Read first data 4 bytes
+ nLength = MSG28XX_EMEM_SIZE_BYTES_ONE_WORD;
+
+ szFirstData[0] = g_FwData[0][0];
+ szFirstData[1] = g_FwData[0][1];
+ szFirstData[2] = g_FwData[0][2];
+ szFirstData[3] = g_FwData[0][3];
+
+ _DrvFwCtrlMsg28xxIspBurstWriteEFlashStart(nIndex, &szFirstData[0], MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE*1024, nPageNum, EMEM_MAIN);
+
+ nIndex += nLength;
+
+ nLength = MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE - MSG28XX_EMEM_SIZE_BYTES_ONE_WORD; // 124 = 128 - 4
+
+ for (j = 0; j < nLength; j ++)
+ {
+ szBufferData[j] = g_FwData[0][4+j];
+ }
+ }
+ else
+ {
+ nLength = MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE;
+
+ for (j = 0; j < nLength; j ++)
+ {
+ szBufferData[j] = g_FwData[i/8][MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE*(i-(8*(i/8)))+j];
+ }
+ }
+
+ _DrvFwCtrlMsg28xxIspBurstWriteEFlashDoWrite(&szBufferData[0], nLength);
+
+ udelay(2000); // delay about 2ms
+
+ nIndex += nLength;
+ }
+
+ _DrvFwCtrlMsg28xxIspBurstWriteEFlashEnd();
+
+ // Set write done
+ RegSet16BitValueOn(0x1606, BIT2);
+
+ // Check RBB
+ nRegData = RegGetLByteValue(0x160E);
+ nRetryTime = 0;
+
+ while ((nRegData & BIT3) != BIT3)
+ {
+ mdelay(10);
+
+ nRegData = RegGetLByteValue(0x160E);
+
+ if (nRetryTime ++ > 100)
+ {
+ DBG("main block can't wait write to done.\n");
+
+ goto ProgramEnd;
+ }
+ }
+ }
+ else if (eEmemType == EMEM_INFO) // Program info block
+ {
+ DBG("Program info block\n");
+
+ nPageNum = (MSG28XX_FIRMWARE_INFO_BLOCK_SIZE * 1024) / MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE; // 2*1024/128=16
+ nIndex = 0;
+ nIndex += MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE;
+
+ // Skip firt page(page 0) & Update page 1~14 by isp burst write mode
+ for (i = 1; i < (nPageNum - 1); i ++)
+ {
+ if (i == 1)
+ {
+ // Read first data 4 bytes
+ nLength = MSG28XX_EMEM_SIZE_BYTES_ONE_WORD;
+
+ szFirstData[0] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE][MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE];
+ szFirstData[1] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE][MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE+1];
+ szFirstData[2] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE][MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE+2];
+ szFirstData[3] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE][MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE+3];
+
+ _DrvFwCtrlMsg28xxIspBurstWriteEFlashStart(nIndex, &szFirstData[0], MSG28XX_FIRMWARE_INFO_BLOCK_SIZE*1024, nPageNum-1, EMEM_INFO);
+
+ nIndex += nLength;
+
+ nLength = MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE - MSG28XX_EMEM_SIZE_BYTES_ONE_WORD; // 124 = 128 - 4
+
+ for (j = 0; j < nLength; j ++)
+ {
+ szBufferData[j] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE][MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE+4+j];
+ }
+ }
+ else
+ {
+ nLength = MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE;
+
+ if (i < 8) // 1 < i < 8
+ {
+ for (j = 0; j < nLength; j ++)
+ {
+ szBufferData[j] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE][MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE*i+j];
+ }
+ }
+ else // i >= 8
+ {
+ for (j = 0; j < nLength; j ++)
+ {
+ szBufferData[j] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE+1][MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE*(i-8)+j];
+ }
+ }
+ }
+
+ _DrvFwCtrlMsg28xxIspBurstWriteEFlashDoWrite(&szBufferData[0], nLength);
+
+ udelay(2000); // delay about 2ms
+
+ nIndex += nLength;
+ }
+
+ _DrvFwCtrlMsg28xxIspBurstWriteEFlashEnd();
+
+ // Set write done
+ RegSet16BitValueOn(0x1606, BIT2);
+
+ // Check RBB
+ nRegData = RegGetLByteValue(0x160E);
+ nRetryTime = 0;
+
+ while ((nRegData & BIT3) != BIT3)
+ {
+ mdelay(10);
+
+ nRegData = RegGetLByteValue(0x160E);
+
+ if (nRetryTime ++ > 100)
+ {
+ DBG("Info block page 1~14 can't wait write to done.\n");
+
+ goto ProgramEnd;
+ }
+ }
+
+ RegSet16BitValueOff(0x1EBE, BIT15);
+
+ // Update page 15 by write mode
+ nIndex = 15 * MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE;
+ nWordNum = MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE / MSG28XX_EMEM_SIZE_BYTES_ONE_WORD; // 128/4=32
+ nLength = MSG28XX_EMEM_SIZE_BYTES_ONE_WORD;
+
+ for (i = 0; i < nWordNum; i ++)
+ {
+ if (i == 0)
+ {
+ szFirstData[0] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE+1][7*MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE];
+ szFirstData[1] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE+1][7*MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE+1];
+ szFirstData[2] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE+1][7*MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE+2];
+ szFirstData[3] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE+1][7*MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE+3];
+
+ _DrvFwCtrlMsg28xxWriteEFlashStart(nIndex, &szFirstData[0], EMEM_INFO);
+ }
+ else
+ {
+ for (j = 0; j < nLength; j ++)
+ {
+ szFirstData[j] = g_FwData[MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE+1][7*MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE+(4*i)+j];
+ }
+
+ _DrvFwCtrlMsg28xxWriteEFlashDoWrite(nIndex, &szFirstData[0]);
+ }
+
+ udelay(2000); // delay about 2ms
+
+ nIndex += nLength;
+ }
+
+ _DrvFwCtrlMsg28xxWriteEFlashEnd();
+
+ // Set write done
+ RegSet16BitValueOn(0x1606, BIT2);
+
+ // Check RBB
+ nRegData = RegGetLByteValue(0x160E);
+ nRetryTime = 0;
+
+ while ((nRegData & BIT3) != BIT3)
+ {
+ mdelay(10);
+
+ nRegData = RegGetLByteValue(0x160E);
+
+ if (nRetryTime ++ > 100)
+ {
+ DBG("Info block page 15 can't wait write to done.\n");
+
+ goto ProgramEnd;
+ }
+ }
+ }
+
+ ProgramEnd:
+
+ _DrvFwCtrlMsg28xxSetProtectBit();
+
+ // Clear PROGRAM erase password
+ RegSet16BitValue(0x1618, 0xA55A);
+
+ DBG("Program end\n");
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+}
+
+static u16 _DrvFwCtrlMsg28xxGetSwId(EmemType_e eEmemType)
+{
+ u16 nRetVal = 0;
+ u16 nReadAddr = 0;
+ u8 szTmpData[4] = {0};
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01);
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55);
+
+ if (eEmemType == EMEM_MAIN) // Read SW ID from main block
+ {
+ _DrvFwCtrlMsg28xxReadEFlashStart(0x7FFD, EMEM_MAIN);
+ nReadAddr = 0x7FFD;
+ }
+ else if (eEmemType == EMEM_INFO) // Read SW ID from info block
+ {
+ _DrvFwCtrlMsg28xxReadEFlashStart(0x81FB, EMEM_INFO);
+ nReadAddr = 0x81FB;
+ }
+
+ _DrvFwCtrlMsg28xxReadEFlashDoRead(nReadAddr, &szTmpData[0]);
+
+ _DrvFwCtrlMsg28xxReadEFlashEnd();
+
+ /*
+ Ex. SW ID in Main Block :
+ Major low byte at address 0x7FFD
+
+ SW ID in Info Block :
+ Major low byte at address 0x81FB
+ */
+
+ nRetVal = (szTmpData[1] << 8);
+ nRetVal |= szTmpData[0];
+
+ DBG("SW ID = 0x%x\n", nRetVal);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return nRetVal;
+}
+
+static u32 _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EmemType_e eEmemType)
+{
+ u32 nRetVal = 0;
+ u32 nRetryTime = 0;
+ u32 nCrcEndAddr = 0;
+ u16 nCrcDown = 0;
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ _DrvFwCtrlMsg28xxAccessEFlashInit();
+
+ if (eEmemType == EMEM_MAIN)
+ {
+ // Disable cpu read flash
+ RegSetLByteValue(0x1608, 0x20);
+ RegSetLByteValue(0x1606, 0x20);
+
+ // Set read flag
+ RegSet16BitValue(0x1610, 0x0001);
+
+ // Mode reset main block
+ RegSet16BitValue(0x1606, 0x0000);
+
+ // CRC reset
+ RegSet16BitValue(0x1620, 0x0002);
+
+ RegSet16BitValue(0x1620, 0x0000);
+
+ // Set CRC e-flash block start address => Main Block : 0x0000 ~ 0x7FFE
+ RegSet16BitValue(0x1600, 0x0000);
+
+ nCrcEndAddr = (MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE*1024)/4-2;
+
+ RegSet16BitValue(0x1622, nCrcEndAddr);
+
+ // Trigger CRC check
+ RegSet16BitValue(0x1620, 0x0001);
+
+ nCrcDown = RegGet16BitValue(0x1620);
+
+ nRetryTime = 0;
+ while ((nCrcDown >> 15) == 0)
+ {
+ mdelay(10);
+
+ nCrcDown = RegGet16BitValue(0x1620);
+ nRetryTime ++;
+
+ if (nRetryTime > 30)
+ {
+ DBG("Wait main block nCrcDown failed.\n");
+ break;
+ }
+ }
+
+ nRetVal = RegGet16BitValue(0x1626);
+ nRetVal = (nRetVal << 16) | RegGet16BitValue(0x1624);
+ }
+ else if (eEmemType == EMEM_INFO)
+ {
+ // Disable cpu read flash
+ RegSetLByteValue(0x1608, 0x20);
+ RegSetLByteValue(0x1606, 0x20);
+
+ // Set read flag
+ RegSet16BitValue(0x1610, 0x0001);
+
+ // Mode reset info block
+ RegSet16BitValue(0x1606, 0x0800);
+
+ RegSetLByteValue(0x1604, 0x01);
+
+ // CRC reset
+ RegSet16BitValue(0x1620, 0x0002);
+
+ RegSet16BitValue(0x1620, 0x0000);
+
+ // Set CRC e-flash block start address => Info Block : 0x0020 ~ 0x01FE
+ RegSet16BitValue(0x1600, 0x0020);
+ RegSet16BitValue(0x1622, 0x01FE);
+
+ // Trigger CRC check
+ RegSet16BitValue(0x1620, 0x0001);
+
+ nCrcDown = RegGet16BitValue(0x1620);
+
+ nRetryTime = 0;
+ while ((nCrcDown >> 15) == 0)
+ {
+ mdelay(10);
+
+ nCrcDown = RegGet16BitValue(0x1620);
+ nRetryTime ++;
+
+ if (nRetryTime > 30)
+ {
+ DBG("Wait info block nCrcDown failed.\n");
+ break;
+ }
+ }
+
+ nRetVal = RegGet16BitValue(0x1626);
+ nRetVal = (nRetVal << 16) | RegGet16BitValue(0x1624);
+ }
+
+ DBG("Hardware CRC = 0x%x\n", nRetVal);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return nRetVal;
+}
+
+static s32 _DrvFwCtrlMsg28xxUpdateFirmware(u8 szFwData[][1024], EmemType_e eEmemType)
+{
+ u32 nCrcMain = 0, nCrcMainTp = 0;
+ u32 nCrcInfo = 0, nCrcInfoTp = 0;
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ /////////////////////////
+ // Erase
+ /////////////////////////
+
+ if (eEmemType == EMEM_ALL)
+ {
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_MAIN);
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_INFO);
+ }
+ else if (eEmemType == EMEM_MAIN)
+ {
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_MAIN);
+ }
+ else if (eEmemType == EMEM_INFO)
+ {
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_INFO);
+ }
+
+ DBG("erase OK\n");
+
+ /////////////////////////
+ // Program
+ /////////////////////////
+
+ if (eEmemType == EMEM_ALL)
+ {
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_MAIN);
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_INFO);
+ }
+ else if (eEmemType == EMEM_MAIN)
+ {
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_MAIN);
+ }
+ else if (eEmemType == EMEM_INFO)
+ {
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_INFO);
+ }
+
+ DBG("program OK\n");
+
+ /* Calculate main block & info block CRC by device driver itself */
+ _DrvFwCtrlMsg28xxConvertFwDataTwoDimenToOneDimen(szFwData, _gOneDimenFwData);
+
+ /* Read main block CRC from TP */
+ if (eEmemType == EMEM_ALL)
+ {
+ nCrcMain = _DrvFwCtrlMsg28xxCalculateCrc(_gOneDimenFwData, 0, MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE*1024-MSG28XX_EMEM_SIZE_BYTES_ONE_WORD);
+ nCrcInfo = _DrvFwCtrlMsg28xxCalculateCrc(_gOneDimenFwData, MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE*1024+MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE, MSG28XX_FIRMWARE_INFO_BLOCK_SIZE*1024-MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE-MSG28XX_EMEM_SIZE_BYTES_ONE_WORD);
+
+ nCrcMainTp = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_MAIN);
+ nCrcInfoTp = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_INFO);
+ }
+ else if (eEmemType == EMEM_MAIN)
+ {
+ nCrcMain = _DrvFwCtrlMsg28xxCalculateCrc(_gOneDimenFwData, 0, MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE*1024-MSG28XX_EMEM_SIZE_BYTES_ONE_WORD);
+
+ nCrcMainTp = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_MAIN);
+ }
+ else if (eEmemType == EMEM_INFO)
+ {
+ nCrcInfo = _DrvFwCtrlMsg28xxCalculateCrc(_gOneDimenFwData, MSG28XX_FIRMWARE_MAIN_BLOCK_SIZE*1024+MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE, MSG28XX_FIRMWARE_INFO_BLOCK_SIZE*1024-MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE-MSG28XX_EMEM_SIZE_BYTES_ONE_WORD);
+
+ nCrcInfoTp = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_INFO);
+ }
+
+ DBG("nCrcMain=0x%x, nCrcInfo=0x%x, nCrcMainTp=0x%x, nCrcInfoTp=0x%x\n",
+ nCrcMain, nCrcInfo, nCrcMainTp, nCrcInfoTp);
+
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after update firmware
+
+ DrvPlatformLyrTouchDeviceResetHw();
+ mdelay(300);
+
+ if (eEmemType == EMEM_ALL)
+ {
+ if ((nCrcMainTp != nCrcMain) || (nCrcInfoTp != nCrcInfo))
+ {
+ DBG("Update FAILED\n");
+
+ return -1;
+ }
+ }
+ else if (eEmemType == EMEM_MAIN)
+ {
+ if (nCrcMainTp != nCrcMain)
+ {
+ DBG("Update FAILED\n");
+
+ return -1;
+ }
+ }
+ else if (eEmemType == EMEM_INFO)
+ {
+ if (nCrcInfoTp != nCrcInfo)
+ {
+ DBG("Update FAILED\n");
+
+ return -1;
+ }
+ }
+
+ DBG("Update SUCCESS\n");
+
+ return 0;
+}
+
+static s32 _DrvFwCtrlUpdateFirmwareCash(u8 szFwData[][1024], EmemType_e eEmemType)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("chip type = 0x%x\n", g_ChipType);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM) // (0x03)
+ {
+ return _DrvFwCtrlMsg26xxmUpdateFirmware(szFwData, eEmemType);
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX) // (0x85)
+ {
+ u16 eSwId = 0x0000;
+ u16 eVendorId = 0x0000;
+
+ eVendorId = szFwData[129][1005] << 8 | szFwData[129][1004]; // Retrieve major from info block
+ eSwId = _DrvFwCtrlMsg28xxGetSwId(EMEM_INFO);
+
+ DBG("eVendorId = 0x%x, eSwId = 0x%x\n", eVendorId, eSwId);
+
+ // Check if the vendor id of the update firmware bin file is equal to the vendor id on e-flash. YES => allow update, NO => not allow update
+ if (eSwId != eVendorId)
+ {
+ DrvPlatformLyrTouchDeviceResetHw(); // Reset HW here to avoid touch may be not worked after get sw id.
+
+ DBG("The vendor id of the update firmware bin file is different from the vendor id on e-flash. Not allow to update.\n");
+
+ return -1;
+ }
+ else
+ {
+ return _DrvFwCtrlMsg28xxUpdateFirmware(szFwData, EMEM_MAIN);
+ }
+ }
+ else
+ {
+ DBG("Undefined chip type.\n");
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after update firmware
+
+ return -1;
+ }
+}
+
+static s32 _DrvFwCtrlUpdateFirmwareBySdCard(const char *pFilePath)
+{
+ s32 nRetVal = 0;
+ struct file *pfile = NULL;
+ struct inode *inode;
+ s32 fsize = 0;
+ u8 *pbt_buf = NULL;
+ mm_segment_t old_fs;
+ loff_t pos;
+ u16 eSwId = 0x0000;
+ u16 eVendorId = 0x0000;
+
+ DBG("*** %s() ***\n", __func__);
+
+ pfile = filp_open(pFilePath, O_RDONLY, 0);
+ if (IS_ERR(pfile))
+ {
+ DBG("Error occured while opening file %s.\n", pFilePath);
+ return -1;
+ }
+
+ inode = pfile->f_dentry->d_inode;
+ fsize = inode->i_size;
+
+ DBG("fsize = %d\n", fsize);
+
+ if (fsize <= 0)
+ {
+ filp_close(pfile, NULL);
+ return -1;
+ }
+
+ // read firmware
+ pbt_buf = kmalloc(fsize, GFP_KERNEL);
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ pos = 0;
+ vfs_read(pfile, pbt_buf, fsize, &pos);
+
+ filp_close(pfile, NULL);
+ set_fs(old_fs);
+
+ _DrvFwCtrlStoreFirmwareData(pbt_buf, fsize);
+
+ kfree(pbt_buf);
+
+ DrvPlatformLyrDisableFingerTouchReport();
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ eVendorId = g_FwData[0][0x2B] <<8 | g_FwData[0][0x2A];
+ eSwId = _DrvFwCtrlMsg26xxmGetSwId(EMEM_MAIN);
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ eVendorId = g_FwData[127][1013] <<8 | g_FwData[127][1012];
+ eSwId = _DrvFwCtrlMsg28xxGetSwId(EMEM_MAIN);
+ }
+
+ DBG("eVendorId = 0x%x, eSwId = 0x%x\n", eVendorId, eSwId);
+
+ if (eSwId == eVendorId)
+ {
+ if ((g_ChipType == CHIP_TYPE_MSG26XXM && fsize == 40960/* 40KB */) || (g_ChipType == CHIP_TYPE_MSG28XX && fsize == 133120/* 130KB */))
+ {
+ nRetVal = _DrvFwCtrlUpdateFirmwareCash(g_FwData, EMEM_ALL);
+ }
+ else
+ {
+ DBG("The file size of the update firmware bin file is not supported, fsize = %d\n", fsize);
+ nRetVal = -1;
+ }
+ }
+ else
+ {
+ DBG("The vendor id of the update firmware bin file is different from the vendor id on e-flash. Not allow to update.\n");
+ nRetVal = -1;
+ }
+
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after update firmware
+
+ DrvPlatformLyrEnableFingerTouchReport();
+
+ return nRetVal;
+}
+
+//------------------------------------------------------------------------------//
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+
+void DrvFwCtrlOpenGestureWakeup(u32 *pMode)
+{
+ u8 szDbBusTxData[4] = {0};
+ u32 i = 0;
+ s32 rc;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("wakeup mode 0 = 0x%x\n", pMode[0]);
+ DBG("wakeup mode 1 = 0x%x\n", pMode[1]);
+
+#ifdef CONFIG_SUPPORT_64_TYPES_GESTURE_WAKEUP_MODE
+ szDbBusTxData[0] = 0x59;
+ szDbBusTxData[1] = 0x00;
+ szDbBusTxData[2] = ((pMode[1] & 0xFF000000) >> 24);
+ szDbBusTxData[3] = ((pMode[1] & 0x00FF0000) >> 16);
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 4);
+ mdelay(10); // delay 10ms
+
+ if (rc > 0)
+ {
+ DBG("Enable gesture wakeup index 0 success\n");
+ break;
+ }
+
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Enable gesture wakeup index 0 failed\n");
+ }
+
+ szDbBusTxData[0] = 0x59;
+ szDbBusTxData[1] = 0x01;
+ szDbBusTxData[2] = ((pMode[1] & 0x0000FF00) >> 8);
+ szDbBusTxData[3] = ((pMode[1] & 0x000000FF) >> 0);
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 4);
+ mdelay(10); // delay 10ms
+
+ if (rc > 0)
+ {
+ DBG("Enable gesture wakeup index 1 success\n");
+ break;
+ }
+
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Enable gesture wakeup index 1 failed\n");
+ }
+
+ szDbBusTxData[0] = 0x59;
+ szDbBusTxData[1] = 0x02;
+ szDbBusTxData[2] = ((pMode[0] & 0xFF000000) >> 24);
+ szDbBusTxData[3] = ((pMode[0] & 0x00FF0000) >> 16);
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 4);
+ mdelay(10); // delay 10ms
+
+ if (rc > 0)
+ {
+ DBG("Enable gesture wakeup index 2 success\n");
+ break;
+ }
+
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Enable gesture wakeup index 2 failed\n");
+ }
+
+ szDbBusTxData[0] = 0x59;
+ szDbBusTxData[1] = 0x03;
+ szDbBusTxData[2] = ((pMode[0] & 0x0000FF00) >> 8);
+ szDbBusTxData[3] = ((pMode[0] & 0x000000FF) >> 0);
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 4);
+ mdelay(10); // delay 10ms
+
+ if (rc > 0)
+ {
+ DBG("Enable gesture wakeup index 3 success\n");
+ break;
+ }
+
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Enable gesture wakeup index 3 failed\n");
+ }
+
+ g_GestureWakeupFlag = 1; // gesture wakeup is enabled
+
+#else
+
+ szDbBusTxData[0] = 0x58;
+ szDbBusTxData[1] = ((pMode[0] & 0x0000FF00) >> 8);
+ szDbBusTxData[2] = ((pMode[0] & 0x000000FF) >> 0);
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 3);
+
+ if (rc > 0)
+ {
+ DBG("Enable gesture wakeup success\n");
+ break;
+ }
+
+ mdelay(10);
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Enable gesture wakeup failed\n");
+ }
+
+ g_GestureWakeupFlag = 1; // gesture wakeup is enabled
+#endif //CONFIG_SUPPORT_64_TYPES_GESTURE_WAKEUP_MODE
+}
+
+void DrvFwCtrlCloseGestureWakeup(void)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ g_GestureWakeupFlag = 0; // gesture wakeup is disabled
+}
+
+#ifdef CONFIG_ENABLE_GESTURE_DEBUG_MODE
+void DrvFwCtrlOpenGestureDebugMode(u8 nGestureFlag)
+{
+ u8 szDbBusTxData[3] = {0};
+ s32 rc;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("Gesture Flag = 0x%x\n", nGestureFlag);
+
+ szDbBusTxData[0] = 0x30;
+ szDbBusTxData[1] = 0x01;
+ szDbBusTxData[2] = nGestureFlag;
+
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 3);
+ if (rc < 0)
+ {
+ DBG("Enable gesture debug mode failed\n");
+ }
+ else
+ {
+ DBG("Enable gesture debug mode success\n");
+ }
+
+ g_GestureDebugMode = 1; // gesture debug mode is enabled
+}
+
+void DrvFwCtrlCloseGestureDebugMode(void)
+{
+ u8 szDbBusTxData[3] = {0};
+ s32 rc;
+
+ DBG("*** %s() ***\n", __func__);
+
+ szDbBusTxData[0] = 0x30;
+ szDbBusTxData[1] = 0x00;
+ szDbBusTxData[2] = 0x00;
+
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 3);
+ if (rc < 0)
+ {
+ DBG("Disable gesture debug mode failed\n");
+ }
+ else
+ {
+ DBG("Disable gesture debug mode success\n");
+ }
+
+ g_GestureDebugMode = 0; // gesture debug mode is disabled
+}
+#endif //CONFIG_ENABLE_GESTURE_DEBUG_MODE
+
+#ifdef CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+static void _DrvFwCtrlCoordinate(u8 *pRawData, u32 *pTranX, u32 *pTranY)
+{
+ u32 nX;
+ u32 nY;
+#ifdef CONFIG_SWAP_X_Y
+ u32 nTempX;
+ u32 nTempY;
+#endif
+
+ nX = (((pRawData[0] & 0xF0) << 4) | pRawData[1]); // parse the packet to coordinate
+ nY = (((pRawData[0] & 0x0F) << 8) | pRawData[2]);
+
+ DBG("[x,y]=[%d,%d]\n", nX, nY);
+
+#ifdef CONFIG_SWAP_X_Y
+ nTempY = nX;
+ nTempX = nY;
+ nX = nTempX;
+ nY = nTempY;
+#endif
+
+#ifdef CONFIG_REVERSE_X
+ nX = 2047 - nX;
+#endif
+
+#ifdef CONFIG_REVERSE_Y
+ nY = 2047 - nY;
+#endif
+
+ /*
+ * pRawData[0]~pRawData[2] : the point abs,
+ * pRawData[0]~pRawData[2] all are 0xFF, release touch
+ */
+ if ((pRawData[0] == 0xFF) && (pRawData[1] == 0xFF) && (pRawData[2] == 0xFF))
+ {
+ *pTranX = 0; // final X coordinate
+ *pTranY = 0; // final Y coordinate
+ }
+ else
+ {
+ /* one touch point */
+ *pTranX = (nX * TOUCH_SCREEN_X_MAX) / TPD_WIDTH;
+ *pTranY = (nY * TOUCH_SCREEN_Y_MAX) / TPD_HEIGHT;
+ DBG("[%s]: [x,y]=[%d,%d]\n", __func__, nX, nY);
+ DBG("[%s]: point[x,y]=[%d,%d]\n", __func__, *pTranX, *pTranY);
+ }
+}
+#endif //CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+static void _DrvFwCtrlReadReadDQMemStart(void)
+{
+ u8 nParCmdSelUseCfg = 0x7F;
+ u8 nParCmdAdByteEn0 = 0x50;
+ u8 nParCmdAdByteEn1 = 0x51;
+ u8 nParCmdDaByteEn0 = 0x54;
+ u8 nParCmdUSetSelB0 = 0x80;
+ u8 nParCmdUSetSelB1 = 0x82;
+ u8 nParCmdSetSelB2 = 0x85;
+ u8 nParCmdIicUse = 0x35;
+ //u8 nParCmdWr = 0x10;
+
+ DBG("*** %s() ***\n", __func__);
+
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &nParCmdSelUseCfg, 1);
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &nParCmdAdByteEn0, 1);
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &nParCmdAdByteEn1, 1);
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &nParCmdDaByteEn0, 1);
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &nParCmdUSetSelB0, 1);
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &nParCmdUSetSelB1, 1);
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &nParCmdSetSelB2, 1);
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &nParCmdIicUse, 1);
+}
+
+static void _DrvFwCtrlReadReadDQMemEnd(void)
+{
+ u8 nParCmdNSelUseCfg = 0x7E;
+
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &nParCmdNSelUseCfg, 1);
+}
+
+u32 DrvFwCtrlReadDQMemValue(u16 nAddr)
+{
+ u8 tx_data[3] = {0x10, (nAddr >> 8) & 0xFF, nAddr & 0xFF};
+ u8 rx_data[4] = {0};
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("DQMem Addr = 0x%x\n", nAddr);
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+ mdelay(100);
+
+ _DrvFwCtrlReadReadDQMemStart();
+
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &tx_data[0], 3);
+ IicReadData(SLAVE_I2C_ID_DBBUS, &rx_data[0], 4);
+
+ _DrvFwCtrlReadReadDQMemEnd();
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return (rx_data[3] <<24 | rx_data[2] <<16 | rx_data[1] << 8 | rx_data[0]);
+}
+
+void DrvFwCtrlWriteDQMemValue(u16 nAddr, u32 nData)
+{
+ u8 szDbBusTxData[7] = {0};
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("DQMem Addr = 0x%x\n", nAddr);
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+ mdelay(100);
+
+ _DrvFwCtrlReadReadDQMemStart();
+ szDbBusTxData[0] = 0x10;
+ szDbBusTxData[1] = ((nAddr >> 8) & 0xff);
+ szDbBusTxData[2] = (nAddr & 0xff);
+ szDbBusTxData[3] = nData & 0x000000FF;
+ szDbBusTxData[4] = ((nData & 0x0000FF00) >> 8);
+ szDbBusTxData[5] = ((nData & 0x00FF0000) >> 16);
+ szDbBusTxData[6] = ((nData & 0xFF000000) >> 24);
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 7);
+
+ _DrvFwCtrlReadReadDQMemEnd();
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+ mdelay(100);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+}
+
+//------------------------------------------------------------------------------//
+
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_SW_ID
+
+//-------------------------Start of SW ID for MSG26XXM----------------------------//
+
+static u32 _DrvFwCtrlMsg26xxmCalculateFirmwareCrcFromEFlash(EmemType_e eEmemType, u8 nIsNeedResetHW)
+{
+ u32 nRetVal = 0;
+ u16 nRegData = 0;
+
+ DBG("*** %s() eEmemType = %d, nIsNeedResetHW = %d ***\n", __func__, eEmemType, nIsNeedResetHW);
+
+ if (1 == nIsNeedResetHW)
+ {
+ DrvPlatformLyrTouchDeviceResetHw();
+ }
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // cmd
+ RegSet16BitValue(0x3CE4, 0xDF4C); //bank:reg_PIU_MISC_0, addr:h0072
+
+ // TP SW reset
+ RegSet16BitValue(0x1E04, 0x7d60); //bank:chip, addr:h0002
+ RegSet16BitValue(0x1E04, 0x829F);
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+
+ mdelay(100);
+
+ // Polling 0x3CE4 is 0x9432
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4); //bank:reg_PIU_MISC_0, addr:h0072
+ } while (nRegData != 0x9432);
+
+ if (eEmemType == EMEM_MAIN) // Read calculated main block CRC(32K-8) from register
+ {
+ nRetVal = RegGet16BitValue(0x3C80);
+ nRetVal = (nRetVal << 16) | RegGet16BitValue(0x3C82);
+
+ DBG("Main Block CRC = 0x%x\n", nRetVal);
+ }
+ else if (eEmemType == EMEM_INFO) // Read calculated info block CRC(8K) from register
+ {
+ nRetVal = RegGet16BitValue(0x3CA0);
+ nRetVal = (nRetVal << 16) | RegGet16BitValue(0x3CA2);
+
+ DBG("Info Block CRC = 0x%x\n", nRetVal);
+ }
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return nRetVal;
+}
+
+static u32 _DrvFwCtrlMsg26xxmRetrieveFirmwareCrcFromMainBlock(EmemType_e eEmemType)
+{
+ u32 nRetVal = 0;
+ u16 nRegData = 0;
+ u8 szDbBusTxData[5] = {0};
+ u8 szDbBusRxData[4] = {0};
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // cmd
+ RegSet16BitValue(0x3CE4, 0xA4AB); //bank:reg_PIU_MISC_0, addr:h0072
+
+ // TP SW reset
+ RegSet16BitValue(0x1E04, 0x7d60); //bank:chip, addr:h0002
+ RegSet16BitValue(0x1E04, 0x829F);
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+
+ mdelay(100);
+
+ // Polling 0x3CE4 is 0x5B58
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4); //bank:reg_PIU_MISC_0, addr:h0072
+ } while (nRegData != 0x5B58);
+
+ szDbBusTxData[0] = 0x72;
+ if (eEmemType == EMEM_MAIN) // Read main block CRC(32K-8) from main block
+ {
+ szDbBusTxData[1] = 0x7F;
+ szDbBusTxData[2] = 0xF8;
+ }
+ else if (eEmemType == EMEM_INFO) // Read info block CRC(8K) from main block
+ {
+ szDbBusTxData[1] = 0x7F;
+ szDbBusTxData[2] = 0xFC;
+ }
+ szDbBusTxData[3] = 0x00;
+ szDbBusTxData[4] = 0x04;
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 5);
+ IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 4);
+
+ /*
+ The order of 4 bytes [ 0 : 1 : 2 : 3 ]
+ Ex. CRC32 = 0x12345678
+ 0x7FF8 = 0x78, 0x7FF9 = 0x56,
+ 0x7FFA = 0x34, 0x7FFB = 0x12
+ */
+
+ nRetVal = szDbBusRxData[3];
+ nRetVal = (nRetVal << 8) | szDbBusRxData[2];
+ nRetVal = (nRetVal << 8) | szDbBusRxData[1];
+ nRetVal = (nRetVal << 8) | szDbBusRxData[0];
+
+ DBG("CRC = 0x%x\n", nRetVal);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return nRetVal;
+}
+
+static u32 _DrvFwCtrlMsg26xxmRetrieveInfoCrcFromInfoBlock(void)
+{
+ u32 nRetVal = 0;
+ u16 nRegData = 0;
+ u8 szDbBusTxData[5] = {0};
+ u8 szDbBusRxData[4] = {0};
+
+ DBG("*** %s() ***\n", __func__);
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // cmd
+ RegSet16BitValue(0x3CE4, 0xA4AB); //bank:reg_PIU_MISC_0, addr:h0072
+
+ // TP SW reset
+ RegSet16BitValue(0x1E04, 0x7d60); //bank:chip, addr:h0002
+ RegSet16BitValue(0x1E04, 0x829F);
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+
+ mdelay(100);
+
+ // Polling 0x3CE4 is 0x5B58
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4); //bank:reg_PIU_MISC_0, addr:h0072
+ } while (nRegData != 0x5B58);
+
+
+ // Read info CRC(8K-4) from info block
+ szDbBusTxData[0] = 0x72;
+ szDbBusTxData[1] = 0x80;
+ szDbBusTxData[2] = 0x00;
+ szDbBusTxData[3] = 0x00;
+ szDbBusTxData[4] = 0x04;
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 5);
+ IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 4);
+
+ nRetVal = szDbBusRxData[3];
+ nRetVal = (nRetVal << 8) | szDbBusRxData[2];
+ nRetVal = (nRetVal << 8) | szDbBusRxData[1];
+ nRetVal = (nRetVal << 8) | szDbBusRxData[0];
+
+ DBG("CRC = 0x%x\n", nRetVal);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return nRetVal;
+}
+
+static u32 _DrvFwCtrlMsg26xxmRetrieveFrimwareCrcFromBinFile(u8 szTmpBuf[][1024], EmemType_e eEmemType)
+{
+ u32 nRetVal = 0;
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ if (szTmpBuf != NULL)
+ {
+ if (eEmemType == EMEM_MAIN) // Read main block CRC(32K-8) from bin file
+ {
+ nRetVal = szTmpBuf[31][1019];
+ nRetVal = (nRetVal << 8) | szTmpBuf[31][1018];
+ nRetVal = (nRetVal << 8) | szTmpBuf[31][1017];
+ nRetVal = (nRetVal << 8) | szTmpBuf[31][1016];
+ }
+ else if (eEmemType == EMEM_INFO) // Read info block CRC(8K) from bin file
+ {
+ nRetVal = szTmpBuf[31][1023];
+ nRetVal = (nRetVal << 8) | szTmpBuf[31][1022];
+ nRetVal = (nRetVal << 8) | szTmpBuf[31][1021];
+ nRetVal = (nRetVal << 8) | szTmpBuf[31][1020];
+ }
+ }
+
+ return nRetVal;
+}
+
+static u32 _DrvFwCtrlMsg26xxmCalculateInfoCrcByDeviceDriver(void)
+{
+ u32 nRetVal = 0xffffffff;
+ u32 i, j;
+ u16 nRegData = 0;
+ u8 szDbBusTxData[5] = {0};
+
+ DBG("*** %s() ***\n", __func__);
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_ENABLE_DMA_IIC
+ DmaReset();
+#endif //CONFIG_ENABLE_DMA_IIC
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // cmd
+ RegSet16BitValue(0x3CE4, 0xA4AB); //bank:reg_PIU_MISC_0, addr:h0072
+
+ // TP SW reset
+ RegSet16BitValue(0x1E04, 0x7d60); //bank:chip, addr:h0002
+ RegSet16BitValue(0x1E04, 0x829F);
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+
+ mdelay(100);
+
+ // Polling 0x3CE4 is 0x5B58
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4); //bank:reg_PIU_MISC_0, addr:h0072
+ } while (nRegData != 0x5B58);
+
+ DrvCommonCrcInitTable();
+
+ // Read info data(8K) from info block
+ szDbBusTxData[0] = 0x72;
+ szDbBusTxData[3] = 0x00; // read 128 bytes
+ szDbBusTxData[4] = 0x80;
+
+ for (i = 0; i < 8; i ++)
+ {
+ for (j = 0; j < 8; j ++)
+ {
+ szDbBusTxData[1] = 0x80 + (i*0x04) + (((j*128)&0xff00)>>8);
+ szDbBusTxData[2] = (j*128)&0x00ff;
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 5);
+
+ // Receive info data
+ IicReadData(SLAVE_I2C_ID_DWI2C, &_gTempData[j*128], 128);
+ }
+
+ if (i == 0)
+ {
+ for (j = 4; j < 1024; j ++)
+ {
+ nRetVal = DrvCommonCrcGetValue(_gTempData[j], nRetVal);
+ }
+ }
+ else
+ {
+ for (j = 0; j < 1024; j ++)
+ {
+ nRetVal = DrvCommonCrcGetValue(_gTempData[j], nRetVal);
+ }
+ }
+ }
+
+ nRetVal = nRetVal ^ 0xffffffff;
+
+ DBG("Info(8K-4) CRC = 0x%x\n", nRetVal);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return nRetVal;
+}
+
+static s32 _DrvFwCtrlMsg26xxmCompare8BytesForCrc(u8 szTmpBuf[][1024])
+{
+ s32 nRetVal = -1;
+ u16 nRegData = 0;
+ u8 szDbBusTxData[5] = {0};
+ u8 szDbBusRxData[8] = {0};
+ u8 crc[8] = {0};
+
+ DBG("*** %s() ***\n", __func__);
+
+ // Read 8 bytes from bin file
+ if (szTmpBuf != NULL)
+ {
+ crc[0] = szTmpBuf[31][1016];
+ crc[1] = szTmpBuf[31][1017];
+ crc[2] = szTmpBuf[31][1018];
+ crc[3] = szTmpBuf[31][1019];
+ crc[4] = szTmpBuf[31][1020];
+ crc[5] = szTmpBuf[31][1021];
+ crc[6] = szTmpBuf[31][1022];
+ crc[7] = szTmpBuf[31][1023];
+ }
+
+ // Read 8 bytes from the firmware on e-flash
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // cmd
+ RegSet16BitValue(0x3CE4, 0xA4AB); //bank:reg_PIU_MISC_0, addr:h0072
+
+ // TP SW reset
+ RegSet16BitValue(0x1E04, 0x7d60); //bank:chip, addr:h0002
+ RegSet16BitValue(0x1E04, 0x829F);
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+
+ mdelay(100);
+
+ // Polling 0x3CE4 is 0x5B58
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4); //bank:reg_PIU_MISC_0, addr:h0072
+ } while (nRegData != 0x5B58);
+
+ szDbBusTxData[0] = 0x72;
+ szDbBusTxData[1] = 0x7F;
+ szDbBusTxData[2] = 0xF8;
+ szDbBusTxData[3] = 0x00;
+ szDbBusTxData[4] = 0x08;
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 5);
+ IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 8);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ if (crc[0] == szDbBusRxData[0]
+ && crc[1] == szDbBusRxData[1]
+ && crc[2] == szDbBusRxData[2]
+ && crc[3] == szDbBusRxData[3]
+ && crc[4] == szDbBusRxData[4]
+ && crc[5] == szDbBusRxData[5]
+ && crc[6] == szDbBusRxData[6]
+ && crc[7] == szDbBusRxData[7])
+ {
+ nRetVal = 0;
+ }
+ else
+ {
+ nRetVal = -1;
+ }
+
+ DBG("compare 8bytes for CRC = %d\n", nRetVal);
+
+ return nRetVal;
+}
+
+static void _DrvFwCtrlMsg26xxmEraseFirmwareOnEFlash(EmemType_e eEmemType)
+{
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ DBG("erase 0\n");
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // cmd
+ RegSet16BitValue(0x3CE4, 0x78C5); //bank:reg_PIU_MISC_0, addr:h0072
+
+ // TP SW reset
+ RegSet16BitValue(0x1E04, 0x7d60); //bank:chip, addr:h0002
+ RegSet16BitValue(0x1E04, 0x829F);
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+
+ mdelay(100);
+
+ DBG("erase 1\n");
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // Set PROGRAM password
+ RegSet16BitValue(0x161A, 0xABBA); //bank:emem, addr:h000D
+
+ if (eEmemType == EMEM_INFO)
+ {
+ RegSet16BitValue(0x1600, 0x8000); //bank:emem, addr:h0000
+ }
+
+ // Clear pce
+ RegSetLByteValue(0x1618, 0x80); //bank:emem, addr:h000C
+
+ DBG("erase 2\n");
+
+ // Clear setting
+ RegSetLByteValue(0x1618, 0x40); //bank:emem, addr:h000C
+
+ mdelay(10);
+
+ // Clear pce
+ RegSetLByteValue(0x1618, 0x80); //bank:emem, addr:h000C
+
+ DBG("erase 3\n");
+
+ // Trigger erase
+ if (eEmemType == EMEM_ALL)
+ {
+ RegSetLByteValue(0x160E, 0x08); //all chip //bank:emem, addr:h0007
+ }
+ else if (eEmemType == EMEM_MAIN || eEmemType == EMEM_INFO)
+ {
+ RegSetLByteValue(0x160E, 0x04); //sector //bank:emem, addr:h0007
+ }
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ mdelay(200);
+
+ DBG("erase OK\n");
+}
+
+static void _DrvFwCtrlMsg26xxmProgramFirmwareOnEFlash(EmemType_e eEmemType)
+{
+ u32 nStart = 0, nEnd = 0;
+ u32 i, j;
+ u16 nRegData = 0;
+// u16 nRegData2 = 0, nRegData3 = 0; // add for debug
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_ENABLE_DMA_IIC
+ DmaReset();
+#endif //CONFIG_ENABLE_DMA_IIC
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+ DBG("program 0\n");
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ if (eEmemType == EMEM_INFO || eEmemType == EMEM_MAIN)
+ {
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // cmd
+ RegSet16BitValue(0x3CE4, 0x78C5); //bank:reg_PIU_MISC_0, addr:h0072
+
+ // TP SW reset
+ RegSet16BitValue(0x1E04, 0x7d60); //bank:chip, addr:h0002
+ RegSet16BitValue(0x1E04, 0x829F);
+
+ nRegData = RegGet16BitValue(0x1618);
+// DBG("*** reg(0x16, 0x18) = 0x%x ***\n", nRegData); // add for debug
+
+ nRegData |= 0x40;
+// DBG("*** nRegData = 0x%x ***\n", nRegData); // add for debug
+
+ RegSetLByteValue(0x1618, nRegData);
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+
+ mdelay(100);
+ }
+
+ DBG("program 1\n");
+
+ RegSet16BitValue(0x0F52, 0xDB00); // add for analysis
+
+ // Check_Loader_Ready: Polling 0x3CE4 is 0x1C70
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4); //bank:reg_PIU_MISC_0, addr:h0072
+// DBG("*** reg(0x3C, 0xE4) = 0x%x ***\n", nRegData); // add for debug
+
+// nRegData2 = RegGet16BitValue(0x0F00); // add for debug
+// DBG("*** reg(0x0F, 0x00) = 0x%x ***\n", nRegData2);
+
+// nRegData3 = RegGet16BitValue(0x1E04); // add for debug
+// DBG("*** reg(0x1E, 0x04) = 0x%x ***\n", nRegData3);
+
+ } while (nRegData != 0x1C70);
+
+ DBG("program 2\n");
+
+ if (eEmemType == EMEM_ALL)
+ {
+ RegSet16BitValue(0x3CE4, 0xE38F); //all chip
+
+ nStart = 0;
+ nEnd = MSG26XXM_FIRMWARE_WHOLE_SIZE; //32K + 8K
+ }
+ else if (eEmemType == EMEM_MAIN)
+ {
+ RegSet16BitValue(0x3CE4, 0x7731); //main block
+
+ nStart = 0;
+ nEnd = MSG26XXM_FIRMWARE_MAIN_BLOCK_SIZE; //32K
+ }
+ else if (eEmemType == EMEM_INFO)
+ {
+ RegSet16BitValue(0x3CE4, 0xB9D6); //info block
+
+ nStart = MSG26XXM_FIRMWARE_MAIN_BLOCK_SIZE;
+ nEnd = MSG26XXM_FIRMWARE_MAIN_BLOCK_SIZE + MSG26XXM_FIRMWARE_INFO_BLOCK_SIZE;
+ }
+
+ // Check_Loader_Ready2Program: Polling 0x3CE4 is 0x2F43
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4);
+ } while (nRegData != 0x2F43);
+
+ DBG("program 3\n");
+
+ for (i = nStart; i < nEnd; i ++)
+ {
+ for (j = 0; j < 8; j ++)
+ {
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &g_FwData[i][j*128], 128);
+ }
+
+ mdelay(100);
+
+ // Check_Program_Done: Polling 0x3CE4 is 0xD0BC
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4);
+ } while (nRegData != 0xD0BC);
+
+ // Continue_Program
+ RegSet16BitValue(0x3CE4, 0x2F43);
+ }
+
+ DBG("program 4\n");
+
+ // Notify_Write_Done
+ RegSet16BitValue(0x3CE4, 0x1380);
+ mdelay(100);
+
+ DBG("program 5\n");
+
+ // Check_CRC_Done: Polling 0x3CE4 is 0x9432
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4);
+ } while (nRegData != 0x9432);
+
+ DBG("program 6\n");
+
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after update firmware
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ mdelay(300);
+
+ DBG("program OK\n");
+}
+
+static s32 _DrvFwCtrlMsg26xxmUpdateFirmwareBySwId(void)
+{
+ s32 nRetVal = -1;
+ u32 nCrcInfoA = 0, nCrcInfoB = 0, nCrcMainA = 0, nCrcMainB = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("_gIsUpdateInfoBlockFirst = %d, g_IsUpdateFirmware = 0x%x\n", _gIsUpdateInfoBlockFirst, g_IsUpdateFirmware);
+
+ if (_gIsUpdateInfoBlockFirst == 1)
+ {
+ if ((g_IsUpdateFirmware & 0x10) == 0x10)
+ {
+ _DrvFwCtrlMsg26xxmEraseFirmwareOnEFlash(EMEM_INFO);
+ _DrvFwCtrlMsg26xxmProgramFirmwareOnEFlash(EMEM_INFO);
+
+ nCrcInfoA = _DrvFwCtrlMsg26xxmRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_INFO);
+ nCrcInfoB = _DrvFwCtrlMsg26xxmCalculateFirmwareCrcFromEFlash(EMEM_INFO, 0);
+
+ DBG("nCrcInfoA = 0x%x, nCrcInfoB = 0x%x\n", nCrcInfoA, nCrcInfoB);
+
+ if (nCrcInfoA == nCrcInfoB)
+ {
+ _DrvFwCtrlMsg26xxmEraseFirmwareOnEFlash(EMEM_MAIN);
+ _DrvFwCtrlMsg26xxmProgramFirmwareOnEFlash(EMEM_MAIN);
+
+ nCrcMainA = _DrvFwCtrlMsg26xxmRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_MAIN);
+ nCrcMainB = _DrvFwCtrlMsg26xxmCalculateFirmwareCrcFromEFlash(EMEM_MAIN, 0);
+
+ DBG("nCrcMainA = 0x%x, nCrcMainB = 0x%x\n", nCrcMainA, nCrcMainB);
+
+ if (nCrcMainA == nCrcMainB)
+ {
+ nRetVal = _DrvFwCtrlMsg26xxmCompare8BytesForCrc(g_FwData);
+
+ if (nRetVal == 0)
+ {
+ g_IsUpdateFirmware = 0x00;
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x11;
+ }
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x01;
+ }
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x11;
+ }
+ }
+ else if ((g_IsUpdateFirmware & 0x01) == 0x01)
+ {
+ _DrvFwCtrlMsg26xxmEraseFirmwareOnEFlash(EMEM_MAIN);
+ _DrvFwCtrlMsg26xxmProgramFirmwareOnEFlash(EMEM_MAIN);
+
+ nCrcMainA = _DrvFwCtrlMsg26xxmRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_MAIN);
+ nCrcMainB = _DrvFwCtrlMsg26xxmCalculateFirmwareCrcFromEFlash(EMEM_MAIN, 0);
+
+ DBG("nCrcMainA=0x%x, nCrcMainB=0x%x\n", nCrcMainA, nCrcMainB);
+
+ if (nCrcMainA == nCrcMainB)
+ {
+ nRetVal = _DrvFwCtrlMsg26xxmCompare8BytesForCrc(g_FwData);
+
+ if (nRetVal == 0)
+ {
+ g_IsUpdateFirmware = 0x00;
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x11;
+ }
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x01;
+ }
+ }
+ }
+ else //_gIsUpdateInfoBlockFirst == 0
+ {
+ if ((g_IsUpdateFirmware & 0x10) == 0x10)
+ {
+ _DrvFwCtrlMsg26xxmEraseFirmwareOnEFlash(EMEM_MAIN);
+ _DrvFwCtrlMsg26xxmProgramFirmwareOnEFlash(EMEM_MAIN);
+
+ nCrcMainA = _DrvFwCtrlMsg26xxmRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_MAIN);
+ nCrcMainB = _DrvFwCtrlMsg26xxmCalculateFirmwareCrcFromEFlash(EMEM_MAIN, 0);
+
+ DBG("nCrcMainA=0x%x, nCrcMainB=0x%x\n", nCrcMainA, nCrcMainB);
+
+ if (nCrcMainA == nCrcMainB)
+ {
+ _DrvFwCtrlMsg26xxmEraseFirmwareOnEFlash(EMEM_INFO);
+ _DrvFwCtrlMsg26xxmProgramFirmwareOnEFlash(EMEM_INFO);
+
+ nCrcInfoA = _DrvFwCtrlMsg26xxmRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_INFO);
+ nCrcInfoB = _DrvFwCtrlMsg26xxmCalculateFirmwareCrcFromEFlash(EMEM_INFO, 0);
+
+ DBG("nCrcInfoA=0x%x, nCrcInfoB=0x%x\n", nCrcInfoA, nCrcInfoB);
+
+ if (nCrcInfoA == nCrcInfoB)
+ {
+ nRetVal = _DrvFwCtrlMsg26xxmCompare8BytesForCrc(g_FwData);
+
+ if (nRetVal == 0)
+ {
+ g_IsUpdateFirmware = 0x00;
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x11;
+ }
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x01;
+ }
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x11;
+ }
+ }
+ else if ((g_IsUpdateFirmware & 0x01) == 0x01)
+ {
+ _DrvFwCtrlMsg26xxmEraseFirmwareOnEFlash(EMEM_INFO);
+ _DrvFwCtrlMsg26xxmProgramFirmwareOnEFlash(EMEM_INFO);
+
+ nCrcInfoA = _DrvFwCtrlMsg26xxmRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_INFO);
+ nCrcInfoB = _DrvFwCtrlMsg26xxmCalculateFirmwareCrcFromEFlash(EMEM_INFO, 0);
+
+ DBG("nCrcInfoA=0x%x, nCrcInfoB=0x%x\n", nCrcInfoA, nCrcInfoB);
+
+ if (nCrcInfoA == nCrcInfoB)
+ {
+ nRetVal = _DrvFwCtrlMsg26xxmCompare8BytesForCrc(g_FwData);
+
+ if (nRetVal == 0)
+ {
+ g_IsUpdateFirmware = 0x00;
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x11;
+ }
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x01;
+ }
+ }
+ }
+
+ return nRetVal;
+}
+
+void _DrvFwCtrlMsg26xxmCheckFirmwareUpdateBySwId(void)
+{
+ u32 nCrcMainA, nCrcInfoA, nCrcMainB, nCrcInfoB;
+ u32 i;
+ u16 nUpdateBinMajor = 0, nUpdateBinMinor = 0;
+ u16 nMajor = 0, nMinor = 0;
+ u8 *pVersion = NULL;
+ Msg26xxmSwId_e eSwId = MSG26XXM_SW_ID_UNDEFINED;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DrvPlatformLyrDisableFingerTouchReport();
+
+ nCrcMainA = _DrvFwCtrlMsg26xxmCalculateFirmwareCrcFromEFlash(EMEM_MAIN, 1);
+ nCrcMainB = _DrvFwCtrlMsg26xxmRetrieveFirmwareCrcFromMainBlock(EMEM_MAIN);
+
+ nCrcInfoA = _DrvFwCtrlMsg26xxmCalculateFirmwareCrcFromEFlash(EMEM_INFO, 1);
+ nCrcInfoB = _DrvFwCtrlMsg26xxmRetrieveFirmwareCrcFromMainBlock(EMEM_INFO);
+
+ _gUpdateFirmwareBySwIdWorkQueue = create_singlethread_workqueue("update_firmware_by_sw_id");
+ INIT_WORK(&_gUpdateFirmwareBySwIdWork, _DrvFwCtrlUpdateFirmwareBySwIdDoWork);
+
+ DBG("nCrcMainA=0x%x, nCrcInfoA=0x%x, nCrcMainB=0x%x, nCrcInfoB=0x%x\n", nCrcMainA, nCrcInfoA, nCrcMainB, nCrcInfoB);
+
+ if (nCrcMainA == nCrcMainB && nCrcInfoA == nCrcInfoB) // Case 1. Main Block:OK, Info Block:OK
+ {
+ eSwId = _DrvFwCtrlMsg26xxmGetSwId(EMEM_MAIN);
+
+ DBG("eSwId=0x%x\n", eSwId);
+
+ if (eSwId == MSG26XXM_SW_ID_XXXX)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ nUpdateBinMajor = msg26xxm_xxxx_update_bin[0][0x2B]<<8 | msg26xxm_xxxx_update_bin[0][0x2A];
+ nUpdateBinMinor = msg26xxm_xxxx_update_bin[0][0x2D]<<8 | msg26xxm_xxxx_update_bin[0][0x2C];
+#else // By one dimensional array
+ nUpdateBinMajor = msg26xxm_xxxx_update_bin[0x002B]<<8 | msg26xxm_xxxx_update_bin[0x002A];
+ nUpdateBinMinor = msg26xxm_xxxx_update_bin[0x002D]<<8 | msg26xxm_xxxx_update_bin[0x002C];
+#endif
+ }
+ else if (eSwId == MSG26XXM_SW_ID_YYYY)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ nUpdateBinMajor = msg26xxm_yyyy_update_bin[0][0x2B]<<8 | msg26xxm_yyyy_update_bin[0][0x2A];
+ nUpdateBinMinor = msg26xxm_yyyy_update_bin[0][0x2D]<<8 | msg26xxm_yyyy_update_bin[0][0x2C];
+#else // By one dimensional array
+ nUpdateBinMajor = msg26xxm_yyyy_update_bin[0x002B]<<8 | msg26xxm_yyyy_update_bin[0x002A];
+ nUpdateBinMinor = msg26xxm_yyyy_update_bin[0x002D]<<8 | msg26xxm_yyyy_update_bin[0x002C];
+#endif
+ }
+ else //eSwId == MSG26XXM_SW_ID_UNDEFINED
+ {
+ DBG("eSwId = 0x%x is an undefined SW ID.\n", eSwId);
+
+ eSwId = MSG26XXM_SW_ID_UNDEFINED;
+ nUpdateBinMajor = 0;
+ nUpdateBinMinor = 0;
+ }
+
+ DrvFwCtrlGetCustomerFirmwareVersion(&nMajor, &nMinor, &pVersion);
+
+ DBG("eSwId=0x%x, nMajor=%d, nMinor=%d, nUpdateBinMajor=%d, nUpdateBinMinor=%d\n", eSwId, nMajor, nMinor, nUpdateBinMajor, nUpdateBinMinor);
+
+ if (nUpdateBinMinor > nMinor)
+ {
+ if (eSwId == MSG26XXM_SW_ID_XXXX)
+ {
+ for (i = 0; i < MSG26XXM_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg26xxm_xxxx_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg26xxm_xxxx_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else if (eSwId == MSG26XXM_SW_ID_YYYY)
+ {
+ for (i = 0; i < MSG26XXM_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg26xxm_yyyy_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg26xxm_yyyy_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else
+ {
+ DBG("eSwId = 0x%x is an undefined SW ID.\n", eSwId);
+
+ eSwId = MSG26XXM_SW_ID_UNDEFINED;
+ }
+
+ if (eSwId < MSG26XXM_SW_ID_UNDEFINED && eSwId != 0x0000 && eSwId != 0xFFFF)
+ {
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after copying update firmware data to temp buffer
+
+ _gUpdateRetryCount = UPDATE_FIRMWARE_RETRY_COUNT;
+ _gIsUpdateInfoBlockFirst = 1; // Set 1 for indicating main block is complete
+ g_IsUpdateFirmware = 0x11;
+ queue_work(_gUpdateFirmwareBySwIdWorkQueue, &_gUpdateFirmwareBySwIdWork);
+ return;
+ }
+ else
+ {
+ DBG("The sw id is invalid.\n");
+ DBG("Go to normal boot up process.\n");
+ }
+ }
+ else
+ {
+ DBG("The update bin version is older than or equal to the current firmware version on e-flash.\n");
+ DBG("Go to normal boot up process.\n");
+ }
+ }
+ else if (nCrcMainA == nCrcMainB && nCrcInfoA != nCrcInfoB) // Case 2. Main Block:OK, Info Block:FAIL
+ {
+ eSwId = _DrvFwCtrlMsg26xxmGetSwId(EMEM_MAIN);
+
+ DBG("eSwId=0x%x\n", eSwId);
+
+ if (eSwId == MSG26XXM_SW_ID_XXXX)
+ {
+ for (i = 0; i < MSG26XXM_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg26xxm_xxxx_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg26xxm_xxxx_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else if (eSwId == MSG26XXM_SW_ID_YYYY)
+ {
+ for (i = 0; i < MSG26XXM_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg26xxm_yyyy_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg26xxm_yyyy_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else
+ {
+ DBG("eSwId = 0x%x is an undefined SW ID.\n", eSwId);
+
+ eSwId = MSG26XXM_SW_ID_UNDEFINED;
+ }
+
+ if (eSwId < MSG26XXM_SW_ID_UNDEFINED && eSwId != 0x0000 && eSwId != 0xFFFF)
+ {
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after copying update firmware data to temp buffer
+
+ _gUpdateRetryCount = UPDATE_FIRMWARE_RETRY_COUNT;
+ _gIsUpdateInfoBlockFirst = 1; // Set 1 for indicating main block is complete
+ g_IsUpdateFirmware = 0x11;
+ queue_work(_gUpdateFirmwareBySwIdWorkQueue, &_gUpdateFirmwareBySwIdWork);
+ return;
+ }
+ else
+ {
+ DBG("The sw id is invalid.\n");
+ DBG("Go to normal boot up process.\n");
+ }
+ }
+ else // Case 3. Main Block:FAIL, Info Block:FAIL/OK
+ {
+ nCrcInfoA = _DrvFwCtrlMsg26xxmRetrieveInfoCrcFromInfoBlock();
+ nCrcInfoB = _DrvFwCtrlMsg26xxmCalculateInfoCrcByDeviceDriver();
+
+ DBG("8K-4 : nCrcInfoA=0x%x, nCrcInfoB=0x%x\n", nCrcInfoA, nCrcInfoB);
+
+ if (nCrcInfoA == nCrcInfoB) // Check if info block is actually OK.
+ {
+ eSwId = _DrvFwCtrlMsg26xxmGetSwId(EMEM_INFO);
+
+ DBG("eSwId=0x%x\n", eSwId);
+
+ if (eSwId == MSG26XXM_SW_ID_XXXX)
+ {
+ for (i = 0; i < MSG26XXM_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg26xxm_xxxx_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg26xxm_xxxx_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else if (eSwId == MSG26XXM_SW_ID_YYYY)
+ {
+ for (i = 0; i < MSG26XXM_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg26xxm_yyyy_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg26xxm_yyyy_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else
+ {
+ DBG("eSwId = 0x%x is an undefined SW ID.\n", eSwId);
+
+ eSwId = MSG26XXM_SW_ID_UNDEFINED;
+ }
+
+ if (eSwId < MSG26XXM_SW_ID_UNDEFINED && eSwId != 0x0000 && eSwId != 0xFFFF)
+ {
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after copying update firmware data to temp buffer
+
+ _gUpdateRetryCount = UPDATE_FIRMWARE_RETRY_COUNT;
+ _gIsUpdateInfoBlockFirst = 0; // Set 0 for indicating main block is broken
+ g_IsUpdateFirmware = 0x11;
+ queue_work(_gUpdateFirmwareBySwIdWorkQueue, &_gUpdateFirmwareBySwIdWork);
+ return;
+ }
+ else
+ {
+ DBG("The sw id is invalid.\n");
+ DBG("Go to normal boot up process.\n");
+ }
+ }
+ else
+ {
+ DBG("Info block is broken.\n");
+ }
+ }
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DrvPlatformLyrEnableFingerTouchReport();
+}
+
+//-------------------------End of SW ID for MSG26XXM----------------------------//
+
+//-------------------------Start of SW ID for MSG28XX----------------------------//
+
+static u32 _DrvFwCtrlMsg28xxRetrieveFirmwareCrcFromEFlash(EmemType_e eEmemType)
+{
+ u32 nRetVal = 0;
+ u16 nReadAddr = 0;
+ u8 szTmpData[4] = {0};
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01);
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55);
+
+ if (eEmemType == EMEM_MAIN) // Read main block CRC(128KB-4) from main block
+ {
+ _DrvFwCtrlMsg28xxReadEFlashStart(0x7FFF, EMEM_MAIN);
+ nReadAddr = 0x7FFF;
+ }
+ else if (eEmemType == EMEM_INFO) // Read info block CRC(2KB-MSG28XX_EMEM_SIZE_BYTES_PER_ONE_PAGE-4) from info block
+ {
+ _DrvFwCtrlMsg28xxReadEFlashStart(0x81FF, EMEM_INFO);
+ nReadAddr = 0x81FF;
+ }
+
+ _DrvFwCtrlMsg28xxReadEFlashDoRead(nReadAddr, &szTmpData[0]);
+
+ DBG("szTmpData[0] = 0x%x\n", szTmpData[0]); // add for debug
+ DBG("szTmpData[1] = 0x%x\n", szTmpData[1]); // add for debug
+ DBG("szTmpData[2] = 0x%x\n", szTmpData[2]); // add for debug
+ DBG("szTmpData[3] = 0x%x\n", szTmpData[3]); // add for debug
+
+ _DrvFwCtrlMsg28xxReadEFlashEnd();
+
+ nRetVal = (szTmpData[3] << 24);
+ nRetVal |= (szTmpData[2] << 16);
+ nRetVal |= (szTmpData[1] << 8);
+ nRetVal |= szTmpData[0];
+
+ DBG("CRC = 0x%x\n", nRetVal);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return nRetVal;
+}
+
+static u32 _DrvFwCtrlMsg28xxRetrieveFrimwareCrcFromBinFile(u8 szTmpBuf[][1024], EmemType_e eEmemType)
+{
+ u32 nRetVal = 0;
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ if (szTmpBuf != NULL)
+ {
+ if (eEmemType == EMEM_MAIN)
+ {
+ nRetVal = szTmpBuf[127][1023];
+ nRetVal = (nRetVal << 8) | szTmpBuf[127][1022];
+ nRetVal = (nRetVal << 8) | szTmpBuf[127][1021];
+ nRetVal = (nRetVal << 8) | szTmpBuf[127][1020];
+ }
+ else if (eEmemType == EMEM_INFO)
+ {
+ nRetVal = szTmpBuf[129][1023];
+ nRetVal = (nRetVal << 8) | szTmpBuf[129][1022];
+ nRetVal = (nRetVal << 8) | szTmpBuf[129][1021];
+ nRetVal = (nRetVal << 8) | szTmpBuf[129][1020];
+ }
+ }
+
+ return nRetVal;
+}
+
+/*
+static s32 _DrvFwCtrlMsg28xxUpdateFirmwareBySwId(void)
+{
+ s32 nRetVal = -1;
+ u32 nCrcInfoA = 0, nCrcInfoB = 0, nCrcMainA = 0, nCrcMainB = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DBG("_gIsUpdateInfoBlockFirst = %d, g_IsUpdateFirmware = 0x%x\n", _gIsUpdateInfoBlockFirst, g_IsUpdateFirmware);
+
+ if (_gIsUpdateInfoBlockFirst == 1)
+ {
+ if ((g_IsUpdateFirmware & 0x10) == 0x10)
+ {
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_INFO);
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_INFO);
+
+ nCrcInfoA = _DrvFwCtrlMsg28xxRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_INFO);
+ nCrcInfoB = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_INFO);
+
+ DBG("nCrcInfoA = 0x%x, nCrcInfoB = 0x%x\n", nCrcInfoA, nCrcInfoB);
+
+ if (nCrcInfoA == nCrcInfoB)
+ {
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_MAIN);
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_MAIN);
+
+ nCrcMainA = _DrvFwCtrlMsg28xxRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_MAIN);
+ nCrcMainB = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_MAIN);
+
+ DBG("nCrcMainA = 0x%x, nCrcMainB = 0x%x\n", nCrcMainA, nCrcMainB);
+
+ if (nCrcMainA == nCrcMainB)
+ {
+ g_IsUpdateFirmware = 0x00;
+ nRetVal = 0;
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x01;
+ }
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x11;
+ }
+ }
+ else if ((g_IsUpdateFirmware & 0x01) == 0x01)
+ {
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_MAIN);
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_MAIN);
+
+ nCrcMainA = _DrvFwCtrlMsg28xxRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_MAIN);
+ nCrcMainB = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_MAIN);
+
+ DBG("nCrcMainA=0x%x, nCrcMainB=0x%x\n", nCrcMainA, nCrcMainB);
+
+ if (nCrcMainA == nCrcMainB)
+ {
+ g_IsUpdateFirmware = 0x00;
+ nRetVal = 0;
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x01;
+ }
+ }
+ }
+ else //_gIsUpdateInfoBlockFirst == 0
+ {
+ if ((g_IsUpdateFirmware & 0x10) == 0x10)
+ {
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_MAIN);
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_MAIN);
+
+ nCrcMainA = _DrvFwCtrlMsg28xxRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_MAIN);
+ nCrcMainB = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_MAIN);
+
+ DBG("nCrcMainA=0x%x, nCrcMainB=0x%x\n", nCrcMainA, nCrcMainB);
+
+ if (nCrcMainA == nCrcMainB)
+ {
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_INFO);
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_INFO);
+
+ nCrcInfoA = _DrvFwCtrlMsg28xxRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_INFO);
+ nCrcInfoB = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_INFO);
+
+ DBG("nCrcInfoA=0x%x, nCrcInfoB=0x%x\n", nCrcInfoA, nCrcInfoB);
+
+ if (nCrcInfoA == nCrcInfoB)
+ {
+ g_IsUpdateFirmware = 0x00;
+ nRetVal = 0;
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x01;
+ }
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x11;
+ }
+ }
+ else if ((g_IsUpdateFirmware & 0x01) == 0x01)
+ {
+ _DrvFwCtrlMsg28xxEraseEmem(EMEM_INFO);
+ _DrvFwCtrlMsg28xxProgramEmem(EMEM_INFO);
+
+ nCrcInfoA = _DrvFwCtrlMsg28xxRetrieveFrimwareCrcFromBinFile(g_FwData, EMEM_INFO);
+ nCrcInfoB = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_INFO);
+
+ DBG("nCrcInfoA=0x%x, nCrcInfoB=0x%x\n", nCrcInfoA, nCrcInfoB);
+
+ if (nCrcInfoA == nCrcInfoB)
+ {
+ g_IsUpdateFirmware = 0x00;
+ nRetVal = 0;
+ }
+ else
+ {
+ g_IsUpdateFirmware = 0x01;
+ }
+ }
+ }
+
+ return nRetVal;
+}
+*/
+
+void _DrvFwCtrlMsg28xxCheckFirmwareUpdateBySwId(void)
+{
+ u32 nCrcMainA, nCrcMainB;
+ u32 i;
+ u16 nUpdateBinMajor = 0, nUpdateBinMinor = 0;
+ u16 nMajor = 0, nMinor = 0;
+ u8 nIsCompareVersion = 0;
+ u8 *pVersion = NULL;
+ Msg28xxSwId_e eMainSwId = MSG28XX_SW_ID_UNDEFINED, eInfoSwId = MSG28XX_SW_ID_UNDEFINED, eSwId = MSG28XX_SW_ID_UNDEFINED;
+
+ DBG("*** %s() ***\n", __func__);
+
+ DrvPlatformLyrDisableFingerTouchReport();
+
+ nCrcMainA = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_MAIN);
+ nCrcMainB = _DrvFwCtrlMsg28xxRetrieveFirmwareCrcFromEFlash(EMEM_MAIN);
+
+ DBG("nCrcMainA=0x%x, nCrcMainB=0x%x\n", nCrcMainA, nCrcMainB);
+
+#ifdef CONFIG_ENABLE_CODE_FOR_DEBUG // TODO : add for debug
+ {
+ if (nCrcMainA != nCrcMainB)
+ {
+ for (i = 0; i < 5; i ++)
+ {
+ nCrcMainA = _DrvFwCtrlMsg28xxGetFirmwareCrcByHardware(EMEM_MAIN);
+ nCrcMainB = _DrvFwCtrlMsg28xxRetrieveFirmwareCrcFromEFlash(EMEM_MAIN);
+
+ DBG("*** Retry[%d] : nCrcMainA=0x%x, nCrcMainB=0x%x ***\n", i, nCrcMainA, nCrcMainB);
+
+ if (nCrcMainA == nCrcMainB)
+ {
+ break;
+ }
+
+ mdelay(50);
+ }
+ }
+ }
+#endif //CONFIG_ENABLE_CODE_FOR_DEBUG
+
+ _gUpdateFirmwareBySwIdWorkQueue = create_singlethread_workqueue("update_firmware_by_sw_id");
+ INIT_WORK(&_gUpdateFirmwareBySwIdWork, _DrvFwCtrlUpdateFirmwareBySwIdDoWork);
+
+ if (nCrcMainA == nCrcMainB)
+ {
+ eMainSwId = _DrvFwCtrlMsg28xxGetSwId(EMEM_MAIN);
+ eInfoSwId = _DrvFwCtrlMsg28xxGetSwId(EMEM_INFO);
+
+ DBG("eMainSwId=0x%x, eInfoSwId=0x%x\n", eMainSwId, eInfoSwId);
+
+ if (eMainSwId == eInfoSwId)
+ {
+ eSwId = eMainSwId;
+ nIsCompareVersion = 1;
+
+ DrvFwCtrlGetCustomerFirmwareVersionByDbBus(EMEM_MAIN, &nMajor, &nMinor, &pVersion);
+ }
+ else
+ {
+ eSwId = eInfoSwId;
+ nIsCompareVersion = 0;
+ }
+
+ if (eSwId == MSG28XX_SW_ID_XXXX)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ nUpdateBinMajor = msg28xx_xxxx_update_bin[127][1013]<<8 | msg28xx_xxxx_update_bin[127][1012];
+ nUpdateBinMinor = msg28xx_xxxx_update_bin[127][1015]<<8 | msg28xx_xxxx_update_bin[127][1014];
+#else // By one dimensional array
+ nUpdateBinMajor = msg28xx_xxxx_update_bin[0x1FFF5]<<8 | msg28xx_xxxx_update_bin[0x1FFF4];
+ nUpdateBinMinor = msg28xx_xxxx_update_bin[0x1FFF7]<<8 | msg28xx_xxxx_update_bin[0x1FFF6];
+#endif
+ }
+ else if (eSwId == MSG28XX_SW_ID_YYYY)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ nUpdateBinMajor = msg28xx_yyyy_update_bin[127][1013]<<8 | msg28xx_yyyy_update_bin[127][1012];
+ nUpdateBinMinor = msg28xx_yyyy_update_bin[127][1015]<<8 | msg28xx_yyyy_update_bin[127][1014];
+#else // By one dimensional array
+ nUpdateBinMajor = msg28xx_yyyy_update_bin[0x1FFF5]<<8 | msg28xx_yyyy_update_bin[0x1FFF4];
+ nUpdateBinMinor = msg28xx_yyyy_update_bin[0x1FFF7]<<8 | msg28xx_yyyy_update_bin[0x1FFF6];
+#endif
+ }
+ else //eSwId == MSG28XX_SW_ID_UNDEFINED
+ {
+ DBG("eSwId = 0x%x is an undefined SW ID.\n", eSwId);
+
+ eSwId = MSG28XX_SW_ID_UNDEFINED;
+ nUpdateBinMajor = 0;
+ nUpdateBinMinor = 0;
+ }
+
+
+ DBG("eSwId=0x%x, nMajor=%d, nMinor=%d, nUpdateBinMajor=%d, nUpdateBinMinor=%d\n", eSwId, nMajor, nMinor, nUpdateBinMajor, nUpdateBinMinor);
+
+ if ((nUpdateBinMinor > nMinor && nIsCompareVersion == 1) || (nIsCompareVersion == 0))
+ {
+ if (eSwId == MSG28XX_SW_ID_XXXX)
+ {
+ for (i = 0; i < MSG28XX_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg28xx_xxxx_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg28xx_xxxx_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else if (eSwId == MSG28XX_SW_ID_YYYY)
+ {
+ for (i = 0; i < MSG28XX_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg28xx_yyyy_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg28xx_yyyy_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else
+ {
+ DBG("eSwId = 0x%x is an undefined SW ID.\n", eSwId);
+
+ eSwId = MSG28XX_SW_ID_UNDEFINED;
+ }
+
+ if (eSwId < MSG28XX_SW_ID_UNDEFINED && eSwId != 0x0000 && eSwId != 0xFFFF)
+ {
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after copying update firmware data to temp buffer
+
+ _gUpdateRetryCount = UPDATE_FIRMWARE_RETRY_COUNT;
+ _gIsUpdateInfoBlockFirst = 1; // Set 1 for indicating main block is complete
+ g_IsUpdateFirmware = 0x11;
+ queue_work(_gUpdateFirmwareBySwIdWorkQueue, &_gUpdateFirmwareBySwIdWork);
+ return;
+ }
+ else
+ {
+ DBG("The sw id is invalid.\n");
+ DBG("Go to normal boot up process.\n");
+ }
+ }
+ else
+ {
+ DBG("The update bin version is older than or equal to the current firmware version on e-flash.\n");
+ DBG("Go to normal boot up process.\n");
+ }
+ }
+ else
+ {
+ eSwId = _DrvFwCtrlMsg28xxGetSwId(EMEM_INFO);
+
+ DBG("eSwId=0x%x\n", eSwId);
+
+ if (eSwId == MSG28XX_SW_ID_XXXX)
+ {
+ for (i = 0; i < MSG28XX_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg28xx_xxxx_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg28xx_xxxx_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else if (eSwId == MSG28XX_SW_ID_YYYY)
+ {
+ for (i = 0; i < MSG28XX_FIRMWARE_WHOLE_SIZE; i ++)
+ {
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_TWO_DIMENSIONAL_ARRAY // By two dimensional array
+ _DrvFwCtrlStoreFirmwareData(msg28xx_yyyy_update_bin[i], 1024);
+#else // By one dimensional array
+ _DrvFwCtrlStoreFirmwareData(&(msg28xx_yyyy_update_bin[i*1024]), 1024);
+#endif
+ }
+ }
+ else
+ {
+ DBG("eSwId = 0x%x is an undefined SW ID.\n", eSwId);
+
+ eSwId = MSG28XX_SW_ID_UNDEFINED;
+ }
+
+ if (eSwId < MSG28XX_SW_ID_UNDEFINED && eSwId != 0x0000 && eSwId != 0xFFFF)
+ {
+ g_FwDataCount = 0; // Reset g_FwDataCount to 0 after copying update firmware data to temp buffer
+
+ _gUpdateRetryCount = UPDATE_FIRMWARE_RETRY_COUNT;
+ _gIsUpdateInfoBlockFirst = 0; // Set 0 for indicating main block is broken
+ g_IsUpdateFirmware = 0x11;
+ queue_work(_gUpdateFirmwareBySwIdWorkQueue, &_gUpdateFirmwareBySwIdWork);
+ return;
+ }
+ else
+ {
+ DBG("The sw id is invalid.\n");
+ DBG("Go to normal boot up process.\n");
+ }
+ }
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DrvPlatformLyrEnableFingerTouchReport();
+}
+
+//-------------------------End of SW ID for MSG28XX----------------------------//
+
+static void _DrvFwCtrlUpdateFirmwareBySwIdDoWork(struct work_struct *pWork)
+{
+ s32 nRetVal = 0;
+
+ DBG("*** %s() _gUpdateRetryCount = %d ***\n", __func__, _gUpdateRetryCount);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ nRetVal = _DrvFwCtrlMsg26xxmUpdateFirmwareBySwId();
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ nRetVal = _DrvFwCtrlMsg28xxUpdateFirmware(g_FwData, EMEM_MAIN);
+ }
+ else
+ {
+ DBG("This chip type (0x%x) does not support update firmware by sw id\n", g_ChipType);
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DrvPlatformLyrEnableFingerTouchReport();
+
+ nRetVal = -1;
+ return;
+ }
+
+ DBG("*** update firmware by sw id result = %d ***\n", nRetVal);
+
+ if (nRetVal == 0)
+ {
+ DBG("update firmware by sw id success\n");
+
+ _gIsUpdateInfoBlockFirst = 0;
+ g_IsUpdateFirmware = 0x00;
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DrvPlatformLyrEnableFingerTouchReport();
+ }
+ else //nRetVal == -1
+ {
+ _gUpdateRetryCount --;
+ if (_gUpdateRetryCount > 0)
+ {
+ DBG("_gUpdateRetryCount = %d\n", _gUpdateRetryCount);
+ queue_work(_gUpdateFirmwareBySwIdWorkQueue, &_gUpdateFirmwareBySwIdWork);
+ }
+ else
+ {
+ DBG("update firmware by sw id failed\n");
+
+ _gIsUpdateInfoBlockFirst = 0;
+ g_IsUpdateFirmware = 0x00;
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DrvPlatformLyrEnableFingerTouchReport();
+ }
+ }
+}
+
+#endif //CONFIG_UPDATE_FIRMWARE_BY_SW_ID
+
+/*=============================================================*/
+// GLOBAL FUNCTION DEFINITION
+/*=============================================================*/
+
+void DrvFwCtrlVariableInitialize(void)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ FIRMWARE_MODE_UNKNOWN_MODE = MSG26XXM_FIRMWARE_MODE_UNKNOWN_MODE;
+ FIRMWARE_MODE_DEMO_MODE = MSG26XXM_FIRMWARE_MODE_DEMO_MODE;
+ FIRMWARE_MODE_DEBUG_MODE = MSG26XXM_FIRMWARE_MODE_DEBUG_MODE;
+// FIRMWARE_MODE_RAW_DATA_MODE = MSG26XXM_FIRMWARE_MODE_RAW_DATA_MODE;
+
+ g_FirmwareMode = FIRMWARE_MODE_DEMO_MODE;
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ FIRMWARE_MODE_UNKNOWN_MODE = MSG28XX_FIRMWARE_MODE_UNKNOWN_MODE;
+ FIRMWARE_MODE_DEMO_MODE = MSG28XX_FIRMWARE_MODE_DEMO_MODE;
+ FIRMWARE_MODE_DEBUG_MODE = MSG28XX_FIRMWARE_MODE_DEBUG_MODE;
+// FIRMWARE_MODE_RAW_DATA_MODE = MSG28XX_FIRMWARE_MODE_RAW_DATA_MODE;
+
+ g_FirmwareMode = FIRMWARE_MODE_DEMO_MODE;
+ }
+}
+
+void DrvFwCtrlOptimizeCurrentConsumption(void)
+{
+ u32 i;
+ u8 szDbBusTxData[35] = {0};
+
+ DBG("g_ChipType = 0x%x\n", g_ChipType);
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+ if (g_GestureWakeupFlag == 1)
+ {
+ return;
+ }
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+ if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ DBG("*** %s() ***\n", __func__);
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_ENABLE_DMA_IIC
+ DmaReset();
+#endif //CONFIG_ENABLE_DMA_IIC
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+
+ // Enable burst mode
+ RegSetLByteValue(0x1608, 0x21);
+
+ szDbBusTxData[0] = 0x10;
+ szDbBusTxData[1] = 0x15;
+ szDbBusTxData[2] = 0x20; //bank:0x15, addr:h0010
+
+ for (i = 0; i < 8; i ++)
+ {
+ szDbBusTxData[i+3] = 0xFF;
+ }
+
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 3+8); // Write 0xFF for reg 0x1510~0x1513
+
+ szDbBusTxData[0] = 0x10;
+ szDbBusTxData[1] = 0x15;
+ szDbBusTxData[2] = 0x28; //bank:0x15, addr:h0014
+
+ for (i = 0; i < 16; i ++)
+ {
+ szDbBusTxData[i+3] = 0x00;
+ }
+
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 3+16); // Write 0x00 for reg 0x1514~0x151B
+
+ szDbBusTxData[0] = 0x10;
+ szDbBusTxData[1] = 0x21;
+ szDbBusTxData[2] = 0x40; //bank:0x21, addr:h0020
+
+ for (i = 0; i < 8; i ++)
+ {
+ szDbBusTxData[i+3] = 0xFF;
+ }
+
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 3+8); // Write 0xFF for reg 0x2120~0x2123
+
+ szDbBusTxData[0] = 0x10;
+ szDbBusTxData[1] = 0x21;
+ szDbBusTxData[2] = 0x20; //bank:0x21, addr:h0010
+
+ for (i = 0; i < 32; i ++)
+ {
+ szDbBusTxData[i+3] = 0xFF;
+ }
+
+ IicWriteData(SLAVE_I2C_ID_DBBUS, &szDbBusTxData[0], 3+32); // Write 0xFF for reg 0x2110~0x211F
+
+ // Clear burst mode
+ RegSetLByteValue(0x1608, 0x20);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+ }
+}
+
+u8 DrvFwCtrlGetChipType(void)
+{
+ s32 rc =0;
+ u8 nChipType = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+ // Erase TP Flash first
+ rc = DbBusEnterSerialDebugMode();
+ if (rc < 0)
+ {
+ DBG("*** DbBusEnterSerialDebugMode() failed, rc = %d ***\n", rc);
+ return nChipType;
+ }
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+
+ // Stop MCU
+ RegSetLByteValue(0x0FE6, 0x01);
+
+ // Disable watchdog
+ RegSet16BitValue(0x3C60, 0xAA55);
+
+ nChipType = RegGet16BitValue(0x1ECC) & 0xFF;
+
+ if (nChipType != CHIP_TYPE_MSG21XX && // (0x01)
+ nChipType != CHIP_TYPE_MSG21XXA && // (0x02)
+ nChipType != CHIP_TYPE_MSG26XXM && // (0x03)
+ nChipType != CHIP_TYPE_MSG22XX && // (0x7A)
+ nChipType != CHIP_TYPE_MSG28XX) // (0x85)
+ {
+ nChipType = 0;
+ }
+
+ DBG("*** Chip Type = 0x%x ***\n", nChipType);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ return nChipType;
+}
+
+void DrvFwCtrlGetCustomerFirmwareVersionByDbBus(EmemType_e eEmemType, u16 *pMajor, u16 *pMinor, u8 **ppVersion) // support MSG28xx only
+{
+ u16 nReadAddr = 0;
+ u8 szTmpData[4] = {0};
+
+ DBG("*** %s() eEmemType = %d ***\n", __func__, eEmemType);
+
+ if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01);
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55);
+
+ if (eEmemType == EMEM_MAIN) // Read SW ID from main block
+ {
+ _DrvFwCtrlMsg28xxReadEFlashStart(0x7FFD, EMEM_MAIN);
+ nReadAddr = 0x7FFD;
+ }
+ else if (eEmemType == EMEM_INFO) // Read SW ID from info block
+ {
+ _DrvFwCtrlMsg28xxReadEFlashStart(0x81FB, EMEM_INFO);
+ nReadAddr = 0x81FB;
+ }
+
+ _DrvFwCtrlMsg28xxReadEFlashDoRead(nReadAddr, &szTmpData[0]);
+
+ _DrvFwCtrlMsg28xxReadEFlashEnd();
+
+ /*
+ Ex. Major in Main Block :
+ Major low byte at address 0x7FFD
+
+ Major in Info Block :
+ Major low byte at address 0x81FB
+ */
+
+ *pMajor = (szTmpData[1] << 8);
+ *pMajor |= szTmpData[0];
+ *pMinor = (szTmpData[3] << 8);
+ *pMinor |= szTmpData[2];
+
+ DBG("*** major = %d ***\n", *pMajor);
+ DBG("*** minor = %d ***\n", *pMinor);
+
+ if (*ppVersion == NULL)
+ {
+ *ppVersion = kzalloc(sizeof(u8)*6, GFP_KERNEL);
+ }
+
+ sprintf(*ppVersion, "%03d%03d", *pMajor, *pMinor);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+ }
+}
+
+void DrvFwCtrlGetCustomerFirmwareVersion(u16 *pMajor, u16 *pMinor, u8 **ppVersion)
+{
+ u8 szDbBusTxData[3] = {0};
+ u8 szDbBusRxData[4] = {0};
+
+ DBG("*** %s() ***\n", __func__);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ szDbBusTxData[0] = 0x53;
+ szDbBusTxData[1] = 0x00;
+ szDbBusTxData[2] = 0x2A;
+
+ mutex_lock(&g_Mutex);
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 3);
+ IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 4);
+
+ mutex_unlock(&g_Mutex);
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ szDbBusTxData[0] = 0x03;
+
+ mutex_lock(&g_Mutex);
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 1);
+ IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 4);
+
+ mutex_unlock(&g_Mutex);
+ }
+
+ DBG("szDbBusRxData[0] = 0x%x\n", szDbBusRxData[0]); // add for debug
+ DBG("szDbBusRxData[1] = 0x%x\n", szDbBusRxData[1]); // add for debug
+ DBG("szDbBusRxData[2] = 0x%x\n", szDbBusRxData[2]); // add for debug
+ DBG("szDbBusRxData[3] = 0x%x\n", szDbBusRxData[3]); // add for debug
+
+ *pMajor = (szDbBusRxData[1]<<8) + szDbBusRxData[0];
+ *pMinor = (szDbBusRxData[3]<<8) + szDbBusRxData[2];
+
+ DBG("*** major = %d ***\n", *pMajor);
+ DBG("*** minor = %d ***\n", *pMinor);
+
+ if (*ppVersion == NULL)
+ {
+ *ppVersion = kzalloc(sizeof(u8)*6, GFP_KERNEL);
+ }
+
+ sprintf(*ppVersion, "%03d%03d", *pMajor, *pMinor);
+}
+
+void DrvFwCtrlGetPlatformFirmwareVersion(u8 **ppVersion)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ u32 i;
+ u16 nRegData = 0;
+ u8 szDbBusTxData[5] = {0};
+ u8 szDbBusRxData[16] = {0};
+
+ mutex_lock(&g_Mutex);
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ // Stop mcu
+ RegSetLByteValue(0x0FE6, 0x01); //bank:mheg5, addr:h0073
+
+ // Stop watchdog
+ RegSet16BitValue(0x3C60, 0xAA55); //bank:reg_PIU_MISC_0, addr:h0030
+
+ // cmd
+ RegSet16BitValue(0x3CE4, 0xA4AB); //bank:reg_PIU_MISC_0, addr:h0072
+
+ // TP SW reset
+ RegSet16BitValue(0x1E04, 0x7d60); //bank:chip, addr:h0002
+ RegSet16BitValue(0x1E04, 0x829F);
+
+ // Start mcu
+ RegSetLByteValue(0x0FE6, 0x00); //bank:mheg5, addr:h0073
+
+ mdelay(100);
+
+ // Polling 0x3CE4 is 0x5B58
+ do
+ {
+ nRegData = RegGet16BitValue(0x3CE4); //bank:reg_PIU_MISC_0, addr:h0072
+ } while (nRegData != 0x5B58);
+
+ // Read platform firmware version from info block
+ szDbBusTxData[0] = 0x72;
+ szDbBusTxData[3] = 0x00;
+ szDbBusTxData[4] = 0x08;
+
+ for (i = 0; i < 2; i ++)
+ {
+ szDbBusTxData[1] = 0x80;
+ szDbBusTxData[2] = 0x10 + ((i*8)&0x00ff);
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 5);
+
+ mdelay(50);
+
+ IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[i*8], 8);
+ }
+
+ if (*ppVersion == NULL)
+ {
+ *ppVersion = kzalloc(sizeof(u8)*16, GFP_KERNEL);
+ }
+
+ sprintf(*ppVersion, "%.16s", szDbBusRxData);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+
+ DrvPlatformLyrTouchDeviceResetHw();
+ mdelay(100);
+
+ mutex_unlock(&g_Mutex);
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ u8 szDbBusTxData[1] = {0};
+ u8 szDbBusRxData[10] = {0};
+
+ szDbBusTxData[0] = 0x04;
+
+ mutex_lock(&g_Mutex);
+
+ DrvPlatformLyrTouchDeviceResetHw();
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_ENABLE_DMA_IIC
+ DmaReset();
+#endif //CONFIG_ENABLE_DMA_IIC
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 1);
+ IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 10);
+
+ mutex_unlock(&g_Mutex);
+
+ DBG("szDbBusRxData[0] = 0x%x , %c \n", szDbBusRxData[0], szDbBusRxData[0]); // add for debug
+ DBG("szDbBusRxData[1] = 0x%x , %c \n", szDbBusRxData[1], szDbBusRxData[1]); // add for debug
+ DBG("szDbBusRxData[2] = 0x%x , %c \n", szDbBusRxData[2], szDbBusRxData[2]); // add for debug
+ DBG("szDbBusRxData[3] = 0x%x , %c \n", szDbBusRxData[3], szDbBusRxData[3]); // add for debug
+ DBG("szDbBusRxData[4] = 0x%x , %c \n", szDbBusRxData[4], szDbBusRxData[4]); // add for debug
+ DBG("szDbBusRxData[5] = 0x%x , %c \n", szDbBusRxData[5], szDbBusRxData[5]); // add for debug
+ DBG("szDbBusRxData[6] = 0x%x , %c \n", szDbBusRxData[6], szDbBusRxData[6]); // add for debug
+ DBG("szDbBusRxData[7] = 0x%x , %c \n", szDbBusRxData[7], szDbBusRxData[7]); // add for debug
+ DBG("szDbBusRxData[8] = 0x%x , %c \n", szDbBusRxData[8], szDbBusRxData[8]); // add for debug
+ DBG("szDbBusRxData[9] = 0x%x , %c \n", szDbBusRxData[9], szDbBusRxData[9]); // add for debug
+
+ if (*ppVersion == NULL)
+ {
+ *ppVersion = kzalloc(sizeof(u8)*10, GFP_KERNEL);
+ }
+
+ sprintf(*ppVersion, "%.10s", szDbBusRxData);
+ }
+
+ DBG("*** platform firmware version = %s ***\n", *ppVersion);
+}
+
+s32 DrvFwCtrlUpdateFirmware(u8 szFwData[][1024], EmemType_e eEmemType)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ return _DrvFwCtrlUpdateFirmwareCash(szFwData, eEmemType);
+}
+
+s32 DrvFwCtrlUpdateFirmwareBySdCard(const char *pFilePath)
+{
+ s32 nRetVal = -1;
+
+ DBG("*** %s() ***\n", __func__);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM || g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ nRetVal = _DrvFwCtrlUpdateFirmwareBySdCard(pFilePath);
+ }
+ else
+ {
+ DBG("This chip type (0x%x) does not support update firmware by sd card\n", g_ChipType);
+ }
+
+ return nRetVal;
+}
+
+//------------------------------------------------------------------------------//
+
+u16 DrvFwCtrlGetFirmwareMode(void) // use for MSG26XXM only
+{
+ u16 nMode = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+
+ nMode = RegGet16BitValue(0x3CF4); //bank:reg_PIU_MISC0, addr:h007a
+
+ DBG("firmware mode = 0x%x\n", nMode);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+ mdelay(100);
+ }
+
+ return nMode;
+}
+
+u16 DrvFwCtrlChangeFirmwareMode(u16 nMode)
+{
+ DBG("*** %s() *** nMode = 0x%x\n", __func__, nMode);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ DrvPlatformLyrTouchDeviceResetHw();
+
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+
+ RegSet16BitValue(0x3CF4, nMode); //bank:reg_PIU_MISC0, addr:h007a
+ nMode = RegGet16BitValue(0x3CF4);
+
+ DBG("firmware mode = 0x%x\n", nMode);
+
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ u8 szDbBusTxData[2] = {0};
+ u32 i = 0;
+ s32 rc;
+
+ _gIsDisableFinagerTouch = 1; // Disable finger touch ISR handling temporarily for device driver can send change firmware mode i2c command to firmware.
+
+ szDbBusTxData[0] = 0x02;
+ szDbBusTxData[1] = (u8)nMode;
+
+ mdelay(20);
+
+ mutex_lock(&g_Mutex);
+ DBG("*** %s() *** mutex_lock(&g_Mutex)\n", __func__); // add for debug
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 2);
+ if (rc > 0)
+ {
+ DBG("Change firmware mode success\n");
+ break;
+ }
+
+ mdelay(10);
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Change firmware mode failed, rc = %d\n", rc);
+ }
+
+ DBG("*** %s() *** mutex_unlock(&g_Mutex)\n", __func__); // add for debug
+ mutex_unlock(&g_Mutex);
+
+ _gIsDisableFinagerTouch = 0;
+ }
+
+ return nMode;
+}
+
+void DrvFwCtrlGetFirmwareInfo(FirmwareInfo_t *pInfo)
+{
+ DBG("*** %s() ***\n", __func__);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ u8 szDbBusTxData[3] = {0};
+ u8 szDbBusRxData[8] = {0};
+ u32 i = 0;
+ s32 rc;
+
+ _gIsDisableFinagerTouch = 1; // Disable finger touch ISR handling temporarily for device driver can send get firmware info i2c command to firmware.
+
+ szDbBusTxData[0] = 0x53;
+ szDbBusTxData[1] = 0x00;
+ szDbBusTxData[2] = 0x48;
+
+ mutex_lock(&g_Mutex);
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 3);
+ if (rc > 0)
+ {
+ DBG("Get firmware info IicWriteData() success\n");
+ }
+ mdelay(20);
+ rc = IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 8);
+ if (rc > 0)
+ {
+ DBG("Get firmware info IicReadData() success\n");
+ break;
+ }
+
+ mdelay(10);
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Get firmware info failed, rc = %d\n", rc);
+ }
+
+ mutex_unlock(&g_Mutex);
+
+ if (szDbBusRxData[0] == 8 && szDbBusRxData[1] == 0 && szDbBusRxData[2] == 9 && szDbBusRxData[3] == 0)
+ {
+ DBG("*** Debug Mode Packet Header is 0xA5 ***\n");
+/*
+ DbBusEnterSerialDebugMode();
+ DbBusStopMCU();
+ DbBusIICUseBus();
+ DbBusIICReshape();
+ mdelay(100);
+*/
+ pInfo->nLogModePacketHeader = 0xA5;
+ pInfo->nMy = 0;
+ pInfo->nMx = 0;
+// *pDriveLineNumber = AnaGetMutualSubframeNum();
+// *pSenseLineNumber = AnaGetMutualChannelNum();
+
+/*
+ DbBusIICNotUseBus();
+ DbBusNotStopMCU();
+ DbBusExitSerialDebugMode();
+ mdelay(100);
+*/
+ }
+ else if (szDbBusRxData[0] == 0xAB)
+ {
+ DBG("*** Debug Mode Packet Header is 0xAB ***\n");
+
+ pInfo->nLogModePacketHeader = szDbBusRxData[0];
+ pInfo->nMy = szDbBusRxData[1];
+ pInfo->nMx = szDbBusRxData[2];
+// pInfo->nSd = szDbBusRxData[1];
+// pInfo->nSs = szDbBusRxData[2];
+ }
+ else if (szDbBusRxData[0] == 0xA7 && szDbBusRxData[3] == PACKET_TYPE_TOOTH_PATTERN)
+ {
+ DBG("*** Debug Packet Header is 0xA7 ***\n");
+
+ pInfo->nLogModePacketHeader = szDbBusRxData[0];
+ pInfo->nType = szDbBusRxData[3];
+ pInfo->nMy = szDbBusRxData[4];
+ pInfo->nMx = szDbBusRxData[5];
+ pInfo->nSd = szDbBusRxData[6];
+ pInfo->nSs = szDbBusRxData[7];
+ }
+
+ if (pInfo->nLogModePacketHeader == 0xA5)
+ {
+ if (pInfo->nMy != 0 && pInfo->nMx != 0)
+ {
+ // for parsing debug mode packet 0xA5
+ pInfo->nLogModePacketLength = 1+1+1+1+10*3+pInfo->nMx*pInfo->nMy*2+1;
+ }
+ else
+ {
+ DBG("Failed to retrieve channel number or subframe number for debug mode packet 0xA5.\n");
+ }
+ }
+ else if (pInfo->nLogModePacketHeader == 0xAB)
+ {
+ if (pInfo->nMy != 0 && pInfo->nMx != 0)
+ {
+ // for parsing debug mode packet 0xAB
+ pInfo->nLogModePacketLength = 1+1+1+1+10*3+pInfo->nMy*pInfo->nMx*2+pInfo->nMy*2+pInfo->nMx*2+2*2+8*2+1;
+ }
+ else
+ {
+ DBG("Failed to retrieve channel number or subframe number for debug mode packet 0xAB.\n");
+ }
+ }
+ else if (pInfo->nLogModePacketHeader == 0xA7 && pInfo->nType == PACKET_TYPE_TOOTH_PATTERN)
+ {
+ if (pInfo->nMy != 0 && pInfo->nMx != 0 && pInfo->nSd != 0 && pInfo->nSs != 0)
+ {
+ // for parsing debug mode packet 0xA7
+ pInfo->nLogModePacketLength = 1+1+1+1+1+10*3+pInfo->nMy*pInfo->nMx*2+pInfo->nSd*2+pInfo->nSs*2+10*2+1;
+ }
+ else
+ {
+ DBG("Failed to retrieve channel number or subframe number for debug mode packet 0xA7.\n");
+ }
+ }
+ else
+ {
+ DBG("Undefined debug mode packet header = 0x%x\n", pInfo->nLogModePacketHeader);
+ }
+
+ DBG("*** debug mode packet header = 0x%x ***\n", pInfo->nLogModePacketHeader);
+ DBG("*** debug mode packet length = %d ***\n", pInfo->nLogModePacketLength);
+ DBG("*** Type = 0x%x ***\n", pInfo->nType);
+ DBG("*** My = %d ***\n", pInfo->nMy);
+ DBG("*** Mx = %d ***\n", pInfo->nMx);
+ DBG("*** Sd = %d ***\n", pInfo->nSd);
+ DBG("*** Ss = %d ***\n", pInfo->nSs);
+
+ _gIsDisableFinagerTouch = 0;
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ u8 szDbBusTxData[1] = {0};
+ u8 szDbBusRxData[10] = {0};
+ u32 i = 0;
+ s32 rc;
+
+ _gIsDisableFinagerTouch = 1; // Disable finger touch ISR handling temporarily for device driver can send get firmware info i2c command to firmware.
+
+ szDbBusTxData[0] = 0x01;
+
+ mutex_lock(&g_Mutex);
+ DBG("*** %s() *** mutex_lock(&g_Mutex)\n", __func__); // add for debug
+
+#ifdef CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+#ifdef CONFIG_ENABLE_DMA_IIC
+ DmaReset();
+#endif //CONFIG_ENABLE_DMA_IIC
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 1);
+ if (rc > 0)
+ {
+ DBG("Get firmware info IicWriteData() success\n");
+ }
+ mdelay(20);
+ rc = IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 10);
+ if (rc > 0)
+ {
+ DBG("Get firmware info IicReadData() success\n");
+
+ if (szDbBusRxData[1] == FIRMWARE_MODE_DEMO_MODE || szDbBusRxData[1] == FIRMWARE_MODE_DEBUG_MODE)
+ {
+ break;
+ }
+ else
+ {
+ i = 0;
+ }
+ }
+
+ mdelay(10);
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Get firmware info failed, rc = %d\n", rc);
+ }
+
+ DBG("*** %s() *** mutex_unlock(&g_Mutex)\n", __func__); // add for debug
+ mutex_unlock(&g_Mutex);
+
+ // Add protection for incorrect firmware info check
+ if ((szDbBusRxData[1] == FIRMWARE_MODE_DEBUG_MODE && szDbBusRxData[2] == 0xA7 && szDbBusRxData[5] == PACKET_TYPE_TOOTH_PATTERN) || (szDbBusRxData[1] == FIRMWARE_MODE_DEMO_MODE && szDbBusRxData[2] == 0x5A))
+ {
+ pInfo->nFirmwareMode = szDbBusRxData[1];
+ DBG("pInfo->nFirmwareMode = 0x%x\n", pInfo->nFirmwareMode);
+
+ pInfo->nLogModePacketHeader = szDbBusRxData[2];
+ pInfo->nLogModePacketLength = (szDbBusRxData[3]<<8) + szDbBusRxData[4];
+ pInfo->nType = szDbBusRxData[5];
+ pInfo->nMy = szDbBusRxData[6];
+ pInfo->nMx = szDbBusRxData[7];
+ pInfo->nSd = szDbBusRxData[8];
+ pInfo->nSs = szDbBusRxData[9];
+
+ DBG("pInfo->nLogModePacketHeader = 0x%x\n", pInfo->nLogModePacketHeader);
+ DBG("pInfo->nLogModePacketLength = %d\n", pInfo->nLogModePacketLength);
+ DBG("pInfo->nType = 0x%x\n", pInfo->nType);
+ DBG("pInfo->nMy = %d\n", pInfo->nMy);
+ DBG("pInfo->nMx = %d\n", pInfo->nMx);
+ DBG("pInfo->nSd = %d\n", pInfo->nSd);
+ DBG("pInfo->nSs = %d\n", pInfo->nSs);
+ }
+ else
+ {
+ DBG("Firmware info before correcting :\n");
+
+ DBG("FirmwareMode = 0x%x\n", szDbBusRxData[1]);
+ DBG("LogModePacketHeader = 0x%x\n", szDbBusRxData[2]);
+ DBG("LogModePacketLength = %d\n", (szDbBusRxData[3]<<8) + szDbBusRxData[4]);
+ DBG("Type = 0x%x\n", szDbBusRxData[5]);
+ DBG("My = %d\n", szDbBusRxData[6]);
+ DBG("Mx = %d\n", szDbBusRxData[7]);
+ DBG("Sd = %d\n", szDbBusRxData[8]);
+ DBG("Ss = %d\n", szDbBusRxData[9]);
+
+ // Set firmware mode to demo mode(default)
+ pInfo->nFirmwareMode = FIRMWARE_MODE_DEMO_MODE;
+ pInfo->nLogModePacketHeader = 0x5A;
+ pInfo->nLogModePacketLength = DEMO_MODE_PACKET_LENGTH;
+ pInfo->nType = 0;
+ pInfo->nMy = 0;
+ pInfo->nMx = 0;
+ pInfo->nSd = 0;
+ pInfo->nSs = 0;
+
+ DBG("Firmware info after correcting :\n");
+
+ DBG("pInfo->nFirmwareMode = 0x%x\n", pInfo->nFirmwareMode);
+ DBG("pInfo->nLogModePacketHeader = 0x%x\n", pInfo->nLogModePacketHeader);
+ DBG("pInfo->nLogModePacketLength = %d\n", pInfo->nLogModePacketLength);
+ DBG("pInfo->nType = 0x%x\n", pInfo->nType);
+ DBG("pInfo->nMy = %d\n", pInfo->nMy);
+ DBG("pInfo->nMx = %d\n", pInfo->nMx);
+ DBG("pInfo->nSd = %d\n", pInfo->nSd);
+ DBG("pInfo->nSs = %d\n", pInfo->nSs);
+ }
+
+ _gIsDisableFinagerTouch = 0;
+ }
+}
+
+void DrvFwCtrlRestoreFirmwareModeToLogDataMode(void)
+{
+ DBG("*** %s() g_IsSwitchModeByAPK = %d ***\n", __func__, g_IsSwitchModeByAPK);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ if (g_IsSwitchModeByAPK == 1)
+ {
+ DBG("g_FirmwareMode = 0x%x\n", g_FirmwareMode);
+
+ // Since reset_hw() will reset the firmware mode to demo mode, we must reset the firmware mode again after reset_hw().
+ if (g_FirmwareMode == FIRMWARE_MODE_DEBUG_MODE && FIRMWARE_MODE_DEMO_MODE == DrvFwCtrlGetFirmwareMode())
+ {
+ g_FirmwareMode = DrvFwCtrlChangeFirmwareMode(FIRMWARE_MODE_DEBUG_MODE);
+ }
+ else
+ {
+ DBG("firmware mode is not restored\n");
+ }
+ }
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ if (g_IsSwitchModeByAPK == 1)
+ {
+ FirmwareInfo_t tInfo;
+
+ memset(&tInfo, 0x0, sizeof(FirmwareInfo_t));
+
+ DrvFwCtrlGetFirmwareInfo(&tInfo);
+
+ DBG("g_FirmwareMode = 0x%x, tInfo.nFirmwareMode = 0x%x\n", g_FirmwareMode, tInfo.nFirmwareMode);
+
+ // Since reset_hw() will reset the firmware mode to demo mode, we must reset the firmware mode again after reset_hw().
+ if (g_FirmwareMode == FIRMWARE_MODE_DEBUG_MODE && FIRMWARE_MODE_DEBUG_MODE != tInfo.nFirmwareMode)
+ {
+ g_FirmwareMode = DrvFwCtrlChangeFirmwareMode(FIRMWARE_MODE_DEBUG_MODE);
+ }
+ else
+ {
+ DBG("firmware mode is not restored\n");
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------//
+
+#ifdef CONFIG_UPDATE_FIRMWARE_BY_SW_ID
+
+void DrvFwCtrlCheckFirmwareUpdateBySwId(void)
+{
+ if (g_ChipType == CHIP_TYPE_MSG26XXM)
+ {
+ _DrvFwCtrlMsg26xxmCheckFirmwareUpdateBySwId();
+ }
+ else if (g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ _DrvFwCtrlMsg28xxCheckFirmwareUpdateBySwId();
+ }
+ else
+ {
+ DBG("This chip type (0x%x) does not support update firmware by sw id\n", g_ChipType);
+ }
+}
+
+#endif //CONFIG_UPDATE_FIRMWARE_BY_SW_ID
+
+//------------------------------------------------------------------------------//
+
+#ifdef CONFIG_ENABLE_SEGMENT_READ_FINGER_TOUCH_DATA
+void DrvFwCtrlGetTouchPacketAddress(u16* pDataAddress, u16* pFlagAddress)
+{
+ s32 rc = 0;
+ u8 szDbBusTxData[1] = {0};
+ u8 szDbBusRxData[4] = {0};
+
+ DBG("*** %s() ***\n", __func__);
+
+ szDbBusTxData[0] = 0x05;
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 1);
+ rc = IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 4);
+ if (rc < 0)
+ {
+ g_FwSupportSegment = 0;
+ }
+ else
+ {
+ *pDataAddress = (szDbBusRxData[0]<<8) + szDbBusRxData[1];
+ *pFlagAddress = (szDbBusRxData[2]<<8) + szDbBusRxData[3];
+
+ g_FwSupportSegment = 1;
+
+ DBG("*** *pDataAddress = 0x%2X ***\n", *pDataAddress); // add for debug
+ DBG("*** *pFlagAddress = 0x%2X ***\n", *pFlagAddress); // add for debug
+ }
+}
+
+static int _DrvFwCtrlCheckFingerTouchPacketFlagBit1(void)
+{
+ u8 szDbBusTxData[3] = {0};
+ s32 nRetVal;
+
+ DBG("*** %s() ***\n", __func__);
+
+ szDbBusTxData[0] = 0x53;
+ szDbBusTxData[1] = (g_FwPacketFlagAddress >> 8) & 0xFF;
+ szDbBusTxData[2] = g_FwPacketFlagAddress & 0xFF;
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 3);
+ IicReadData(SLAVE_I2C_ID_DWI2C, &_gTouchPacketFlag[0], 2);
+
+ if ((_gTouchPacketFlag[0] & BIT1) == 0x00)
+ {
+ nRetVal = 0; // Bit1 is 0
+ }
+ else
+ {
+ nRetVal = 1; // Bit1 is 1
+ }
+ DBG("Bit1 = %d\n", nRetVal);
+
+ return nRetVal;
+}
+
+static void _DrvFwCtrlResetFingerTouchPacketFlagBit1(void)
+{
+ u8 szDbBusTxData[4] = {0};
+
+ DBG("*** %s() ***\n", __func__);
+
+ szDbBusTxData[0] = 0x52;
+ szDbBusTxData[1] = (g_FwPacketFlagAddress >> 8) & 0xFF;
+ szDbBusTxData[2] = g_FwPacketFlagAddress & 0xFF;
+ szDbBusTxData[3] = _gTouchPacketFlag[0] | BIT1;
+
+ IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 4);
+}
+#endif //CONFIG_ENABLE_SEGMENT_READ_FINGER_TOUCH_DATA
+
+//------------------------------------------------------------------------------//
+
+#ifdef CONFIG_ENABLE_PROXIMITY_DETECTION
+
+s32 DrvFwCtrlEnableProximity(void)
+{
+ u8 szDbBusTxData[4] = {0};
+ s32 rc;
+
+ DBG("*** %s() ***\n", __func__);
+
+ szDbBusTxData[0] = 0x52;
+ szDbBusTxData[1] = 0x00;
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM || g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ szDbBusTxData[2] = 0x47;
+ }
+ else
+ {
+ DBG("*** Un-recognized chip type = 0x%x ***\n", g_ChipType);
+ return -1;
+ }
+
+ szDbBusTxData[3] = 0xa0;
+
+ mutex_lock(&g_Mutex);
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 4);
+ mutex_unlock(&g_Mutex);
+
+ if (rc > 0)
+ {
+ DBG("Enable proximity detection success\n");
+ }
+ else
+ {
+ DBG("Enable proximity detection failed\n");
+ }
+
+ g_EnableTpProximity = 1;
+
+ return rc;
+}
+
+s32 DrvFwCtrlDisableProximity(void)
+{
+ u8 szDbBusTxData[4] = {0};
+ s32 rc;
+
+ DBG("*** %s() ***\n", __func__);
+
+ szDbBusTxData[0] = 0x52;
+ szDbBusTxData[1] = 0x00;
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM || g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ szDbBusTxData[2] = 0x47;
+ }
+ else
+ {
+ DBG("*** Un-recognized chip type = 0x%x ***\n", g_ChipType);
+ return -1;
+ }
+
+ szDbBusTxData[3] = 0xa1;
+
+ mutex_lock(&g_Mutex);
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 4);
+ mutex_unlock(&g_Mutex);
+
+ if (rc > 0)
+ {
+ DBG("Disable proximity detection success\n");
+ }
+ else
+ {
+ DBG("Disable proximity detection failed\n");
+ }
+
+ g_EnableTpProximity = 0;
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM) || defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ g_FaceClosingTp = 0;
+#endif //CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM || CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM
+
+ return rc;
+}
+
+#endif //CONFIG_ENABLE_PROXIMITY_DETECTION
+
+//------------------------------------------------------------------------------//
+
+#ifdef CONFIG_ENABLE_GLOVE_MODE
+void DrvIcFwCtrlOpenGloveMode(void)
+{
+ s32 rc = 0;
+ u8 szDbBusTxData[3] = {0};
+ u32 i = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+ _gIsDisableFinagerTouch = 1; // Disable finger touch ISR handling temporarily for device driver can send change firmware mode i2c command to firmware.
+
+ szDbBusTxData[0] = 0x06;
+ szDbBusTxData[1] = 0x01;
+ szDbBusTxData[2] = 0x01;
+
+ mdelay(20);
+
+ mutex_lock(&g_Mutex);
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 3);
+ if (rc > 0)
+ {
+ DBG("Open glove mode success\n");
+ break;
+ }
+ mdelay(10);
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Open glove mode failed, rc = %d\n", rc);
+ }
+
+ mutex_unlock(&g_Mutex);
+
+ g_IsGloveModeOpen = 1;
+
+ _gIsDisableFinagerTouch = 0;
+}
+
+void DrvIcFwCtrlCloseGloveMode(void)
+{
+ s32 rc = 0;
+ u8 szDbBusTxData[3] = {0};
+ u32 i = 0;
+
+ DBG("*** %s() ***\n", __func__);
+
+ _gIsDisableFinagerTouch = 1; // Disable finger touch ISR handling temporarily for device driver can send change firmware mode i2c command to firmware.
+
+ szDbBusTxData[0] = 0x06;
+ szDbBusTxData[1] = 0x01;
+ szDbBusTxData[2] = 0x00;
+
+ mdelay(20);
+
+ mutex_lock(&g_Mutex);
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 3);
+ if (rc > 0)
+ {
+ DBG("Close glove mode success\n");
+ break;
+ }
+ mdelay(10);
+ i++;
+ }
+ if (i == 5)
+ {
+ DBG("Close glove mode failed, rc = %d\n", rc);
+ }
+
+ mutex_unlock(&g_Mutex);
+
+ g_IsGloveModeOpen = 0;
+
+ _gIsDisableFinagerTouch = 0;
+}
+
+void DrvIcFwCtrlGetGloveInfo(u8 *pGloveMode)
+{
+ u8 szDbBusTxData[3] = {0};
+ u8 szDbBusRxData[2] = {0};
+ u32 i = 0;
+ s32 rc;
+
+ _gIsDisableFinagerTouch = 1; // Disable finger touch ISR handling temporarily for device driver can send get firmware info i2c command to firmware.
+
+ szDbBusTxData[0] = 0x06;
+ szDbBusTxData[1] = 0x01;
+ szDbBusTxData[2] = 0x02;
+
+ mutex_lock(&g_Mutex);
+
+ while (i < 5)
+ {
+ rc = IicWriteData(SLAVE_I2C_ID_DWI2C, &szDbBusTxData[0], 3);
+ if (rc > 0)
+ {
+ DBG("Get glove info IicWriteData() success\n");
+ }
+ mdelay(20);
+ rc = IicReadData(SLAVE_I2C_ID_DWI2C, &szDbBusRxData[0], 1);
+ if (rc > 0)
+ {
+ DBG("Get glove info IicReadData() success\n");
+
+ if (szDbBusRxData[0] == 0x00 || szDbBusRxData[0] == 0x01)
+ {
+ break;
+ }
+ else
+ {
+ i = 0;
+ }
+ }
+
+ mdelay(10);
+ i++;
+ }
+
+ if (i == 5)
+ {
+ DBG("Get glove info failed, rc = %d\n", rc);
+ }
+
+ mutex_unlock(&g_Mutex);
+
+ *pGloveMode = szDbBusRxData[0];
+
+ DBG("pGloveMode = 0x%x\n", *pGloveMode);
+
+ _gIsDisableFinagerTouch = 0;
+}
+
+#endif //CONFIG_ENABLE_GLOVE_MODE
+//------------------------------------------------------------------------------//
+
+static s32 _DrvFwCtrlReadFingerTouchData(u8 *pPacket, u16 nReportPacketLength)
+{
+ s32 rc;
+
+ if (IS_FIRMWARE_DATA_LOG_ENABLED)
+ {
+ if (g_FirmwareMode == FIRMWARE_MODE_DEMO_MODE)
+ {
+ rc = IicReadData(SLAVE_I2C_ID_DWI2C, &pPacket[0], nReportPacketLength);
+ if (rc < 0)
+ {
+ DBG("I2C read packet data failed, rc = %d\n", rc);
+ return -1;
+ }
+ }
+ else if (g_FirmwareMode == FIRMWARE_MODE_DEBUG_MODE)
+ {
+#ifdef CONFIG_ENABLE_SEGMENT_READ_FINGER_TOUCH_DATA
+ DBG("*** g_FwPacketDataAddress = 0x%2X ***\n", g_FwPacketDataAddress); // add for debug
+ DBG("*** g_FwPacketFlagAddress = 0x%2X ***\n", g_FwPacketFlagAddress); // add for debug
+
+ if (g_FwSupportSegment == 0)
+ {
+ DBG("g_FwPacketDataAddress & g_FwPacketFlagAddress is un-initialized\n");
+ return -1;
+ }
+
+ if (_gIsDisableFinagerTouch == 1)
+ {
+ DBG("Skip finger touch for handling get firmware info or change firmware mode\n");
+ return -1;
+ }
+
+ IicSegmentReadDataBySmBus(g_FwPacketDataAddress, &pPacket[0], nReportPacketLength, MAX_I2C_TRANSACTION_LENGTH_LIMIT);
+
+ _DrvFwCtrlCheckFingerTouchPacketFlagBit1();
+ _DrvFwCtrlResetFingerTouchPacketFlagBit1();
+#else
+ rc = IicReadData(SLAVE_I2C_ID_DWI2C, &pPacket[0], nReportPacketLength);
+ if (rc < 0)
+ {
+ DBG("I2C read packet data failed, rc = %d\n", rc);
+ return -1;
+ }
+#endif //CONFIG_ENABLE_SEGMENT_READ_FINGER_TOUCH_DATA
+ }
+ else
+ {
+ DBG("WRONG FIRMWARE MODE : 0x%x\n", g_FirmwareMode);
+ return -1;
+ }
+ }
+ else
+ {
+ rc = IicReadData(SLAVE_I2C_ID_DWI2C, &pPacket[0], nReportPacketLength);
+ if (rc < 0)
+ {
+ DBG("I2C read packet data failed, rc = %d\n", rc);
+ return -1;
+ }
+ } //IS_FIRMWARE_DATA_LOG_ENABLED
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------//
+
+void DrvFwCtrlHandleFingerTouch(void)
+{
+ TouchInfo_t tInfo;
+ u32 i = 0;
+ static u32 nLastKeyCode = 0xFF;
+ static u32 nLastCount = 0;
+ u8 *pPacket = NULL;
+ u16 nReportPacketLength = 0;
+
+// DBG("*** %s() ***\n", __func__); // add for debug
+
+ if (_gIsDisableFinagerTouch == 1)
+ {
+ DBG("Skip finger touch for handling get firmware info or change firmware mode\n");
+ return;
+ }
+
+ mutex_lock(&g_Mutex);
+ DBG("*** %s() *** mutex_lock(&g_Mutex)\n", __func__); // add for debug
+
+ memset(&tInfo, 0x0, sizeof(TouchInfo_t));
+
+ if (IS_FIRMWARE_DATA_LOG_ENABLED)
+ {
+ if (g_FirmwareMode == FIRMWARE_MODE_DEMO_MODE)
+ {
+#ifdef CONFIG_ENABLE_HOTKNOT //demo mode
+ if (g_HotKnotState == HOTKNOT_TRANS_STATE)
+ {
+ nReportPacketLength = DEMO_HOTKNOT_SEND_RET_LEN;
+ pPacket = g_DemoModeHotKnotSndRetPacket;
+ }
+ else
+#endif //CONFIG_ENABLE_HOTKNOT
+ {
+ DBG("FIRMWARE_MODE_DEMO_MODE\n");
+
+ nReportPacketLength = DEMO_MODE_PACKET_LENGTH;
+ pPacket = g_DemoModePacket;
+ }
+ }
+ else if (g_FirmwareMode == FIRMWARE_MODE_DEBUG_MODE)
+ {
+ DBG("FIRMWARE_MODE_DEBUG_MODE\n");
+
+ if (g_FirmwareInfo.nLogModePacketHeader != 0xA5 && g_FirmwareInfo.nLogModePacketHeader != 0xAB && g_FirmwareInfo.nLogModePacketHeader != 0xA7)
+ {
+ DBG("WRONG DEBUG MODE HEADER : 0x%x\n", g_FirmwareInfo.nLogModePacketHeader);
+ goto TouchHandleEnd;
+ }
+
+#ifdef CONFIG_ENABLE_HOTKNOT //debug mode
+ if(g_HotKnotState == HOTKNOT_TRANS_STATE)
+ {
+ nReportPacketLength = DEBUG_HOTKNOT_SEND_RET_LEN;
+ pPacket = g_DebugModeHotKnotSndRetPacket;
+ }
+ else
+#endif //CONFIG_ENABLE_HOTKNOT
+ {
+ nReportPacketLength = g_FirmwareInfo.nLogModePacketLength;
+ pPacket = g_LogModePacket;
+ }
+ }
+ else
+ {
+ DBG("WRONG FIRMWARE MODE : 0x%x\n", g_FirmwareMode);
+ goto TouchHandleEnd;
+ }
+ }
+ else
+ {
+#ifdef CONFIG_ENABLE_HOTKNOT //demo mode
+ if (g_HotKnotState == HOTKNOT_TRANS_STATE)
+ {
+ nReportPacketLength = DEMO_HOTKNOT_SEND_RET_LEN;
+ pPacket = g_DemoModeHotKnotSndRetPacket;
+ }
+ else
+#endif //CONFIG_ENABLE_HOTKNOT
+ {
+ DBG("FIRMWARE_MODE_DEMO_MODE\n");
+
+ nReportPacketLength = DEMO_MODE_PACKET_LENGTH;
+ pPacket = g_DemoModePacket;
+ }
+ } //IS_FIRMWARE_DATA_LOG_ENABLED
+
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+
+#ifdef CONFIG_ENABLE_GESTURE_DEBUG_MODE
+ if (g_GestureDebugMode == 1 && g_GestureWakeupFlag == 1)
+ {
+ DBG("Set gesture debug mode packet length, g_ChipType=%d\n", g_ChipType);
+
+ if (g_ChipType == CHIP_TYPE_MSG26XXM || g_ChipType == CHIP_TYPE_MSG28XX)
+ {
+ nReportPacketLength = GESTURE_DEBUG_MODE_PACKET_LENGTH;
+ pPacket = _gGestureWakeupPacket;
+ }
+ else
+ {
+ DBG("This chip type does not support gesture debug mode.\n");
+ goto TouchHandleEnd;
+ }
+ }
+ else if (g_GestureWakeupFlag == 1)
+ {
+ DBG("Set gesture wakeup packet length\n");
+
+#ifdef CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+ nReportPacketLength = GESTURE_WAKEUP_INFORMATION_PACKET_LENGTH;
+#else
+ nReportPacketLength = GESTURE_WAKEUP_PACKET_LENGTH;
+#endif //CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+
+ pPacket = _gGestureWakeupPacket;
+ }
+
+#else
+
+ if (g_GestureWakeupFlag == 1)
+ {
+ DBG("Set gesture wakeup packet length\n");
+
+#ifdef CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+ nReportPacketLength = GESTURE_WAKEUP_INFORMATION_PACKET_LENGTH;
+#else
+ nReportPacketLength = GESTURE_WAKEUP_PACKET_LENGTH;
+#endif //CONFIG_ENABLE_GESTURE_INFORMATION_MODE
+
+ pPacket = _gGestureWakeupPacket;
+ }
+#endif //CONFIG_ENABLE_GESTURE_DEBUG_MODE
+
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+
+#if defined(CONFIG_TOUCH_DRIVER_RUN_ON_SPRD_PLATFORM)
+#ifdef CONFIG_ENABLE_GESTURE_WAKEUP
+ if (g_GestureWakeupFlag == 1)
+ {
+ s32 rc;
+
+ while (i < 5)
+ {
+ mdelay(50);
+
+ rc = IicReadData(SLAVE_I2C_ID_DWI2C, &pPacket[0], nReportPacketLength);
+
+ if (rc > 0)
+ {
+ break;
+ }
+
+ i ++;
+ }
+ if (i == 5)
+ {
+ DBG("I2C read packet data failed, rc = %d\n", rc);
+ goto TouchHandleEnd;
+ }
+ }
+ else
+ {
+ if (0 != _DrvFwCtrlReadFingerTouchData(&pPacket[0], nReportPacketLength))
+ {
+ goto TouchHandleEnd;
+ }
+ }
+#else
+ if (0 != _DrvFwCtrlReadFingerTouchData(&pPacket[0], nReportPacketLength))
+ {
+ goto TouchHandleEnd;
+ }
+#endif //CONFIG_ENABLE_GESTURE_WAKEUP
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_QCOM_PLATFORM)
+ if (0 != _DrvFwCtrlReadFingerTouchData(&pPacket[0], nReportPacketLength))
+ {
+ goto TouchHandleEnd;
+ }
+#elif defined(CONFIG_TOUCH_DRIVER_RUN_ON_MTK_PLATFORM)
+ {
+ s32 nRetVal = 0;
+
+#ifdef CONFIG_ENABLE_DMA_IIC
+ DmaReset();
+#endif //CONFIG_ENABLE_DMA_IIC
+
+ nRetVal = _DrvFwCtrlReadFingerTouchData(&pPacket[0], nReportPacketLength);
+ if (0 != nRetVal)
+ {
+ goto TouchHandleEnd;
+ }
+ }
+#endif
+
+ if (0 == _DrvFwCtrlParsePacket(pPacket, nReportPacketLength, &tInfo))
+ {
+#ifdef CONFIG_TP_HAVE_KEY
+ if (tInfo.nKeyCode != 0xFF) //key touch pressed
+ {
+ DBG("tInfo.nKeyCode=%x, nLastKeyCode=%x, g_TpVirtualKey[%d]=%d\n", tInfo.nKeyCode, nLastKeyCode, tInfo.nKeyCode, g_TpVirtualKey[tInfo.nKeyCode]);
+
+ if (tInfo.nKeyCode < MAX_KEY_NUM)
+ {
+ if (tInfo.nKeyCode != nLastKeyCode)
+ {
+ DBG("key touch pressed\n");
+
+ input_report_key(g_InputDevice, BTN_TOUCH, 1);
+ input_report_key(g_InputDevice, g_TpVirtualKey[tInfo.nKeyCode], 1);
+
+ input_sync(g_InputDevice);
+
+ nLastKeyCode = tInfo.nKeyCode;
+ }
+ else
+ {
+ /// pass duplicate key-pressing
+ DBG("REPEATED KEY\n");
+ }
+ }
+ else
+ {
+ DBG("WRONG KEY\n");
+ }
+ }
+ else //key touch released
+ {
+ if (nLastKeyCode != 0xFF)
+ {
+ DBG("key touch released\n");
+
+ input_report_key(g_InputDevice, BTN_TOUCH, 0);
+ input_report_key(g_InputDevice, g_TpVirtualKey[nLastKeyCode], 0);
+
+ input_sync(g_InputDevice);
+
+ nLastKeyCode = 0xFF;
+ }
+ }
+#endif //CONFIG_TP_HAVE_KEY
+
+ DBG("tInfo.nCount = %d, nLastCount = %d\n", tInfo.nCount, nLastCount);
+
+ if (tInfo.nCount > 0) //point touch pressed
+ {
+ for (i = 0; i < tInfo.nCount; i ++)
+ {
+ DrvPlatformLyrFingerTouchPressed(tInfo.tPoint[i].nX, tInfo.tPoint[i].nY, tInfo.tPoint[i].nP, tInfo.tPoint[i].nId);
+ }
+
+ input_sync(g_InputDevice);
+
+ nLastCount = tInfo.nCount;
+ }
+ else //point touch released
+ {
+ if (nLastCount > 0)
+ {
+ DrvPlatformLyrFingerTouchReleased(tInfo.tPoint[0].nX, tInfo.tPoint[0].nY);
+
+ input_sync(g_InputDevice);
+
+ nLastCount = 0;
+ }
+ }
+
+#ifdef CONFIG_ENABLE_COUNT_REPORT_RATE
+ if (g_IsEnableReportRate == 1)
+ {
+ if (g_ValidTouchCount == 4294967296)
+ {
+ g_ValidTouchCount = 0; // Reset count if overflow
+ DBG("g_ValidTouchCount reset to 0\n");
+ }
+
+ g_ValidTouchCount ++;
+
+ DBG("g_ValidTouchCount = %d\n", g_ValidTouchCount);
+ }
+#endif //CONFIG_ENABLE_COUNT_REPORT_RATE
+ }
+
+ TouchHandleEnd:
+
+ DBG("*** %s() *** mutex_unlock(&g_Mutex)\n", __func__); // add for debug
+ mutex_unlock(&g_Mutex);
+}
+
+#endif //CONFIG_ENABLE_TOUCH_DRIVER_FOR_MUTUAL_IC \ No newline at end of file