From 8e4bff4cab0ddac6060645b0715210484d02ff40 Mon Sep 17 00:00:00 2001 From: Yuval Adam <_@yuv.al> Date: Wed, 30 Aug 2017 08:25:59 +0000 Subject: Initial file dump from open source release --- .../msg2233/mstar_drv_mutual_fw_control.c | 6412 ++++++++++++++++++++ 1 file changed, 6412 insertions(+) create mode 100644 drivers/input/touchscreen/msg2233/mstar_drv_mutual_fw_control.c (limited to 'drivers/input/touchscreen/msg2233/mstar_drv_mutual_fw_control.c') 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<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<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 -- cgit v1.3.1