module will be called bu21023_ts.
source "drivers/input/touchscreen/synaptics_dsx/Kconfig"
+source "drivers/input/touchscreen/nt36xxx/Kconfig"
endif
obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o
obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_DSX) += synaptics_dsx/
+obj-$(CONFIG_TOUCHSCREEN_NT36xxx) += nt36xxx/
+++ /dev/null
-#
-# Novatek NT36xxx touchscreen driver configuration
-#
-config TOUCHSCREEN_NT36xxx
- bool "Novatek NT36xxx"
- default y
- help
- Say Y here if you have a Novatek NT36xxx touchscreen connected
- to your system.
-
- If unsure, say N.
+++ /dev/null
-#
-# Makefile for the Novatek NT36xxx touchscreen driver.
-#
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_TOUCHSCREEN_NT36xxx) += nt36xxx.o nt36xxx_fw_update.o nt36xxx_ext_proc.o nt36xxx_mp_ctrlram.o
+++ /dev/null
-/*
- * Copyright (C) 2010 - 2017 Novatek, Inc.
- *
- * $Revision: 22971 $
- * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#include <linux/init.h>
-#include <linux/cdev.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/miscdevice.h>
-#include <linux/platform_device.h>
-#include <linux/gfp.h>
-#include <linux/slab.h>
-#include <linux/miscdevice.h>
-#include <linux/list.h>
-#include <linux/device.h>
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/proc_fs.h>
-#include <asm/uaccess.h>
-#include <linux/input/mt.h>
-#include <linux/wakelock.h>
-#include <linux/of_gpio.h>
-#include <linux/of_irq.h>
-
-#if defined(CONFIG_HQ_DEV_INFO)
-#include <linux/dev_info.h>
-#endif
-
-#if defined(CONFIG_FB)
-#include <linux/notifier.h>
-#include <linux/fb.h>
-#elif defined(CONFIG_HAS_EARLYSUSPEND)
-#include <linux/earlysuspend.h>
-#endif
-
-#include "nt36xxx.h"
-
-#if NVT_TOUCH_ESD_PROTECT
-#include <linux/jiffies.h>
-
-static struct delayed_work nvt_esd_check_work;
-static struct workqueue_struct *nvt_esd_check_wq;
-static unsigned long irq_timer;
-uint8_t esd_check = false;
-uint8_t esd_retry = 0;
-uint8_t esd_retry_max = 5;
-#endif
-
-#if NVT_TOUCH_EXT_PROC
-extern int32_t nvt_extra_proc_init(void);
-#endif
-
-#if NVT_TOUCH_FW
-extern int32_t nvt_fw_sysfs_init(void);
-extern int32_t nvt_fw_sysfs_deinit(void);
-#endif
-
-#if NVT_TOUCH_MP
-extern int32_t nvt_mp_proc_init(void);
-#endif
-
-struct nvt_ts_data *ts;
-
-static struct workqueue_struct *nvt_wq;
-
-#if BOOT_UPDATE_FIRMWARE
-static struct workqueue_struct *nvt_fwu_wq;
-extern void Boot_Update_Firmware(struct work_struct *work);
-#endif
-
-#if defined(CONFIG_FB)
-static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
-#elif defined(CONFIG_HAS_EARLYSUSPEND)
-static void nvt_ts_early_suspend(struct early_suspend *h);
-static void nvt_ts_late_resume(struct early_suspend *h);
-#endif
-
-#if TOUCH_KEY_NUM > 0
-const uint16_t touch_key_array[TOUCH_KEY_NUM] = {
- KEY_BACK,
- KEY_HOME,
- KEY_MENU
-};
-#endif
-
-#if WAKEUP_GESTURE
-const uint16_t gesture_key_array[] = {
- KEY_POWER, //GESTURE_WORD_C
- KEY_POWER, //GESTURE_WORD_W
- KEY_POWER, //GESTURE_WORD_V
- KEY_POWER, //GESTURE_DOUBLE_CLICK
- KEY_POWER, //GESTURE_WORD_Z
- KEY_POWER, //GESTURE_WORD_M
- KEY_POWER, //GESTURE_WORD_O
- KEY_POWER, //GESTURE_WORD_e
- KEY_POWER, //GESTURE_WORD_S
- KEY_POWER, //GESTURE_SLIDE_UP
- KEY_POWER, //GESTURE_SLIDE_DOWN
- KEY_POWER, //GESTURE_SLIDE_LEFT
- KEY_POWER, //GESTURE_SLIDE_RIGHT
-};
-#endif
-
-static uint8_t bTouchIsAwake = 0;
-
-/*******************************************************
-Description:
- Novatek touchscreen i2c read function.
-
-return:
- Executive outcomes. 2---succeed. -5---I/O error
-*******************************************************/
-int32_t CTP_I2C_READ(struct i2c_client *client, uint16_t address, uint8_t *buf, uint16_t len)
-{
- struct i2c_msg msgs[2];
- int32_t ret = -1;
- int32_t retries = 0;
-
- msgs[0].flags = !I2C_M_RD;
- msgs[0].addr = address;
- msgs[0].len = 1;
- msgs[0].buf = &buf[0];
-
- msgs[1].flags = I2C_M_RD;
- msgs[1].addr = address;
- msgs[1].len = len - 1;
- msgs[1].buf = &buf[1];
-
- while (retries < 5) {
- ret = i2c_transfer(client->adapter, msgs, 2);
- if (ret == 2) break;
- retries++;
- }
-
- if (unlikely(retries == 5)) {
- NVT_ERR("error, ret=%d\n", ret);
- ret = -EIO;
- }
-
- return ret;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen i2c write function.
-
-return:
- Executive outcomes. 1---succeed. -5---I/O error
-*******************************************************/
-int32_t CTP_I2C_WRITE(struct i2c_client *client, uint16_t address, uint8_t *buf, uint16_t len)
-{
- struct i2c_msg msg;
- int32_t ret = -1;
- int32_t retries = 0;
-
- msg.flags = !I2C_M_RD;
- msg.addr = address;
- msg.len = len;
- msg.buf = buf;
-
- while (retries < 5) {
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (ret == 1) break;
- retries++;
- }
-
- if (unlikely(retries == 5)) {
- NVT_ERR("error, ret=%d\n", ret);
- ret = -EIO;
- }
-
- return ret;
-}
-
-
-/*******************************************************
-Description:
- Novatek touchscreen reset MCU then into idle mode
- function.
-
-return:
- n.a.
-*******************************************************/
-void nvt_sw_reset_idle(void)
-{
- uint8_t buf[4]={0};
-
- /* ---write i2c cmds to reset idle--- */
- buf[0]=0x00;
- buf[1]=0xA5;
- CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
-
- msleep(15);
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen reset MCU (boot) function.
-
-return:
- n.a.
-*******************************************************/
-void nvt_bootloader_reset(void)
-{
- uint8_t buf[8] = {0};
- NVT_ERR("xlixiang---enter-%s\n", __func__);
- //---write i2c cmds to reset---
- buf[0] = 0x00;
- buf[1] = 0x69;
- CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
-
- // need 35ms delay after bootloader reset
- msleep(35);
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen clear FW status function.
-
-return:
- Executive outcomes. 0---succeed. -1---fail.
-*******************************************************/
-int32_t nvt_clear_fw_status(void)
-{
- uint8_t buf[8] = {0};
- int32_t i = 0;
- const int32_t retry = 20;
-
- for (i = 0; i < retry; i++) {
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---clear fw status---
- buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
- buf[1] = 0x00;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
-
- //---read fw status---
- buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
- buf[1] = 0xFF;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
-
- if (buf[1] == 0x00)
- break;
-
- msleep(10);
- }
-
- if (i >= retry) {
- NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]);
- return -1;
- } else {
- return 0;
- }
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen check FW status function.
-
-return:
- Executive outcomes. 0---succeed. -1---failed.
-*******************************************************/
-int32_t nvt_check_fw_status(void)
-{
- uint8_t buf[8] = {0};
- int32_t i = 0;
- const int32_t retry = 50;
-
- for (i = 0; i < retry; i++) {
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---read fw status---
- buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
- buf[1] = 0x00;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
-
- if ((buf[1] & 0xF0) == 0xA0)
- break;
-
- msleep(10);
- }
-
- if (i >= retry) {
- NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]);
- return -1;
- } else {
- return 0;
- }
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen check FW reset state function.
-
-return:
- Executive outcomes. 0---succeed. -1---failed.
-*******************************************************/
-int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state)
-{
- uint8_t buf[8] = {0};
- int32_t ret = 0;
- int32_t retry = 0;
- NVT_ERR("xlixiang---enter-%s\n", __func__);
- while (1) {
- msleep(10);
- //---read reset state---
- buf[0] = EVENT_MAP_RESET_COMPLETE;
- buf[1] = 0x00;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 6);
-
- if ((buf[1] >= check_reset_state) && (buf[1] <= RESET_STATE_MAX)) {
- ret = 0;
- break;
- }
-
- retry++;
- if (check_reset_state <= RESET_STATE_REK) {
- if( unlikely(retry > 50)) {
- NVT_ERR("error,retry = %d,buf[1] = 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",retry,buf[1],buf[2], buf[3], buf[4], buf[5]);
- ret = -1;
- break;
- }
- }
- else
- {
- if(unlikely(retry > 100)) {
- NVT_ERR("error, retry=%d, buf[1]=0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", retry, buf[1], buf[2], buf[3], buf[4], buf[5]);
- ret = -1;
- break;
- }
- }
- }
-
- return ret;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen get novatek project id information
- function.
-
-return:
- Executive outcomes. 0---success. -1---fail.
-*******************************************************/
-int32_t nvt_read_pid(void)
-{
- uint8_t buf[3] = {0};
- int32_t ret = 0;
-
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---read project id---
- buf[0] = EVENT_MAP_PROJECTID;
- buf[1] = 0x00;
- buf[2] = 0x00;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 3);
-
- ts->nvt_pid = (buf[2] << 8) + buf[1];
-
- NVT_LOG("PID=%04X\n", ts->nvt_pid);
-
- return ret;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen get firmware related information
- function.
-
-return:
- Executive outcomes. 0---success. -1---fail.
-*******************************************************/
-int32_t nvt_get_fw_info(void)
-{
- uint8_t buf[64] = {0};
- uint32_t retry_count = 0;
- int32_t ret = 0;
-
-info_retry:
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---read fw info---
- buf[0] = EVENT_MAP_FWINFO;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 17);
- ts->fw_ver = buf[1];
- ts->x_num = buf[3];
- ts->y_num = buf[4];
- ts->abs_x_max = (uint16_t)((buf[5] << 8) | buf[6]);
- ts->abs_y_max = (uint16_t)((buf[7] << 8) | buf[8]);
- ts->max_button_num = buf[11];
-
- //---clear x_num, y_num if fw info is broken---
- if ((buf[1] + buf[2]) != 0xFF) {
- NVT_ERR("FW info is broken! fw_ver=0x%02X, ~fw_ver=0x%02X\n", buf[1], buf[2]);
- ts->fw_ver = 0;
- ts->x_num = 18;
- ts->y_num = 32;
- ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH;
- ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT;
- ts->max_button_num = TOUCH_KEY_NUM;
-
- if(retry_count < 3) {
- retry_count++;
- NVT_ERR("retry_count=%d\n", retry_count);
- goto info_retry;
- } else {
- NVT_ERR("Set default fw_ver=%d, x_num=%d, y_num=%d, \
- abs_x_max=%d, abs_y_max=%d, max_button_num=%d!\n",
- ts->fw_ver, ts->x_num, ts->y_num,
- ts->abs_x_max, ts->abs_y_max, ts->max_button_num);
- ret = -1;
- }
- } else {
- ret = 0;
- }
-
- //---Get Novatek PID---
- nvt_read_pid();
-
- return ret;
-}
-
-/*******************************************************
- Create Device Node (Proc Entry)
-*******************************************************/
-#if NVT_TOUCH_PROC
-static struct proc_dir_entry *NVT_proc_entry;
-#define DEVICE_NAME "NVTflash"
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/NVTflash read function.
-
-return:
- Executive outcomes. 2---succeed. -5,-14---failed.
-*******************************************************/
-static ssize_t nvt_flash_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
-{
- uint8_t str[68] = {0};
- int32_t ret = -1;
- int32_t retries = 0;
- int8_t i2c_wr = 0;
-
- if (count > sizeof(str)) {
- NVT_ERR("error count=%zu\n", count);
- return -EFAULT;
- }
-
- if (copy_from_user(str, buff, count)) {
- NVT_ERR("copy from user error\n");
- return -EFAULT;
- }
-#if NVT_TOUCH_ESD_PROTECT
- /*
- * stop esd check work to avoid case that 0x77 report righ after here to enable esd check again
- * finally lead to trigger esd recovery bootloader reset
- */
- cancel_delayed_work_sync(&nvt_esd_check_work);
- nvt_esd_check_enable(false);
-#endif
-
- i2c_wr = str[0] >> 7;
-
- if (i2c_wr == 0) { //I2C write
- while (retries < 20) {
- ret = CTP_I2C_WRITE(ts->client, (str[0] & 0x7F), &str[2], str[1]);
- if (ret == 1)
- break;
- else
- NVT_ERR("error, retries=%d, ret=%d\n", retries, ret);
-
- retries++;
- }
-
- if (unlikely(retries == 20)) {
- NVT_ERR("error, ret = %d\n", ret);
- return -EIO;
- }
-
- return ret;
- } else if (i2c_wr == 1) { //I2C read
- while (retries < 20) {
- ret = CTP_I2C_READ(ts->client, (str[0] & 0x7F), &str[2], str[1]);
- if (ret == 2)
- break;
- else
- NVT_ERR("error, retries=%d, ret=%d\n", retries, ret);
-
- retries++;
- }
-
- // copy buff to user if i2c transfer
- if (retries < 20) {
- if (copy_to_user(buff, str, count))
- return -EFAULT;
- }
-
- if (unlikely(retries == 20)) {
- NVT_ERR("error, ret = %d\n", ret);
- return -EIO;
- }
-
- return ret;
- } else {
- NVT_ERR("Call error, str[0]=%d\n", str[0]);
- return -EFAULT;
- }
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/NVTflash open function.
-
-return:
- Executive outcomes. 0---succeed. -12---failed.
-*******************************************************/
-static int32_t nvt_flash_open(struct inode *inode, struct file *file)
-{
- struct nvt_flash_data *dev;
-
- dev = kmalloc(sizeof(struct nvt_flash_data), GFP_KERNEL);
- if (dev == NULL) {
- NVT_ERR("Failed to allocate memory for nvt flash data\n");
- return -ENOMEM;
- }
-
- rwlock_init(&dev->lock);
- file->private_data = dev;
-
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/NVTflash close function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t nvt_flash_close(struct inode *inode, struct file *file)
-{
- struct nvt_flash_data *dev = file->private_data;
-
- if (dev)
- kfree(dev);
-
- return 0;
-}
-
-static const struct file_operations nvt_flash_fops = {
- .owner = THIS_MODULE,
- .open = nvt_flash_open,
- .release = nvt_flash_close,
- .read = nvt_flash_read,
-};
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/NVTflash initial function.
-
-return:
- Executive outcomes. 0---succeed. -12---failed.
-*******************************************************/
-static int32_t nvt_flash_proc_init(void)
-{
- NVT_proc_entry = proc_create(DEVICE_NAME, 0444, NULL,&nvt_flash_fops);
- if (NVT_proc_entry == NULL) {
- NVT_ERR("Failed!\n");
- return -ENOMEM;
- } else {
- NVT_LOG("Succeeded!\n");
- }
-
- NVT_LOG("============================================================\n");
- NVT_LOG("Create /proc/NVTflash\n");
- NVT_LOG("============================================================\n");
-
- return 0;
-}
-#endif
-
-#if WAKEUP_GESTURE
-#define GESTURE_WORD_C 12
-#define GESTURE_WORD_W 13
-#define GESTURE_WORD_V 14
-#define GESTURE_DOUBLE_CLICK 15
-#define GESTURE_WORD_Z 16
-#define GESTURE_WORD_M 17
-#define GESTURE_WORD_O 18
-#define GESTURE_WORD_e 19
-#define GESTURE_WORD_S 20
-#define GESTURE_SLIDE_UP 21
-#define GESTURE_SLIDE_DOWN 22
-#define GESTURE_SLIDE_LEFT 23
-#define GESTURE_SLIDE_RIGHT 24
-/* customized gesture id */
-#define DATA_PROTOCOL 30
-
-/* function page definition */
-#define FUNCPAGE_GESTURE 1
-
-static struct wake_lock gestrue_wakelock;
-
-/*******************************************************
-Description:
- Novatek touchscreen wake up gesture key report function.
-
-return:
- n.a.
-*******************************************************/
-void nvt_ts_wakeup_gesture_report(uint8_t gesture_id, uint8_t *data)
-{
- uint32_t keycode = 0;
- uint8_t func_type = data[2];
- uint8_t func_id = data[3];
-
- /* support fw specifal data protocol */
- if ((gesture_id == DATA_PROTOCOL) && (func_type == FUNCPAGE_GESTURE)) {
- gesture_id = func_id;
- } else if (gesture_id > DATA_PROTOCOL) {
- NVT_ERR("gesture_id %d is invalid, func_type=%d, func_id=%d\n", gesture_id, func_type, func_id);
- return;
- }
-
- NVT_LOG("gesture_id = %d\n", gesture_id);
-
- switch (gesture_id) {
- case GESTURE_WORD_C:
- NVT_LOG("Gesture : Word-C.\n");
- keycode = gesture_key_array[0];
- break;
- case GESTURE_WORD_W:
- NVT_LOG("Gesture : Word-W.\n");
- keycode = gesture_key_array[1];
- break;
- case GESTURE_WORD_V:
- NVT_LOG("Gesture : Word-V.\n");
- keycode = gesture_key_array[2];
- break;
- case GESTURE_DOUBLE_CLICK:
- NVT_LOG("Gesture : Double Click.\n");
- keycode = gesture_key_array[3];
- break;
- case GESTURE_WORD_Z:
- NVT_LOG("Gesture : Word-Z.\n");
- keycode = gesture_key_array[4];
- break;
- case GESTURE_WORD_M:
- NVT_LOG("Gesture : Word-M.\n");
- keycode = gesture_key_array[5];
- break;
- case GESTURE_WORD_O:
- NVT_LOG("Gesture : Word-O.\n");
- keycode = gesture_key_array[6];
- break;
- case GESTURE_WORD_e:
- NVT_LOG("Gesture : Word-e.\n");
- keycode = gesture_key_array[7];
- break;
- case GESTURE_WORD_S:
- NVT_LOG("Gesture : Word-S.\n");
- keycode = gesture_key_array[8];
- break;
- case GESTURE_SLIDE_UP:
- NVT_LOG("Gesture : Slide UP.\n");
- keycode = gesture_key_array[9];
- break;
- case GESTURE_SLIDE_DOWN:
- NVT_LOG("Gesture : Slide DOWN.\n");
- keycode = gesture_key_array[10];
- break;
- case GESTURE_SLIDE_LEFT:
- NVT_LOG("Gesture : Slide LEFT.\n");
- keycode = gesture_key_array[11];
- break;
- case GESTURE_SLIDE_RIGHT:
- NVT_LOG("Gesture : Slide RIGHT.\n");
- keycode = gesture_key_array[12];
- break;
- default:
- break;
- }
-
- if (keycode > 0) {
- input_report_key(ts->input_dev, keycode, 1);
- input_sync(ts->input_dev);
- input_report_key(ts->input_dev, keycode, 0);
- input_sync(ts->input_dev);
- }
-}
-#endif
-
-/*******************************************************
-Description:
- Novatek touchscreen parse device tree function.
-
-return:
- n.a.
-*******************************************************/
-#ifdef CONFIG_OF
-static void nvt_parse_dt(struct device *dev)
-{
- struct device_node *np = dev->of_node;
-
-#if NVT_TOUCH_SUPPORT_HW_RST
- ts->reset_gpio = of_get_named_gpio_flags(np, "novatek,reset-gpio", 0, &ts->reset_flags);
- NVT_LOG("novatek,reset-gpio=%d\n", ts->reset_gpio);
-#endif
- ts->irq_gpio = of_get_named_gpio_flags(np, "novatek,irq-gpio", 0, &ts->irq_flags);
- NVT_LOG("novatek,irq-gpio=%d\n", ts->irq_gpio);
-
-}
-#else
-static void nvt_parse_dt(struct device *dev)
-{
-#if NVT_TOUCH_SUPPORT_HW_RST
- ts->reset_gpio = NVTTOUCH_RST_PIN;
-#endif
- ts->irq_gpio = NVTTOUCH_INT_PIN;
-}
-#endif
-
-/*******************************************************
-Description:
- Novatek touchscreen config and request gpio
-
-return:
- Executive outcomes. 0---succeed. not 0---failed.
-*******************************************************/
-static int nvt_gpio_config(struct nvt_ts_data *ts)
-{
- int32_t ret = 0;
-
-#if NVT_TOUCH_SUPPORT_HW_RST
- /* request RST-pin (Output/High) */
- if (gpio_is_valid(ts->reset_gpio)) {
- ret = gpio_request_one(ts->reset_gpio, GPIOF_OUT_INIT_HIGH, "NVT-tp-rst");
- if (ret) {
- NVT_ERR("Failed to request NVT-tp-rst GPIO\n");
- goto err_request_reset_gpio;
- }
- }
-#endif
- /* request INT-pin (Input) */
- if (gpio_is_valid(ts->irq_gpio)) {
- ret = gpio_request_one(ts->irq_gpio, GPIOF_IN, "NVT-int");
- if (ret) {
- NVT_ERR("Failed to request NVT-int GPIO\n");
- goto err_request_irq_gpio;
- }
- }
-
- return ret;
-
-err_request_irq_gpio:
-#if NVT_TOUCH_SUPPORT_HW_RST
- gpio_free(ts->reset_gpio);
-err_request_reset_gpio:
-#endif
- return ret;
-}
-
-#if NVT_TOUCH_ESD_PROTECT
-void nvt_esd_check_enable(uint8_t enable)
-{
- /* enable/disable esd check flag */
- esd_check = enable;
- /* update interrupt timer */
- irq_timer = jiffies;
- /* clear esd_retry counter, if protect function is enabled */
- esd_retry = enable ? 0 : esd_retry;
-}
-
-static uint8_t nvt_fw_recovery(uint8_t *point_data)
-{
- uint8_t i = 0;
- uint8_t detected = true;
-
- /* check pattern */
- for (i = 1 ; i < 7 ; i++) {
- if (point_data[i] != 0x77) {
- detected = false;
- break;
- }
- }
-
- return detected;
-}
-
-static void nvt_esd_check_func(struct work_struct *work)
-{
- unsigned int timer = jiffies_to_msecs(jiffies - irq_timer);
-
-
- if (esd_retry >= esd_retry_max)
- nvt_esd_check_enable(false);
-
- if ((timer > NVT_TOUCH_ESD_CHECK_PERIOD) && esd_check) {
- NVT_ERR("do ESD recovery, timer = %d, retry = %d\n", timer, esd_retry);
- printk("do ESD recovery, timer = %d, retry = %d\n", timer, esd_retry);
- /* do esd recovery, bootloader reset */
- nvt_bootloader_reset();
- /* update interrupt timer */
- irq_timer = jiffies;
- /* update esd_retry counter */
- esd_retry++;
- }
-
- queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work,
- msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD));
-}
-#endif
-
-#define POINT_DATA_LEN 65
-/*******************************************************
-Description:
- Novatek touchscreen work function.
-
-return:
- n.a.
-*******************************************************/
-static void nvt_ts_work_func(struct work_struct *work)
-{
- int32_t ret = -1;
- uint8_t point_data[POINT_DATA_LEN + 1] = {0};
- uint32_t position = 0;
- uint32_t input_x = 0;
- uint32_t input_y = 0;
- uint32_t input_w = 0;
- uint32_t input_p = 0;
- uint8_t input_id = 0;
-#if MT_PROTOCOL_B
- uint8_t press_id[TOUCH_MAX_FINGER_NUM] = {0};
-#endif /* MT_PROTOCOL_B */
- int32_t i = 0;
- int32_t finger_cnt = 0;
-
- mutex_lock(&ts->lock);
-
- ret = CTP_I2C_READ(ts->client, I2C_FW_Address, point_data, POINT_DATA_LEN + 1);
- if (ret < 0) {
- NVT_ERR("CTP_I2C_READ failed.(%d)\n", ret);
- goto XFER_ERROR;
- }
-
-#if NVT_TOUCH_ESD_PROTECT
-
- if (nvt_fw_recovery(point_data)) {
- nvt_esd_check_enable(true);
- goto XFER_ERROR;
- }
-#endif
-
-#if WAKEUP_GESTURE
- if (bTouchIsAwake == 0) {
- input_id = (uint8_t)(point_data[1] >> 3);
- nvt_ts_wakeup_gesture_report(input_id, point_data);
- enable_irq(ts->client->irq);
- mutex_unlock(&ts->lock);
- return;
- }
-#endif
-
- finger_cnt = 0;
-
- for (i = 0; i < ts->max_touch_num; i++) {
- position = 1 + 6 * i;
- input_id = (uint8_t)(point_data[position + 0] >> 3);
- if ((input_id == 0) || (input_id > ts->max_touch_num))
- continue;
-
- if (((point_data[position] & 0x07) == 0x01) || ((point_data[position] & 0x07) == 0x02)) {
-#if NVT_TOUCH_ESD_PROTECT
- /* update interrupt timer */
- irq_timer = jiffies;
-#endif
- input_x = (uint32_t)(point_data[position + 1] << 4) + (uint32_t) (point_data[position + 3] >> 4);
- input_y = (uint32_t)(point_data[position + 2] << 4) + (uint32_t) (point_data[position + 3] & 0x0F);
- if ((input_x < 0) || (input_y < 0))
- continue;
- if ((input_x > ts->abs_x_max) || (input_y > ts->abs_y_max))
- continue;
- input_w = (uint32_t)(point_data[position + 4]);
- if (input_w == 0)
- input_w = 1;
- if (i < 2) {
- input_p = (uint32_t)(point_data[position + 5]) + (uint32_t)(point_data[i + 63] << 8);
- if (input_p > TOUCH_FORCE_NUM)
- input_p = TOUCH_FORCE_NUM;
- } else {
- input_p = (uint32_t)(point_data[position + 5]);
- }
- if (input_p == 0)
- input_p = 1;
-
-#if MT_PROTOCOL_B
- press_id[input_id - 1] = 1;
- input_mt_slot(ts->input_dev, input_id - 1);
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
-#else /* MT_PROTOCOL_B */
- input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, input_id - 1);
- input_report_key(ts->input_dev, BTN_TOUCH, 1);
-#endif /* MT_PROTOCOL_B */
-
- input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y);
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE, input_p);
-
-#if MT_PROTOCOL_B
-#else /* MT_PROTOCOL_B */
- input_mt_sync(ts->input_dev);
-#endif /* MT_PROTOCOL_B */
-
- finger_cnt++;
- }
- }
-
-#if MT_PROTOCOL_B
- for (i = 0; i < ts->max_touch_num; i++) {
- if (press_id[i] != 1) {
- input_mt_slot(ts->input_dev, i);
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0);
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
- }
- }
-
- input_report_key(ts->input_dev, BTN_TOUCH, (finger_cnt > 0));
-#else /* MT_PROTOCOL_B */
- if (finger_cnt == 0) {
- input_report_key(ts->input_dev, BTN_TOUCH, 0);
- input_mt_sync(ts->input_dev);
- }
-#endif /* MT_PROTOCOL_B */
-
-#if TOUCH_KEY_NUM > 0
- if (point_data[61] == 0xF8) {
- for (i = 0; i < ts->max_button_num; i++) {
- input_report_key(ts->input_dev, touch_key_array[i], ((point_data[62] >> i) & 0x01));
- }
- } else {
- for (i = 0; i < ts->max_button_num; i++) {
- input_report_key(ts->input_dev, touch_key_array[i], 0);
- }
- }
-#endif
-
- input_sync(ts->input_dev);
-
-XFER_ERROR:
- enable_irq(ts->client->irq);
-
- mutex_unlock(&ts->lock);
-}
-
-/*******************************************************
-Description:
- External interrupt service routine.
-
-return:
- irq execute status.
-*******************************************************/
-static irqreturn_t nvt_ts_irq_handler(int32_t irq, void *dev_id)
-{
- disable_irq_nosync(ts->client->irq);
-
-#if WAKEUP_GESTURE
- if (bTouchIsAwake == 0) {
- wake_lock_timeout(&gestrue_wakelock, msecs_to_jiffies(5000));
- }
-#endif
-
- queue_work(nvt_wq, &ts->nvt_work);
-
- return IRQ_HANDLED;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen check and stop crc reboot loop.
-
-return:
- n.a.
-*******************************************************/
-void nvt_stop_crc_reboot(void)
-{
- uint8_t buf[8] = {0};
- int32_t retry = 0;
-
- //read dummy buffer to check CRC fail reboot is happening or not
-
- //---change I2C index to prevent geting 0xFF, but not 0xFC---
- buf[0] = 0xFF;
- buf[1] = 0x01;
- buf[2] = 0xF6;
- CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
-
- //---read to check if buf is 0xFC which means IC is in CRC reboot ---
- buf[0] = 0x4E;
- CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 4);
-
- if (((buf[1] == 0xFC) && (buf[2] == 0xFC) && (buf[3] == 0xFC)) ||
- ((buf[1] == 0xFF) && (buf[2] == 0xFF) && (buf[3] == 0xFF))) {
-
- //IC is in CRC fail reboot loop, needs to be stopped!
- for (retry = 5; retry > 0; retry--) {
-
- //---write i2c cmds to reset idle : 1st---
- buf[0]=0x00;
- buf[1]=0xA5;
- CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
-
- //---write i2c cmds to reset idle : 2rd---
- buf[0]=0x00;
- buf[1]=0xA5;
- CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- msleep(1);
-
- //---clear CRC_ERR_FLAG---
- buf[0] = 0xFF;
- buf[1] = 0x03;
- buf[2] = 0xF1;
- CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
-
- buf[0] = 0x35;
- buf[1] = 0xA5;
- CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 2);
-
- //---check CRC_ERR_FLAG---
- buf[0] = 0xFF;
- buf[1] = 0x03;
- buf[2] = 0xF1;
- CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
-
- buf[0] = 0x35;
- buf[1] = 0x00;
- CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 2);
-
- if (buf[1] == 0xA5)
- break;
- }
- if (retry == 0)
- NVT_ERR("CRC auto reboot is not able to be stopped! buf[1]=0x%02X\n", buf[1]);
- }
-
- return;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen check chip version trim function.
-
-return:
- Executive outcomes. 0---NVT IC. -1---not NVT IC.
-*******************************************************/
-static int8_t nvt_ts_check_chip_ver_trim(void)
-{
- uint8_t buf[8] = {0};
- int32_t retry = 0;
- int32_t list = 0;
- int32_t i = 0;
- int32_t found_nvt_chip = 0;
- int32_t ret = -1;
-
- nvt_bootloader_reset(); // NOT in retry loop
-
- //---Check for 5 times---
- for (retry = 5; retry > 0; retry--) {
- nvt_sw_reset_idle();
-
- buf[0] = 0x00;
- buf[1] = 0x35;
- CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- msleep(10);
-
- buf[0] = 0xFF;
- buf[1] = 0x01;
- buf[2] = 0xF6;
- CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
-
- buf[0] = 0x4E;
- buf[1] = 0x00;
- buf[2] = 0x00;
- buf[3] = 0x00;
- buf[4] = 0x00;
- buf[5] = 0x00;
- buf[6] = 0x00;
- CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 7);
- NVT_LOG("buf[1]=0x%02X, buf[2]=0x%02X, buf[3]=0x%02X, buf[4]=0x%02X, buf[5]=0x%02X, buf[6]=0x%02X\n",
- buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
-
- // compare read chip id on supported list
- for (list = 0; list < (sizeof(trim_id_table) / sizeof(struct nvt_ts_trim_id_table)); list++) {
- found_nvt_chip = 0;
-
- // compare each byte
- for (i = 0; i < NVT_ID_BYTE_MAX; i++) {
- if (trim_id_table[list].mask[i]) {
- if (buf[i + 1] != trim_id_table[list].id[i])
- break;
- }
- }
-
- if (i == NVT_ID_BYTE_MAX) {
- found_nvt_chip = 1;
- }
-
- if (found_nvt_chip) {
- NVT_LOG("This is NVT touch IC\n");
-#if NVT_TOUCH_FW
- if (list == 0) {
- snprintf(ts->product_id, sizeof(ts->product_id), "NT36672A");
- } else if (list == 9) {
- snprintf(ts->product_id, sizeof(ts->product_id), "NT36525");
- } else if (list == 10) {
- snprintf(ts->product_id, sizeof(ts->product_id), "NT36870");
- } else if (list == 11) {
- snprintf(ts->product_id, sizeof(ts->product_id), "NT36676F");
- } else {
- snprintf(ts->product_id, sizeof(ts->product_id), "NT36772");
- }
-#endif
- ts->mmap = trim_id_table[list].mmap;
- ts->carrier_system = trim_id_table[list].carrier_system;
- ret = 0;
- goto out;
- } else {
- ts->mmap = NULL;
- ret = -1;
- }
- }
-
- //---Stop CRC check to prevent IC auto reboot---
- if (((buf[1] == 0xFC) && (buf[2] == 0xFC) && (buf[3] == 0xFC)) ||
- ((buf[1] == 0xFF) && (buf[2] == 0xFF) && (buf[3] == 0xFF))) {
- nvt_stop_crc_reboot();
- }
-
- msleep(10);
- }
-
-out:
- return ret;
-}
-
-
-/*******************************************************
-Description:
- Novatek touchscreen driver probe function.
-
-return:
- Executive outcomes. 0---succeed. negative---failed
-*******************************************************/
-static int32_t nvt_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- int32_t ret = 0;
-#if ((TOUCH_KEY_NUM > 0) || WAKEUP_GESTURE)
- int32_t retry = 0;
-#endif
-
- NVT_LOG("start\n");
-
- ts = kmalloc(sizeof(struct nvt_ts_data), GFP_KERNEL);
- if (ts == NULL) {
- NVT_ERR("failed to allocated memory for nvt ts data\n");
- return -ENOMEM;
- }
-
- ts->client = client;
- i2c_set_clientdata(client, ts);
-
- //---parse dts---
- nvt_parse_dt(&client->dev);
-
- //---request and config GPIOs---
- ret = nvt_gpio_config(ts);
- if (ret) {
- NVT_ERR("gpio config error!\n");
- goto err_gpio_config_failed;
- }
-
- //---check i2c func.---
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- NVT_ERR("i2c_check_functionality failed. (no I2C_FUNC_I2C)\n");
- ret = -ENODEV;
- goto err_check_functionality_failed;
- }
-
- // need 10ms delay after POR(power on reset)
- msleep(10);
-
- //---check chip version trim---
- ret = nvt_ts_check_chip_ver_trim();
- if (ret) {
- NVT_ERR("chip is not identified\n");
- ret = -EINVAL;
- goto err_chipvertrim_failed;
- }
-
- mutex_init(&ts->lock);
-
- mutex_lock(&ts->lock);
- nvt_bootloader_reset();
- nvt_check_fw_reset_state(RESET_STATE_INIT);
- nvt_get_fw_info();
- mutex_unlock(&ts->lock);
-
- //---create workqueue---
- nvt_wq = create_workqueue("nvt_wq");
- if (!nvt_wq) {
- NVT_ERR("nvt_wq create workqueue failed\n");
- ret = -ENOMEM;
- goto err_create_nvt_wq_failed;
- }
- INIT_WORK(&ts->nvt_work, nvt_ts_work_func);
-
-
- //---allocate input device---
- ts->input_dev = input_allocate_device();
- if (ts->input_dev == NULL) {
- NVT_ERR("allocate input device failed\n");
- ret = -ENOMEM;
- goto err_input_dev_alloc_failed;
- }
-
- ts->max_touch_num = TOUCH_MAX_FINGER_NUM;
-
-#if TOUCH_KEY_NUM > 0
- ts->max_button_num = TOUCH_KEY_NUM;
-#endif
-
- ts->int_trigger_type = INT_TRIGGER_TYPE;
-
-
- //---set input device info.---
- ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ;
- ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
- ts->input_dev->propbit[0] = BIT(INPUT_PROP_DIRECT);
-
-#if MT_PROTOCOL_B
- input_mt_init_slots(ts->input_dev, ts->max_touch_num, 0);
-#endif
-
- input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, TOUCH_FORCE_NUM, 0, 0); //pressure = TOUCH_FORCE_NUM
-
-#if TOUCH_MAX_FINGER_NUM > 1
- input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); //area = 255
-
- input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0);
- input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0);
-#if MT_PROTOCOL_B
- // no need to set ABS_MT_TRACKING_ID, input_mt_init_slots() already set it
-#else
- input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, ts->max_touch_num, 0, 0);
-#endif //MT_PROTOCOL_B
-#endif //TOUCH_MAX_FINGER_NUM > 1
-
-#if TOUCH_KEY_NUM > 0
- for (retry = 0; retry < ts->max_button_num; retry++) {
- input_set_capability(ts->input_dev, EV_KEY, touch_key_array[retry]);
- }
-#endif
-
-#if WAKEUP_GESTURE
- for (retry = 0; retry < (sizeof(gesture_key_array) / sizeof(gesture_key_array[0])); retry++) {
- input_set_capability(ts->input_dev, EV_KEY, gesture_key_array[retry]);
- }
- wake_lock_init(&gestrue_wakelock, WAKE_LOCK_SUSPEND, "poll-wake-lock");
-#endif
-
- sprintf(ts->phys, "input/ts");
- ts->input_dev->name = NVT_TS_NAME;
- ts->input_dev->phys = ts->phys;
- ts->input_dev->id.bustype = BUS_I2C;
-
- //---register input device---
- ret = input_register_device(ts->input_dev);
- if (ret) {
- NVT_ERR("register input device (%s) failed. ret=%d\n", ts->input_dev->name, ret);
- goto err_input_register_device_failed;
- }
-
- //---set int-pin & request irq---
- client->irq = gpio_to_irq(ts->irq_gpio);
- if (client->irq) {
- NVT_LOG("int_trigger_type=%d\n", ts->int_trigger_type);
-
-#if WAKEUP_GESTURE
- ret = request_irq(client->irq, nvt_ts_irq_handler, ts->int_trigger_type | IRQF_NO_SUSPEND, client->name, ts);
-#else
- ret = request_irq(client->irq, nvt_ts_irq_handler, ts->int_trigger_type, client->name, ts);
-#endif
- if (ret != 0) {
- NVT_ERR("request irq failed. ret=%d\n", ret);
- goto err_int_request_failed;
- } else {
- disable_irq(client->irq);
- NVT_LOG("request irq %d succeed\n", client->irq);
- }
- }
-
-#if BOOT_UPDATE_FIRMWARE
- nvt_fwu_wq = create_singlethread_workqueue("nvt_fwu_wq");
- if (!nvt_fwu_wq) {
- NVT_ERR("nvt_fwu_wq create workqueue failed\n");
- ret = -ENOMEM;
- goto err_create_nvt_fwu_wq_failed;
- }
- INIT_DELAYED_WORK(&ts->nvt_fwu_work, Boot_Update_Firmware);
- // please make sure boot update start after display reset(RESX) sequence
- queue_delayed_work(nvt_fwu_wq, &ts->nvt_fwu_work, msecs_to_jiffies(14000));
-#endif
-
-#if NVT_TOUCH_ESD_PROTECT
- INIT_DELAYED_WORK(&nvt_esd_check_work, nvt_esd_check_func);
- nvt_esd_check_wq = create_workqueue("nvt_esd_check_wq");
- queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work,
- msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD));
-#endif
- //---set device node---
-#if NVT_TOUCH_PROC
- ret = nvt_flash_proc_init();
- if (ret != 0) {
- NVT_ERR("nvt flash proc init failed. ret=%d\n", ret);
- goto err_init_NVT_ts;
- }
-#endif
-
-#if NVT_TOUCH_EXT_PROC
- ret = nvt_extra_proc_init();
- if (ret != 0) {
- NVT_ERR("nvt extra proc init failed. ret=%d\n", ret);
- goto err_init_NVT_ts;
- }
-#endif
-
-#if NVT_TOUCH_FW
- ts->suspended = 0;
- ts->force_reflash = 0;
- ts->loading_fw = 0;
-
- ret = nvt_fw_sysfs_init();
- if (ret != 0) {
- NVT_ERR("nvt fw class init failed. ret=%d\n", ret);
- goto err_init_NVT_ts;
- }
-#endif
-
-#if NVT_TOUCH_MP
- ret = nvt_mp_proc_init();
- if (ret != 0) {
- NVT_ERR("nvt mp proc init failed. ret=%d\n", ret);
- goto err_init_NVT_ts;
- }
-#endif
-
-#if defined(CONFIG_FB)
- ts->fb_notif.notifier_call = fb_notifier_callback;
- ret = fb_register_client(&ts->fb_notif);
- if(ret) {
- NVT_ERR("register fb_notifier failed. ret=%d\n", ret);
- goto err_register_fb_notif_failed;
- }
-#elif defined(CONFIG_HAS_EARLYSUSPEND)
- ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
- ts->early_suspend.suspend = nvt_ts_early_suspend;
- ts->early_suspend.resume = nvt_ts_late_resume;
- ret = register_early_suspend(&ts->early_suspend);
- if(ret) {
- NVT_ERR("register early suspend failed. ret=%d\n", ret);
- goto err_register_early_suspend_failed;
- }
-#endif
-
- bTouchIsAwake = 1;
- NVT_LOG("end\n");
-
- enable_irq(client->irq);
-
- return 0;
-
-#if defined(CONFIG_FB)
-err_register_fb_notif_failed:
-#elif defined(CONFIG_HAS_EARLYSUSPEND)
-err_register_early_suspend_failed:
-#endif
-#if (NVT_TOUCH_PROC || NVT_TOUCH_EXT_PROC || NVT_TOUCH_MP)
-err_init_NVT_ts:
-#endif
- free_irq(client->irq, ts);
-#if BOOT_UPDATE_FIRMWARE
-err_create_nvt_fwu_wq_failed:
-#endif
-err_int_request_failed:
-err_input_register_device_failed:
- input_free_device(ts->input_dev);
-err_input_dev_alloc_failed:
-err_create_nvt_wq_failed:
- mutex_destroy(&ts->lock);
-err_chipvertrim_failed:
-err_check_functionality_failed:
- gpio_free(ts->irq_gpio);
-err_gpio_config_failed:
- i2c_set_clientdata(client, NULL);
- kfree(ts);
- return ret;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen driver release function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t nvt_ts_remove(struct i2c_client *client)
-{
- //struct nvt_ts_data *ts = i2c_get_clientdata(client);
-
-#if defined(CONFIG_FB)
- if (fb_unregister_client(&ts->fb_notif))
- NVT_ERR("Error occurred while unregistering fb_notifier.\n");
-#elif defined(CONFIG_HAS_EARLYSUSPEND)
- unregister_early_suspend(&ts->early_suspend);
-#endif
-
-#if NVT_TOUCH_FW
- nvt_fw_sysfs_deinit();
-#endif
-
- mutex_destroy(&ts->lock);
-
- NVT_LOG("Removing driver...\n");
-
- free_irq(client->irq, ts);
- input_unregister_device(ts->input_dev);
- i2c_set_clientdata(client, NULL);
- kfree(ts);
-
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen driver suspend function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t nvt_ts_suspend(struct device *dev)
-{
- uint8_t buf[4] = {0};
-#if MT_PROTOCOL_B
- uint32_t i = 0;
-#endif
-
- if (!bTouchIsAwake) {
- NVT_LOG("Touch is already suspend\n");
- return 0;
- }
-
- mutex_lock(&ts->lock);
-
- NVT_LOG("start\n");
-#if NVT_TOUCH_FW
- ts->suspended = 1;
-#endif
- bTouchIsAwake = 0;
-#if NVT_TOUCH_ESD_PROTECT
- cancel_delayed_work_sync(&nvt_esd_check_work);
- nvt_esd_check_enable(false);
-#endif
-
-#if WAKEUP_GESTURE
- //---write i2c command to enter "wakeup gesture mode"---
- buf[0] = EVENT_MAP_HOST_CMD;
- buf[1] = 0x13;
-#if 0 // Do not set 0xFF first, ToDo
- buf[2] = 0xFF;
- buf[3] = 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 4);
-#else
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
-#endif
-
- enable_irq_wake(ts->client->irq);
-
- NVT_LOG("Enabled touch wakeup gesture\n");
-
-#else // WAKEUP_GESTURE
-
- disable_irq(ts->client->irq);
-
- //---write i2c command to enter "deep sleep mode"---
- buf[0] = EVENT_MAP_HOST_CMD;
- buf[1] = 0x11;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
-#endif // WAKEUP_GESTURE
-
- /* release all touches */
-#if MT_PROTOCOL_B
- for (i = 0; i < ts->max_touch_num; i++) {
- input_mt_slot(ts->input_dev, i);
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0);
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
- }
-#endif
- input_report_key(ts->input_dev, BTN_TOUCH, 0);
-#if !MT_PROTOCOL_B
- input_mt_sync(ts->input_dev);
-#endif
- input_sync(ts->input_dev);
-
- msleep(50);
-
- mutex_unlock(&ts->lock);
-
- NVT_LOG("end\n");
-
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen driver resume function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t nvt_ts_resume(struct device *dev)
-{
- int res = 0;
-
- if (bTouchIsAwake) {
- NVT_LOG("Touch is already resume\n");
- return 0;
- }
-
- msleep(10);
-
- mutex_lock(&ts->lock);
-
- NVT_LOG("start\n");
- // please make sure display reset(RESX) sequence and mipi dsi cmds sent before this
-#if NVT_TOUCH_SUPPORT_HW_RST
- gpio_set_value(ts->reset_gpio, 1);
-#endif
- nvt_bootloader_reset();
- res = nvt_check_fw_reset_state(RESET_STATE_REK);
-
- NVT_ERR("xlixiang---enter-%s-----res=%d\n", __func__, res);
-
-#if !WAKEUP_GESTURE
- enable_irq(ts->client->irq);
-#endif
-
-#if NVT_TOUCH_ESD_PROTECT
- queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work,
- msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD));
-#endif
- bTouchIsAwake = 1;
-#if NVT_TOUCH_FW
- ts->suspended = 0;
-#endif
-
- mutex_unlock(&ts->lock);
-
- NVT_LOG("end\n");
-
- return 0;
-}
-
-
-#if defined(CONFIG_FB)
-static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data)
-{
- struct fb_event *evdata = data;
- int *blank;
- struct nvt_ts_data *ts =
- container_of(self, struct nvt_ts_data, fb_notif);
-
- if (evdata && evdata->data && event == FB_EARLY_EVENT_BLANK) {
- blank = evdata->data;
- if (*blank == FB_BLANK_POWERDOWN) {
- nvt_ts_suspend(&ts->client->dev);
- }
- } else if (evdata && evdata->data && event == FB_EVENT_BLANK) {
- blank = evdata->data;
- if (*blank == FB_BLANK_UNBLANK ||
- (*blank == FB_BLANK_NORMAL && 0 == bTouchIsAwake)) {
- nvt_ts_resume(&ts->client->dev);
- }
- }
-
- return 0;
-}
-#elif defined(CONFIG_HAS_EARLYSUSPEND)
-/*******************************************************
-Description:
- Novatek touchscreen driver early suspend function.
-
-return:
- n.a.
-*******************************************************/
-static void nvt_ts_early_suspend(struct early_suspend *h)
-{
- nvt_ts_suspend(ts->client, PMSG_SUSPEND);
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen driver late resume function.
-
-return:
- n.a.
-*******************************************************/
-static void nvt_ts_late_resume(struct early_suspend *h)
-{
- nvt_ts_resume(ts->client);
-}
-#endif
-
-#if 0
-static const struct dev_pm_ops nvt_ts_dev_pm_ops = {
- .suspend = nvt_ts_suspend,
- .resume = nvt_ts_resume,
-};
-#endif
-
-static const struct i2c_device_id nvt_ts_id[] = {
- { NVT_I2C_NAME, 0 },
- { }
-};
-
-#ifdef CONFIG_OF
-static struct of_device_id nvt_match_table[] = {
- { .compatible = "novatek,NVT-ts",},
- { },
-};
-#endif
-/*
-static struct i2c_board_info __initdata nvt_i2c_boardinfo[] = {
- {
- I2C_BOARD_INFO(NVT_I2C_NAME, I2C_FW_Address),
- },
-};
-*/
-
-static struct i2c_driver nvt_i2c_driver = {
- .probe = nvt_ts_probe,
- .remove = nvt_ts_remove,
-// .suspend = nvt_ts_suspend,
-// .resume = nvt_ts_resume,
- .id_table = nvt_ts_id,
- .driver = {
- .name = NVT_I2C_NAME,
- .owner = THIS_MODULE,
-#if 0
-#ifdef CONFIG_PM
- .pm = &nvt_ts_dev_pm_ops,
-#endif
-#endif
-#ifdef CONFIG_OF
- .of_match_table = nvt_match_table,
-#endif
- },
-};
-
-/*******************************************************
-Description:
- Driver Install function.
-
-return:
- Executive Outcomes. 0---succeed. not 0---failed.
-********************************************************/
-static int32_t __init nvt_driver_init(void)
-{
- int32_t ret = 0;
-
- NVT_LOG("start\n");
- //---add i2c driver---
- ret = i2c_add_driver(&nvt_i2c_driver);
- if (ret) {
- pr_err("%s: failed to add i2c driver", __func__);
- goto err_driver;
- }
-
- pr_info("%s: finished\n", __func__);
-
-err_driver:
- return ret;
-}
-
-/*******************************************************
-Description:
- Driver uninstall function.
-
-return:
- n.a.
-********************************************************/
-static void __exit nvt_driver_exit(void)
-{
- i2c_del_driver(&nvt_i2c_driver);
-
- if (nvt_wq)
- destroy_workqueue(nvt_wq);
-
-#if BOOT_UPDATE_FIRMWARE
- if (nvt_fwu_wq)
- destroy_workqueue(nvt_fwu_wq);
-#endif
-#if NVT_TOUCH_ESD_PROTECT
- if (nvt_esd_check_wq)
- destroy_workqueue(nvt_esd_check_wq);
-#endif
-
-}
-
-//late_initcall(nvt_driver_init);
-module_init(nvt_driver_init);
-module_exit(nvt_driver_exit);
-
-MODULE_DESCRIPTION("Novatek Touchscreen Driver");
-MODULE_LICENSE("GPL");
+++ /dev/null
-/*
- * Copyright (C) 2010 - 2017 Novatek, Inc.
- *
- * $Revision: 22971 $
- * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-#ifndef _LINUX_NVT_TOUCH_H
-#define _LINUX_NVT_TOUCH_H
-
-#include <linux/i2c.h>
-#include <linux/input.h>
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif
-
-#include "nt36xxx_mem_map.h"
-
-#define NVT_DEBUG 1
-
-//---GPIO number---
-#define NVTTOUCH_RST_PIN 980
-#define NVTTOUCH_INT_PIN 943
-
-
-//---INT trigger mode---
-//#define IRQ_TYPE_EDGE_RISING 1
-//#define IRQ_TYPE_EDGE_FALLING 2
-#define INT_TRIGGER_TYPE IRQ_TYPE_EDGE_RISING
-
-
-//---I2C driver info.---
-#define NVT_I2C_NAME "NVT-ts"
-#define I2C_BLDR_Address 0x01
-#define I2C_FW_Address 0x01
-#define I2C_HW_Address 0x62
-
-#if NVT_DEBUG
-#define NVT_LOG(fmt, args...) pr_err("[%s] %s %d: " fmt, NVT_I2C_NAME, __func__, __LINE__, ##args)
-#else
-#define NVT_LOG(fmt, args...) pr_info("[%s] %s %d: " fmt, NVT_I2C_NAME, __func__, __LINE__, ##args)
-#endif
-#define NVT_ERR(fmt, args...) pr_err("[%s] %s %d: " fmt, NVT_I2C_NAME, __func__, __LINE__, ##args)
-
-//---Input device info.---
-#define NVT_TS_NAME "NVTCapacitiveTouchScreen"
-
-
-//---Touch info.---
-#define TOUCH_DEFAULT_MAX_WIDTH 1080
-#define TOUCH_DEFAULT_MAX_HEIGHT 2246
-#define TOUCH_MAX_FINGER_NUM 10
-#define TOUCH_KEY_NUM 0
-#if TOUCH_KEY_NUM > 0
-extern const uint16_t touch_key_array[TOUCH_KEY_NUM];
-#endif
-#define TOUCH_FORCE_NUM 1000
-
-/* Enable only when module have tp reset pin and connected to host */
-#define NVT_TOUCH_SUPPORT_HW_RST 1
-
-//---Customerized func.---
-#define NVT_TOUCH_PROC 1
-#define NVT_TOUCH_EXT_PROC 1
-#define NVT_TOUCH_FW 1
-#define NVT_TOUCH_MP 1
-#define NVT_TOUCH_MP_LENOVO 1
-#define MT_PROTOCOL_B 1
-#define WAKEUP_GESTURE 0
-#if WAKEUP_GESTURE
-extern const uint16_t gesture_key_array[];
-#endif
-#define BOOT_UPDATE_FIRMWARE 0
-#define BOOT_UPDATE_FIRMWARE_NAME "novatek_ts_fw.bin"
-/* ---ESD Protect.--- */
-#define NVT_TOUCH_ESD_PROTECT 1
-#define NVT_TOUCH_ESD_CHECK_PERIOD 2000 /* ms */
-
-struct nvt_ts_data {
- struct i2c_client *client;
- struct input_dev *input_dev;
- struct work_struct nvt_work;
- struct delayed_work nvt_fwu_work;
- uint16_t addr;
- int8_t phys[32];
-#if defined(CONFIG_FB)
- struct notifier_block fb_notif;
-#elif defined(CONFIG_HAS_EARLYSUSPEND)
- struct early_suspend early_suspend;
-#endif
- uint8_t fw_ver;
- uint8_t x_num;
- uint8_t y_num;
- uint16_t abs_x_max;
- uint16_t abs_y_max;
- uint8_t max_touch_num;
- uint8_t max_button_num;
- uint32_t int_trigger_type;
- int32_t irq_gpio;
- uint32_t irq_flags;
- int32_t reset_gpio;
- uint32_t reset_flags;
- struct mutex lock;
- const struct nvt_ts_mem_map *mmap;
- uint8_t carrier_system;
- uint16_t nvt_pid;
-#if NVT_TOUCH_FW
- int8_t product_id[10];
- uint8_t suspended;
- uint8_t force_reflash;
- uint8_t loading_fw;
-#endif
-};
-
-#if NVT_TOUCH_FW
-#define FW_NAME_MAX_LEN 80
-#define VENDOR_NAME "novatek_ts"
-#endif
-
-#if NVT_TOUCH_PROC
-struct nvt_flash_data{
- rwlock_t lock;
- struct i2c_client *client;
-};
-#endif
-
-typedef enum {
- RESET_STATE_INIT = 0xA0,// IC reset
- RESET_STATE_REK, // ReK baseline
- RESET_STATE_REK_FINISH, // baseline is ready
- RESET_STATE_NORMAL_RUN,
- RESET_STATE_MAX = 0xAF
-} RST_COMPLETE_STATE;
-
-typedef enum {
- EVENT_MAP_HOST_CMD = 0x50,
- EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE = 0x51,
- EVENT_MAP_RESET_COMPLETE = 0x60,
- EVENT_MAP_FWINFO = 0x78,
- EVENT_MAP_PROJECTID = 0x9A,
- EVENT_MAP_FWDATE = 0x9C,
-} I2C_EVENT_MAP;
-
-#if NVT_TOUCH_MP_LENOVO
-typedef enum {
- MP_RESULT_SHIFT_SHORT = 0x00,
- MP_RESULT_SHIFT_SHORT_DIFF,
- MP_RESULT_SHIFT_SHORT_BASE,
- MP_RESULT_SHIFT_OPEN,
- MP_RESULT_SHIFT_RAWDATA,
- MP_RESULT_SHIFT_CC,
- MP_RESULT_SHIFT_CC_I,
- MP_RESULT_SHIFT_CC_Q,
- MP_RESULT_SHIFT_NOISE,
- MP_RESULT_SHIFT_DIFF_MAX,
- MP_RESULT_SHIFT_DIFF_MIN,
-/* MP_RESULT_SHIFT_READFAIL,*/
-} MP_TEST_RESULT;
-#endif
-
-//---extern structures---
-extern struct nvt_ts_data *ts;
-
-//---extern functions---
-extern int32_t CTP_I2C_READ(struct i2c_client *client, uint16_t address, uint8_t *buf, uint16_t len);
-extern int32_t CTP_I2C_WRITE(struct i2c_client *client, uint16_t address, uint8_t *buf, uint16_t len);
-extern void nvt_bootloader_reset(void);
-extern void nvt_sw_reset_idle(void);
-extern int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state);
-extern int32_t nvt_get_fw_info(void);
-extern int32_t nvt_clear_fw_status(void);
-extern int32_t nvt_check_fw_status(void);
-
-#if NVT_TOUCH_ESD_PROTECT
-extern void nvt_esd_check_enable(uint8_t enable);
-#endif
-extern void nvt_stop_crc_reboot(void);
-
-#endif /* _LINUX_NVT_TOUCH_H */
+++ /dev/null
-/*
- * Copyright (C) 2010 - 2017 Novatek, Inc.
- *
- * $Revision: 22971 $
- * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/delay.h>
-
-#include "nt36xxx.h"
-
-#if NVT_TOUCH_EXT_PROC
-#define NVT_FW_VERSION "nvt_fw_version"
-#define NVT_BASELINE "nvt_baseline"
-#define NVT_RAW "nvt_raw"
-#define NVT_DIFF "nvt_diff"
-
-#define I2C_TANSFER_LENGTH 64
-
-#define NORMAL_MODE 0x00
-#define TEST_MODE_1 0x21
-#define TEST_MODE_2 0x22
-#define HANDSHAKING_HOST_READY 0xBB
-
-#define XDATA_SECTOR_SIZE 256
-#define XDATA_BUF_SIZE 2048
-
-static uint8_t xdata_tmp[XDATA_BUF_SIZE] = {0};
-static int32_t xdata[XDATA_BUF_SIZE] = {0};
-static int32_t xdata_i[XDATA_BUF_SIZE] = {0};
-static int32_t xdata_q[XDATA_BUF_SIZE] = {0};
-
-static struct proc_dir_entry *NVT_proc_fw_version_entry;
-static struct proc_dir_entry *NVT_proc_baseline_entry;
-static struct proc_dir_entry *NVT_proc_raw_entry;
-static struct proc_dir_entry *NVT_proc_diff_entry;
-
-/*******************************************************
-Description:
- Novatek touchscreen change mode function.
-
-return:
- n.a.
-*******************************************************/
-void nvt_change_mode(uint8_t mode)
-{
- uint8_t buf[8] = {0};
-
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---set mode---
- buf[0] = EVENT_MAP_HOST_CMD;
- buf[1] = mode;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
-
- if (mode == NORMAL_MODE) {
- buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
- buf[1] = HANDSHAKING_HOST_READY;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
- msleep(20);
- }
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen get firmware pipe function.
-
-return:
- Executive outcomes. 0---pipe 0. 1---pipe 1.
-*******************************************************/
-uint8_t nvt_get_fw_pipe(void)
-{
- uint8_t buf[8]= {0};
-
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---read fw status---
- buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
- buf[1] = 0x00;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
-
- //NVT_LOG("FW pipe=%d, buf[1]=0x%02X\n", (buf[1]&0x01), buf[1]);
-
- return (buf[1] & 0x01);
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen read mass data function.
-
-return:
- n.a.
-*******************************************************/
-int32_t nvt_read_mass_data(uint8_t i2c_addr, uint8_t *temp_buf, uint32_t count)
-{
- int32_t i = 0;
- int32_t j = 0;
- int32_t k = 0;
- uint8_t i2c_buf[I2C_TANSFER_LENGTH + 1] = {0};
- uint32_t xdata_addr = 0;
- uint32_t head_addr = 0;
- int32_t dummy_len = 0;
- int32_t data_len = 0;
- int32_t residual_len = 0;
-
- xdata_addr = (temp_buf[3] << 24) + (temp_buf[4] << 16) + (temp_buf[5] << 8) + temp_buf[6];
- head_addr = xdata_addr - (xdata_addr % XDATA_SECTOR_SIZE);
- dummy_len = xdata_addr - head_addr;
- data_len = (int32_t)((temp_buf[1] << 8) + temp_buf[2]);
- residual_len = (head_addr + dummy_len + data_len) % XDATA_SECTOR_SIZE;
-
- if (data_len > XDATA_BUF_SIZE)
- return -EINVAL;
-
- for (i = 0; i < ((dummy_len + data_len) / XDATA_SECTOR_SIZE); i++) {
- i2c_buf[0] = 0xFF;
- i2c_buf[1] = ((head_addr + XDATA_SECTOR_SIZE * i) >> 16) & 0xFF;
- i2c_buf[2] = ((head_addr + XDATA_SECTOR_SIZE * i) >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, (uint16_t)i2c_addr, i2c_buf, 3);
- for (j = 0; j < (XDATA_SECTOR_SIZE / I2C_TANSFER_LENGTH); j++) {
- i2c_buf[0] = I2C_TANSFER_LENGTH * j;
- CTP_I2C_READ(ts->client, (uint16_t)i2c_addr, i2c_buf, I2C_TANSFER_LENGTH + 1);
- for (k = 0; k < I2C_TANSFER_LENGTH; k++) {
- xdata_tmp[XDATA_SECTOR_SIZE * i + I2C_TANSFER_LENGTH * j + k] = i2c_buf[k + 1];
- }
- }
- }
-
- if (residual_len != 0) {
- i2c_buf[0] = 0xFF;
- i2c_buf[1] = ((xdata_addr + data_len - residual_len) >> 16) & 0xFF;
- i2c_buf[2] = ((xdata_addr + data_len - residual_len) >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, (uint16_t)i2c_addr, i2c_buf, 3);
- for (j = 0; j < (residual_len / I2C_TANSFER_LENGTH + 1); j++) {
- i2c_buf[0] = I2C_TANSFER_LENGTH * j;
- CTP_I2C_READ(ts->client, (uint16_t)i2c_addr, i2c_buf, I2C_TANSFER_LENGTH + 1);
- for (k = 0; k < I2C_TANSFER_LENGTH; k++) {
- xdata_tmp[(dummy_len + data_len - residual_len) + I2C_TANSFER_LENGTH * j + k] = i2c_buf[k + 1];
- }
- }
- }
-
- i2c_buf[0] = 0xFF;
- i2c_buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- i2c_buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, (uint16_t)i2c_addr, i2c_buf, 3);
-
- for (i = 0; i < data_len; i++) {
- *(temp_buf + i) = xdata_tmp[dummy_len + i];
- }
-
- return data_len;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen read meta data function.
-
-return:
- n.a.
-*******************************************************/
-void nvt_read_mdata(uint32_t xdata_addr, uint32_t xdata_btn_addr)
-{
- int32_t i = 0;
- int32_t j = 0;
- int32_t k = 0;
- uint8_t buf[I2C_TANSFER_LENGTH + 1] = {0};
- uint32_t head_addr = 0;
- int32_t dummy_len = 0;
- int32_t data_len = 0;
- int32_t residual_len = 0;
-
- //---set xdata sector address & length---
- head_addr = xdata_addr - (xdata_addr % XDATA_SECTOR_SIZE);
- dummy_len = xdata_addr - head_addr;
- data_len = ts->x_num * ts->y_num * 2;
- residual_len = (head_addr + dummy_len + data_len) % XDATA_SECTOR_SIZE;
-
- //printk("head_addr=0x%05X, dummy_len=0x%05X, data_len=0x%05X, residual_len=0x%05X\n", head_addr, dummy_len, data_len, residual_len);
-
- //read xdata : step 1
- for (i = 0; i < ((dummy_len + data_len) / XDATA_SECTOR_SIZE); i++) {
- //---change xdata index---
- buf[0] = 0xFF;
- buf[1] = ((head_addr + XDATA_SECTOR_SIZE * i) >> 16) & 0xFF;
- buf[2] = ((head_addr + XDATA_SECTOR_SIZE * i) >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---read xdata by I2C_TANSFER_LENGTH
- for (j = 0; j < (XDATA_SECTOR_SIZE / I2C_TANSFER_LENGTH); j++) {
- //---read data---
- buf[0] = I2C_TANSFER_LENGTH * j;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, I2C_TANSFER_LENGTH + 1);
-
- //---copy buf to xdata_tmp---
- for (k = 0; k < I2C_TANSFER_LENGTH; k++) {
- xdata_tmp[XDATA_SECTOR_SIZE * i + I2C_TANSFER_LENGTH * j + k] = buf[k + 1];
- //printk("0x%02X, 0x%04X\n", buf[k+1], (XDATA_SECTOR_SIZE*i + I2C_TANSFER_LENGTH*j + k));
- }
- }
- //printk("addr=0x%05X\n", (head_addr+XDATA_SECTOR_SIZE*i));
- }
-
- //read xdata : step2
- if (residual_len != 0) {
- //---change xdata index---
- buf[0] = 0xFF;
- buf[1] = ((xdata_addr + data_len - residual_len) >> 16) & 0xFF;
- buf[2] = ((xdata_addr + data_len - residual_len) >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---read xdata by I2C_TANSFER_LENGTH
- for (j = 0; j < (residual_len / I2C_TANSFER_LENGTH + 1); j++) {
- //---read data---
- buf[0] = I2C_TANSFER_LENGTH * j;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, I2C_TANSFER_LENGTH + 1);
-
- //---copy buf to xdata_tmp---
- for (k = 0; k < I2C_TANSFER_LENGTH; k++) {
- xdata_tmp[(dummy_len + data_len - residual_len) + I2C_TANSFER_LENGTH * j + k] = buf[k + 1];
- //printk("0x%02X, 0x%04x\n", buf[k+1], ((dummy_len+data_len-residual_len) + I2C_TANSFER_LENGTH*j + k));
- }
- }
- //printk("addr=0x%05X\n", (xdata_addr+data_len-residual_len));
- }
-
- //---remove dummy data and 2bytes-to-1data---
- for (i = 0; i < (data_len / 2); i++) {
- xdata[i] = (int16_t)(xdata_tmp[dummy_len + i * 2] + 256 * xdata_tmp[dummy_len + i * 2 + 1]);
- }
-
-#if TOUCH_KEY_NUM > 0
- //read button xdata : step3
- //---change xdata index---
- buf[0] = 0xFF;
- buf[1] = (xdata_btn_addr >> 16) & 0xFF;
- buf[2] = ((xdata_btn_addr >> 8) & 0xFF);
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---read data---
- buf[0] = (xdata_btn_addr & 0xFF);
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, (TOUCH_KEY_NUM * 2 + 1));
-
- //---2bytes-to-1data---
- for (i = 0; i < TOUCH_KEY_NUM; i++) {
- xdata[ts->x_num * ts->y_num + i] = (int16_t)(buf[1 + i * 2] + 256 * buf[1 + i * 2 + 1]);
- }
-#endif
-
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen read meta data from IQ to rss function.
-
-return:
- n.a.
-*******************************************************/
-void nvt_read_mdata_rss(uint32_t xdata_i_addr, uint32_t xdata_q_addr, uint32_t xdata_btn_i_addr, uint32_t xdata_btn_q_addr)
-{
- int i = 0;
-
- nvt_read_mdata(xdata_i_addr, xdata_btn_i_addr);
- memcpy(xdata_i, xdata, ((ts->x_num * ts->y_num + TOUCH_KEY_NUM) * sizeof(int32_t)));
-
- nvt_read_mdata(xdata_q_addr, xdata_btn_q_addr);
- memcpy(xdata_q, xdata, ((ts->x_num * ts->y_num + TOUCH_KEY_NUM) * sizeof(int32_t)));
-
- for (i = 0; i < (ts->x_num * ts->y_num + TOUCH_KEY_NUM); i++) {
- xdata[i] = (int32_t)int_sqrt((unsigned long)(xdata_i[i] * xdata_i[i]) + (unsigned long)(xdata_q[i] * xdata_q[i]));
- }
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen get meta data function.
-
-return:
- n.a.
-*******************************************************/
-void nvt_get_mdata(int32_t *buf, uint8_t *m_x_num, uint8_t *m_y_num)
-{
- *m_x_num = ts->x_num;
- *m_y_num = ts->y_num;
- memcpy(buf, xdata, ((ts->x_num * ts->y_num + TOUCH_KEY_NUM) * sizeof(int32_t)));
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen firmware version show function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t c_fw_version_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "fw_ver=%d, x_num=%d, y_num=%d, button_num=%d\n", ts->fw_ver, ts->x_num, ts->y_num, ts->max_button_num);
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen xdata sequence print show
- function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t c_show(struct seq_file *m, void *v)
-{
- int32_t i = 0;
- int32_t j = 0;
-
- for (i = 0; i < ts->y_num; i++) {
- for (j = 0; j < ts->x_num; j++) {
- seq_printf(m, "%5d, ", xdata[i * ts->x_num + j]);
- }
- seq_puts(m, "\n");
- }
-
-#if TOUCH_KEY_NUM > 0
- for (i = 0; i < TOUCH_KEY_NUM; i++) {
- seq_printf(m, "%5d, ", xdata[ts->x_num * ts->y_num + i]);
- }
- seq_puts(m, "\n");
-#endif
-
- seq_printf(m, "\n\n");
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen xdata sequence print start
- function.
-
-return:
- Executive outcomes. 1---call next function.
- NULL---not call next function and sequence loop
- stop.
-*******************************************************/
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
- return *pos < 1 ? (void *)1 : NULL;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen xdata sequence print next
- function.
-
-return:
- Executive outcomes. NULL---no next and call sequence
- stop function.
-*******************************************************/
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
- ++*pos;
- return NULL;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen xdata sequence print stop
- function.
-
-return:
- n.a.
-*******************************************************/
-static void c_stop(struct seq_file *m, void *v)
-{
- return;
-}
-
-const struct seq_operations nvt_fw_version_seq_ops = {
- .start = c_start,
- .next = c_next,
- .stop = c_stop,
- .show = c_fw_version_show
-};
-
-const struct seq_operations nvt_seq_ops = {
- .start = c_start,
- .next = c_next,
- .stop = c_stop,
- .show = c_show
-};
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/nvt_fw_version open
- function.
-
-return:
- n.a.
-*******************************************************/
-static int32_t nvt_info_open(struct inode *inode, struct file *file)
-{
- if (mutex_lock_interruptible(&ts->lock)) {
- return -ERESTARTSYS;
- }
-
- NVT_LOG("++\n");
-#if NVT_TOUCH_ESD_PROTECT
- nvt_esd_check_enable(false);
-#endif
- if (nvt_get_fw_info()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- mutex_unlock(&ts->lock);
-
- NVT_LOG("--\n");
-
- return seq_open(file, &nvt_fw_version_seq_ops);
-}
-
-static const struct file_operations nvt_info_proc_fops = {
- .owner = THIS_MODULE,
- .open = nvt_info_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static int32_t nvt_fw_version_open(struct inode *inode, struct file *file)
-{
- if (mutex_lock_interruptible(&ts->lock)) {
- return -ERESTARTSYS;
- }
-
- NVT_LOG("++\n");
-#if NVT_TOUCH_ESD_PROTECT
- nvt_esd_check_enable(false);
-#endif
- if (nvt_get_fw_info()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- mutex_unlock(&ts->lock);
-
- NVT_LOG("--\n");
-
- return seq_open(file, &nvt_fw_version_seq_ops);
-}
-
-static const struct file_operations nvt_fw_version_fops = {
- .owner = THIS_MODULE,
- .open = nvt_fw_version_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/nvt_baseline open function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t nvt_baseline_open(struct inode *inode, struct file *file)
-{
- if (mutex_lock_interruptible(&ts->lock)) {
- return -ERESTARTSYS;
- }
-
- NVT_LOG("++\n");
-#if NVT_TOUCH_ESD_PROTECT
- nvt_esd_check_enable(false);
-#endif
- if (nvt_clear_fw_status()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- nvt_change_mode(TEST_MODE_2);
-
- if (nvt_check_fw_status()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- if (nvt_get_fw_info()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- if (ts->carrier_system) {
- nvt_read_mdata_rss(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_Q_ADDR,
- ts->mmap->BASELINE_BTN_ADDR, ts->mmap->BASELINE_BTN_Q_ADDR);
- } else {
- nvt_read_mdata(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_BTN_ADDR);
- }
-
- nvt_change_mode(NORMAL_MODE);
-
- mutex_unlock(&ts->lock);
-
- NVT_LOG("--\n");
-
- return seq_open(file, &nvt_seq_ops);
-}
-
-static const struct file_operations nvt_baseline_fops = {
- .owner = THIS_MODULE,
- .open = nvt_baseline_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/nvt_raw open function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t nvt_raw_open(struct inode *inode, struct file *file)
-{
- if (mutex_lock_interruptible(&ts->lock)) {
- return -ERESTARTSYS;
- }
-
- NVT_LOG("++\n");
-#if NVT_TOUCH_ESD_PROTECT
- nvt_esd_check_enable(false);
-#endif
- if (nvt_clear_fw_status()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- nvt_change_mode(TEST_MODE_2);
-
- if (nvt_check_fw_status()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- if (nvt_get_fw_info()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- if (ts->carrier_system) {
- if (nvt_get_fw_pipe() == 0)
- nvt_read_mdata_rss(ts->mmap->RAW_PIPE0_ADDR, ts->mmap->RAW_PIPE0_Q_ADDR,
- ts->mmap->RAW_BTN_PIPE0_ADDR, ts->mmap->RAW_BTN_PIPE0_Q_ADDR);
- else
- nvt_read_mdata_rss(ts->mmap->RAW_PIPE1_ADDR, ts->mmap->RAW_PIPE1_Q_ADDR,
- ts->mmap->RAW_BTN_PIPE1_ADDR, ts->mmap->RAW_BTN_PIPE1_Q_ADDR);
- } else {
- if (nvt_get_fw_pipe() == 0)
- nvt_read_mdata(ts->mmap->RAW_PIPE0_ADDR, ts->mmap->RAW_BTN_PIPE0_ADDR);
- else
- nvt_read_mdata(ts->mmap->RAW_PIPE1_ADDR, ts->mmap->RAW_BTN_PIPE1_ADDR);
- }
-
- nvt_change_mode(NORMAL_MODE);
-
- mutex_unlock(&ts->lock);
-
- NVT_LOG("--\n");
-
- return seq_open(file, &nvt_seq_ops);
-}
-
-static const struct file_operations nvt_raw_fops = {
- .owner = THIS_MODULE,
- .open = nvt_raw_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/nvt_diff open function.
-
-return:
- Executive outcomes. 0---succeed. negative---failed.
-*******************************************************/
-static int32_t nvt_diff_open(struct inode *inode, struct file *file)
-{
- if (mutex_lock_interruptible(&ts->lock)) {
- return -ERESTARTSYS;
- }
-
- NVT_LOG("++\n");
-#if NVT_TOUCH_ESD_PROTECT
- nvt_esd_check_enable(false);
-#endif
- if (nvt_clear_fw_status()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- nvt_change_mode(TEST_MODE_2);
-
- if (nvt_check_fw_status()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- if (nvt_get_fw_info()) {
- mutex_unlock(&ts->lock);
- return -EAGAIN;
- }
-
- if (ts->carrier_system) {
- if (nvt_get_fw_pipe() == 0)
- nvt_read_mdata_rss(ts->mmap->DIFF_PIPE0_ADDR, ts->mmap->DIFF_PIPE0_Q_ADDR,
- ts->mmap->DIFF_BTN_PIPE0_ADDR, ts->mmap->DIFF_BTN_PIPE0_Q_ADDR);
- else
- nvt_read_mdata_rss(ts->mmap->DIFF_PIPE1_ADDR, ts->mmap->DIFF_PIPE1_Q_ADDR,
- ts->mmap->DIFF_BTN_PIPE1_ADDR, ts->mmap->DIFF_BTN_PIPE1_Q_ADDR);
- } else {
- if (nvt_get_fw_pipe() == 0)
- nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, ts->mmap->DIFF_BTN_PIPE0_ADDR);
- else
- nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, ts->mmap->DIFF_BTN_PIPE1_ADDR);
- }
-
- nvt_change_mode(NORMAL_MODE);
-
- mutex_unlock(&ts->lock);
-
- NVT_LOG("--\n");
-
- return seq_open(file, &nvt_seq_ops);
-}
-
-static const struct file_operations nvt_diff_fops = {
- .owner = THIS_MODULE,
- .open = nvt_diff_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-/*******************************************************
-Description:
- Novatek touchscreen extra function proc. file node
- initial function.
-
-return:
- Executive outcomes. 0---succeed. -12---failed.
-*******************************************************/
-int32_t nvt_extra_proc_init(void)
-{
- NVT_proc_fw_version_entry = proc_create(NVT_FW_VERSION, 0444, NULL,&nvt_fw_version_fops);
- if (NVT_proc_fw_version_entry == NULL) {
- NVT_ERR("create proc/nvt_fw_version Failed!\n");
- return -ENOMEM;
- } else {
- NVT_LOG("create proc/nvt_fw_version Succeeded!\n");
- }
-
- NVT_proc_baseline_entry = proc_create(NVT_BASELINE, 0444, NULL,&nvt_baseline_fops);
- if (NVT_proc_baseline_entry == NULL) {
- NVT_ERR("create proc/nvt_baseline Failed!\n");
- return -ENOMEM;
- } else {
- NVT_LOG("create proc/nvt_baseline Succeeded!\n");
- }
-
- NVT_proc_raw_entry = proc_create(NVT_RAW, 0444, NULL,&nvt_raw_fops);
- if (NVT_proc_raw_entry == NULL) {
- NVT_ERR("create proc/nvt_raw Failed!\n");
- return -ENOMEM;
- } else {
- NVT_LOG("create proc/nvt_raw Succeeded!\n");
- }
-
- NVT_proc_diff_entry = proc_create(NVT_DIFF, 0444, NULL,&nvt_diff_fops);
- if (NVT_proc_diff_entry == NULL) {
- NVT_ERR("create proc/nvt_diff Failed!\n");
- return -ENOMEM;
- } else {
- NVT_LOG("create proc/nvt_diff Succeeded!\n");
- }
-
- return 0;
-}
-#endif
+++ /dev/null
-/*
- * Copyright (C) 2010 - 2017 Novatek, Inc.
- *
- * $Revision: 22971 $
- * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#include <linux/delay.h>
-#include <linux/firmware.h>
-
-#include "nt36xxx.h"
-
-#if (BOOT_UPDATE_FIRMWARE || NVT_TOUCH_FW)
-
-#define FW_BIN_SIZE_116KB 118784
-#define FW_BIN_SIZE FW_BIN_SIZE_116KB
-#define FW_BIN_VER_OFFSET 0x1A000
-#define FW_BIN_VER_BAR_OFFSET 0x1A001
-#define FLASH_SECTOR_SIZE 4096
-#define SIZE_64KB 65536
-#define BLOCK_64KB_NUM 4
-
-const struct firmware *fw_entry = NULL;
-
-/*******************************************************
-Description:
- Novatek touchscreen request update firmware function.
-
-return:
- Executive outcomes. 0---succeed. -1,-22---failed.
-*******************************************************/
-int32_t update_firmware_request(char *filename)
-{
- int32_t ret = 0;
-
- if (NULL == filename) {
- return -1;
- }
-
- NVT_LOG("filename is %s\n", filename);
-
- ret = request_firmware(&fw_entry, filename, &ts->client->dev);
- if (ret) {
- NVT_ERR("firmware load failed, ret=%d\n", ret);
- return ret;
- }
-
- // check bin file size (116kb)
- if (fw_entry->size != FW_BIN_SIZE) {
- NVT_ERR("bin file size not match. (%zu)\n", fw_entry->size);
- return -EINVAL;
- }
-
- // check if FW version add FW version bar equals 0xFF
- if (*(fw_entry->data + FW_BIN_VER_OFFSET) + *(fw_entry->data + FW_BIN_VER_BAR_OFFSET) != 0xFF) {
- NVT_ERR("bin file FW_VER + FW_VER_BAR should be 0xFF!\n");
- NVT_ERR("FW_VER=0x%02X, FW_VER_BAR=0x%02X\n", *(fw_entry->data+FW_BIN_VER_OFFSET), *(fw_entry->data+FW_BIN_VER_BAR_OFFSET));
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen release update firmware function.
-
-return:
- n.a.
-*******************************************************/
-void update_firmware_release(void)
-{
- if (fw_entry) {
- release_firmware(fw_entry);
- }
- fw_entry=NULL;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen check firmware version function.
-
-return:
- Executive outcomes. 0---need update. 1---need not
- update.
-*******************************************************/
-int32_t Check_FW_Ver(void)
-{
- uint8_t buf[16] = {0};
- int32_t ret = 0;
-
- //write i2c index to EVENT BUF ADDR
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("i2c write error!(%d)\n", ret);
- return ret;
- }
-
- //read Firmware Version
- buf[0] = EVENT_MAP_FWINFO;
- buf[1] = 0x00;
- buf[2] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("i2c read error!(%d)\n", ret);
- return ret;
- }
-
- NVT_LOG("IC FW Ver = 0x%02X, FW Ver Bar = 0x%02X\n", buf[1], buf[2]);
- NVT_LOG("Bin FW Ver = 0x%02X, FW ver Bar = 0x%02X\n",
- fw_entry->data[FW_BIN_VER_OFFSET], fw_entry->data[FW_BIN_VER_BAR_OFFSET]);
-
- // check IC FW_VER + FW_VER_BAR equals 0xFF or not, need to update if not
- if ((buf[1] + buf[2]) != 0xFF) {
- NVT_ERR("IC FW_VER + FW_VER_BAR not equals to 0xFF!\n");
- return 0;
- }
-
- // compare IC and binary FW version
- if (buf[1] > fw_entry->data[FW_BIN_VER_OFFSET])
- return 1;
- else
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen resume from deep power down function.
-
-return:
- Executive outcomes. 0---succeed. negative---failed.
-*******************************************************/
-int32_t Resume_PD(void)
-{
- uint8_t buf[8] = {0};
- int32_t ret = 0;
- int32_t retry = 0;
-
- // Resume Command
- buf[0] = 0x00;
- buf[1] = 0xAB;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Write Enable error!!(%d)\n", ret);
- return ret;
- }
-
- // Check 0xAA (Resume Command)
- retry = 0;
- while(1) {
- msleep(1);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Resume Command) error!!(%d)\n", ret);
- return ret;
- }
- if (buf[1] == 0xAA) {
- break;
- }
- retry++;
- if (unlikely(retry > 20)) {
- NVT_ERR("Check 0xAA (Resume Command) error!! status=0x%02X\n", buf[1]);
- return -1;
- }
- }
- msleep(10);
-
- NVT_LOG("Resume PD OK\n");
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen check firmware checksum function.
-
-return:
- Executive outcomes. 0---checksum not match.
- 1---checksum match. -1--- checksum read failed.
-*******************************************************/
-int32_t Check_CheckSum(void)
-{
- uint8_t buf[64] = {0};
- uint32_t XDATA_Addr = ts->mmap->READ_FLASH_CHECKSUM_ADDR;
- int32_t ret = 0;
- int32_t i = 0;
- int32_t k = 0;
- uint16_t WR_Filechksum[BLOCK_64KB_NUM] = {0};
- uint16_t RD_Filechksum[BLOCK_64KB_NUM] = {0};
- size_t fw_bin_size = 0;
- size_t len_in_blk = 0;
- int32_t retry = 0;
-
- if (Resume_PD()) {
- NVT_ERR("Resume PD error!!\n");
- return -1;
- }
-
- fw_bin_size = fw_entry->size;
-
- for (i = 0; i < BLOCK_64KB_NUM; i++) {
- if (fw_bin_size > (i * SIZE_64KB)) {
- // Calculate WR_Filechksum of each 64KB block
- len_in_blk = min(fw_bin_size - i * SIZE_64KB, (size_t)SIZE_64KB);
- WR_Filechksum[i] = i + 0x00 + 0x00 + (((len_in_blk - 1) >> 8) & 0xFF) + ((len_in_blk - 1) & 0xFF);
- for (k = 0; k < len_in_blk; k++) {
- WR_Filechksum[i] += fw_entry->data[k + i * SIZE_64KB];
- }
- WR_Filechksum[i] = 65535 - WR_Filechksum[i] + 1;
-
- // Fast Read Command
- buf[0] = 0x00;
- buf[1] = 0x07;
- buf[2] = i;
- buf[3] = 0x00;
- buf[4] = 0x00;
- buf[5] = ((len_in_blk - 1) >> 8) & 0xFF;
- buf[6] = (len_in_blk - 1) & 0xFF;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 7);
- if (ret < 0) {
- NVT_ERR("Fast Read Command error!!(%d)\n", ret);
- return ret;
- }
- // Check 0xAA (Fast Read Command)
- retry = 0;
- while (1) {
- msleep(80);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Fast Read Command) error!!(%d)\n", ret);
- return ret;
- }
- if (buf[1] == 0xAA) {
- break;
- }
- retry++;
- if (unlikely(retry > 5)) {
- NVT_ERR("Check 0xAA (Fast Read Command) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
- return -1;
- }
- }
- // Read Checksum (write addr high byte & middle byte)
- buf[0] = 0xFF;
- buf[1] = XDATA_Addr >> 16;
- buf[2] = (XDATA_Addr >> 8) & 0xFF;
- ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("Read Checksum (write addr high byte & middle byte) error!!(%d)\n", ret);
- return ret;
- }
- // Read Checksum
- buf[0] = (XDATA_Addr) & 0xFF;
- buf[1] = 0x00;
- buf[2] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("Read Checksum error!!(%d)\n", ret);
- return ret;
- }
-
- RD_Filechksum[i] = (uint16_t)((buf[2] << 8) | buf[1]);
- if (WR_Filechksum[i] != RD_Filechksum[i]) {
- NVT_ERR("RD_Filechksum[%d]=0x%04X, WR_Filechksum[%d]=0x%04X\n", i, RD_Filechksum[i], i, WR_Filechksum[i]);
- NVT_ERR("firmware checksum not match!!\n");
- return 0;
- }
- }
- }
-
- NVT_LOG("firmware checksum match\n");
- return 1;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen initial bootloader and flash
- block function.
-
-return:
- Executive outcomes. 0---succeed. negative---failed.
-*******************************************************/
-int32_t Init_BootLoader(void)
-{
- uint8_t buf[64] = {0};
- int32_t ret = 0;
- int32_t retry = 0;
-
- // SW Reset & Idle
- nvt_sw_reset_idle();
-
- // Initiate Flash Block
- buf[0] = 0x00;
- buf[1] = 0x00;
- buf[2] = I2C_FW_Address;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("Inittial Flash Block error!!(%d)\n", ret);
- return ret;
- }
-
- // Check 0xAA (Initiate Flash Block)
- retry = 0;
- while(1) {
- msleep(1);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Inittial Flash Block) error!!(%d)\n", ret);
- return ret;
- }
- if (buf[1] == 0xAA) {
- break;
- }
- retry++;
- if (unlikely(retry > 20)) {
- NVT_ERR("Check 0xAA (Inittial Flash Block) error!! status=0x%02X\n", buf[1]);
- return -1;
- }
- }
-
- NVT_LOG("Init OK \n");
- msleep(20);
-
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen erase flash sectors function.
-
-return:
- Executive outcomes. 0---succeed. negative---failed.
-*******************************************************/
-int32_t Erase_Flash(void)
-{
- uint8_t buf[64] = {0};
- int32_t ret = 0;
- int32_t count = 0;
- int32_t i = 0;
- int32_t Flash_Address = 0;
- int32_t retry = 0;
-
- // Write Enable
- buf[0] = 0x00;
- buf[1] = 0x06;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Write Enable (for Write Status Register) error!!(%d)\n", ret);
- return ret;
- }
- // Check 0xAA (Write Enable)
- retry = 0;
- while (1) {
- mdelay(1);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Write Enable for Write Status Register) error!!(%d)\n", ret);
- return ret;
- }
- if (buf[1] == 0xAA) {
- break;
- }
- retry++;
- if (unlikely(retry > 20)) {
- NVT_ERR("Check 0xAA (Write Enable for Write Status Register) error!! status=0x%02X\n", buf[1]);
- return -1;
- }
- }
-
- // Write Status Register
- buf[0] = 0x00;
- buf[1] = 0x01;
- buf[2] = 0x00;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("Write Status Register error!!(%d)\n", ret);
- return ret;
- }
- // Check 0xAA (Write Status Register)
- retry = 0;
- while (1) {
- mdelay(1);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Write Status Register) error!!(%d)\n", ret);
- return ret;
- }
- if (buf[1] == 0xAA) {
- break;
- }
- retry++;
- if (unlikely(retry > 20)) {
- NVT_ERR("Check 0xAA (Write Status Register) error!! status=0x%02X\n", buf[1]);
- return -1;
- }
- }
-
- // Read Status
- retry = 0;
- while (1) {
- mdelay(5);
- buf[0] = 0x00;
- buf[1] = 0x05;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Read Status (for Write Status Register) error!!(%d)\n", ret);
- return ret;
- }
-
- // Check 0xAA (Read Status)
- buf[0] = 0x00;
- buf[1] = 0x00;
- buf[2] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Read Status for Write Status Register) error!!(%d)\n", ret);
- return ret;
- }
- if ((buf[1] == 0xAA) && (buf[2] == 0x00)) {
- break;
- }
- retry++;
- if (unlikely(retry > 100)) {
- NVT_ERR("Check 0xAA (Read Status for Write Status Register) failed, buf[1]=0x%02X, buf[2]=0x%02X, retry=%d\n", buf[1], buf[2], retry);
- return -1;
- }
- }
-
- if (fw_entry->size % FLASH_SECTOR_SIZE)
- count = fw_entry->size / FLASH_SECTOR_SIZE + 1;
- else
- count = fw_entry->size / FLASH_SECTOR_SIZE;
-
- for(i = 0; i < count; i++) {
- // Write Enable
- buf[0] = 0x00;
- buf[1] = 0x06;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Write Enable error!!(%d,%d)\n", ret, i);
- return ret;
- }
- // Check 0xAA (Write Enable)
- retry = 0;
- while (1) {
- mdelay(1);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Write Enable) error!!(%d,%d)\n", ret, i);
- return ret;
- }
- if (buf[1] == 0xAA) {
- break;
- }
- retry++;
- if (unlikely(retry > 20)) {
- NVT_ERR("Check 0xAA (Write Enable) error!! status=0x%02X\n", buf[1]);
- return -1;
- }
- }
-
- Flash_Address = i * FLASH_SECTOR_SIZE;
-
- // Sector Erase
- buf[0] = 0x00;
- buf[1] = 0x20; // Command : Sector Erase
- buf[2] = ((Flash_Address >> 16) & 0xFF);
- buf[3] = ((Flash_Address >> 8) & 0xFF);
- buf[4] = (Flash_Address & 0xFF);
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 5);
- if (ret < 0) {
- NVT_ERR("Sector Erase error!!(%d,%d)\n", ret, i);
- return ret;
- }
- // Check 0xAA (Sector Erase)
- retry = 0;
- while (1) {
- mdelay(1);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Sector Erase) error!!(%d,%d)\n", ret, i);
- return ret;
- }
- if (buf[1] == 0xAA) {
- break;
- }
- retry++;
- if (unlikely(retry > 20)) {
- NVT_ERR("Check 0xAA (Sector Erase) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
- return -1;
- }
- }
-
- // Read Status
- retry = 0;
- while (1) {
- mdelay(5);
- buf[0] = 0x00;
- buf[1] = 0x05;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Read Status error!!(%d,%d)\n", ret, i);
- return ret;
- }
-
- // Check 0xAA (Read Status)
- buf[0] = 0x00;
- buf[1] = 0x00;
- buf[2] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Read Status) error!!(%d,%d)\n", ret, i);
- return ret;
- }
- if ((buf[1] == 0xAA) && (buf[2] == 0x00)) {
- break;
- }
- retry++;
- if (unlikely(retry > 100)) {
- NVT_ERR("Check 0xAA (Read Status) failed, buf[1]=0x%02X, buf[2]=0x%02X, retry=%d\n", buf[1], buf[2], retry);
- return -1;
- }
- }
- }
-
- NVT_LOG("Erase OK \n");
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen write flash sectors function.
-
-return:
- Executive outcomes. 0---succeed. negative---failed.
-*******************************************************/
-int32_t Write_Flash(void)
-{
- uint8_t buf[64] = {0};
- uint32_t XDATA_Addr = ts->mmap->RW_FLASH_DATA_ADDR;
- uint32_t Flash_Address = 0;
- int32_t i = 0, j = 0, k = 0;
- uint8_t tmpvalue = 0;
- int32_t count = 0;
- int32_t ret = 0;
- int32_t retry = 0;
-
- // change I2C buffer index
- buf[0] = 0xFF;
- buf[1] = XDATA_Addr >> 16;
- buf[2] = (XDATA_Addr >> 8) & 0xFF;
- ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("change I2C buffer index error!!(%d)\n", ret);
- return ret;
- }
-
- if (fw_entry->size % 256)
- count = fw_entry->size / 256 + 1;
- else
- count = fw_entry->size / 256;
-
- for (i = 0; i < count; i++) {
- Flash_Address = i * 256;
-
- // Write Enable
- buf[0] = 0x00;
- buf[1] = 0x06;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Write Enable error!!(%d)\n", ret);
- return ret;
- }
- // Check 0xAA (Write Enable)
- retry = 0;
- while (1) {
- udelay(100);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Write Enable) error!!(%d,%d)\n", ret, i);
- return ret;
- }
- if (buf[1] == 0xAA) {
- break;
- }
- retry++;
- if (unlikely(retry > 20)) {
- NVT_ERR("Check 0xAA (Write Enable) error!! status=0x%02X\n", buf[1]);
- return -1;
- }
- }
-
- // Write Page : 256 bytes
- for (j = 0; j < min(fw_entry->size - i * 256, (size_t)256); j += 32) {
- buf[0] = (XDATA_Addr + j) & 0xFF;
- for (k = 0; k < 32; k++) {
- buf[1 + k] = fw_entry->data[Flash_Address + j + k];
- }
- ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 33);
- if (ret < 0) {
- NVT_ERR("Write Page error!!(%d), j=%d\n", ret, j);
- return ret;
- }
- }
- if (fw_entry->size - Flash_Address >= 256)
- tmpvalue=(Flash_Address >> 16) + ((Flash_Address >> 8) & 0xFF) + (Flash_Address & 0xFF) + 0x00 + (255);
- else
- tmpvalue=(Flash_Address >> 16) + ((Flash_Address >> 8) & 0xFF) + (Flash_Address & 0xFF) + 0x00 + (fw_entry->size - Flash_Address - 1);
-
- for (k = 0;k < min(fw_entry->size - Flash_Address,(size_t)256); k++)
- tmpvalue += fw_entry->data[Flash_Address + k];
-
- tmpvalue = 255 - tmpvalue + 1;
-
- // Page Program
- buf[0] = 0x00;
- buf[1] = 0x02;
- buf[2] = ((Flash_Address >> 16) & 0xFF);
- buf[3] = ((Flash_Address >> 8) & 0xFF);
- buf[4] = (Flash_Address & 0xFF);
- buf[5] = 0x00;
- buf[6] = min(fw_entry->size - Flash_Address,(size_t)256) - 1;
- buf[7] = tmpvalue;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 8);
- if (ret < 0) {
- NVT_ERR("Page Program error!!(%d), i=%d\n", ret, i);
- return ret;
- }
- // Check 0xAA (Page Program)
- retry = 0;
- while (1) {
- mdelay(1);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Page Program error!!(%d)\n", ret);
- return ret;
- }
- if (buf[1] == 0xAA || buf[1] == 0xEA) {
- break;
- }
- retry++;
- if (unlikely(retry > 20)) {
- NVT_ERR("Check 0xAA (Page Program) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
- return -1;
- }
- }
- if (buf[1] == 0xEA) {
- NVT_ERR("Page Program error!! i=%d\n", i);
- return -3;
- }
-
- // Read Status
- retry = 0;
- while (1) {
- mdelay(5);
- buf[0] = 0x00;
- buf[1] = 0x05;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Read Status error!!(%d)\n", ret);
- return ret;
- }
-
- // Check 0xAA (Read Status)
- buf[0] = 0x00;
- buf[1] = 0x00;
- buf[2] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Read Status) error!!(%d)\n", ret);
- return ret;
- }
- if (((buf[1] == 0xAA) && (buf[2] == 0x00)) || (buf[1] == 0xEA)) {
- break;
- }
- retry++;
- if (unlikely(retry > 100)) {
- NVT_ERR("Check 0xAA (Read Status) failed, buf[1]=0x%02X, buf[2]=0x%02X, retry=%d\n", buf[1], buf[2], retry);
- return -1;
- }
- }
- if (buf[1] == 0xEA) {
- NVT_ERR("Page Program error!! i=%d\n", i);
- return -4;
- }
-
- NVT_LOG("Programming...%2d%%\r", ((i * 100) / count));
- }
-
- NVT_LOG("Programming...%2d%%\r", 100);
- NVT_LOG("Program OK \n");
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen verify checksum of written
- flash function.
-
-return:
- Executive outcomes. 0---succeed. negative---failed.
-*******************************************************/
-int32_t Verify_Flash(void)
-{
- uint8_t buf[64] = {0};
- uint32_t XDATA_Addr = ts->mmap->READ_FLASH_CHECKSUM_ADDR;
- int32_t ret = 0;
- int32_t i = 0;
- int32_t k = 0;
- uint16_t WR_Filechksum[BLOCK_64KB_NUM] = {0};
- uint16_t RD_Filechksum[BLOCK_64KB_NUM] = {0};
- size_t fw_bin_size = 0;
- size_t len_in_blk = 0;
- int32_t retry = 0;
-
- fw_bin_size = fw_entry->size;
-
- for (i = 0; i < BLOCK_64KB_NUM; i++) {
- if (fw_bin_size > (i * SIZE_64KB)) {
- // Calculate WR_Filechksum of each 64KB block
- len_in_blk = min(fw_bin_size - i * SIZE_64KB, (size_t)SIZE_64KB);
- WR_Filechksum[i] = i + 0x00 + 0x00 + (((len_in_blk - 1) >> 8) & 0xFF) + ((len_in_blk - 1) & 0xFF);
- for (k = 0; k < len_in_blk; k++) {
- WR_Filechksum[i] += fw_entry->data[k + i * SIZE_64KB];
- }
- WR_Filechksum[i] = 65535 - WR_Filechksum[i] + 1;
-
- // Fast Read Command
- buf[0] = 0x00;
- buf[1] = 0x07;
- buf[2] = i;
- buf[3] = 0x00;
- buf[4] = 0x00;
- buf[5] = ((len_in_blk - 1) >> 8) & 0xFF;
- buf[6] = (len_in_blk - 1) & 0xFF;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 7);
- if (ret < 0) {
- NVT_ERR("Fast Read Command error!!(%d)\n", ret);
- return ret;
- }
- // Check 0xAA (Fast Read Command)
- retry = 0;
- while (1) {
- msleep(80);
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Fast Read Command) error!!(%d)\n", ret);
- return ret;
- }
- if (buf[1] == 0xAA) {
- break;
- }
- retry++;
- if (unlikely(retry > 5)) {
- NVT_ERR("Check 0xAA (Fast Read Command) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
- return -1;
- }
- }
- // Read Checksum (write addr high byte & middle byte)
- buf[0] = 0xFF;
- buf[1] = XDATA_Addr >> 16;
- buf[2] = (XDATA_Addr >> 8) & 0xFF;
- ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("Read Checksum (write addr high byte & middle byte) error!!(%d)\n", ret);
- return ret;
- }
- // Read Checksum
- buf[0] = (XDATA_Addr) & 0xFF;
- buf[1] = 0x00;
- buf[2] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("Read Checksum error!!(%d)\n", ret);
- return ret;
- }
-
- RD_Filechksum[i] = (uint16_t)((buf[2] << 8) | buf[1]);
- if (WR_Filechksum[i] != RD_Filechksum[i]) {
- NVT_ERR("Verify Fail%d!!\n", i);
- NVT_ERR("RD_Filechksum[%d]=0x%04X, WR_Filechksum[%d]=0x%04X\n", i, RD_Filechksum[i], i, WR_Filechksum[i]);
- return -1;
- }
- }
- }
-
- NVT_LOG("Verify OK \n");
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen update firmware function.
-
-return:
- Executive outcomes. 0---succeed. negative---failed.
-*******************************************************/
-int32_t Update_Firmware(void)
-{
- int32_t ret = 0;
-
- //---Stop CRC check to prevent IC auto reboot---
- nvt_stop_crc_reboot();
-
- // Step 1 : initial bootloader
- ret = Init_BootLoader();
- if (ret) {
- return ret;
- }
-
- // Step 2 : Resume PD
- ret = Resume_PD();
- if (ret) {
- return ret;
- }
-
- // Step 3 : Erase
- ret = Erase_Flash();
- if (ret) {
- return ret;
- }
-
- // Step 4 : Program
- ret = Write_Flash();
- if (ret) {
- return ret;
- }
-
- // Step 5 : Verify
- ret = Verify_Flash();
- if (ret) {
- return ret;
- }
-
- //Step 6 : Bootloader Reset
- nvt_bootloader_reset();
- nvt_check_fw_reset_state(RESET_STATE_INIT);
-
- return ret;
-}
-/*******************************************************
-Description:
- Novatek touchscreen check flash end flag function.
-
-return:
- Executive outcomes. 0---succeed. 1,negative---failed.
-*******************************************************/
-#define NVT_FLASH_END_FLAG_LEN 3
-#define NVT_FLASH_END_FLAG_ADDR 0x1AFFD
-int32_t nvt_check_flash_end_flag(void)
-{
- uint8_t buf[8] = {0};
- uint8_t nvt_end_flag[NVT_FLASH_END_FLAG_LEN + 1] = {0};
- int32_t ret = 0;
-
- // Step 1 : initial bootloader
- ret = Init_BootLoader();
- if (ret) {
- return ret;
- }
-
- // Step 2 : Resume PD
- ret = Resume_PD();
- if (ret) {
- return ret;
- }
-
- // Step 3 : unlock
- buf[0] = 0x00;
- buf[1] = 0x35;
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("write unlock error!!(%d)\n", ret);
- return ret;
- }
- msleep(10);
-
- //Step 4 : Flash Read Command
- buf[0] = 0x00;
- buf[1] = 0x03;
- buf[2] = (NVT_FLASH_END_FLAG_ADDR >> 16) & 0xFF; //Addr_H
- buf[3] = (NVT_FLASH_END_FLAG_ADDR >> 8) & 0xFF; //Addr_M
- buf[4] = NVT_FLASH_END_FLAG_ADDR & 0xFF; //Addr_L
- buf[5] = (NVT_FLASH_END_FLAG_LEN >> 8) & 0xFF; //Len_H
- buf[6] = NVT_FLASH_END_FLAG_LEN & 0xFF; //Len_L
- ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 7);
- if (ret < 0) {
- NVT_ERR("write Read Command error!!(%d)\n", ret);
- return ret;
- }
- msleep(10);
-
- // Check 0xAA (Read Command)
- buf[0] = 0x00;
- buf[1] = 0x00;
- ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
- if (ret < 0) {
- NVT_ERR("Check 0xAA (Read Command) error!!(%d)\n", ret);
- return ret;
- }
- if (buf[1] != 0xAA) {
- NVT_ERR("Check 0xAA (Read Command) error!! status=0x%02X\n", buf[1]);
- return -1;
- }
-
- msleep(10);
-
- //Step 5 : Read Flash Data
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->READ_FLASH_CHECKSUM_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->READ_FLASH_CHECKSUM_ADDR >> 8) & 0xFF;
- ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
- if (ret < 0) {
- NVT_ERR("change index error!! (%d)\n", ret);
- return ret;
- }
- msleep(10);
-
- // Read Back
- buf[0] = ts->mmap->READ_FLASH_CHECKSUM_ADDR & 0xFF;
- ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 6);
- if (ret < 0) {
- NVT_ERR("Read Back error!! (%d)\n", ret);
- return ret;
- }
-
- //buf[3:5] => NVT End Flag
- strncpy(nvt_end_flag, &buf[3], NVT_FLASH_END_FLAG_LEN);
- NVT_LOG("nvt_end_flag=%s (%02X %02X %02X)\n", nvt_end_flag, buf[3], buf[4], buf[5]);
-
- if (strncmp(nvt_end_flag, "NVT", 3) == 0) {
- return 0;
- } else {
- NVT_ERR("\"NVT\" end flag not found!\n");
- return 1;
- }
-}
-#endif
-
-#if BOOT_UPDATE_FIRMWARE
-/*******************************************************
-Description:
- Novatek touchscreen update firmware when booting
- function.
-
-return:
- n.a.
-*******************************************************/
-void Boot_Update_Firmware(struct work_struct *work)
-{
- int32_t ret = 0;
-
- char firmware_name[256] = "";
- sprintf(firmware_name, BOOT_UPDATE_FIRMWARE_NAME);
-
- // request bin file in "/etc/firmware"
- ret = update_firmware_request(firmware_name);
- if (ret) {
- NVT_ERR("update_firmware_request failed. (%d)\n", ret);
- return;
- }
-
- mutex_lock(&ts->lock);
-#if NVT_TOUCH_ESD_PROTECT
- nvt_esd_check_enable(false);
-#endif
-#if NVT_TOUCH_FW
- ts->loading_fw = 1;
-#endif
- nvt_sw_reset_idle();
-
- ret = Check_CheckSum();
-
- if (ret < 0) { // read firmware checksum failed
- NVT_ERR("read firmware checksum failed\n");
- Update_Firmware();
- } else if ((ret == 0) && (Check_FW_Ver() == 0)) { // (fw checksum not match) && (bin fw version >= ic fw version)
- NVT_LOG("firmware version not match\n");
- Update_Firmware();
- } else if (nvt_check_flash_end_flag()) {
- NVT_LOG("check flash end flag failed\n");
- Update_Firmware();
- } else {
- // Bootloader Reset
- nvt_bootloader_reset();
- nvt_check_fw_reset_state(RESET_STATE_INIT);
- }
-
-#if NVT_TOUCH_FW
- ts->loading_fw = 0;
-#endif
- mutex_unlock(&ts->lock);
-
- update_firmware_release();
-}
-#endif /* BOOT_UPDATE_FIRMWARE */
-
-#if NVT_TOUCH_FW
-static ssize_t nvt_poweron_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- bool val;
-
- mutex_lock(&ts->lock);
- val = ts->suspended;
- mutex_unlock(&ts->lock);
-
- return scnprintf(buf, PAGE_SIZE, "%d\n",
- val == 0);
-}
-
-static DEVICE_ATTR(poweron, 0444, nvt_poweron_show, NULL);
-
-static ssize_t nvt_ic_ver_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return scnprintf(buf, PAGE_SIZE, "[FW]%02x,[IC]NT36525\n",
- ts->fw_ver);
-}
-
-static DEVICE_ATTR(ic_ver, 0444, nvt_ic_ver_show, NULL);
-
-static ssize_t nvt_productinfo_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
-/* Update script use as $touch_product_id in fw name ==> (chip id from Lenovo&script) OR (vendor name from Focaltech) OR (project ID from Longcheer&Himax)
- Project ID ?? ( - Jeter - Hannah)
- Chip ID ?? (NVT-ts or NVTCapacitiveTouchScreen or NT36xxx) */
- return scnprintf(buf, PAGE_SIZE, "%s\n",
- ts->product_id);
-}
-
-static DEVICE_ATTR(productinfo, 0444, nvt_productinfo_show, NULL);
-
-static ssize_t nvt_force_reflash_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- unsigned int input;
-
- if (sscanf(buf, "%u", &input) != 1)
- return -EINVAL;
-
- ts->force_reflash = (input == 0) ? false : true;
-
- return count;
-}
-
-static DEVICE_ATTR(forcereflash, 0220, NULL, nvt_force_reflash_store);
-
-static ssize_t nvt_flashprog_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return scnprintf(buf, PAGE_SIZE, "%d\n",
- (ts->loading_fw) ? 1 : 0);
-}
-
-static DEVICE_ATTR(flashprog, 0444, nvt_flashprog_show, NULL);
-
-static ssize_t nvt_do_reflash_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int retval;
- char prefix[FW_NAME_MAX_LEN] = VENDOR_NAME;
- char template[FW_NAME_MAX_LEN];
- char firmware_name[256] = "";
-
- if (count > FW_NAME_MAX_LEN) {
- NVT_ERR("FW filename is too long\n");
- retval = -EINVAL;
- goto exit;
- }
-
- if (ts->suspended) {
- NVT_ERR("In suspend state, try again later\n");
- retval = -EINVAL;
- goto exit;
- }
-
- if (ts->loading_fw) {
- NVT_ERR("In FW flashing state, try again later\n");
- retval = -EINVAL;
- goto exit;
- }
-
- if (!ts->force_reflash) {
- if (strncmp(buf, prefix,
- strnlen(prefix, sizeof(prefix)))) {
- NVT_ERR("FW does not belong to Novatek\n");
- retval = -EINVAL;
- goto exit;
- }
-
- snprintf(template, sizeof(template), "-%s-",
- ts->product_id);
- if (!strnstr(buf + strnlen(prefix, sizeof(prefix)), template,
- count)) {
- NVT_ERR("FW does not belong to %s\n", ts->product_id);
- retval = -EINVAL;
- goto exit;
- }
- }
-
- strlcpy(firmware_name, buf, count);
- NVT_LOG("FW filename: %s\n", firmware_name);
-
- retval = update_firmware_request(firmware_name);
- if (retval) {
- NVT_ERR("update_firmware_request failed. (%d)\n", retval);
- goto exit;
- }
-
- mutex_lock(&ts->lock);
-#if NVT_TOUCH_ESD_PROTECT
- nvt_esd_check_enable(false);
-#endif
- ts->loading_fw = 1;
- nvt_sw_reset_idle();
-
- retval = Check_CheckSum();
-
- if (retval < 0) {
- NVT_ERR("read firmware checksum failed\n");
- Update_Firmware();
- } else if ((retval == 0) && (Check_FW_Ver() == 0)) {
- NVT_LOG("firmware version not match\n");
- Update_Firmware();
- } else if (nvt_check_flash_end_flag()) {
- NVT_LOG("check flash end flag failed\n");
- Update_Firmware();
- } else {
- /* Bootloader Reset */
- nvt_bootloader_reset();
- nvt_check_fw_reset_state(RESET_STATE_INIT);
- }
-
- ts->loading_fw = 0;
- mutex_unlock(&ts->lock);
-
- update_firmware_release();
-
- retval = count;
-exit:
- return retval;
-}
-
-static DEVICE_ATTR(doreflash, 0220, NULL, nvt_do_reflash_store);
-
-static ssize_t nvt_build_id_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
-/* Update script use for comparing $str_cfg_id_latest in fw name */
- uint8_t tmp_buf[4] = {0};
- uint8_t fw_version = 0;
- uint8_t date_Y = 0;
- uint8_t date_M = 0;
- uint8_t date_D = 0;
-
- tmp_buf[0] = 0xFF;
- tmp_buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- tmp_buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, tmp_buf, 3);
-
- tmp_buf[0] = EVENT_MAP_FWINFO;
- CTP_I2C_READ(ts->client, I2C_FW_Address, tmp_buf, 2);
- fw_version = tmp_buf[1];
-
- tmp_buf[0] = EVENT_MAP_FWDATE;
- CTP_I2C_READ(ts->client, I2C_FW_Address, tmp_buf, 4);
- date_Y = tmp_buf[1];
- date_M = tmp_buf[2];
- date_D = tmp_buf[3];
-
- return scnprintf(buf, PAGE_SIZE, "%02x-%02d%02d%02d\n",
- fw_version, date_Y, date_M, date_D);
-}
-
-static DEVICE_ATTR(buildid, 0444, nvt_build_id_show, NULL);
-
-
-#include <linux/slab.h>
-#include <linux/major.h>
-#include <linux/kdev_t.h>
-
-/* Attribute: path (RO) */
-static ssize_t path_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- ssize_t blen;
- const char *path;
-
- path = kobject_get_path(&ts->client->dev.kobj, GFP_KERNEL);
- blen = scnprintf(buf, PAGE_SIZE, "%s", path ? path : "na");
- kfree(path);
- return blen;
-}
-
-/* Attribute: vendor (RO) */
-static ssize_t vendor_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return scnprintf(buf, PAGE_SIZE, VENDOR_NAME);
-}
-
-static struct device_attribute touchscreen_attributes[] = {
- __ATTR_RO(path),
- __ATTR_RO(vendor),
- __ATTR_NULL
-};
-
-#define TSDEV_MINOR_BASE 128
-#define TSDEV_MINOR_MAX 32
-
-/*******************************************************
-Description:
- Novatek touchscreen FW function class. file node
- initial function.
-
-return:
- Executive outcomes. 0---succeed. -1---failed.
-*******************************************************/
-int32_t nvt_fw_class_init(bool create)
-{
- struct device_attribute *attrs = touchscreen_attributes;
- int i, error = 0;
- static struct class *touchscreen_class;
- static struct device *ts_class_dev;
- static int minor;
-
- if (create) {
- minor = input_get_new_minor(ts->client->addr,
- 1, false);
- if (minor < 0)
- minor = input_get_new_minor(TSDEV_MINOR_BASE,
- TSDEV_MINOR_MAX, true);
- NVT_LOG("assigned minor %d\n", minor);
-
- touchscreen_class = class_create(THIS_MODULE, "touchscreen");
- if (IS_ERR(touchscreen_class)) {
- error = PTR_ERR(touchscreen_class);
- touchscreen_class = NULL;
- return error;
- }
-
- ts_class_dev = device_create(touchscreen_class, NULL,
- MKDEV(INPUT_MAJOR, minor),
- ts, NVT_I2C_NAME);
- if (IS_ERR(ts_class_dev)) {
- error = PTR_ERR(ts_class_dev);
- ts_class_dev = NULL;
- return error;
- }
-
- for (i = 0; attrs[i].attr.name != NULL; ++i) {
- error = device_create_file(ts_class_dev, &attrs[i]);
- if (error)
- break;
- }
-
- if (error)
- goto device_destroy;
- else
- NVT_LOG("create /sys/class/touchscreen/%s Succeeded!\n", NVT_I2C_NAME);
- } else {
- if (!touchscreen_class || !ts_class_dev)
- return -ENODEV;
-
- for (i = 0; attrs[i].attr.name != NULL; ++i)
- device_remove_file(ts_class_dev, &attrs[i]);
-
- device_unregister(ts_class_dev);
- class_unregister(touchscreen_class);
- }
-
- return 0;
-
-device_destroy:
- for (--i; i >= 0; --i)
- device_remove_file(ts_class_dev, &attrs[i]);
- device_destroy(touchscreen_class, MKDEV(INPUT_MAJOR, minor));
- ts_class_dev = NULL;
- class_unregister(touchscreen_class);
- NVT_ERR("error creating touchscreen class\n");
-
- return -ENODEV;
-}
-
-int nvt_fw_sysfs_init(void)
-{
- int ret;
- struct i2c_client *client = ts->client;
-
- ret = nvt_fw_class_init(true);
- if (ret != 0) {
- NVT_ERR("fw class init failed. ret=%d\n", ret);
- return ret;
- }
-
- ret = device_create_file(&client->dev, &dev_attr_forcereflash);
- if (ret) {
- NVT_ERR("create_file dev_attr_forcereflash failed\n");
- return ret;
- }
-
- ret = device_create_file(&client->dev, &dev_attr_flashprog);
- if (ret) {
- NVT_ERR("create_file dev_attr_flashprog failed\n");
- return ret;
- }
- ret = device_create_file(&client->dev, &dev_attr_doreflash);
- if (ret) {
- NVT_ERR("create_file dev_attr_doreflash failed\n");
- return ret;
- }
-
- ret = device_create_file(&client->dev, &dev_attr_buildid);
- if (ret) {
- NVT_ERR("create_file dev_attr_buildid failed\n");
- return ret;
- }
-
- ret = device_create_file(&client->dev, &dev_attr_productinfo);
- if (ret) {
- NVT_ERR("create_file dev_attr_productinfo failed\n");
- return ret;
- }
-
- ret = device_create_file(&client->dev, &dev_attr_poweron);
- if (ret) {
- NVT_ERR("create_file dev_attr_poweron failed\n");
- return ret;
- }
-
- ret = device_create_file(&client->dev, &dev_attr_ic_ver);
- if (ret) {
- NVT_ERR("create_file dev_attr_ic_ver failed\n");
- return ret;
- }
-
- return 0;
-}
-void nvt_fw_sysfs_deinit(void)
-{
- struct i2c_client *client = ts->client;
- device_remove_file(&client->dev, &dev_attr_forcereflash);
- device_remove_file(&client->dev, &dev_attr_flashprog);
- device_remove_file(&client->dev, &dev_attr_doreflash);
- device_remove_file(&client->dev, &dev_attr_buildid);
- device_remove_file(&client->dev, &dev_attr_productinfo);
- device_remove_file(&client->dev, &dev_attr_poweron);
- device_remove_file(&client->dev, &dev_attr_ic_ver);
- nvt_fw_class_init(false);
-}
-#endif
+++ /dev/null
-/*
- * Copyright (C) 2010 - 2017 Novatek, Inc.
- *
- * $Revision: 22971 $
- * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-struct nvt_ts_mem_map {
- uint32_t EVENT_BUF_ADDR;
- uint32_t RAW_PIPE0_ADDR;
- uint32_t RAW_PIPE0_Q_ADDR;
- uint32_t RAW_PIPE1_ADDR;
- uint32_t RAW_PIPE1_Q_ADDR;
- uint32_t BASELINE_ADDR;
- uint32_t BASELINE_Q_ADDR;
- uint32_t BASELINE_BTN_ADDR;
- uint32_t BASELINE_BTN_Q_ADDR;
- uint32_t DIFF_PIPE0_ADDR;
- uint32_t DIFF_PIPE0_Q_ADDR;
- uint32_t DIFF_PIPE1_ADDR;
- uint32_t DIFF_PIPE1_Q_ADDR;
- uint32_t RAW_BTN_PIPE0_ADDR;
- uint32_t RAW_BTN_PIPE0_Q_ADDR;
- uint32_t RAW_BTN_PIPE1_ADDR;
- uint32_t RAW_BTN_PIPE1_Q_ADDR;
- uint32_t DIFF_BTN_PIPE0_ADDR;
- uint32_t DIFF_BTN_PIPE0_Q_ADDR;
- uint32_t DIFF_BTN_PIPE1_ADDR;
- uint32_t DIFF_BTN_PIPE1_Q_ADDR;
- uint32_t READ_FLASH_CHECKSUM_ADDR;
- uint32_t RW_FLASH_DATA_ADDR;
-};
-
-static const struct nvt_ts_mem_map NT36672A_memory_map = {
- .EVENT_BUF_ADDR = 0x21C00,
- .RAW_PIPE0_ADDR = 0x20000,
- .RAW_PIPE0_Q_ADDR = 0,
- .RAW_PIPE1_ADDR = 0x23000,
- .RAW_PIPE1_Q_ADDR = 0,
- .BASELINE_ADDR = 0x20BFC,
- .BASELINE_Q_ADDR = 0,
- .BASELINE_BTN_ADDR = 0x23BFC,
- .BASELINE_BTN_Q_ADDR = 0,
- .DIFF_PIPE0_ADDR = 0x206DC,
- .DIFF_PIPE0_Q_ADDR = 0,
- .DIFF_PIPE1_ADDR = 0x236DC,
- .DIFF_PIPE1_Q_ADDR = 0,
- .RAW_BTN_PIPE0_ADDR = 0x20510,
- .RAW_BTN_PIPE0_Q_ADDR = 0,
- .RAW_BTN_PIPE1_ADDR = 0x23510,
- .RAW_BTN_PIPE1_Q_ADDR = 0,
- .DIFF_BTN_PIPE0_ADDR = 0x20BF0,
- .DIFF_BTN_PIPE0_Q_ADDR = 0,
- .DIFF_BTN_PIPE1_ADDR = 0x23BF0,
- .DIFF_BTN_PIPE1_Q_ADDR = 0,
- .READ_FLASH_CHECKSUM_ADDR = 0x24000,
- .RW_FLASH_DATA_ADDR = 0x24002,
-};
-
-static const struct nvt_ts_mem_map NT36772_memory_map = {
- .EVENT_BUF_ADDR = 0x11E00,
- .RAW_PIPE0_ADDR = 0x10000,
- .RAW_PIPE0_Q_ADDR = 0,
- .RAW_PIPE1_ADDR = 0x12000,
- .RAW_PIPE1_Q_ADDR = 0,
- .BASELINE_ADDR = 0x10E70,
- .BASELINE_Q_ADDR = 0,
- .BASELINE_BTN_ADDR = 0x12E70,
- .BASELINE_BTN_Q_ADDR = 0,
- .DIFF_PIPE0_ADDR = 0x10830,
- .DIFF_PIPE0_Q_ADDR = 0,
- .DIFF_PIPE1_ADDR = 0x12830,
- .DIFF_PIPE1_Q_ADDR = 0,
- .RAW_BTN_PIPE0_ADDR = 0x10E60,
- .RAW_BTN_PIPE0_Q_ADDR = 0,
- .RAW_BTN_PIPE1_ADDR = 0x12E60,
- .RAW_BTN_PIPE1_Q_ADDR = 0,
- .DIFF_BTN_PIPE0_ADDR = 0x10E68,
- .DIFF_BTN_PIPE0_Q_ADDR = 0,
- .DIFF_BTN_PIPE1_ADDR = 0x12E68,
- .DIFF_BTN_PIPE1_Q_ADDR = 0,
- .READ_FLASH_CHECKSUM_ADDR = 0x14000,
- .RW_FLASH_DATA_ADDR = 0x14002,
-};
-
-static const struct nvt_ts_mem_map NT36525_memory_map = {
- .EVENT_BUF_ADDR = 0x11A00,
- .RAW_PIPE0_ADDR = 0x10000,
- .RAW_PIPE0_Q_ADDR = 0,
- .RAW_PIPE1_ADDR = 0x12000,
- .RAW_PIPE1_Q_ADDR = 0,
- .BASELINE_ADDR = 0x10B08,
- .BASELINE_Q_ADDR = 0,
- .BASELINE_BTN_ADDR = 0x12B08,
- .BASELINE_BTN_Q_ADDR = 0,
- .DIFF_PIPE0_ADDR = 0x1064C,
- .DIFF_PIPE0_Q_ADDR = 0,
- .DIFF_PIPE1_ADDR = 0x1264C,
- .DIFF_PIPE1_Q_ADDR = 0,
- .RAW_BTN_PIPE0_ADDR = 0x10634,
- .RAW_BTN_PIPE0_Q_ADDR = 0,
- .RAW_BTN_PIPE1_ADDR = 0x12634,
- .RAW_BTN_PIPE1_Q_ADDR = 0,
- .DIFF_BTN_PIPE0_ADDR = 0x10AFC,
- .DIFF_BTN_PIPE0_Q_ADDR = 0,
- .DIFF_BTN_PIPE1_ADDR = 0x12AFC,
- .DIFF_BTN_PIPE1_Q_ADDR = 0,
- .READ_FLASH_CHECKSUM_ADDR = 0x14000,
- .RW_FLASH_DATA_ADDR = 0x14002,
-};
-
-static const struct nvt_ts_mem_map NT36870_memory_map = {
- .EVENT_BUF_ADDR = 0x25000,
- .RAW_PIPE0_ADDR = 0x20000,
- .RAW_PIPE0_Q_ADDR = 0x204C8,
- .RAW_PIPE1_ADDR = 0x23000,
- .RAW_PIPE1_Q_ADDR = 0x234C8,
- .BASELINE_ADDR = 0x21350,
- .BASELINE_Q_ADDR = 0x21818,
- .BASELINE_BTN_ADDR = 0x24350,
- .BASELINE_BTN_Q_ADDR = 0x24358,
- .DIFF_PIPE0_ADDR = 0x209B0,
- .DIFF_PIPE0_Q_ADDR = 0x20E78,
- .DIFF_PIPE1_ADDR = 0x239B0,
- .DIFF_PIPE1_Q_ADDR = 0x23E78,
- .RAW_BTN_PIPE0_ADDR = 0x20990,
- .RAW_BTN_PIPE0_Q_ADDR = 0x20998,
- .RAW_BTN_PIPE1_ADDR = 0x23990,
- .RAW_BTN_PIPE1_Q_ADDR = 0x23998,
- .DIFF_BTN_PIPE0_ADDR = 0x21340,
- .DIFF_BTN_PIPE0_Q_ADDR = 0x21348,
- .DIFF_BTN_PIPE1_ADDR = 0x24340,
- .DIFF_BTN_PIPE1_Q_ADDR = 0x24348,
- .READ_FLASH_CHECKSUM_ADDR = 0x24000,
- .RW_FLASH_DATA_ADDR = 0x24002,
-};
-
-static const struct nvt_ts_mem_map NT36676F_memory_map = {
- .EVENT_BUF_ADDR = 0x11A00,
- .RAW_PIPE0_ADDR = 0x10000,
- .RAW_PIPE0_Q_ADDR = 0,
- .RAW_PIPE1_ADDR = 0x12000,
- .RAW_PIPE1_Q_ADDR = 0,
- .BASELINE_ADDR = 0x10B08,
- .BASELINE_Q_ADDR = 0,
- .BASELINE_BTN_ADDR = 0x12B08,
- .BASELINE_BTN_Q_ADDR = 0,
- .DIFF_PIPE0_ADDR = 0x1064C,
- .DIFF_PIPE0_Q_ADDR = 0,
- .DIFF_PIPE1_ADDR = 0x1264C,
- .DIFF_PIPE1_Q_ADDR = 0,
- .RAW_BTN_PIPE0_ADDR = 0x10634,
- .RAW_BTN_PIPE0_Q_ADDR = 0,
- .RAW_BTN_PIPE1_ADDR = 0x12634,
- .RAW_BTN_PIPE1_Q_ADDR = 0,
- .DIFF_BTN_PIPE0_ADDR = 0x10AFC,
- .DIFF_BTN_PIPE0_Q_ADDR = 0,
- .DIFF_BTN_PIPE1_ADDR = 0x12AFC,
- .DIFF_BTN_PIPE1_Q_ADDR = 0,
- .READ_FLASH_CHECKSUM_ADDR = 0x14000,
- .RW_FLASH_DATA_ADDR = 0x14002,
-};
-
-#define NVT_ID_BYTE_MAX 6
-struct nvt_ts_trim_id_table {
- uint8_t id[NVT_ID_BYTE_MAX];
- uint8_t mask[NVT_ID_BYTE_MAX];
- const struct nvt_ts_mem_map *mmap;
- uint8_t carrier_system;
-};
-
-static const struct nvt_ts_trim_id_table trim_id_table[] = {
- {.id = {0x0A, 0xFF, 0xFF, 0x72, 0x66, 0x03}, .mask = {1, 0, 0, 1, 1, 1},
- .mmap = &NT36672A_memory_map, .carrier_system = 0},
- {.id = {0x55, 0x00, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1},
- .mmap = &NT36772_memory_map, .carrier_system = 0},
- {.id = {0x55, 0x72, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1},
- .mmap = &NT36772_memory_map, .carrier_system = 0},
- {.id = {0xAA, 0x00, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1},
- .mmap = &NT36772_memory_map, .carrier_system = 0},
- {.id = {0xAA, 0x72, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1},
- .mmap = &NT36772_memory_map, .carrier_system = 0},
- {.id = {0xFF, 0xFF, 0xFF, 0x72, 0x67, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
- .mmap = &NT36772_memory_map, .carrier_system = 0},
- {.id = {0xFF, 0xFF, 0xFF, 0x70, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
- .mmap = &NT36772_memory_map, .carrier_system = 0},
- {.id = {0xFF, 0xFF, 0xFF, 0x70, 0x67, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
- .mmap = &NT36772_memory_map, .carrier_system = 0},
- {.id = {0xFF, 0xFF, 0xFF, 0x72, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
- .mmap = &NT36772_memory_map, .carrier_system = 0},
- {.id = {0xFF, 0xFF, 0xFF, 0x25, 0x65, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
- .mmap = &NT36525_memory_map, .carrier_system = 0},
- {.id = {0xFF, 0xFF, 0xFF, 0x70, 0x68, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
- .mmap = &NT36870_memory_map, .carrier_system = 1},
- {.id = {0xFF, 0xFF, 0xFF, 0x76, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
- .mmap = &NT36676F_memory_map, .carrier_system = 0}
-};
+++ /dev/null
-/*
- * Copyright (C) 2010 - 2017 Novatek, Inc.
- *
- * $Revision: 23067 $
- * $Date: 2018-02-09 11:39:27 +0800 (ι±δΊ, 09 δΊζ 2018) $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-
-#include "nt36xxx.h"
-#include "nt36xxx_mp_ctrlram.h"
-
-#if NVT_TOUCH_MP
-
-#define NORMAL_MODE 0x00
-#define TEST_MODE_1 0x21
-#define TEST_MODE_2 0x22
-#define MP_MODE_CC 0x41
-#define FREQ_HOP_DISABLE 0x66
-#define FREQ_HOP_ENABLE 0x65
-
-#define SHORT_TEST_CSV_FILE "/data/local/tmp/ShortTest.csv"
-#define OPEN_TEST_CSV_FILE "/data/local/tmp/OpenTest.csv"
-#define FW_RAWDATA_CSV_FILE "/data/local/tmp/FWMutualTest.csv"
-#define FW_CC_CSV_FILE "/data/local/tmp/FWCCTest.csv"
-#define NOISE_TEST_CSV_FILE "/data/local/tmp/NoiseTest.csv"
-
-#define nvt_mp_seq_printf(m, fmt, args...) do { \
- seq_printf(m, fmt, ##args); \
- if (!nvt_mp_test_result_printed) \
- printk(fmt, ##args); \
-} while (0)
-
-static uint8_t *RecordResult_Short = NULL;
-static uint8_t *RecordResult_Short_Diff = NULL;
-static uint8_t *RecordResult_Short_Base = NULL;
-static uint8_t *RecordResult_Open = NULL;
-static uint8_t *RecordResult_FWMutual = NULL;
-static uint8_t *RecordResult_FW_CC = NULL;
-static uint8_t *RecordResult_FW_CC_I = NULL;
-static uint8_t *RecordResult_FW_CC_Q = NULL;
-static uint8_t *RecordResult_FW_DiffMax = NULL;
-static uint8_t *RecordResult_FW_DiffMin = NULL;
-
-static int32_t TestResult_Short = 0;
-static int32_t TestResult_Short_Diff = 0;
-static int32_t TestResult_Short_Base = 0;
-static int32_t TestResult_Open = 0;
-static int32_t TestResult_FW_Rawdata = 0;
-static int32_t TestResult_FWMutual = 0;
-static int32_t TestResult_FW_CC = 0;
-static int32_t TestResult_FW_CC_I = 0;
-static int32_t TestResult_FW_CC_Q = 0;
-static int32_t TestResult_Noise = 0;
-static int32_t TestResult_FW_DiffMax = 0;
-static int32_t TestResult_FW_DiffMin = 0;
-
-static int32_t *RawData_Short = NULL;
-static int32_t *RawData_Short_Diff = NULL;
-static int32_t *RawData_Short_Base = NULL;
-static int32_t *RawData_Open = NULL;
-static int32_t *RawData_Diff = NULL;
-static int32_t *RawData_Diff_Min = NULL;
-static int32_t *RawData_Diff_Max = NULL;
-static int32_t *RawData_FWMutual = NULL;
-static int32_t *RawData_FW_CC = NULL;
-static int32_t *RawData_FW_CC_I = NULL;
-static int32_t *RawData_FW_CC_Q = NULL;
-
-static struct proc_dir_entry *NVT_proc_selftest_entry = NULL;
-#if NVT_TOUCH_MP_LENOVO
-static struct proc_dir_entry *NVT_proc_selftest_read_data = NULL;
-#endif
-static int8_t nvt_mp_test_result_printed = 0;
-
-extern void nvt_change_mode(uint8_t mode);
-extern uint8_t nvt_get_fw_pipe(void);
-extern void nvt_read_mdata(uint32_t xdata_addr, uint32_t xdata_btn_addr);
-extern void nvt_get_mdata(int32_t *buf, uint8_t *m_x_num, uint8_t *m_y_num);
-void nvt_mp_parse_dt(struct device_node *root, const char *node_compatible);
-extern int32_t nvt_read_mass_data(uint32_t xdata_addr, uint8_t *temp_buf, uint32_t len);
-
-/*******************************************************
-Description:
- Novatek touchscreen allocate buffer for mp selftest.
-
-return:
- Executive outcomes. 0---succeed. -12---Out of memory
-*******************************************************/
-static int nvt_mp_buffer_init(void)
-{
- size_t RecordResult_BufSize = IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE;
- size_t RawData_BufSize = (IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE) * sizeof(int32_t);
-
- RecordResult_Short = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
- if (!RecordResult_Short) {
- NVT_ERR("kzalloc for RecordResult_Short failed!\n");
- return -ENOMEM;
- }
-
- RecordResult_Short_Diff = RecordResult_Short;
-
- RecordResult_Short_Base = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
- if (!RecordResult_Short_Base) {
- NVT_ERR("kzalloc for RecordResult_Short_Base failed!\n");
- return -ENOMEM;
- }
-
- RecordResult_Open = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
- if (!RecordResult_Open) {
- NVT_ERR("kzalloc for RecordResult_Open failed!\n");
- return -ENOMEM;
- }
-
- RecordResult_FWMutual = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
- if (!RecordResult_FWMutual) {
- NVT_ERR("kzalloc for RecordResult_FWMutual failed!\n");
- return -ENOMEM;
- }
-
- RecordResult_FW_CC = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
- if (!RecordResult_FW_CC) {
- NVT_ERR("kzalloc for RecordResult_FW_CC failed!\n");
- return -ENOMEM;
- }
-
- RecordResult_FW_CC_I = RecordResult_FW_CC;
-
- RecordResult_FW_CC_Q = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
- if (!RecordResult_FW_CC_Q) {
- NVT_ERR("kzalloc for RecordResult_FW_CC_Q failed!\n");
- return -ENOMEM;
- }
-
- RecordResult_FW_DiffMax = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
- if (!RecordResult_FW_DiffMax) {
- NVT_ERR("kzalloc for RecordResult_FW_DiffMax failed!\n");
- return -ENOMEM;
- }
-
- RecordResult_FW_DiffMin = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
- if (!RecordResult_FW_DiffMin) {
- NVT_ERR("kzalloc for RecordResult_FW_DiffMin failed!\n");
- return -ENOMEM;
- }
-
- RawData_Short = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
- if (!RawData_Short) {
- NVT_ERR("kzalloc for RawData_Short failed!\n");
- return -ENOMEM;
- }
-
- RawData_Short_Diff = RawData_Short;
-
- RawData_Short_Base = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
- if (!RawData_Short_Base) {
- NVT_ERR("kzalloc for RawData_Short_Base failed!\n");
- return -ENOMEM;
- }
-
- RawData_Open = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
- if (!RawData_Open) {
- NVT_ERR("kzalloc for RawData_Open failed!\n");
- return -ENOMEM;
- }
-
- RawData_Diff = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
- if (!RawData_Diff) {
- NVT_ERR("kzalloc for RawData_Diff failed!\n");
- return -ENOMEM;
- }
-
- RawData_Diff_Min = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
- if (!RawData_Diff_Min) {
- NVT_ERR("kzalloc for RawData_Diff_Min failed!\n");
- return -ENOMEM;
- }
-
- RawData_Diff_Max = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
- if (!RawData_Diff_Max) {
- NVT_ERR("kzalloc for RawData_Diff_Max failed!\n");
- return -ENOMEM;
- }
-
- RawData_FWMutual = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
- if (!RawData_FWMutual) {
- NVT_ERR("kzalloc for RawData_FWMutual failed!\n");
- return -ENOMEM;
- }
-
- RawData_FW_CC = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
- if (!RawData_FW_CC) {
- NVT_ERR("kzalloc for RawData_FW_CC failed!\n");
- return -ENOMEM;
- }
-
- RawData_FW_CC_I = RawData_FW_CC;
-
- RawData_FW_CC_Q = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
- if (!RawData_FW_CC_Q) {
- NVT_ERR("kzalloc for RawData_FW_CC_Q failed!\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen self-test criteria print function.
-
-return:
- n.a.
-*******************************************************/
-static void nvt_print_lmt_array(int32_t *array, int32_t x_ch, int32_t y_ch)
-{
- int32_t i = 0;
- int32_t j = 0;
-#if TOUCH_KEY_NUM > 0
- int32_t k = 0;
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- for (j = 0; j < y_ch; j++) {
- for(i = 0; i < x_ch; i++) {
- printk("%5d, ", array[j * x_ch + i]);
- }
- printk("\n");
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- printk("%5d, ", array[y_ch * x_ch + k]);
- }
- printk("\n");
-#endif /* #if TOUCH_KEY_NUM > 0 */
-}
-
-static void nvt_print_criteria(void)
-{
- NVT_LOG("++\n");
-
- if (ts->carrier_system) {
- //---PS_Config_Lmt_Short_Diff---
- printk("PS_Config_Lmt_Short_Diff_P:\n");
- nvt_print_lmt_array(PS_Config_Lmt_Short_Diff_P, X_Channel, Y_Channel);
- printk("PS_Config_Lmt_Short_Diff_N:\n");
- nvt_print_lmt_array(PS_Config_Lmt_Short_Diff_N, X_Channel, Y_Channel);
- //---PS_Config_Lmt_Short_Base---
- printk("PS_Config_Lmt_Short_Base_P:\n");
- nvt_print_lmt_array(PS_Config_Lmt_Short_Base_P, X_Channel, Y_Channel);
- printk("PS_Config_Lmt_Short_Base_N:\n");
- nvt_print_lmt_array(PS_Config_Lmt_Short_Base_N, X_Channel, Y_Channel);
- } else {
- //---PS_Config_Lmt_Short_Rawdata---
- printk("PS_Config_Lmt_Short_Rawdata_P:\n");
- nvt_print_lmt_array(PS_Config_Lmt_Short_Rawdata_P, X_Channel, Y_Channel);
- printk("PS_Config_Lmt_Short_Rawdata_N:\n");
- nvt_print_lmt_array(PS_Config_Lmt_Short_Rawdata_N, X_Channel, Y_Channel);
- }
-
- //---PS_Config_Lmt_Open_Rawdata---
- printk("PS_Config_Lmt_Open_Rawdata_P:\n");
- nvt_print_lmt_array(PS_Config_Lmt_Open_Rawdata_P, X_Channel, Y_Channel);
- printk("PS_Config_Lmt_Open_Rawdata_N:\n");
- nvt_print_lmt_array(PS_Config_Lmt_Open_Rawdata_N, X_Channel, Y_Channel);
-
- //---PS_Config_Lmt_FW_Rawdata---
- printk("PS_Config_Lmt_FW_Rawdata_P:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_Rawdata_P, X_Channel, Y_Channel);
- printk("PS_Config_Lmt_FW_Rawdata_N:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_Rawdata_N, X_Channel, Y_Channel);
-
- if (ts->carrier_system) {
- //---PS_Config_Lmt_FW_CC_I---
- printk("PS_Config_Lmt_FW_CC_I_P:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_CC_I_P, X_Channel, Y_Channel);
- printk("PS_Config_Lmt_FW_CC_I_N:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_CC_I_N, X_Channel, Y_Channel);
- //---PS_Config_Lmt_FW_CC_Q---
- printk("PS_Config_Lmt_FW_CC_Q_P:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_CC_Q_P, X_Channel, Y_Channel);
- printk("PS_Config_Lmt_FW_CC_Q_N:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_CC_Q_N, X_Channel, Y_Channel);
- } else {
- //---PS_Config_Lmt_FW_CC---
- printk("PS_Config_Lmt_FW_CC_P:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_CC_P, X_Channel, Y_Channel);
- printk("PS_Config_Lmt_FW_CC_N:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_CC_N, X_Channel, Y_Channel);
- }
-
- //---PS_Config_Lmt_FW_Diff---
- printk("PS_Config_Lmt_FW_Diff_P:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_Diff_P, X_Channel, Y_Channel);
- printk("PS_Config_Lmt_FW_Diff_N:\n");
- nvt_print_lmt_array(PS_Config_Lmt_FW_Diff_N, X_Channel, Y_Channel);
-
- NVT_LOG("--\n");
-}
-
-static int32_t nvt_save_rawdata_to_csv(int32_t *rawdata, uint8_t x_ch, uint8_t y_ch, const char *file_path, uint32_t offset)
-{
- int32_t x = 0;
- int32_t y = 0;
- int32_t iArrayIndex = 0;
-#if TOUCH_KEY_NUM > 0
- int32_t k = 0;
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- printk("%s:++%s\n", __func__, file_path);
-
- for (y = 0; y < y_ch; y++) {
- for (x = 0; x < x_ch; x++) {
- iArrayIndex = y * x_ch + x;
- printk("%5d, ", rawdata[iArrayIndex]);
- }
- printk("\n");
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = y_ch * x_ch + k;
- printk("%5d, ", rawdata[iArrayIndex]);
- }
- printk("\n");
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- printk("%s:--\n", __func__);
-
- return 0;
-}
-
-static int32_t nvt_polling_hand_shake_status(void)
-{
- uint8_t buf[8] = {0};
- int32_t i = 0;
- const int32_t retry = 50;
-
- for (i = 0; i < retry; i++) {
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---read fw status---
- buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
- buf[1] = 0x00;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
-
- if ((buf[1] == 0xA0) || (buf[1] == 0xA1))
- break;
-
- msleep(10);
- }
-
- if (i >= retry) {
- NVT_ERR("polling hand shake status failed, buf[1]=0x%02X\n", buf[1]);
-
- // Read back 5 bytes from offset EVENT_MAP_HOST_CMD for debug check
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- buf[0] = EVENT_MAP_HOST_CMD;
- buf[1] = 0x00;
- buf[2] = 0x00;
- buf[3] = 0x00;
- buf[4] = 0x00;
- buf[5] = 0x00;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 6);
- NVT_ERR("Read back 5 bytes from offset EVENT_MAP_HOST_CMD: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", buf[1], buf[2], buf[3], buf[4], buf[5]);
-
- return -1;
- } else {
- return 0;
- }
-}
-
-static int8_t nvt_switch_FreqHopEnDis(uint8_t FreqHopEnDis)
-{
- uint8_t buf[8] = {0};
- uint8_t retry = 0;
- int8_t ret = 0;
-
- NVT_LOG("++\n");
-
- for (retry = 0; retry < 20; retry++) {
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---switch FreqHopEnDis---
- buf[0] = EVENT_MAP_HOST_CMD;
- buf[1] = FreqHopEnDis;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
-
- msleep(35);
-
- buf[0] = EVENT_MAP_HOST_CMD;
- buf[1] = 0xFF;
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
-
- if (buf[1] == 0x00)
- break;
- }
-
- if (unlikely(retry == 20)) {
- NVT_ERR("switch FreqHopEnDis 0x%02X failed, buf[1]=0x%02X\n", FreqHopEnDis, buf[1]);
- ret = -1;
- }
-
- NVT_LOG("--\n");
-
- return ret;
-}
-
-static int32_t nvt_read_baseline(int32_t *xdata)
-{
- uint8_t x_num = 0;
- uint8_t y_num = 0;
- uint32_t x = 0;
- uint32_t y = 0;
- int32_t iArrayIndex = 0;
-#if TOUCH_KEY_NUM > 0
- int32_t k = 0;
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- NVT_LOG("++\n");
-
- nvt_read_mdata(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_BTN_ADDR);
-
- nvt_get_mdata(xdata, &x_num, &y_num);
-
- for (y = 0; y < y_num; y++) {
- for (x = 0; x < x_num; x++) {
- iArrayIndex = y * x_num + x;
- if (ts->carrier_system) {
- xdata[iArrayIndex] = (uint16_t)xdata[iArrayIndex];
- } else {
- xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex];
- }
- }
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = Y_Channel * X_Channel + k;
- if (ts->carrier_system) {
- xdata[iArrayIndex] = (uint16_t)xdata[iArrayIndex];
- } else {
- xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex];
- }
- }
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- printk("%s:\n", __func__);
- // Save Rawdata to CSV file
- if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, FW_RAWDATA_CSV_FILE, 0) < 0) {
- NVT_ERR("save rawdata to CSV file failed\n");
- return -EAGAIN;
- }
-
- NVT_LOG("--\n");
-
- return 0;
-}
-
-static int32_t nvt_read_CC(int32_t *xdata)
-{
- uint8_t x_num = 0;
- uint8_t y_num = 0;
- uint32_t x = 0;
- uint32_t y = 0;
- int32_t iArrayIndex = 0;
- int32_t xdata_tmp = 0;
-#if TOUCH_KEY_NUM > 0
- int32_t k = 0;
-#endif /* #if TOUCH_KEY_NUM > 0 */
- uint32_t rawdata_cc_q_offset = 0;
-
- NVT_LOG("++\n");
-
- if (nvt_get_fw_pipe() == 0)
- nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, ts->mmap->DIFF_BTN_PIPE1_ADDR);
- else
- nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, ts->mmap->DIFF_BTN_PIPE0_ADDR);
-
- nvt_get_mdata(xdata, &x_num, &y_num);
-
- for (y = 0; y < y_num; y++) {
- for (x = 0; x < x_num; x++) {
- iArrayIndex = y * x_num + x;
- if (ts->carrier_system) {
- xdata_tmp = xdata[iArrayIndex];
- RawData_FW_CC_I[iArrayIndex] = (uint8_t)(xdata_tmp & 0xFF);
- RawData_FW_CC_Q[iArrayIndex] = (uint8_t)((xdata_tmp >> 8) & 0xFF);
- } else {
- xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex];
- }
- }
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = Y_Channel * X_Channel + k;
- if (ts->carrier_system) {
- xdata_tmp = xdata[iArrayIndex];
- RawData_FW_CC_I[iArrayIndex] = (uint8_t)(xdata_tmp & 0xFF);
- RawData_FW_CC_Q[iArrayIndex] = (uint8_t)((xdata_tmp >> 8) & 0xFF);
- } else {
- xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex];
- }
- }
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- printk("%s:\n", __func__);
- if (ts->carrier_system) {
- printk("%s:RawData_CC_I:\n", __func__);
- // Save Rawdata to CSV file
- if (nvt_save_rawdata_to_csv(RawData_FW_CC_I, X_Channel, Y_Channel, FW_CC_CSV_FILE, 0) < 0) {
- NVT_ERR("save rawdata to CSV file failed\n");
- return -EAGAIN;
- }
-#if TOUCH_KEY_NUM > 0
- rawdata_cc_q_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2 + Key_Channel * 7 + 2;
-#else
- rawdata_cc_q_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2;
-#endif /* #if TOUCH_KEY_NUM > 0 */
- printk("%s:RawData_CC_Q:\n", __func__);
- // Save Rawdata to CSV file
- if (nvt_save_rawdata_to_csv(RawData_FW_CC_Q, X_Channel, Y_Channel, FW_CC_CSV_FILE, rawdata_cc_q_offset) < 0) {
- NVT_ERR("save rawdata to CSV file failed\n");
- return -EAGAIN;
- }
- } else {
- // Save Rawdata to CSV file
- if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, FW_CC_CSV_FILE, 0) < 0) {
- NVT_ERR("save rawdata to CSV file failed\n");
- return -EAGAIN;
- }
- }
-
- NVT_LOG("--\n");
-
- return 0;
-}
-
-static void nvt_enable_noise_collect(int32_t frame_num)
-{
- uint8_t buf[8] = {0};
-
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---enable noise collect---
- buf[0] = EVENT_MAP_HOST_CMD;
- buf[1] = 0x47;
- buf[2] = 0xAA;
- buf[3] = frame_num;
- buf[4] = 0x00;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 5);
-}
-
-static int32_t nvt_read_fw_noise(int32_t *xdata)
-{
- uint8_t x_num = 0;
- uint8_t y_num = 0;
- uint32_t x = 0;
- uint32_t y = 0;
- int32_t iArrayIndex = 0;
- int32_t frame_num = 0;
- uint32_t rawdata_diff_min_offset = 0;
-#if TOUCH_KEY_NUM > 0
- int32_t k = 0;
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- NVT_LOG("++\n");
-
- //---Enter Test Mode---
- if (nvt_clear_fw_status()) {
- return -EAGAIN;
- }
-
- frame_num = PS_Config_Diff_Test_Frame / 10;
- if (frame_num <= 0)
- frame_num = 1;
- printk("%s: frame_num=%d\n", __func__, frame_num);
- nvt_enable_noise_collect(frame_num);
- // need wait PS_Config_Diff_Test_Frame * 8.3ms
- msleep(frame_num * 83);
-
- if (nvt_polling_hand_shake_status()) {
- return -EAGAIN;
- }
-
- if (nvt_get_fw_info()) {
- return -EAGAIN;
- }
-
- if (nvt_get_fw_pipe() == 0)
- nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, ts->mmap->DIFF_BTN_PIPE0_ADDR);
- else
- nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, ts->mmap->DIFF_BTN_PIPE1_ADDR);
-
- nvt_get_mdata(xdata, &x_num, &y_num);
-
- for (y = 0; y < y_num; y++) {
- for (x = 0; x < x_num; x++) {
- iArrayIndex = y * x_num + x;
- if (ts->carrier_system) {
- RawData_Diff_Max[iArrayIndex] = (uint16_t)xdata[iArrayIndex];
- RawData_Diff_Min[iArrayIndex] = 0;
- } else {
- RawData_Diff_Max[iArrayIndex] = (int8_t)((xdata[iArrayIndex] >> 8) & 0xFF);
- RawData_Diff_Min[iArrayIndex] = (int8_t)(xdata[iArrayIndex] & 0xFF);
- }
- }
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = Y_Channel * X_Channel + k;
- if (ts->carrier_system) {
- RawData_Diff_Max[iArrayIndex] = (uint16_t)xdata[iArrayIndex];
- RawData_Diff_Min[iArrayIndex] = 0;
- } else {
- RawData_Diff_Max[iArrayIndex] = (int8_t)((xdata[iArrayIndex] >> 8) & 0xFF);
- RawData_Diff_Min[iArrayIndex] = (int8_t)(xdata[iArrayIndex] & 0xFF);
- }
- }
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- //---Leave Test Mode---
- nvt_change_mode(NORMAL_MODE);
-
- printk("%s:RawData_Diff_Max:\n", __func__);
- // Save Rawdata to CSV file
- if (nvt_save_rawdata_to_csv(RawData_Diff_Max, X_Channel, Y_Channel, NOISE_TEST_CSV_FILE, 0) < 0) {
- NVT_ERR("save rawdata to CSV file failed\n");
- return -EAGAIN;
- }
-
- if (!ts->carrier_system) {
-#if TOUCH_KEY_NUM > 0
- rawdata_diff_min_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2 + Key_Channel * 7 + 2;
-#else
- rawdata_diff_min_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2;
-#endif /* #if TOUCH_KEY_NUM > 0 */
- printk("%s:RawData_Diff_Min:\n", __func__);
- // Save Rawdata to CSV file
- if (nvt_save_rawdata_to_csv(RawData_Diff_Min, X_Channel, Y_Channel, NOISE_TEST_CSV_FILE, rawdata_diff_min_offset) < 0) {
- NVT_ERR("save rawdata to CSV file failed\n");
- return -EAGAIN;
- }
- }
-
- NVT_LOG("--\n");
-
- return 0;
-}
-
-static void nvt_enable_open_test(void)
-{
- uint8_t buf[8] = {0};
-
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---enable open test---
- buf[0] = EVENT_MAP_HOST_CMD;
- buf[1] = 0x45;
- buf[2] = 0xAA;
- buf[3] = 0x02;
- buf[4] = 0x00;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 5);
-}
-
-static void nvt_enable_short_test(void)
-{
- uint8_t buf[8] = {0};
-
- //---set xdata index to EVENT BUF ADDR---
- buf[0] = 0xFF;
- buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
- buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
-
- //---enable short test---
- buf[0] = EVENT_MAP_HOST_CMD;
- buf[1] = 0x43;
- buf[2] = 0xAA;
- buf[3] = 0x02;
- buf[4] = 0x00;
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 5);
-}
-
-static int32_t nvt_read_fw_open(int32_t *xdata)
-{
- uint32_t raw_pipe_addr = 0;
- uint8_t *rawdata_buf = NULL;
- uint32_t x = 0;
- uint32_t y = 0;
- uint8_t buf[128] = {0};
-#if TOUCH_KEY_NUM > 0
- uint32_t raw_btn_pipe_addr = 0;
- int32_t k = 0;
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- NVT_LOG("++\n");
-
- //---Enter Test Mode---
- if (nvt_clear_fw_status()) {
- return -EAGAIN;
- }
-
- nvt_enable_open_test();
-
- if (nvt_polling_hand_shake_status()) {
- return -EAGAIN;
- }
-
-#if TOUCH_KEY_NUM > 0
- rawdata_buf = (uint8_t *)kzalloc((IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE) * 2, GFP_KERNEL);
-#else
- rawdata_buf = (uint8_t *)kzalloc(IC_X_CFG_SIZE * IC_Y_CFG_SIZE * 2, GFP_KERNEL);
-#endif /* #if TOUCH_KEY_NUM > 0 */
- if (!rawdata_buf) {
- NVT_ERR("kzalloc for rawdata_buf failed!\n");
- return -ENOMEM;
- }
-
- if (nvt_get_fw_pipe() == 0)
- raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR;
- else
- raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR;
-
- for (y = 0; y < IC_Y_CFG_SIZE; y++) {
- //---change xdata index---
- buf[0] = 0xFF;
- buf[1] = (uint8_t)(((raw_pipe_addr + y * IC_X_CFG_SIZE * 2) >> 16) & 0xFF);
- buf[2] = (uint8_t)(((raw_pipe_addr + y * IC_X_CFG_SIZE * 2) >> 8) & 0xFF);
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
- buf[0] = (uint8_t)((raw_pipe_addr + y * IC_X_CFG_SIZE * 2) & 0xFF);
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, IC_X_CFG_SIZE * 2 + 1);
- memcpy(rawdata_buf + y * IC_X_CFG_SIZE * 2, buf + 1, IC_X_CFG_SIZE * 2);
- }
-#if TOUCH_KEY_NUM > 0
- if (nvt_get_fw_pipe() == 0)
- raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE0_ADDR;
- else
- raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE1_ADDR;
-
- //---change xdata index---
- buf[0] = 0xFF;
- buf[1] = (uint8_t)((raw_btn_pipe_addr >> 16) & 0xFF);
- buf[2] = (uint8_t)((raw_btn_pipe_addr >> 8) & 0xFF);
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
- buf[0] = (uint8_t)(raw_btn_pipe_addr & 0xFF);
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, IC_KEY_CFG_SIZE * 2 + 1);
- memcpy(rawdata_buf + IC_Y_CFG_SIZE * IC_X_CFG_SIZE * 2, buf + 1, IC_KEY_CFG_SIZE * 2);
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- for (y = 0; y < IC_Y_CFG_SIZE; y++) {
- for (x = 0; x < IC_X_CFG_SIZE; x++) {
- if ((AIN_Y[y] != 0xFF) && (AIN_X[x] != 0xFF)) {
- xdata[AIN_Y[y] * X_Channel + AIN_X[x]] = (int16_t)((rawdata_buf[(y * IC_X_CFG_SIZE + x) * 2] + 256 * rawdata_buf[(y * IC_X_CFG_SIZE + x) * 2 + 1]));
- }
- }
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < IC_KEY_CFG_SIZE; k++) {
- if (AIN_KEY[k] != 0xFF)
- xdata[Y_Channel * X_Channel + AIN_KEY[k]] = (int16_t)(rawdata_buf[(IC_Y_CFG_SIZE * IC_X_CFG_SIZE + k) * 2] + 256 * rawdata_buf[(IC_Y_CFG_SIZE * IC_X_CFG_SIZE + k) * 2 + 1]);
- }
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- if (rawdata_buf) {
- kfree(rawdata_buf);
- rawdata_buf = NULL;
- }
-
- //---Leave Test Mode---
- nvt_change_mode(NORMAL_MODE);
-
-
- printk("%s:RawData_Open\n", __func__);
- // Save RawData to CSV file
- if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, OPEN_TEST_CSV_FILE, 0) < 0) {
- NVT_ERR("save rawdata to CSV file failed\n");
- return -EAGAIN;
- }
-
- NVT_LOG("--\n");
-
- return 0;
-}
-
-static int32_t nvt_read_fw_short(int32_t *xdata)
-{
- uint32_t raw_pipe_addr = 0;
- uint8_t *rawdata_buf = NULL;
- uint32_t x = 0;
- uint32_t y = 0;
- uint8_t buf[128] = {0};
- int32_t iArrayIndex = 0;
-#if TOUCH_KEY_NUM > 0
- uint32_t raw_btn_pipe_addr = 0;
- int32_t k = 0;
-#endif /* #if TOUCH_KEY_NUM > 0 */
- uint32_t rawdata_short_base_offset = 0;
-
- NVT_LOG("++\n");
-
- //---Enter Test Mode---
- if (nvt_clear_fw_status()) {
- return -EAGAIN;
- }
-
- nvt_enable_short_test();
-
- if (nvt_polling_hand_shake_status()) {
- return -EAGAIN;
- }
-
-#if TOUCH_KEY_NUM > 0
- rawdata_buf = (uint8_t *)kzalloc((X_Channel * Y_Channel + Key_Channel) * 2, GFP_KERNEL);
-#else
- rawdata_buf = (uint8_t *)kzalloc(X_Channel * Y_Channel * 2, GFP_KERNEL);
-#endif /* #if TOUCH_KEY_NUM > 0 */
- if (!rawdata_buf) {
- NVT_ERR("kzalloc for rawdata_buf failed!\n");
- return -ENOMEM;
- }
-
- if (ts->carrier_system) {
- // to get short diff rawdata at pipe0
- raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR;
- } else {
- if (nvt_get_fw_pipe() == 0)
- raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR;
- else
- raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR;
- }
-
- for (y = 0; y < Y_Channel; y++) {
- //---change xdata index---
- buf[0] = 0xFF;
- buf[1] = (uint8_t)(((raw_pipe_addr + y * X_Channel * 2) >> 16) & 0xFF);
- buf[2] = (uint8_t)(((raw_pipe_addr + y * X_Channel * 2) >> 8) & 0xFF);
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
- buf[0] = (uint8_t)((raw_pipe_addr + y * X_Channel * 2) & 0xFF);
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, X_Channel * 2 + 1);
- memcpy(rawdata_buf + y * X_Channel * 2, buf + 1, X_Channel * 2);
- }
-#if TOUCH_KEY_NUM > 0
- if (ts->carrier_system) {
- // to get button short diff rawdata at pipe0
- raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE0_ADDR;
- } else {
- if (nvt_get_fw_pipe() == 0)
- raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE0_ADDR;
- else
- raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE1_ADDR;
- }
-
- //---change xdata index---
- buf[0] = 0xFF;
- buf[1] = (uint8_t)((raw_btn_pipe_addr >> 16) & 0xFF);
- buf[2] = (uint8_t)((raw_btn_pipe_addr >> 8) & 0xFF);
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
- buf[0] = (uint8_t)(raw_btn_pipe_addr & 0xFF);
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, Key_Channel * 2 + 1);
- memcpy(rawdata_buf + Y_Channel * X_Channel * 2, buf + 1, Key_Channel * 2);
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- for (y = 0; y < Y_Channel; y++) {
- for (x = 0; x < X_Channel; x++) {
- iArrayIndex = y * X_Channel + x;
- xdata[iArrayIndex] = (int16_t)(rawdata_buf[iArrayIndex * 2] + 256 * rawdata_buf[iArrayIndex * 2 + 1]);
- }
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = Y_Channel * X_Channel + k;
- xdata[iArrayIndex] = (int16_t)(rawdata_buf[iArrayIndex * 2] + 256 * rawdata_buf[iArrayIndex * 2 + 1]);
- }
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- // for carrier sensing system to get short baseline rawdata
- if (ts->carrier_system) {
- // to get short baseline rawdata at pipe1
- raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR;
-
- for (y = 0; y < Y_Channel; y++) {
- //---change xdata index---
- buf[0] = 0xFF;
- buf[1] = (uint8_t)(((raw_pipe_addr + y * X_Channel * 2) >> 16) & 0xFF);
- buf[2] = (uint8_t)(((raw_pipe_addr + y * X_Channel * 2) >> 8) & 0xFF);
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
- buf[0] = (uint8_t)((raw_pipe_addr + y * X_Channel * 2) & 0xFF);
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, X_Channel * 2 + 1);
- memcpy(rawdata_buf + y * X_Channel * 2, buf + 1, X_Channel * 2);
- }
-#if TOUCH_KEY_NUM > 0
- // to get button short baseline rawdata at pipe1
- raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE1_ADDR;
-
- //---change xdata index---
- buf[0] = 0xFF;
- buf[1] = (uint8_t)((raw_btn_pipe_addr >> 16) & 0xFF);
- buf[2] = (uint8_t)((raw_btn_pipe_addr >> 8) & 0xFF);
- CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
- buf[0] = (uint8_t)(raw_btn_pipe_addr & 0xFF);
- CTP_I2C_READ(ts->client, I2C_FW_Address, buf, Key_Channel * 2 + 1);
- memcpy(rawdata_buf + Y_Channel * X_Channel * 2, buf + 1, Key_Channel * 2);
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- for (y = 0; y < Y_Channel; y++) {
- for (x = 0; x < X_Channel; x++) {
- iArrayIndex = y * X_Channel + x;
- RawData_Short_Base[iArrayIndex] = (int16_t)(rawdata_buf[iArrayIndex * 2] + 256 * rawdata_buf[iArrayIndex * 2 + 1]);
- }
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = Y_Channel * X_Channel + k;
- RawData_Short_Base[iArrayIndex] = (int16_t)(rawdata_buf[iArrayIndex * 2] + 256 * rawdata_buf[iArrayIndex * 2 + 1]);
- }
-#endif /* #if TOUCH_KEY_NUM > 0 */
- }
-
- if (rawdata_buf) {
- kfree(rawdata_buf);
- rawdata_buf = NULL;
- }
-
- //---Leave Test Mode---
- nvt_change_mode(NORMAL_MODE);
-
- if (ts->carrier_system)
- printk("%s:RawData_Short_Diff:\n", __func__);
- else
- printk("%s:RawData_Short\n", __func__);
- // Save Rawdata to CSV file
- if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, SHORT_TEST_CSV_FILE, 0) < 0) {
- NVT_ERR("save rawdata to CSV file failed\n");
- return -EAGAIN;
- }
- if (ts->carrier_system) {
-#if TOUCH_KEY_NUM > 0
- rawdata_short_base_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2 + Key_Channel * 7 + 2;
-#else
- rawdata_short_base_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2;
-#endif /* #if TOUCH_KEY_NUM > 0 */
- printk("%s:RawData_Short_Base:\n", __func__);
- // Save Rawdata to CSV file
- if (nvt_save_rawdata_to_csv(RawData_Short_Base, X_Channel, Y_Channel, SHORT_TEST_CSV_FILE, rawdata_short_base_offset) < 0) {
- NVT_ERR("save rawdata to CSV file failed\n");
- return -EAGAIN;
- }
- }
-
- NVT_LOG("--\n");
-
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen raw data test for each single point function.
-
-return:
- Executive outcomes. 0---passed. negative---failed.
-*******************************************************/
-static int32_t RawDataTest_SinglePoint_Sub(int32_t rawdata[], uint8_t RecordResult[], uint8_t x_ch, uint8_t y_ch, int32_t Rawdata_Limit_Postive[], int32_t Rawdata_Limit_Negative[])
-{
- int32_t i = 0;
- int32_t j = 0;
-#if TOUCH_KEY_NUM > 0
- int32_t k = 0;
-#endif /* #if TOUCH_KEY_NUM > 0 */
- int32_t iArrayIndex = 0;
- bool isPass = true;
-
- for (j = 0; j < y_ch; j++) {
- for (i = 0; i < x_ch; i++) {
- iArrayIndex = j * x_ch + i;
-
- RecordResult[iArrayIndex] = 0x00; // default value for PASS
-
- if(rawdata[iArrayIndex] > Rawdata_Limit_Postive[iArrayIndex])
- RecordResult[iArrayIndex] |= 0x01;
-
- if(rawdata[iArrayIndex] < Rawdata_Limit_Negative[iArrayIndex])
- RecordResult[iArrayIndex] |= 0x02;
- }
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = y_ch * x_ch + k;
-
- RecordResult[iArrayIndex] = 0x00; // default value for PASS
-
- if(rawdata[iArrayIndex] > Rawdata_Limit_Postive[iArrayIndex])
- RecordResult[iArrayIndex] |= 0x01;
-
- if(rawdata[iArrayIndex] < Rawdata_Limit_Negative[iArrayIndex])
- RecordResult[iArrayIndex] |= 0x02;
- }
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- //---Check RecordResult---
- for (j = 0; j < y_ch; j++) {
- for (i = 0; i < x_ch; i++) {
- if (RecordResult[j * x_ch + i] != 0) {
- isPass = false;
- break;
- }
- }
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = y_ch * x_ch + k;
- if (RecordResult[iArrayIndex] != 0) {
- isPass = false;
- break;
- }
- }
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- if (isPass == false) {
- return -1; // FAIL
- } else {
- return 0; // PASS
- }
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen print self-test result function.
-
-return:
- n.a.
-*******************************************************/
-void print_selftest_result(struct seq_file *m, int32_t TestResult, uint8_t RecordResult[], int32_t rawdata[], uint8_t x_len, uint8_t y_len)
-{
- int32_t i = 0;
- int32_t j = 0;
- int32_t iArrayIndex = 0;
-#if TOUCH_KEY_NUM > 0
- int32_t k = 0;
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
- switch (TestResult) {
- case 0:
- nvt_mp_seq_printf(m, " PASS!\n");
- break;
-
- case 1:
- nvt_mp_seq_printf(m, " ERROR! Read Data FAIL!\n");
- break;
-
- case -1:
- nvt_mp_seq_printf(m, " FAIL!\n");
- nvt_mp_seq_printf(m, "RecordResult:\n");
- for (i = 0; i < y_len; i++) {
- for (j = 0; j < x_len; j++) {
- iArrayIndex = i * x_len + j;
- nvt_mp_seq_printf(m, "0x%02X, ", RecordResult[iArrayIndex]);
- }
- nvt_mp_seq_printf(m, "\n");
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = y_len * x_len + k;
- nvt_mp_seq_printf(m, "0x%02X, ", RecordResult[iArrayIndex]);
- }
- nvt_mp_seq_printf(m, "\n");
-#endif /* #if TOUCH_KEY_NUM > 0 */
- nvt_mp_seq_printf(m, "ReadData:\n");
- for (i = 0; i < y_len; i++) {
- for (j = 0; j < x_len; j++) {
- iArrayIndex = i * x_len + j;
- nvt_mp_seq_printf(m, "%5d, ", rawdata[iArrayIndex]);
- }
- nvt_mp_seq_printf(m, "\n");
- }
-#if TOUCH_KEY_NUM > 0
- for (k = 0; k < Key_Channel; k++) {
- iArrayIndex = y_len * x_len + k;
- nvt_mp_seq_printf(m, "%5d, ", rawdata[iArrayIndex]);
- }
- nvt_mp_seq_printf(m, "\n");
-#endif /* #if TOUCH_KEY_NUM > 0 */
- break;
- }
- nvt_mp_seq_printf(m, "\n");
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen self-test sequence print show
- function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t c_show_selftest(struct seq_file *m, void *v)
-{
-#if NVT_TOUCH_MP_LENOVO
- MP_TEST_RESULT mp_result = 0;
-#endif
-
- NVT_LOG("++\n");
-#if !NVT_TOUCH_MP_LENOVO
- nvt_mp_seq_printf(m, "FW Version: %d\n\n", ts->fw_ver);
-
- nvt_mp_seq_printf(m, "Short Test");
- if ((TestResult_Short == 0) || (TestResult_Short == 1)) {
- print_selftest_result(m, TestResult_Short, RecordResult_Short, RawData_Short, X_Channel, Y_Channel);
- } else { // TestResult_Short is -1
- if (ts->carrier_system) {
- nvt_mp_seq_printf(m, " FAIL!\n");
- if (TestResult_Short_Diff == -1) {
- nvt_mp_seq_printf(m, "Short Diff");
- print_selftest_result(m, TestResult_Short_Diff, RecordResult_Short_Diff, RawData_Short_Diff, X_Channel, Y_Channel);
- }
- if (TestResult_Short_Base == -1) {
- nvt_mp_seq_printf(m, "Short Base");
- print_selftest_result(m, TestResult_Short_Base, RecordResult_Short_Base, RawData_Short_Base, X_Channel, Y_Channel);
- }
- } else {
- print_selftest_result(m, TestResult_Short, RecordResult_Short, RawData_Short, X_Channel, Y_Channel);
- }
- }
-
- nvt_mp_seq_printf(m, "Open Test");
- print_selftest_result(m, TestResult_Open, RecordResult_Open, RawData_Open, X_Channel, Y_Channel);
-
- nvt_mp_seq_printf(m, "FW Rawdata Test");
- if ((TestResult_FW_Rawdata == 0) || (TestResult_FW_Rawdata == 1)) {
- print_selftest_result(m, TestResult_FWMutual, RecordResult_FWMutual, RawData_FWMutual, X_Channel, Y_Channel);
- } else { // TestResult_FW_Rawdata is -1
- nvt_mp_seq_printf(m, " FAIL!\n");
- if (TestResult_FWMutual == -1) {
- nvt_mp_seq_printf(m, "FW Mutual");
- print_selftest_result(m, TestResult_FWMutual, RecordResult_FWMutual, RawData_FWMutual, X_Channel, Y_Channel);
- }
- if (TestResult_FW_CC == -1) {
- if (ts->carrier_system) {
- if (TestResult_FW_CC_I == -1) {
- nvt_mp_seq_printf(m, "FW CC_I");
- print_selftest_result(m, TestResult_FW_CC_I, RecordResult_FW_CC_I, RawData_FW_CC_I, X_Channel, Y_Channel);
- }
- if (TestResult_FW_CC_Q == -1) {
- nvt_mp_seq_printf(m, "FW CC_Q");
- print_selftest_result(m, TestResult_FW_CC_Q, RecordResult_FW_CC_Q, RawData_FW_CC_Q, X_Channel, Y_Channel);
- }
- } else {
- nvt_mp_seq_printf(m, "FW CC");
- print_selftest_result(m, TestResult_FW_CC, RecordResult_FW_CC, RawData_FW_CC, X_Channel, Y_Channel);
- }
- }
- }
-
- nvt_mp_seq_printf(m, "Noise Test");
- if ((TestResult_Noise == 0) || (TestResult_Noise == 1)) {
- print_selftest_result(m, TestResult_FW_DiffMax, RecordResult_FW_DiffMax, RawData_Diff_Max, X_Channel, Y_Channel);
- } else { // TestResult_Noise is -1
- nvt_mp_seq_printf(m, " FAIL!\n");
-
- if (TestResult_FW_DiffMax == -1) {
- nvt_mp_seq_printf(m, "FW Diff Max");
- print_selftest_result(m, TestResult_FW_DiffMax, RecordResult_FW_DiffMax, RawData_Diff_Max, X_Channel, Y_Channel);
- }
- if (TestResult_FW_DiffMin == -1) {
- nvt_mp_seq_printf(m, "FW Diff Min");
- print_selftest_result(m, TestResult_FW_DiffMin, RecordResult_FW_DiffMin, RawData_Diff_Min, X_Channel, Y_Channel);
- }
- }
-#else
- /* short */
- if (TestResult_Short >= 0)
- mp_result |= (!!TestResult_Short << MP_RESULT_SHIFT_SHORT);
- else {
- if (ts->carrier_system) {
- mp_result |= (!!TestResult_Short_Diff << MP_RESULT_SHIFT_SHORT_DIFF);
- mp_result |= (!!TestResult_Short_Base << MP_RESULT_SHIFT_SHORT_BASE);
- } else {
- mp_result |= (!!TestResult_Short << MP_RESULT_SHIFT_SHORT);
- }
- }
-
- /* open */
- mp_result |= (!!TestResult_Open << MP_RESULT_SHIFT_OPEN);
-
- /* raw data & cc */
- if (TestResult_FW_Rawdata >= 0)
- mp_result |= (!!TestResult_FWMutual << MP_RESULT_SHIFT_RAWDATA);
- else {
- if (TestResult_FWMutual == -1) {
- mp_result |= (!!TestResult_FWMutual << MP_RESULT_SHIFT_RAWDATA);
- }
- if (TestResult_FW_CC == -1) {
- if (ts->carrier_system) {
- mp_result |= (!!TestResult_FW_CC_I << MP_RESULT_SHIFT_CC_I);
- mp_result |= (!!TestResult_FW_CC_Q << MP_RESULT_SHIFT_CC_Q);
- } else {
- mp_result |= (!!TestResult_FW_CC << MP_RESULT_SHIFT_CC);
- }
- }
- }
-
- /* noise */
- if (TestResult_Noise >= 0)
- mp_result |= (!!TestResult_FW_DiffMax << MP_RESULT_SHIFT_DIFF_MAX);
- else {
- if (TestResult_FW_DiffMax == -1) {
- mp_result |= (!!TestResult_FW_DiffMax << MP_RESULT_SHIFT_DIFF_MAX);
- }
- if (TestResult_FW_DiffMin == -1) {
- mp_result |= (!!TestResult_FW_DiffMin << MP_RESULT_SHIFT_DIFF_MIN);
- }
- }
-
- nvt_mp_seq_printf(m, "%d", mp_result);
-#endif
- nvt_mp_test_result_printed = 1;
-
- NVT_LOG("--\n");
-
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen self-test sequence print start
- function.
-
-return:
- Executive outcomes. 1---call next function.
- NULL---not call next function and sequence loop
- stop.
-*******************************************************/
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
- return *pos < 1 ? (void *)1 : NULL;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen self-test sequence print next
- function.
-
-return:
- Executive outcomes. NULL---no next and call sequence
- stop function.
-*******************************************************/
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
- ++*pos;
- return NULL;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen self-test sequence print stop
- function.
-
-return:
- n.a.
-*******************************************************/
-static void c_stop(struct seq_file *m, void *v)
-{
- return;
-}
-
-const struct seq_operations nvt_selftest_seq_ops = {
- .start = c_start,
- .next = c_next,
- .stop = c_stop,
- .show = c_show_selftest
-};
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/nvt_selftest open function.
-
-return:
- Executive outcomes. 0---succeed. negative---failed.
-*******************************************************/
-static int32_t nvt_selftest_open(struct inode *inode, struct file *file)
-{
- struct device_node *np = ts->client->dev.of_node;
- unsigned char mpcriteria[32] = {0}; //novatek-mp-criteria-default
-
- TestResult_Short = 0;
- TestResult_Short_Diff = 0;
- TestResult_Short_Base = 0;
- TestResult_Open = 0;
- TestResult_FW_Rawdata = 0;
- TestResult_FWMutual = 0;
- TestResult_FW_CC = 0;
- TestResult_FW_CC_I = 0;
- TestResult_FW_CC_Q = 0;
- TestResult_Noise = 0;
- TestResult_FW_DiffMax = 0;
- TestResult_FW_DiffMin = 0;
-
- NVT_LOG("++\n");
-
- if (mutex_lock_interruptible(&ts->lock)) {
- return -ERESTARTSYS;
- }
-#if NVT_TOUCH_ESD_PROTECT
- nvt_esd_check_enable(false);
-#endif
-
- if (nvt_get_fw_info()) {
- mutex_unlock(&ts->lock);
- NVT_ERR("get fw info failed!\n");
- return -EAGAIN;
- }
-
- /* Parsing criteria from dts */
- if(of_property_read_bool(np, "novatek,mp-support-dt")) {
- /*
- * Parsing Criteria by Novatek PID
- * The string rule is "novatek-mp-criteria-<nvt_pid>"
- * nvt_pid is 2 bytes (show hex).
- *
- * Ex. nvt_pid = 500A
- * mpcriteria = "novatek-mp-criteria-500A"
- */
- snprintf(mpcriteria, PAGE_SIZE, "novatek-mp-criteria-%04X", ts->nvt_pid);
-
- nvt_mp_parse_dt(np, mpcriteria);
- } else {
- NVT_LOG("Not found novatek,mp-support-dt, use default setting\n");
- //---Print Test Criteria---
- nvt_print_criteria();
- }
-
- if (nvt_switch_FreqHopEnDis(FREQ_HOP_DISABLE)) {
- mutex_unlock(&ts->lock);
- NVT_ERR("switch frequency hopping disable failed!\n");
- return -EAGAIN;
- }
-
- if (nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN)) {
- mutex_unlock(&ts->lock);
- NVT_ERR("check fw reset state failed!\n");
- return -EAGAIN;
- }
-
- msleep(100);
-
- //---Enter Test Mode---
- if (nvt_clear_fw_status()) {
- mutex_unlock(&ts->lock);
- NVT_ERR("clear fw status failed!\n");
- return -EAGAIN;
- }
-
- nvt_change_mode(MP_MODE_CC);
-
- if (nvt_check_fw_status()) {
- mutex_unlock(&ts->lock);
- NVT_ERR("check fw status failed!\n");
- return -EAGAIN;
- }
-
- //---FW Rawdata Test---
- if (nvt_read_baseline(RawData_FWMutual) != 0) {
- TestResult_FWMutual = 1;
- } else {
- TestResult_FWMutual = RawDataTest_SinglePoint_Sub(RawData_FWMutual, RecordResult_FWMutual, X_Channel, Y_Channel,
- PS_Config_Lmt_FW_Rawdata_P, PS_Config_Lmt_FW_Rawdata_N);
- }
- if (nvt_read_CC(RawData_FW_CC) != 0) {
- TestResult_FW_CC = 1;
- if (ts->carrier_system) {
- TestResult_FW_CC_I = 1;
- TestResult_FW_CC_Q = 1;
- }
- } else {
- if (ts->carrier_system) {
- TestResult_FW_CC_I = RawDataTest_SinglePoint_Sub(RawData_FW_CC_I, RecordResult_FW_CC_I, X_Channel, Y_Channel,
- PS_Config_Lmt_FW_CC_I_P, PS_Config_Lmt_FW_CC_I_N);
- TestResult_FW_CC_Q = RawDataTest_SinglePoint_Sub(RawData_FW_CC_Q, RecordResult_FW_CC_Q, X_Channel, Y_Channel,
- PS_Config_Lmt_FW_CC_Q_P, PS_Config_Lmt_FW_CC_Q_N);
- if ((TestResult_FW_CC_I == -1) || (TestResult_FW_CC_Q == -1))
- TestResult_FW_CC = -1;
- else
- TestResult_FW_CC = 0;
- } else {
- TestResult_FW_CC = RawDataTest_SinglePoint_Sub(RawData_FW_CC, RecordResult_FW_CC, X_Channel, Y_Channel,
- PS_Config_Lmt_FW_CC_P, PS_Config_Lmt_FW_CC_N);
- }
- }
-
- if ((TestResult_FWMutual == 1) || (TestResult_FW_CC == 1)) {
- TestResult_FW_Rawdata = 1;
- } else {
- if ((TestResult_FWMutual == -1) || (TestResult_FW_CC == -1))
- TestResult_FW_Rawdata = -1;
- else
- TestResult_FW_Rawdata = 0;
- }
-
- //---Leave Test Mode---
- nvt_change_mode(NORMAL_MODE);
-
- //---Noise Test---
- if (nvt_read_fw_noise(RawData_Diff) != 0) {
- TestResult_Noise = 1; // 1: ERROR
- TestResult_FW_DiffMax = 1;
- TestResult_FW_DiffMin = 1;
- } else {
- TestResult_FW_DiffMax = RawDataTest_SinglePoint_Sub(RawData_Diff_Max, RecordResult_FW_DiffMax, X_Channel, Y_Channel,
- PS_Config_Lmt_FW_Diff_P, PS_Config_Lmt_FW_Diff_N);
-
- // for carrier sensing system, only positive noise data
- if (ts->carrier_system) {
- TestResult_FW_DiffMin = 0;
- } else {
- TestResult_FW_DiffMin = RawDataTest_SinglePoint_Sub(RawData_Diff_Min, RecordResult_FW_DiffMin, X_Channel, Y_Channel,
- PS_Config_Lmt_FW_Diff_P, PS_Config_Lmt_FW_Diff_N);
- }
-
- if ((TestResult_FW_DiffMax == -1) || (TestResult_FW_DiffMin == -1))
- TestResult_Noise = -1;
- else
- TestResult_Noise = 0;
- }
-
- //--Short Test---
- if (nvt_read_fw_short(RawData_Short) != 0) {
- TestResult_Short = 1; // 1:ERROR
- if (ts->carrier_system) {
- TestResult_Short_Diff = 1;
- TestResult_Short_Base = 1;
- }
- } else {
- //---Self Test Check --- // 0:PASS, -1:FAIL
- if (ts->carrier_system) {
- TestResult_Short_Diff = RawDataTest_SinglePoint_Sub(RawData_Short_Diff, RecordResult_Short_Diff, X_Channel, Y_Channel,
- PS_Config_Lmt_Short_Diff_P, PS_Config_Lmt_Short_Diff_N);
- TestResult_Short_Base = RawDataTest_SinglePoint_Sub(RawData_Short_Base, RecordResult_Short_Base, X_Channel, Y_Channel,
- PS_Config_Lmt_Short_Base_P, PS_Config_Lmt_Short_Base_N);
-
- if ((TestResult_Short_Diff == -1) || (TestResult_Short_Base == -1))
- TestResult_Short = -1;
- else
- TestResult_Short = 0;
- } else {
- TestResult_Short = RawDataTest_SinglePoint_Sub(RawData_Short, RecordResult_Short, X_Channel, Y_Channel,
- PS_Config_Lmt_Short_Rawdata_P, PS_Config_Lmt_Short_Rawdata_N);
- }
- }
-
- //---Open Test---
- if (nvt_read_fw_open(RawData_Open) != 0) {
- TestResult_Open = 1; // 1:ERROR
- } else {
- //---Self Test Check --- // 0:PASS, -1:FAIL
- TestResult_Open = RawDataTest_SinglePoint_Sub(RawData_Open, RecordResult_Open, X_Channel, Y_Channel,
- PS_Config_Lmt_Open_Rawdata_P, PS_Config_Lmt_Open_Rawdata_N);
- }
-
- //---Reset IC---
- nvt_bootloader_reset();
-
- mutex_unlock(&ts->lock);
-
- NVT_LOG("--\n");
-
- nvt_mp_test_result_printed = 0;
-
- return seq_open(file, &nvt_selftest_seq_ops);
-}
-
-static const struct file_operations nvt_selftest_fops = {
- .owner = THIS_MODULE,
- .open = nvt_selftest_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-#if NVT_TOUCH_MP_LENOVO
-/*******************************************************
-Description:
- Novatek touchscreen /proc/NVTflash read function.
-
-return:
- Executive outcomes. 2---succeed. -5,-14---failed.
-*******************************************************/
-static ssize_t nvt_data_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
-{
- uint8_t *str;
- int32_t ret = -1;
- int32_t retries = 0;
- int8_t i2c_wr = 0;
- uint8_t i2c_addr = 0;
- uint32_t data_len = 0;
-
- NVT_LOG("++\n");
-
- if (count > (40 * (40 + 4) * 2 + 7)) {
- NVT_ERR("error count=%zu\n", count);
- return -EFAULT;
- }
-
- str = kmalloc(40 * (40 + 4) * 2 + 7, GFP_KERNEL);
- if (str == NULL) {
- NVT_ERR("failed to allocated memory for input data\n");
- return -ENOMEM;
- }
-
- if (copy_from_user(str, buff, count)) {
- NVT_ERR("copy from user error\n");
- return -EFAULT;
- }
-
-#if NVT_TOUCH_ESD_PROTECT
- nvt_esd_check_enable(false);
-#endif
-
- i2c_wr = str[0] >> 7;
- i2c_addr = str[0] & 0x7F;
- data_len = (int32_t)((str[1] << 8) + str[2]);
-
- if (i2c_wr == 0) {
- return -ENOTSUPP;
- } else if (i2c_wr == 1) {
- while (retries < 20) {
- ret = nvt_read_mass_data(i2c_addr, str, data_len);
- if (ret == data_len)
- break;
- else
- NVT_ERR("error, retries=%d, ret=%d, data_len=%d\n", retries, ret, data_len);
-
- retries++;
- }
-
- if (retries < 20) {
- ret = copy_to_user(buff, str, data_len);
- if (ret) {
- NVT_ERR("error, copy_to_user, ret=%d, data_len=%d\n", ret, data_len);
- return -EFAULT;
- }
- }
-
- if (unlikely(retries == 20)) {
- NVT_ERR("error, ret = %d\n", ret);
- return -EIO;
- }
- } else {
- NVT_ERR("Call error, str[0]=%d\n", str[0]);
- return -EFAULT;
- }
-
- kfree(str);
- NVT_LOG("--\n");
- return ret;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/NVTflash open function.
-
-return:
- Executive outcomes. 0---succeed. -12---failed.
-*******************************************************/
-static int32_t nvt_data_open(struct inode *inode, struct file *file)
-{
- struct nvt_flash_data *dev;
-
- dev = kmalloc(sizeof(struct nvt_flash_data), GFP_KERNEL);
- if (dev == NULL) {
- NVT_ERR("Failed to allocate memory for nvt flash data\n");
- return -ENOMEM;
- }
-
- rwlock_init(&dev->lock);
- file->private_data = dev;
-
- return 0;
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen /proc/NVTflash close function.
-
-return:
- Executive outcomes. 0---succeed.
-*******************************************************/
-static int32_t nvt_data_close(struct inode *inode, struct file *file)
-{
- struct nvt_flash_data *dev = file->private_data;
-
- if (dev)
- kfree(dev);
-
- return 0;
-}
-
-static const struct file_operations nvt_read_data_fops = {
- .owner = THIS_MODULE,
- .open = nvt_data_open,
- .release = nvt_data_close,
- .read = nvt_data_read,
-};
-#endif
-
-#ifdef CONFIG_OF
-/*******************************************************
-Description:
- Novatek touchscreen parse AIN setting for array type.
-
-return:
- n.a.
-*******************************************************/
-void nvt_mp_parse_ain(struct device_node *np, const char *name, uint8_t *array, int32_t size)
-{
- struct property *data;
- int32_t len, ret;
- int32_t tmp[40];
- int32_t i;
-
- data = of_find_property(np, name, &len);
- len /= sizeof(u32);
-
- if ((!data) || (!len) || (len != size)) {
- NVT_ERR("error find %s. len=%d\n", name, len);
- } else {
- NVT_LOG("%s. len=%d\n", name, len);
- ret = of_property_read_u32_array(np, name, tmp, len);
- if (ret) {
- NVT_ERR("error reading %s. ret=%d\n", name, ret);
- return;
- }
-
- for (i = 0; i < len; i++)
- array[i] = tmp[i];
-
-#if NVT_DEBUG
- printk("[NVT-ts] %s = ", name);
- for (i = 0; i < len; i++) {
- printk("%02d ", array[i]);
- }
- printk("\n");
-#endif
- }
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen parse criterion for u32 type.
-
-return:
- n.a.
-*******************************************************/
-void nvt_mp_parse_u32(struct device_node *np, const char *name, int32_t *para)
-{
- int32_t ret;
-
- ret = of_property_read_u32(np, name, para);
- if (ret)
- NVT_ERR("error reading %s. ret=%d\n", name, ret);
- else {
-#if NVT_DEBUG
- NVT_LOG("%s=%d\n", name, *para);
-#endif
- }
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen parse criterion for array type.
-
-return:
- n.a.
-*******************************************************/
-void nvt_mp_parse_array(struct device_node *np, const char *name, int32_t *array,
- int32_t size)
-{
- struct property *data;
- int32_t len, ret;
-#if NVT_DEBUG
- int32_t i, j, iArrayIndex = 0;
-#endif
-
- data = of_find_property(np, name, &len);
- len /= sizeof(u32);
- if ((!data) || (!len) || (len < size)) {
- NVT_ERR("error find %s. len=%d\n", name, len);
- } else {
- NVT_LOG("%s. len=%d\n", name, len);
- ret = of_property_read_u32_array(np, name, array, len);
- if (ret) {
- NVT_ERR("error reading %s. ret=%d\n", name, ret);
- return;
- }
-
-#if NVT_DEBUG
- NVT_LOG("%s =\n", name);
- for (j = 0; j < Y_Channel; j++) {
- printk("[NVT-ts] ");
- for (i = 0; i < X_Channel; i++) {
- iArrayIndex = j * X_Channel + i;
- printk("%5d, ", array[iArrayIndex]);
- }
- printk("\n");
- }
-#if TOUCH_KEY_NUM > 0
- printk("[NVT-ts] ");
- for (i = 0; i < Key_Channel; i++) {
- iArrayIndex++;
- printk("%5d, ", array[iArrayIndex]);
- }
- printk("\n");
-#endif
-#endif
- }
-}
-
-/*******************************************************
-Description:
- Novatek touchscreen parse device tree mp function.
-
-return:
- n.a.
-*******************************************************/
-void nvt_mp_parse_dt(struct device_node *root, const char *node_compatible)
-{
- struct device_node *np = root;
- struct device_node *child = NULL;
-
- NVT_LOG("Parse mp criteria for node %s\n", node_compatible);
-
- /* find each MP sub-nodes */
- for_each_child_of_node(root, child) {
- /* find the specified node */
- if (of_device_is_compatible(child, node_compatible)) {
- NVT_LOG("found child node %s\n", node_compatible);
- np = child;
- break;
- }
- }
- if (child == NULL) {
- NVT_ERR("Not found compatible node %s, use default setting!\n", node_compatible);
- return;
- }
-
- /* MP Config*/
- nvt_mp_parse_u32(np, "IC_X_CFG_SIZE", &IC_X_CFG_SIZE);
-
- nvt_mp_parse_u32(np, "IC_Y_CFG_SIZE", &IC_Y_CFG_SIZE);
-
-#if TOUCH_KEY_NUM > 0
- nvt_mp_parse_u32(np, "IC_KEY_CFG_SIZE", &IC_KEY_CFG_SIZE);
-#endif
-
- nvt_mp_parse_u32(np, "X_Channel", &X_Channel);
-
- nvt_mp_parse_u32(np, "Y_Channel", &Y_Channel);
-
- nvt_mp_parse_ain(np, "AIN_X", AIN_X, IC_X_CFG_SIZE);
-
- nvt_mp_parse_ain(np, "AIN_Y", AIN_Y, IC_Y_CFG_SIZE);
-
-#if TOUCH_KEY_NUM > 0
- nvt_mp_parse_ain(np, "AIN_KEY", AIN_KEY, IC_KEY_CFG_SIZE);
-#endif
-
- /* MP Criteria */
- if (ts->carrier_system) {
- nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Diff_P", PS_Config_Lmt_Short_Diff_P,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Diff_N", PS_Config_Lmt_Short_Diff_N,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Base_P", PS_Config_Lmt_Short_Base_P,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Base_N", PS_Config_Lmt_Short_Base_N,
- X_Channel * Y_Channel + Key_Channel);
- } else {
- nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Rawdata_P", PS_Config_Lmt_Short_Rawdata_P,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Rawdata_N", PS_Config_Lmt_Short_Rawdata_N,
- X_Channel * Y_Channel + Key_Channel);
- }
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_Open_Rawdata_P", PS_Config_Lmt_Open_Rawdata_P,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_Open_Rawdata_N", PS_Config_Lmt_Open_Rawdata_N,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Rawdata_P", PS_Config_Lmt_FW_Rawdata_P,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Rawdata_N", PS_Config_Lmt_FW_Rawdata_N,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_P", PS_Config_Lmt_FW_CC_P,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_N", PS_Config_Lmt_FW_CC_N,
- X_Channel * Y_Channel + Key_Channel);
-
- if (ts->carrier_system) {
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_I_P", PS_Config_Lmt_FW_CC_I_P,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_I_N", PS_Config_Lmt_FW_CC_I_N,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_Q_P", PS_Config_Lmt_FW_CC_Q_P,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_Q_N", PS_Config_Lmt_FW_CC_Q_N,
- X_Channel * Y_Channel + Key_Channel);
- }
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Diff_P", PS_Config_Lmt_FW_Diff_P,
- X_Channel * Y_Channel + Key_Channel);
-
- nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Diff_N", PS_Config_Lmt_FW_Diff_N,
- X_Channel * Y_Channel + Key_Channel);
- nvt_mp_parse_u32(np, "PS_Config_Diff_Test_Frame", &PS_Config_Diff_Test_Frame);
-
- NVT_LOG("Parse mp criteria done!\n");
-}
-#endif
-
-/*******************************************************
-Description:
- Novatek touchscreen MP function proc. file node
- initial function.
-
-return:
- Executive outcomes. 0---succeed. -1---failed.
-*******************************************************/
-int32_t nvt_mp_proc_init(void)
-{
- int32_t ret = 0;
-
- NVT_proc_selftest_entry = proc_create("nvt_selftest", 0444, NULL, &nvt_selftest_fops);
- if (NVT_proc_selftest_entry == NULL) {
- NVT_ERR("create /proc/nvt_selftest Failed!\n");
- ret = -1;
- } else {
- if(nvt_mp_buffer_init()) {
- NVT_ERR("Allocate mp memory failed\n");
- ret = -1;
- }
- else {
- NVT_LOG("create /proc/nvt_selftest Succeeded!\n");
- }
- ret = 0;
- }
-#if NVT_TOUCH_MP_LENOVO
- if (ret == 0) {
- NVT_proc_selftest_read_data = proc_create("nvt_read_data", 0444, NULL, &nvt_read_data_fops);
- if (NVT_proc_selftest_read_data == NULL) {
- NVT_ERR("create /proc/nvt_read_data Failed!\n");
- ret = -1;
- } else {
- NVT_LOG("create /proc/nvt_read_data Succeeded!\n");
- }
- }
-#endif
- return ret;
-}
-
-#endif /* #if NVT_TOUCH_MP */
+++ /dev/null
-/*
- * Copyright (C) 2010 - 2017 Novatek, Inc.
- *
- * $Revision: 22971 $
- * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#if NVT_TOUCH_MP
-
-static uint32_t IC_X_CFG_SIZE = 18;
-static uint32_t IC_Y_CFG_SIZE = 36;
-static uint32_t IC_KEY_CFG_SIZE = 4;
-static uint32_t X_Channel = 18;
-static uint32_t Y_Channel = 34;
-static uint32_t Key_Channel = TOUCH_KEY_NUM;
-static uint8_t AIN_X[40] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
-static uint8_t AIN_Y[40] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 0xFF, 0xFF};
-#if TOUCH_KEY_NUM > 0
-static uint8_t AIN_KEY[8] = {0, 1, 2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
-#endif /* #if TOUCH_KEY_NUM > 0 */
-
-static int32_t PS_Config_Lmt_Short_Rawdata_P[40 * 40] = {
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
- 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
-#if TOUCH_KEY_NUM > 0
- 20000,20000,20000,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_Short_Rawdata_N[40 * 40] = {
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
- 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
-#if TOUCH_KEY_NUM > 0
- 11550,11550,11550,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_Short_Diff_P[40 * 40] = {
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
- 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
-#if TOUCH_KEY_NUM > 0
- 6300,6300,6300,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_Short_Diff_N[40 * 40] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-#if TOUCH_KEY_NUM > 0
- 0,0,0,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_Short_Base_P[40 * 40] = {
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
- 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
-#if TOUCH_KEY_NUM > 0
- 2000,2000,2000,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_Short_Base_N[40 * 40] = {
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
- -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
-#if TOUCH_KEY_NUM > 0
- -2000,-2000,-2000,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_Open_Rawdata_P[40 * 40] = {
- 5830,2470,3134,2675,6215, 590, 616, 542, 600,2505,2447,2511,2488,6273,4533,3227,2617,6119,
- 2967,3669,3098,6069,5039,4702,4552,4654,4525,2545,2653,2584,2695,3051,3680,5123,5934,3186,
- 2831,3440,2926,3081,2920,3067,2910,3055,2916,2883,3046,2916,3049,2907,3448,2893,3039,2908,
- 2762,3353,2877,3020,2873,3008,2865,2999,2872,2813,2961,2871,2990,2862,3389,2846,2979,2861,
- 2815,3410,2895,3040,2892,3031,2886,3023,2891,2863,3015,2890,3012,2881,3408,2865,3000,2881,
- 2773,3357,2846,2980,2844,2974,2840,2967,2846,2817,2958,2843,2952,2832,3347,2816,2942,2838,
- 2775,3362,2822,2953,2846,2975,2846,2970,2851,2825,2966,2823,2929,2838,3353,2823,2943,2838,
- 2730,3176,2803,2925,2797,2898,2800,2914,2807,2778,2906,2804,2901,2787,3160,2772,2879,2788,
- 2741,2939,2813,2938,2807,2909,2814,2930,2817,2791,2922,2815,2914,2798,2913,2784,2893,2801,
- 2691,2875,2761,2878,2758,2849,2767,2869,2765,2756,2857,2764,2863,2745,2849,2734,2830,2748,
- 2684,2861,2750,2862,2724,2812,2758,2859,2757,2750,2843,2759,2855,2714,2809,2726,2821,2743,
- 2714,2871,2768,2868,2771,2852,2785,2881,2788,2787,2867,2786,2866,2759,2844,2743,2830,2768,
- 2725,2885,2781,2884,2781,2871,2803,2901,2799,2804,2881,2798,2877,2770,2863,2755,2849,2780,
- 2554,2710,2612,2700,2616,2690,2607,2683,2624,2629,2676,2623,2693,2604,2680,2569,2649,2614,
- 2558,2712,2615,2703,2620,2697,2638,2717,2629,2634,2683,2627,2694,2607,2684,2598,2688,2621,
- 2487,2628,2541,2619,2548,2616,2567,2626,2554,2560,2605,2553,2607,2534,2599,2525,2611,2548,
- 2492,2625,2538,2616,2545,2617,2567,2618,2531,2561,2605,2552,2605,2531,2598,2524,2615,2527,
- 2399,2515,2447,2508,2450,2506,2476,2508,2461,2466,2499,2461,2494,2437,2491,2433,2508,2457,
- 2393,2510,2442,2501,2446,2503,2471,2502,2469,2465,2507,2458,2489,2433,2489,2430,2513,2450,
- 2316,2419,2363,2414,2372,2418,2394,2413,2387,2386,2414,2377,2399,2354,2399,2352,2432,2370,
- 2287,2391,2354,2404,2369,2415,2387,2407,2373,2360,2374,2365,2389,2344,2391,2342,2431,2363,
- 2214,2303,2260,2294,2276,2306,2296,2295,2278,2286,2300,2272,2276,2251,2284,2252,2316,2270,
- 2283,2365,2323,2419,2345,2376,2370,2379,2355,2360,2374,2341,2338,2316,2349,2317,2447,2344,
- 2225,2304,2245,2634,2280,2300,2303,2304,2284,2278,2285,2254,2257,2247,2265,2262,2684,2285,
- 2099,2175,2147,2528,2158,2167,2175,2165,2146,2149,2154,2145,2143,2128,2141,2145,2553,2157,
- 2005,2144,2065,2312,2074,2119,2085,2137,2057,2055,2112,2055,2113,2044,2112,2059,2337,2060,
- 1970,2107,2031,2273,2042,2082,2052,2081,2028,2018,2074,2021,2072,2011,2072,2029,2301,2026,
- 1894,2019,1958,2188,1958,1983,1977,1992,1954,1938,1978,1940,1980,1924,1971,1954,2213,1948,
- 1840,1957,1908,2127,1918,1929,1925,1929,1895,1888,1917,1891,1919,1886,1925,1907,2154,1896,
- 1767,1872,1837,2045,1846,1845,1854,1844,1822,1813,1827,1815,1834,1814,1842,1836,2067,1818,
- 1726,1830,1800,2004,1810,1802,1813,1791,1784,1772,1779,1776,1791,1776,1798,1796,2021,1777,
- 1658,1750,1733,1929,1741,1722,1750,1719,1709,1701,1695,1704,1713,1709,1724,1737,1948,1706,
- 1499,2086,1889,1954,1768,1745,1774,1735,1732,1720,1710,1724,1735,1732,1748,1762,1975,1461,
- 3326,3789,3764,1741,1713,1721,1704,1695,1703,1796,1816,1835,1821,1834,2028,1708,1674,1383,
-#if TOUCH_KEY_NUM > 0
- 13000,13000,13000,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_Open_Rawdata_N[40 * 40] = {
- 3139,1330,1688,1440,3346, 317, 332, 292, 323,1349,1318,1352,1340,3378,2441,1738,1409,3295,
- 1597,1975,1668,3268,2714,2532,2451,2506,2437,1371,1428,1391,1451,1643,1981,2759,3195,1715,
- 1525,1852,1575,1659,1572,1652,1567,1645,1570,1552,1640,1570,1642,1565,1857,1558,1636,1566,
- 1487,1806,1549,1626,1547,1620,1543,1615,1547,1514,1595,1546,1610,1541,1825,1532,1604,1541,
- 1516,1836,1559,1637,1557,1632,1554,1628,1557,1541,1623,1556,1622,1551,1835,1543,1616,1551,
- 1493,1808,1532,1605,1531,1601,1529,1597,1532,1517,1593,1531,1590,1525,1802,1516,1584,1528,
- 1494,1810,1520,1590,1532,1602,1533,1599,1535,1521,1597,1520,1577,1528,1805,1520,1585,1528,
- 1470,1710,1509,1575,1506,1560,1508,1569,1511,1496,1565,1510,1562,1501,1702,1493,1550,1501,
- 1476,1583,1515,1582,1512,1567,1515,1578,1517,1503,1573,1516,1569,1507,1568,1499,1558,1508,
- 1449,1548,1487,1550,1485,1534,1490,1545,1489,1484,1539,1489,1542,1478,1534,1472,1524,1480,
- 1445,1541,1481,1541,1467,1514,1485,1539,1485,1481,1531,1485,1537,1461,1513,1468,1519,1477,
- 1461,1546,1490,1544,1492,1536,1499,1551,1501,1501,1544,1500,1543,1486,1532,1477,1524,1491,
- 1467,1553,1498,1553,1498,1546,1509,1562,1507,1510,1551,1507,1549,1492,1541,1483,1534,1497,
- 1375,1459,1406,1454,1409,1448,1404,1445,1413,1416,1441,1413,1450,1402,1443,1383,1426,1407,
- 1378,1460,1408,1455,1411,1452,1420,1463,1416,1418,1445,1414,1451,1404,1445,1399,1448,1411,
- 1339,1415,1368,1410,1372,1409,1382,1414,1375,1379,1403,1375,1404,1365,1399,1360,1406,1372,
- 1342,1414,1367,1408,1370,1409,1382,1410,1363,1379,1402,1374,1403,1363,1399,1359,1408,1361,
- 1292,1354,1318,1350,1319,1349,1333,1350,1325,1328,1346,1325,1343,1312,1341,1310,1351,1323,
- 1289,1351,1315,1347,1317,1348,1330,1347,1329,1327,1350,1324,1340,1310,1340,1308,1353,1319,
- 1247,1302,1272,1300,1277,1302,1289,1299,1285,1285,1300,1280,1292,1267,1292,1266,1309,1276,
- 1232,1288,1267,1295,1276,1300,1286,1296,1278,1271,1278,1274,1286,1262,1287,1261,1309,1272,
- 1192,1240,1217,1235,1225,1242,1236,1236,1226,1231,1239,1224,1226,1212,1230,1213,1247,1222,
- 1229,1273,1251,1302,1263,1279,1276,1281,1268,1271,1278,1261,1259,1247,1265,1248,1318,1262,
- 1198,1241,1209,1418,1228,1239,1240,1241,1230,1227,1230,1214,1215,1210,1220,1218,1445,1231,
- 1130,1171,1156,1361,1162,1167,1171,1166,1155,1157,1160,1155,1154,1146,1153,1155,1375,1161,
- 1080,1155,1112,1245,1117,1141,1123,1151,1108,1107,1137,1107,1138,1100,1137,1109,1258,1109,
- 1061,1134,1093,1224,1099,1121,1105,1120,1092,1087,1117,1088,1116,1083,1116,1093,1239,1091,
- 1020,1087,1054,1178,1054,1068,1065,1072,1052,1044,1065,1044,1066,1036,1061,1052,1191,1049,
- 991,1054,1028,1145,1033,1039,1036,1038,1020,1016,1032,1018,1033,1015,1037,1027,1160,1021,
- 952,1008, 989,1101, 994, 993, 998, 993, 981, 976, 984, 977, 988, 977, 992, 989,1113, 979,
- 929, 985, 969,1079, 975, 970, 976, 965, 960, 954, 958, 956, 964, 956, 968, 967,1088, 957,
- 893, 942, 933,1039, 938, 927, 942, 926, 920, 916, 912, 918, 922, 920, 928, 935,1049, 918,
- 807,1123,1017,1052, 952, 940, 955, 934, 932, 926, 921, 928, 934, 933, 941, 949,1063, 787,
- 1791,2040,2027, 937, 922, 927, 918, 913, 917, 967, 978, 988, 981, 987,1092, 920, 901, 745,
-#if TOUCH_KEY_NUM > 0
- 6500,6500,6500,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_Rawdata_P[40 * 40] = {
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
- 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
-#if TOUCH_KEY_NUM > 0
- 2000,2000,2000,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_Rawdata_N[40 * 40] = {
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
- 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
-#if TOUCH_KEY_NUM > 0
- 400,400,400,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_CC_P[40 * 40] = {
- 116,114,119,109,112,106,104,106,103,108,110,108,110,117,113,115,111,113,
- 117,115,118,111,113,111,114,114,109,110,115,114,112,113,112,118,116,119,
- 115,113,116,110,112,109,108,108,107,108,113,111,110,111,110,116,111,115,
- 116,114,117,112,114,110,109,110,108,109,114,111,111,112,111,117,113,116,
- 115,113,116,111,113,110,108,109,107,108,112,111,110,112,111,117,112,116,
- 116,115,118,112,114,111,110,110,108,109,114,112,112,113,112,118,114,117,
- 114,112,115,110,112,108,107,108,106,107,111,110,110,111,110,116,111,115,
- 115,114,117,112,113,110,109,109,108,109,113,111,111,112,111,117,113,116,
- 115,113,116,111,113,110,109,109,108,109,113,111,111,112,111,117,112,116,
- 117,115,118,113,115,112,111,111,110,112,115,112,112,114,113,118,114,117,
- 114,112,115,110,112,109,109,109,107,113,112,110,110,112,110,117,112,115,
- 115,112,116,111,113,110,109,109,108,114,112,110,111,112,111,117,112,115,
- 117,115,118,113,115,112,111,113,110,118,113,112,113,115,113,119,115,118,
- 114,112,116,110,113,110,109,112,108,115,110,110,111,112,111,117,112,115,
- 116,113,117,112,114,111,111,113,109,117,112,111,112,114,112,118,114,117,
- 116,113,117,112,114,111,110,112,109,116,112,111,111,114,112,118,113,116,
- 117,114,119,113,115,112,111,113,110,117,114,112,112,115,113,119,115,117,
- 115,112,116,110,112,110,109,110,108,114,111,109,110,112,111,116,112,114,
- 116,113,118,112,114,111,111,112,110,116,113,111,112,114,112,118,114,116,
- 116,113,117,112,114,111,111,111,110,115,113,111,111,114,112,117,113,115,
- 118,115,119,114,115,113,113,113,111,117,114,112,113,115,113,119,115,117,
- 116,112,117,111,113,110,110,111,109,114,112,110,111,113,112,117,113,115,
- 117,113,118,112,114,111,111,112,109,115,112,111,111,114,112,117,114,116,
- 119,115,120,114,116,114,113,115,111,115,113,113,114,117,115,120,116,118,
- 117,113,118,112,114,112,112,113,110,112,111,111,111,115,113,118,114,116,
- 119,114,119,113,114,113,112,115,111,112,112,112,112,115,114,119,116,119,
- 119,114,118,113,114,112,112,114,110,111,111,111,112,114,114,119,115,119,
- 121,116,120,114,116,114,114,116,112,113,113,113,114,116,115,121,117,120,
- 118,113,117,112,113,111,111,113,109,110,110,110,111,114,113,119,115,118,
- 120,115,119,114,115,113,113,115,111,112,112,112,113,116,114,120,117,119,
- 119,115,119,113,114,113,114,115,111,111,112,111,113,115,114,120,117,119,
- 121,116,121,115,116,114,116,117,113,113,114,113,114,117,115,122,119,121,
- 115,112,116,113,114,112,115,114,110,111,111,111,112,115,113,120,116,118,
- 115,114,120,114,115,112,110,111,110,107,113,113,110,111,111,120,116,118,
-#if TOUCH_KEY_NUM > 0
- 38,38,38,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_CC_N[40 * 40] = {
- 63,61,64,59,60,57,56,57,55,58,59,58,59,63,61,62,60,61,
- 63,62,63,60,61,60,61,61,59,59,62,61,60,61,60,64,62,64,
- 62,61,62,59,60,59,58,58,58,58,61,60,59,60,59,62,60,62,
- 62,61,63,60,61,59,59,59,58,58,61,60,60,61,60,63,61,63,
- 62,61,63,60,61,59,58,59,58,58,60,60,59,60,60,63,60,62,
- 63,62,63,60,61,60,59,59,58,59,61,60,60,61,60,64,61,63,
- 61,60,62,59,60,58,58,58,57,58,60,59,59,60,59,62,60,62,
- 62,61,63,60,61,59,59,59,58,59,61,60,60,60,60,63,61,63,
- 62,61,63,60,61,59,59,59,58,58,61,60,60,60,60,63,61,62,
- 63,62,63,61,62,60,60,60,59,61,62,60,61,61,61,64,61,63,
- 62,60,62,59,60,59,58,59,58,61,60,59,59,60,59,63,60,62,
- 62,61,62,60,61,59,59,59,58,61,60,59,60,60,60,63,60,62,
- 63,62,64,61,62,60,60,61,59,63,61,60,61,62,61,64,62,63,
- 61,60,62,59,61,59,59,60,58,62,59,59,60,60,60,63,60,62,
- 62,61,63,60,61,60,60,61,59,63,60,60,60,61,60,63,61,63,
- 62,61,63,60,61,60,59,60,59,62,60,60,60,61,60,63,61,62,
- 63,62,64,61,62,60,60,61,59,63,61,60,61,62,61,64,62,63,
- 62,60,63,59,61,59,59,59,58,61,60,59,59,60,60,63,60,61,
- 63,61,63,60,61,60,60,60,59,63,61,60,60,61,60,63,61,62,
- 63,61,63,60,61,60,60,60,59,62,61,60,60,61,61,63,61,62,
- 64,62,64,61,62,61,61,61,60,63,61,60,61,62,61,64,62,63,
- 62,60,63,60,61,59,59,60,58,62,61,59,60,61,60,63,61,62,
- 63,61,63,60,61,60,60,61,59,62,60,60,60,61,60,63,61,62,
- 64,62,65,61,62,61,61,62,60,62,61,61,61,63,62,65,63,64,
- 63,61,63,60,61,60,60,61,59,60,60,60,60,62,61,63,62,63,
- 64,61,64,61,61,61,61,62,60,60,60,60,61,62,61,64,62,64,
- 64,61,64,61,61,60,61,61,59,60,60,60,60,62,61,64,62,64,
- 65,62,65,62,62,61,61,62,60,61,61,61,61,63,62,65,63,65,
- 64,61,63,60,61,60,60,61,59,59,59,59,60,61,61,64,62,63,
- 64,62,64,61,62,61,61,62,60,60,60,60,61,62,62,65,63,64,
- 64,62,64,61,62,61,61,62,60,60,60,60,61,62,61,65,63,64,
- 65,62,65,62,63,62,63,63,61,61,61,61,61,63,62,66,64,65,
- 62,60,62,61,61,60,62,61,59,60,60,60,60,62,61,64,63,64,
- 62,61,64,61,62,60,59,60,59,58,61,61,59,60,60,65,62,63,
-#if TOUCH_KEY_NUM > 0
- 9,9,9,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_CC_I_P[40 * 40] = {
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
-#if TOUCH_KEY_NUM > 0
- 25,25,25,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_CC_I_N[40 * 40] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-#if TOUCH_KEY_NUM > 0
- 0,0,0,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_CC_Q_P[40 * 40] = {
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
- 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
-#if TOUCH_KEY_NUM > 0
- 25,25,25,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_CC_Q_N[40 * 40] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-#if TOUCH_KEY_NUM > 0
- 0,0,0,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_Diff_P[40 * 40] = {
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
- 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
-#if TOUCH_KEY_NUM > 0
- 35,35,35,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Lmt_FW_Diff_N[40 *40] = {
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
- -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
-#if TOUCH_KEY_NUM > 0
- -35,-35,-35,
-#endif /* #if TOUCH_KEY_NUM > 0 */
-};
-
-static int32_t PS_Config_Diff_Test_Frame = 50;
-
-#endif /* #if NVT_TOUCH_MP */
--- /dev/null
+#
+# Novatek NT36xxx touchscreen driver configuration
+#
+config TOUCHSCREEN_NT36xxx
+ bool "Novatek NT36xxx"
+ default y
+ help
+ Say Y here if you have a Novatek NT36xxx touchscreen connected
+ to your system.
+
+ If unsure, say N.
--- /dev/null
+#
+# Makefile for the Novatek NT36xxx touchscreen driver.
+#
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_TOUCHSCREEN_NT36xxx) += nt36xxx.o nt36xxx_fw_update.o nt36xxx_ext_proc.o nt36xxx_mp_ctrlram.o
--- /dev/null
+/*
+ * Copyright (C) 2010 - 2017 Novatek, Inc.
+ *
+ * $Revision: 22971 $
+ * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+#include <linux/init.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/gfp.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/list.h>
+#include <linux/device.h>
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+#include <linux/input/mt.h>
+#include <linux/wakelock.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+
+#if defined(CONFIG_HQ_DEV_INFO)
+#include <linux/dev_info.h>
+#endif
+
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#endif
+
+#include "nt36xxx.h"
+
+#if NVT_TOUCH_ESD_PROTECT
+#include <linux/jiffies.h>
+
+static struct delayed_work nvt_esd_check_work;
+static struct workqueue_struct *nvt_esd_check_wq;
+static unsigned long irq_timer;
+uint8_t esd_check = false;
+uint8_t esd_retry = 0;
+uint8_t esd_retry_max = 5;
+#endif
+
+#if NVT_TOUCH_EXT_PROC
+extern int32_t nvt_extra_proc_init(void);
+#endif
+
+#if NVT_TOUCH_FW
+extern int32_t nvt_fw_sysfs_init(void);
+extern int32_t nvt_fw_sysfs_deinit(void);
+#endif
+
+#if NVT_TOUCH_MP
+extern int32_t nvt_mp_proc_init(void);
+#endif
+
+struct nvt_ts_data *ts;
+
+static struct workqueue_struct *nvt_wq;
+
+#if BOOT_UPDATE_FIRMWARE
+static struct workqueue_struct *nvt_fwu_wq;
+extern void Boot_Update_Firmware(struct work_struct *work);
+#endif
+
+#if defined(CONFIG_FB)
+static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+static void nvt_ts_early_suspend(struct early_suspend *h);
+static void nvt_ts_late_resume(struct early_suspend *h);
+#endif
+
+#if TOUCH_KEY_NUM > 0
+const uint16_t touch_key_array[TOUCH_KEY_NUM] = {
+ KEY_BACK,
+ KEY_HOME,
+ KEY_MENU
+};
+#endif
+
+#if WAKEUP_GESTURE
+const uint16_t gesture_key_array[] = {
+ KEY_POWER, //GESTURE_WORD_C
+ KEY_POWER, //GESTURE_WORD_W
+ KEY_POWER, //GESTURE_WORD_V
+ KEY_POWER, //GESTURE_DOUBLE_CLICK
+ KEY_POWER, //GESTURE_WORD_Z
+ KEY_POWER, //GESTURE_WORD_M
+ KEY_POWER, //GESTURE_WORD_O
+ KEY_POWER, //GESTURE_WORD_e
+ KEY_POWER, //GESTURE_WORD_S
+ KEY_POWER, //GESTURE_SLIDE_UP
+ KEY_POWER, //GESTURE_SLIDE_DOWN
+ KEY_POWER, //GESTURE_SLIDE_LEFT
+ KEY_POWER, //GESTURE_SLIDE_RIGHT
+};
+#endif
+
+static uint8_t bTouchIsAwake = 0;
+
+/*******************************************************
+Description:
+ Novatek touchscreen i2c read function.
+
+return:
+ Executive outcomes. 2---succeed. -5---I/O error
+*******************************************************/
+int32_t CTP_I2C_READ(struct i2c_client *client, uint16_t address, uint8_t *buf, uint16_t len)
+{
+ struct i2c_msg msgs[2];
+ int32_t ret = -1;
+ int32_t retries = 0;
+
+ msgs[0].flags = !I2C_M_RD;
+ msgs[0].addr = address;
+ msgs[0].len = 1;
+ msgs[0].buf = &buf[0];
+
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].addr = address;
+ msgs[1].len = len - 1;
+ msgs[1].buf = &buf[1];
+
+ while (retries < 5) {
+ ret = i2c_transfer(client->adapter, msgs, 2);
+ if (ret == 2) break;
+ retries++;
+ }
+
+ if (unlikely(retries == 5)) {
+ NVT_ERR("error, ret=%d\n", ret);
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen i2c write function.
+
+return:
+ Executive outcomes. 1---succeed. -5---I/O error
+*******************************************************/
+int32_t CTP_I2C_WRITE(struct i2c_client *client, uint16_t address, uint8_t *buf, uint16_t len)
+{
+ struct i2c_msg msg;
+ int32_t ret = -1;
+ int32_t retries = 0;
+
+ msg.flags = !I2C_M_RD;
+ msg.addr = address;
+ msg.len = len;
+ msg.buf = buf;
+
+ while (retries < 5) {
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret == 1) break;
+ retries++;
+ }
+
+ if (unlikely(retries == 5)) {
+ NVT_ERR("error, ret=%d\n", ret);
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+
+/*******************************************************
+Description:
+ Novatek touchscreen reset MCU then into idle mode
+ function.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_sw_reset_idle(void)
+{
+ uint8_t buf[4]={0};
+
+ /* ---write i2c cmds to reset idle--- */
+ buf[0]=0x00;
+ buf[1]=0xA5;
+ CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+
+ msleep(15);
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen reset MCU (boot) function.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_bootloader_reset(void)
+{
+ uint8_t buf[8] = {0};
+ NVT_ERR("xlixiang---enter-%s\n", __func__);
+ //---write i2c cmds to reset---
+ buf[0] = 0x00;
+ buf[1] = 0x69;
+ CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+
+ // need 35ms delay after bootloader reset
+ msleep(35);
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen clear FW status function.
+
+return:
+ Executive outcomes. 0---succeed. -1---fail.
+*******************************************************/
+int32_t nvt_clear_fw_status(void)
+{
+ uint8_t buf[8] = {0};
+ int32_t i = 0;
+ const int32_t retry = 20;
+
+ for (i = 0; i < retry; i++) {
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---clear fw status---
+ buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
+ buf[1] = 0x00;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
+
+ //---read fw status---
+ buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
+ buf[1] = 0xFF;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
+
+ if (buf[1] == 0x00)
+ break;
+
+ msleep(10);
+ }
+
+ if (i >= retry) {
+ NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]);
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen check FW status function.
+
+return:
+ Executive outcomes. 0---succeed. -1---failed.
+*******************************************************/
+int32_t nvt_check_fw_status(void)
+{
+ uint8_t buf[8] = {0};
+ int32_t i = 0;
+ const int32_t retry = 50;
+
+ for (i = 0; i < retry; i++) {
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---read fw status---
+ buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
+ buf[1] = 0x00;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
+
+ if ((buf[1] & 0xF0) == 0xA0)
+ break;
+
+ msleep(10);
+ }
+
+ if (i >= retry) {
+ NVT_ERR("failed, i=%d, buf[1]=0x%02X\n", i, buf[1]);
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen check FW reset state function.
+
+return:
+ Executive outcomes. 0---succeed. -1---failed.
+*******************************************************/
+int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state)
+{
+ uint8_t buf[8] = {0};
+ int32_t ret = 0;
+ int32_t retry = 0;
+ NVT_ERR("xlixiang---enter-%s\n", __func__);
+ while (1) {
+ msleep(10);
+ //---read reset state---
+ buf[0] = EVENT_MAP_RESET_COMPLETE;
+ buf[1] = 0x00;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 6);
+
+ if ((buf[1] >= check_reset_state) && (buf[1] <= RESET_STATE_MAX)) {
+ ret = 0;
+ break;
+ }
+
+ retry++;
+ if (check_reset_state <= RESET_STATE_REK) {
+ if( unlikely(retry > 50)) {
+ NVT_ERR("error,retry = %d,buf[1] = 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n",retry,buf[1],buf[2], buf[3], buf[4], buf[5]);
+ ret = -1;
+ break;
+ }
+ }
+ else
+ {
+ if(unlikely(retry > 100)) {
+ NVT_ERR("error, retry=%d, buf[1]=0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", retry, buf[1], buf[2], buf[3], buf[4], buf[5]);
+ ret = -1;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen get novatek project id information
+ function.
+
+return:
+ Executive outcomes. 0---success. -1---fail.
+*******************************************************/
+int32_t nvt_read_pid(void)
+{
+ uint8_t buf[3] = {0};
+ int32_t ret = 0;
+
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---read project id---
+ buf[0] = EVENT_MAP_PROJECTID;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 3);
+
+ ts->nvt_pid = (buf[2] << 8) + buf[1];
+
+ NVT_LOG("PID=%04X\n", ts->nvt_pid);
+
+ return ret;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen get firmware related information
+ function.
+
+return:
+ Executive outcomes. 0---success. -1---fail.
+*******************************************************/
+int32_t nvt_get_fw_info(void)
+{
+ uint8_t buf[64] = {0};
+ uint32_t retry_count = 0;
+ int32_t ret = 0;
+
+info_retry:
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---read fw info---
+ buf[0] = EVENT_MAP_FWINFO;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 17);
+ ts->fw_ver = buf[1];
+ ts->x_num = buf[3];
+ ts->y_num = buf[4];
+ ts->abs_x_max = (uint16_t)((buf[5] << 8) | buf[6]);
+ ts->abs_y_max = (uint16_t)((buf[7] << 8) | buf[8]);
+ ts->max_button_num = buf[11];
+
+ //---clear x_num, y_num if fw info is broken---
+ if ((buf[1] + buf[2]) != 0xFF) {
+ NVT_ERR("FW info is broken! fw_ver=0x%02X, ~fw_ver=0x%02X\n", buf[1], buf[2]);
+ ts->fw_ver = 0;
+ ts->x_num = 18;
+ ts->y_num = 32;
+ ts->abs_x_max = TOUCH_DEFAULT_MAX_WIDTH;
+ ts->abs_y_max = TOUCH_DEFAULT_MAX_HEIGHT;
+ ts->max_button_num = TOUCH_KEY_NUM;
+
+ if(retry_count < 3) {
+ retry_count++;
+ NVT_ERR("retry_count=%d\n", retry_count);
+ goto info_retry;
+ } else {
+ NVT_ERR("Set default fw_ver=%d, x_num=%d, y_num=%d, \
+ abs_x_max=%d, abs_y_max=%d, max_button_num=%d!\n",
+ ts->fw_ver, ts->x_num, ts->y_num,
+ ts->abs_x_max, ts->abs_y_max, ts->max_button_num);
+ ret = -1;
+ }
+ } else {
+ ret = 0;
+ }
+
+ //---Get Novatek PID---
+ nvt_read_pid();
+
+ return ret;
+}
+
+/*******************************************************
+ Create Device Node (Proc Entry)
+*******************************************************/
+#if NVT_TOUCH_PROC
+static struct proc_dir_entry *NVT_proc_entry;
+#define DEVICE_NAME "NVTflash"
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/NVTflash read function.
+
+return:
+ Executive outcomes. 2---succeed. -5,-14---failed.
+*******************************************************/
+static ssize_t nvt_flash_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
+{
+ uint8_t str[68] = {0};
+ int32_t ret = -1;
+ int32_t retries = 0;
+ int8_t i2c_wr = 0;
+
+ if (count > sizeof(str)) {
+ NVT_ERR("error count=%zu\n", count);
+ return -EFAULT;
+ }
+
+ if (copy_from_user(str, buff, count)) {
+ NVT_ERR("copy from user error\n");
+ return -EFAULT;
+ }
+#if NVT_TOUCH_ESD_PROTECT
+ /*
+ * stop esd check work to avoid case that 0x77 report righ after here to enable esd check again
+ * finally lead to trigger esd recovery bootloader reset
+ */
+ cancel_delayed_work_sync(&nvt_esd_check_work);
+ nvt_esd_check_enable(false);
+#endif
+
+ i2c_wr = str[0] >> 7;
+
+ if (i2c_wr == 0) { //I2C write
+ while (retries < 20) {
+ ret = CTP_I2C_WRITE(ts->client, (str[0] & 0x7F), &str[2], str[1]);
+ if (ret == 1)
+ break;
+ else
+ NVT_ERR("error, retries=%d, ret=%d\n", retries, ret);
+
+ retries++;
+ }
+
+ if (unlikely(retries == 20)) {
+ NVT_ERR("error, ret = %d\n", ret);
+ return -EIO;
+ }
+
+ return ret;
+ } else if (i2c_wr == 1) { //I2C read
+ while (retries < 20) {
+ ret = CTP_I2C_READ(ts->client, (str[0] & 0x7F), &str[2], str[1]);
+ if (ret == 2)
+ break;
+ else
+ NVT_ERR("error, retries=%d, ret=%d\n", retries, ret);
+
+ retries++;
+ }
+
+ // copy buff to user if i2c transfer
+ if (retries < 20) {
+ if (copy_to_user(buff, str, count))
+ return -EFAULT;
+ }
+
+ if (unlikely(retries == 20)) {
+ NVT_ERR("error, ret = %d\n", ret);
+ return -EIO;
+ }
+
+ return ret;
+ } else {
+ NVT_ERR("Call error, str[0]=%d\n", str[0]);
+ return -EFAULT;
+ }
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/NVTflash open function.
+
+return:
+ Executive outcomes. 0---succeed. -12---failed.
+*******************************************************/
+static int32_t nvt_flash_open(struct inode *inode, struct file *file)
+{
+ struct nvt_flash_data *dev;
+
+ dev = kmalloc(sizeof(struct nvt_flash_data), GFP_KERNEL);
+ if (dev == NULL) {
+ NVT_ERR("Failed to allocate memory for nvt flash data\n");
+ return -ENOMEM;
+ }
+
+ rwlock_init(&dev->lock);
+ file->private_data = dev;
+
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/NVTflash close function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t nvt_flash_close(struct inode *inode, struct file *file)
+{
+ struct nvt_flash_data *dev = file->private_data;
+
+ if (dev)
+ kfree(dev);
+
+ return 0;
+}
+
+static const struct file_operations nvt_flash_fops = {
+ .owner = THIS_MODULE,
+ .open = nvt_flash_open,
+ .release = nvt_flash_close,
+ .read = nvt_flash_read,
+};
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/NVTflash initial function.
+
+return:
+ Executive outcomes. 0---succeed. -12---failed.
+*******************************************************/
+static int32_t nvt_flash_proc_init(void)
+{
+ NVT_proc_entry = proc_create(DEVICE_NAME, 0444, NULL,&nvt_flash_fops);
+ if (NVT_proc_entry == NULL) {
+ NVT_ERR("Failed!\n");
+ return -ENOMEM;
+ } else {
+ NVT_LOG("Succeeded!\n");
+ }
+
+ NVT_LOG("============================================================\n");
+ NVT_LOG("Create /proc/NVTflash\n");
+ NVT_LOG("============================================================\n");
+
+ return 0;
+}
+#endif
+
+#if WAKEUP_GESTURE
+#define GESTURE_WORD_C 12
+#define GESTURE_WORD_W 13
+#define GESTURE_WORD_V 14
+#define GESTURE_DOUBLE_CLICK 15
+#define GESTURE_WORD_Z 16
+#define GESTURE_WORD_M 17
+#define GESTURE_WORD_O 18
+#define GESTURE_WORD_e 19
+#define GESTURE_WORD_S 20
+#define GESTURE_SLIDE_UP 21
+#define GESTURE_SLIDE_DOWN 22
+#define GESTURE_SLIDE_LEFT 23
+#define GESTURE_SLIDE_RIGHT 24
+/* customized gesture id */
+#define DATA_PROTOCOL 30
+
+/* function page definition */
+#define FUNCPAGE_GESTURE 1
+
+static struct wake_lock gestrue_wakelock;
+
+/*******************************************************
+Description:
+ Novatek touchscreen wake up gesture key report function.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_ts_wakeup_gesture_report(uint8_t gesture_id, uint8_t *data)
+{
+ uint32_t keycode = 0;
+ uint8_t func_type = data[2];
+ uint8_t func_id = data[3];
+
+ /* support fw specifal data protocol */
+ if ((gesture_id == DATA_PROTOCOL) && (func_type == FUNCPAGE_GESTURE)) {
+ gesture_id = func_id;
+ } else if (gesture_id > DATA_PROTOCOL) {
+ NVT_ERR("gesture_id %d is invalid, func_type=%d, func_id=%d\n", gesture_id, func_type, func_id);
+ return;
+ }
+
+ NVT_LOG("gesture_id = %d\n", gesture_id);
+
+ switch (gesture_id) {
+ case GESTURE_WORD_C:
+ NVT_LOG("Gesture : Word-C.\n");
+ keycode = gesture_key_array[0];
+ break;
+ case GESTURE_WORD_W:
+ NVT_LOG("Gesture : Word-W.\n");
+ keycode = gesture_key_array[1];
+ break;
+ case GESTURE_WORD_V:
+ NVT_LOG("Gesture : Word-V.\n");
+ keycode = gesture_key_array[2];
+ break;
+ case GESTURE_DOUBLE_CLICK:
+ NVT_LOG("Gesture : Double Click.\n");
+ keycode = gesture_key_array[3];
+ break;
+ case GESTURE_WORD_Z:
+ NVT_LOG("Gesture : Word-Z.\n");
+ keycode = gesture_key_array[4];
+ break;
+ case GESTURE_WORD_M:
+ NVT_LOG("Gesture : Word-M.\n");
+ keycode = gesture_key_array[5];
+ break;
+ case GESTURE_WORD_O:
+ NVT_LOG("Gesture : Word-O.\n");
+ keycode = gesture_key_array[6];
+ break;
+ case GESTURE_WORD_e:
+ NVT_LOG("Gesture : Word-e.\n");
+ keycode = gesture_key_array[7];
+ break;
+ case GESTURE_WORD_S:
+ NVT_LOG("Gesture : Word-S.\n");
+ keycode = gesture_key_array[8];
+ break;
+ case GESTURE_SLIDE_UP:
+ NVT_LOG("Gesture : Slide UP.\n");
+ keycode = gesture_key_array[9];
+ break;
+ case GESTURE_SLIDE_DOWN:
+ NVT_LOG("Gesture : Slide DOWN.\n");
+ keycode = gesture_key_array[10];
+ break;
+ case GESTURE_SLIDE_LEFT:
+ NVT_LOG("Gesture : Slide LEFT.\n");
+ keycode = gesture_key_array[11];
+ break;
+ case GESTURE_SLIDE_RIGHT:
+ NVT_LOG("Gesture : Slide RIGHT.\n");
+ keycode = gesture_key_array[12];
+ break;
+ default:
+ break;
+ }
+
+ if (keycode > 0) {
+ input_report_key(ts->input_dev, keycode, 1);
+ input_sync(ts->input_dev);
+ input_report_key(ts->input_dev, keycode, 0);
+ input_sync(ts->input_dev);
+ }
+}
+#endif
+
+/*******************************************************
+Description:
+ Novatek touchscreen parse device tree function.
+
+return:
+ n.a.
+*******************************************************/
+#ifdef CONFIG_OF
+static void nvt_parse_dt(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+
+#if NVT_TOUCH_SUPPORT_HW_RST
+ ts->reset_gpio = of_get_named_gpio_flags(np, "novatek,reset-gpio", 0, &ts->reset_flags);
+ NVT_LOG("novatek,reset-gpio=%d\n", ts->reset_gpio);
+#endif
+ ts->irq_gpio = of_get_named_gpio_flags(np, "novatek,irq-gpio", 0, &ts->irq_flags);
+ NVT_LOG("novatek,irq-gpio=%d\n", ts->irq_gpio);
+
+}
+#else
+static void nvt_parse_dt(struct device *dev)
+{
+#if NVT_TOUCH_SUPPORT_HW_RST
+ ts->reset_gpio = NVTTOUCH_RST_PIN;
+#endif
+ ts->irq_gpio = NVTTOUCH_INT_PIN;
+}
+#endif
+
+/*******************************************************
+Description:
+ Novatek touchscreen config and request gpio
+
+return:
+ Executive outcomes. 0---succeed. not 0---failed.
+*******************************************************/
+static int nvt_gpio_config(struct nvt_ts_data *ts)
+{
+ int32_t ret = 0;
+ struct pinctrl *pinctrl_vdd;
+
+ pinctrl_vdd = devm_pinctrl_get_select(&ts->client->dev, "on_state");
+ if (IS_ERR(pinctrl_vdd))
+ NVT_ERR("Failed to on vdd GPIO\n");
+
+#if NVT_TOUCH_SUPPORT_HW_RST
+ /* request RST-pin (Output/High) */
+ if (gpio_is_valid(ts->reset_gpio)) {
+ ret = gpio_request_one(ts->reset_gpio, GPIOF_OUT_INIT_HIGH, "NVT-tp-rst");
+ if (ret) {
+ NVT_ERR("Failed to request NVT-tp-rst GPIO\n");
+ goto err_request_reset_gpio;
+ }
+ }
+#endif
+ /* request INT-pin (Input) */
+ if (gpio_is_valid(ts->irq_gpio)) {
+ ret = gpio_request_one(ts->irq_gpio, GPIOF_IN, "NVT-int");
+ if (ret) {
+ NVT_ERR("Failed to request NVT-int GPIO\n");
+ goto err_request_irq_gpio;
+ }
+ }
+
+ return ret;
+
+err_request_irq_gpio:
+#if NVT_TOUCH_SUPPORT_HW_RST
+ gpio_free(ts->reset_gpio);
+err_request_reset_gpio:
+#endif
+ return ret;
+}
+
+#if NVT_TOUCH_ESD_PROTECT
+void nvt_esd_check_enable(uint8_t enable)
+{
+ /* enable/disable esd check flag */
+ esd_check = enable;
+ /* update interrupt timer */
+ irq_timer = jiffies;
+ /* clear esd_retry counter, if protect function is enabled */
+ esd_retry = enable ? 0 : esd_retry;
+}
+
+static uint8_t nvt_fw_recovery(uint8_t *point_data)
+{
+ uint8_t i = 0;
+ uint8_t detected = true;
+
+ /* check pattern */
+ for (i = 1 ; i < 7 ; i++) {
+ if (point_data[i] != 0x77) {
+ detected = false;
+ break;
+ }
+ }
+
+ return detected;
+}
+
+static void nvt_esd_check_func(struct work_struct *work)
+{
+ unsigned int timer = jiffies_to_msecs(jiffies - irq_timer);
+
+
+ if (esd_retry >= esd_retry_max)
+ nvt_esd_check_enable(false);
+
+ if ((timer > NVT_TOUCH_ESD_CHECK_PERIOD) && esd_check) {
+ NVT_ERR("do ESD recovery, timer = %d, retry = %d\n", timer, esd_retry);
+ printk("do ESD recovery, timer = %d, retry = %d\n", timer, esd_retry);
+ /* do esd recovery, bootloader reset */
+ nvt_bootloader_reset();
+ /* update interrupt timer */
+ irq_timer = jiffies;
+ /* update esd_retry counter */
+ esd_retry++;
+ }
+
+ queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work,
+ msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD));
+}
+#endif
+
+#define POINT_DATA_LEN 65
+/*******************************************************
+Description:
+ Novatek touchscreen work function.
+
+return:
+ n.a.
+*******************************************************/
+static void nvt_ts_work_func(struct work_struct *work)
+{
+ int32_t ret = -1;
+ uint8_t point_data[POINT_DATA_LEN + 1] = {0};
+ uint32_t position = 0;
+ uint32_t input_x = 0;
+ uint32_t input_y = 0;
+ uint32_t input_w = 0;
+ uint32_t input_p = 0;
+ uint8_t input_id = 0;
+#if MT_PROTOCOL_B
+ uint8_t press_id[TOUCH_MAX_FINGER_NUM] = {0};
+#endif /* MT_PROTOCOL_B */
+ int32_t i = 0;
+ int32_t finger_cnt = 0;
+
+ mutex_lock(&ts->lock);
+
+ ret = CTP_I2C_READ(ts->client, I2C_FW_Address, point_data, POINT_DATA_LEN + 1);
+ if (ret < 0) {
+ NVT_ERR("CTP_I2C_READ failed.(%d)\n", ret);
+ goto XFER_ERROR;
+ }
+
+#if NVT_TOUCH_ESD_PROTECT
+
+ if (nvt_fw_recovery(point_data)) {
+ nvt_esd_check_enable(true);
+ goto XFER_ERROR;
+ }
+#endif
+
+#if WAKEUP_GESTURE
+ if (bTouchIsAwake == 0) {
+ input_id = (uint8_t)(point_data[1] >> 3);
+ nvt_ts_wakeup_gesture_report(input_id, point_data);
+ enable_irq(ts->client->irq);
+ mutex_unlock(&ts->lock);
+ return;
+ }
+#endif
+
+ finger_cnt = 0;
+
+ for (i = 0; i < ts->max_touch_num; i++) {
+ position = 1 + 6 * i;
+ input_id = (uint8_t)(point_data[position + 0] >> 3);
+ if ((input_id == 0) || (input_id > ts->max_touch_num))
+ continue;
+
+ if (((point_data[position] & 0x07) == 0x01) || ((point_data[position] & 0x07) == 0x02)) {
+#if NVT_TOUCH_ESD_PROTECT
+ /* update interrupt timer */
+ irq_timer = jiffies;
+#endif
+ input_x = (uint32_t)(point_data[position + 1] << 4) + (uint32_t) (point_data[position + 3] >> 4);
+ input_y = (uint32_t)(point_data[position + 2] << 4) + (uint32_t) (point_data[position + 3] & 0x0F);
+ if ((input_x < 0) || (input_y < 0))
+ continue;
+ if ((input_x > ts->abs_x_max) || (input_y > ts->abs_y_max))
+ continue;
+ input_w = (uint32_t)(point_data[position + 4]);
+ if (input_w == 0)
+ input_w = 1;
+ if (i < 2) {
+ input_p = (uint32_t)(point_data[position + 5]) + (uint32_t)(point_data[i + 63] << 8);
+ if (input_p > TOUCH_FORCE_NUM)
+ input_p = TOUCH_FORCE_NUM;
+ } else {
+ input_p = (uint32_t)(point_data[position + 5]);
+ }
+ if (input_p == 0)
+ input_p = 1;
+
+#if MT_PROTOCOL_B
+ press_id[input_id - 1] = 1;
+ input_mt_slot(ts->input_dev, input_id - 1);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
+#else /* MT_PROTOCOL_B */
+ input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, input_id - 1);
+ input_report_key(ts->input_dev, BTN_TOUCH, 1);
+#endif /* MT_PROTOCOL_B */
+
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
+ input_report_abs(ts->input_dev, ABS_MT_PRESSURE, input_p);
+
+#if MT_PROTOCOL_B
+#else /* MT_PROTOCOL_B */
+ input_mt_sync(ts->input_dev);
+#endif /* MT_PROTOCOL_B */
+
+ finger_cnt++;
+ }
+ }
+
+#if MT_PROTOCOL_B
+ for (i = 0; i < ts->max_touch_num; i++) {
+ if (press_id[i] != 1) {
+ input_mt_slot(ts->input_dev, i);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
+ input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
+ }
+ }
+
+ input_report_key(ts->input_dev, BTN_TOUCH, (finger_cnt > 0));
+#else /* MT_PROTOCOL_B */
+ if (finger_cnt == 0) {
+ input_report_key(ts->input_dev, BTN_TOUCH, 0);
+ input_mt_sync(ts->input_dev);
+ }
+#endif /* MT_PROTOCOL_B */
+
+#if TOUCH_KEY_NUM > 0
+ if (point_data[61] == 0xF8) {
+ for (i = 0; i < ts->max_button_num; i++) {
+ input_report_key(ts->input_dev, touch_key_array[i], ((point_data[62] >> i) & 0x01));
+ }
+ } else {
+ for (i = 0; i < ts->max_button_num; i++) {
+ input_report_key(ts->input_dev, touch_key_array[i], 0);
+ }
+ }
+#endif
+
+ input_sync(ts->input_dev);
+
+XFER_ERROR:
+ enable_irq(ts->client->irq);
+
+ mutex_unlock(&ts->lock);
+}
+
+/*******************************************************
+Description:
+ External interrupt service routine.
+
+return:
+ irq execute status.
+*******************************************************/
+static irqreturn_t nvt_ts_irq_handler(int32_t irq, void *dev_id)
+{
+ disable_irq_nosync(ts->client->irq);
+
+#if WAKEUP_GESTURE
+ if (bTouchIsAwake == 0) {
+ wake_lock_timeout(&gestrue_wakelock, msecs_to_jiffies(5000));
+ }
+#endif
+
+ queue_work(nvt_wq, &ts->nvt_work);
+
+ return IRQ_HANDLED;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen check and stop crc reboot loop.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_stop_crc_reboot(void)
+{
+ uint8_t buf[8] = {0};
+ int32_t retry = 0;
+
+ //read dummy buffer to check CRC fail reboot is happening or not
+
+ //---change I2C index to prevent geting 0xFF, but not 0xFC---
+ buf[0] = 0xFF;
+ buf[1] = 0x01;
+ buf[2] = 0xF6;
+ CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
+
+ //---read to check if buf is 0xFC which means IC is in CRC reboot ---
+ buf[0] = 0x4E;
+ CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 4);
+
+ if (((buf[1] == 0xFC) && (buf[2] == 0xFC) && (buf[3] == 0xFC)) ||
+ ((buf[1] == 0xFF) && (buf[2] == 0xFF) && (buf[3] == 0xFF))) {
+
+ //IC is in CRC fail reboot loop, needs to be stopped!
+ for (retry = 5; retry > 0; retry--) {
+
+ //---write i2c cmds to reset idle : 1st---
+ buf[0]=0x00;
+ buf[1]=0xA5;
+ CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+
+ //---write i2c cmds to reset idle : 2rd---
+ buf[0]=0x00;
+ buf[1]=0xA5;
+ CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ msleep(1);
+
+ //---clear CRC_ERR_FLAG---
+ buf[0] = 0xFF;
+ buf[1] = 0x03;
+ buf[2] = 0xF1;
+ CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
+
+ buf[0] = 0x35;
+ buf[1] = 0xA5;
+ CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 2);
+
+ //---check CRC_ERR_FLAG---
+ buf[0] = 0xFF;
+ buf[1] = 0x03;
+ buf[2] = 0xF1;
+ CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
+
+ buf[0] = 0x35;
+ buf[1] = 0x00;
+ CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 2);
+
+ if (buf[1] == 0xA5)
+ break;
+ }
+ if (retry == 0)
+ NVT_ERR("CRC auto reboot is not able to be stopped! buf[1]=0x%02X\n", buf[1]);
+ }
+
+ return;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen check chip version trim function.
+
+return:
+ Executive outcomes. 0---NVT IC. -1---not NVT IC.
+*******************************************************/
+static int8_t nvt_ts_check_chip_ver_trim(void)
+{
+ uint8_t buf[8] = {0};
+ int32_t retry = 0;
+ int32_t list = 0;
+ int32_t i = 0;
+ int32_t found_nvt_chip = 0;
+ int32_t ret = -1;
+
+ nvt_bootloader_reset(); // NOT in retry loop
+
+ //---Check for 5 times---
+ for (retry = 5; retry > 0; retry--) {
+ nvt_sw_reset_idle();
+
+ buf[0] = 0x00;
+ buf[1] = 0x35;
+ CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ msleep(10);
+
+ buf[0] = 0xFF;
+ buf[1] = 0x01;
+ buf[2] = 0xF6;
+ CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
+
+ buf[0] = 0x4E;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ buf[3] = 0x00;
+ buf[4] = 0x00;
+ buf[5] = 0x00;
+ buf[6] = 0x00;
+ CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 7);
+ NVT_LOG("buf[1]=0x%02X, buf[2]=0x%02X, buf[3]=0x%02X, buf[4]=0x%02X, buf[5]=0x%02X, buf[6]=0x%02X\n",
+ buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
+
+ // compare read chip id on supported list
+ for (list = 0; list < (sizeof(trim_id_table) / sizeof(struct nvt_ts_trim_id_table)); list++) {
+ found_nvt_chip = 0;
+
+ // compare each byte
+ for (i = 0; i < NVT_ID_BYTE_MAX; i++) {
+ if (trim_id_table[list].mask[i]) {
+ if (buf[i + 1] != trim_id_table[list].id[i])
+ break;
+ }
+ }
+
+ if (i == NVT_ID_BYTE_MAX) {
+ found_nvt_chip = 1;
+ }
+
+ if (found_nvt_chip) {
+ NVT_LOG("This is NVT touch IC\n");
+#if NVT_TOUCH_FW
+ if (list == 0) {
+ snprintf(ts->product_id, sizeof(ts->product_id), "NT36672A");
+ } else if (list == 9) {
+ snprintf(ts->product_id, sizeof(ts->product_id), "NT36525");
+ } else if (list == 10) {
+ snprintf(ts->product_id, sizeof(ts->product_id), "NT36870");
+ } else if (list == 11) {
+ snprintf(ts->product_id, sizeof(ts->product_id), "NT36676F");
+ } else {
+ snprintf(ts->product_id, sizeof(ts->product_id), "NT36772");
+ }
+#endif
+ ts->mmap = trim_id_table[list].mmap;
+ ts->carrier_system = trim_id_table[list].carrier_system;
+ ret = 0;
+ goto out;
+ } else {
+ ts->mmap = NULL;
+ ret = -1;
+ }
+ }
+
+ //---Stop CRC check to prevent IC auto reboot---
+ if (((buf[1] == 0xFC) && (buf[2] == 0xFC) && (buf[3] == 0xFC)) ||
+ ((buf[1] == 0xFF) && (buf[2] == 0xFF) && (buf[3] == 0xFF))) {
+ nvt_stop_crc_reboot();
+ }
+
+ msleep(10);
+ }
+
+out:
+ return ret;
+}
+
+
+/*******************************************************
+Description:
+ Novatek touchscreen driver probe function.
+
+return:
+ Executive outcomes. 0---succeed. negative---failed
+*******************************************************/
+static int32_t nvt_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int32_t ret = 0;
+#if ((TOUCH_KEY_NUM > 0) || WAKEUP_GESTURE)
+ int32_t retry = 0;
+#endif
+
+ NVT_LOG("start\n");
+
+ ts = kmalloc(sizeof(struct nvt_ts_data), GFP_KERNEL);
+ if (ts == NULL) {
+ NVT_ERR("failed to allocated memory for nvt ts data\n");
+ return -ENOMEM;
+ }
+
+ ts->client = client;
+ i2c_set_clientdata(client, ts);
+
+ //---parse dts---
+ nvt_parse_dt(&client->dev);
+
+ //---request and config GPIOs---
+ ret = nvt_gpio_config(ts);
+ if (ret) {
+ NVT_ERR("gpio config error!\n");
+ goto err_gpio_config_failed;
+ }
+
+ //---check i2c func.---
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ NVT_ERR("i2c_check_functionality failed. (no I2C_FUNC_I2C)\n");
+ ret = -ENODEV;
+ goto err_check_functionality_failed;
+ }
+
+ // need 10ms delay after POR(power on reset)
+ msleep(10);
+
+ //---check chip version trim---
+ ret = nvt_ts_check_chip_ver_trim();
+ if (ret) {
+ NVT_ERR("chip is not identified\n");
+ ret = -EINVAL;
+ goto err_chipvertrim_failed;
+ }
+
+ mutex_init(&ts->lock);
+
+ mutex_lock(&ts->lock);
+ nvt_bootloader_reset();
+ nvt_check_fw_reset_state(RESET_STATE_INIT);
+ nvt_get_fw_info();
+ mutex_unlock(&ts->lock);
+
+ //---create workqueue---
+ nvt_wq = create_workqueue("nvt_wq");
+ if (!nvt_wq) {
+ NVT_ERR("nvt_wq create workqueue failed\n");
+ ret = -ENOMEM;
+ goto err_create_nvt_wq_failed;
+ }
+ INIT_WORK(&ts->nvt_work, nvt_ts_work_func);
+
+
+ //---allocate input device---
+ ts->input_dev = input_allocate_device();
+ if (ts->input_dev == NULL) {
+ NVT_ERR("allocate input device failed\n");
+ ret = -ENOMEM;
+ goto err_input_dev_alloc_failed;
+ }
+
+ ts->max_touch_num = TOUCH_MAX_FINGER_NUM;
+
+#if TOUCH_KEY_NUM > 0
+ ts->max_button_num = TOUCH_KEY_NUM;
+#endif
+
+ ts->int_trigger_type = INT_TRIGGER_TYPE;
+
+
+ //---set input device info.---
+ ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) ;
+ ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+ ts->input_dev->propbit[0] = BIT(INPUT_PROP_DIRECT);
+
+#if MT_PROTOCOL_B
+ input_mt_init_slots(ts->input_dev, ts->max_touch_num, 0);
+#endif
+
+ input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, TOUCH_FORCE_NUM, 0, 0); //pressure = TOUCH_FORCE_NUM
+
+#if TOUCH_MAX_FINGER_NUM > 1
+ input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); //area = 255
+
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, ts->abs_x_max, 0, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, ts->abs_y_max, 0, 0);
+#if MT_PROTOCOL_B
+ // no need to set ABS_MT_TRACKING_ID, input_mt_init_slots() already set it
+#else
+ input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, ts->max_touch_num, 0, 0);
+#endif //MT_PROTOCOL_B
+#endif //TOUCH_MAX_FINGER_NUM > 1
+
+#if TOUCH_KEY_NUM > 0
+ for (retry = 0; retry < ts->max_button_num; retry++) {
+ input_set_capability(ts->input_dev, EV_KEY, touch_key_array[retry]);
+ }
+#endif
+
+#if WAKEUP_GESTURE
+ for (retry = 0; retry < (sizeof(gesture_key_array) / sizeof(gesture_key_array[0])); retry++) {
+ input_set_capability(ts->input_dev, EV_KEY, gesture_key_array[retry]);
+ }
+ wake_lock_init(&gestrue_wakelock, WAKE_LOCK_SUSPEND, "poll-wake-lock");
+#endif
+
+ sprintf(ts->phys, "input/ts");
+ ts->input_dev->name = NVT_TS_NAME;
+ ts->input_dev->phys = ts->phys;
+ ts->input_dev->id.bustype = BUS_I2C;
+
+ //---register input device---
+ ret = input_register_device(ts->input_dev);
+ if (ret) {
+ NVT_ERR("register input device (%s) failed. ret=%d\n", ts->input_dev->name, ret);
+ goto err_input_register_device_failed;
+ }
+
+ //---set int-pin & request irq---
+ client->irq = gpio_to_irq(ts->irq_gpio);
+ if (client->irq) {
+ NVT_LOG("int_trigger_type=%d\n", ts->int_trigger_type);
+
+#if WAKEUP_GESTURE
+ ret = request_irq(client->irq, nvt_ts_irq_handler, ts->int_trigger_type | IRQF_NO_SUSPEND, client->name, ts);
+#else
+ ret = request_irq(client->irq, nvt_ts_irq_handler, ts->int_trigger_type, client->name, ts);
+#endif
+ if (ret != 0) {
+ NVT_ERR("request irq failed. ret=%d\n", ret);
+ goto err_int_request_failed;
+ } else {
+ disable_irq(client->irq);
+ NVT_LOG("request irq %d succeed\n", client->irq);
+ }
+ }
+
+#if BOOT_UPDATE_FIRMWARE
+ nvt_fwu_wq = create_singlethread_workqueue("nvt_fwu_wq");
+ if (!nvt_fwu_wq) {
+ NVT_ERR("nvt_fwu_wq create workqueue failed\n");
+ ret = -ENOMEM;
+ goto err_create_nvt_fwu_wq_failed;
+ }
+ INIT_DELAYED_WORK(&ts->nvt_fwu_work, Boot_Update_Firmware);
+ // please make sure boot update start after display reset(RESX) sequence
+ queue_delayed_work(nvt_fwu_wq, &ts->nvt_fwu_work, msecs_to_jiffies(14000));
+#endif
+
+#if NVT_TOUCH_ESD_PROTECT
+ INIT_DELAYED_WORK(&nvt_esd_check_work, nvt_esd_check_func);
+ nvt_esd_check_wq = create_workqueue("nvt_esd_check_wq");
+ queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work,
+ msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD));
+#endif
+ //---set device node---
+#if NVT_TOUCH_PROC
+ ret = nvt_flash_proc_init();
+ if (ret != 0) {
+ NVT_ERR("nvt flash proc init failed. ret=%d\n", ret);
+ goto err_init_NVT_ts;
+ }
+#endif
+
+#if NVT_TOUCH_EXT_PROC
+ ret = nvt_extra_proc_init();
+ if (ret != 0) {
+ NVT_ERR("nvt extra proc init failed. ret=%d\n", ret);
+ goto err_init_NVT_ts;
+ }
+#endif
+
+#if NVT_TOUCH_FW
+ ts->suspended = 0;
+ ts->force_reflash = 0;
+ ts->loading_fw = 0;
+
+ ret = nvt_fw_sysfs_init();
+ if (ret != 0) {
+ NVT_ERR("nvt fw class init failed. ret=%d\n", ret);
+ goto err_init_NVT_ts;
+ }
+#endif
+
+#if NVT_TOUCH_MP
+ ret = nvt_mp_proc_init();
+ if (ret != 0) {
+ NVT_ERR("nvt mp proc init failed. ret=%d\n", ret);
+ goto err_init_NVT_ts;
+ }
+#endif
+
+#if defined(CONFIG_FB)
+ ts->fb_notif.notifier_call = fb_notifier_callback;
+ ret = fb_register_client(&ts->fb_notif);
+ if(ret) {
+ NVT_ERR("register fb_notifier failed. ret=%d\n", ret);
+ goto err_register_fb_notif_failed;
+ }
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ ts->early_suspend.suspend = nvt_ts_early_suspend;
+ ts->early_suspend.resume = nvt_ts_late_resume;
+ ret = register_early_suspend(&ts->early_suspend);
+ if(ret) {
+ NVT_ERR("register early suspend failed. ret=%d\n", ret);
+ goto err_register_early_suspend_failed;
+ }
+#endif
+
+ bTouchIsAwake = 1;
+ NVT_LOG("end\n");
+
+ enable_irq(client->irq);
+
+ return 0;
+
+#if defined(CONFIG_FB)
+err_register_fb_notif_failed:
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+err_register_early_suspend_failed:
+#endif
+#if (NVT_TOUCH_PROC || NVT_TOUCH_EXT_PROC || NVT_TOUCH_MP)
+err_init_NVT_ts:
+#endif
+ free_irq(client->irq, ts);
+#if BOOT_UPDATE_FIRMWARE
+err_create_nvt_fwu_wq_failed:
+#endif
+err_int_request_failed:
+err_input_register_device_failed:
+ input_free_device(ts->input_dev);
+err_input_dev_alloc_failed:
+err_create_nvt_wq_failed:
+ mutex_destroy(&ts->lock);
+err_chipvertrim_failed:
+err_check_functionality_failed:
+ gpio_free(ts->irq_gpio);
+err_gpio_config_failed:
+ i2c_set_clientdata(client, NULL);
+ kfree(ts);
+ return ret;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen driver release function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t nvt_ts_remove(struct i2c_client *client)
+{
+ //struct nvt_ts_data *ts = i2c_get_clientdata(client);
+
+#if defined(CONFIG_FB)
+ if (fb_unregister_client(&ts->fb_notif))
+ NVT_ERR("Error occurred while unregistering fb_notifier.\n");
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ unregister_early_suspend(&ts->early_suspend);
+#endif
+
+#if NVT_TOUCH_FW
+ nvt_fw_sysfs_deinit();
+#endif
+
+ mutex_destroy(&ts->lock);
+
+ NVT_LOG("Removing driver...\n");
+
+ free_irq(client->irq, ts);
+ input_unregister_device(ts->input_dev);
+ i2c_set_clientdata(client, NULL);
+ kfree(ts);
+
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen driver suspend function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t nvt_ts_suspend(struct device *dev)
+{
+ uint8_t buf[4] = {0};
+#if MT_PROTOCOL_B
+ uint32_t i = 0;
+#endif
+
+ if (!bTouchIsAwake) {
+ NVT_LOG("Touch is already suspend\n");
+ return 0;
+ }
+
+ mutex_lock(&ts->lock);
+
+ NVT_LOG("start\n");
+#if NVT_TOUCH_FW
+ ts->suspended = 1;
+#endif
+ bTouchIsAwake = 0;
+#if NVT_TOUCH_ESD_PROTECT
+ cancel_delayed_work_sync(&nvt_esd_check_work);
+ nvt_esd_check_enable(false);
+#endif
+
+#if WAKEUP_GESTURE
+ //---write i2c command to enter "wakeup gesture mode"---
+ buf[0] = EVENT_MAP_HOST_CMD;
+ buf[1] = 0x13;
+#if 0 // Do not set 0xFF first, ToDo
+ buf[2] = 0xFF;
+ buf[3] = 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 4);
+#else
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
+#endif
+
+ enable_irq_wake(ts->client->irq);
+
+ NVT_LOG("Enabled touch wakeup gesture\n");
+
+#else // WAKEUP_GESTURE
+
+ disable_irq(ts->client->irq);
+
+ //---write i2c command to enter "deep sleep mode"---
+ buf[0] = EVENT_MAP_HOST_CMD;
+ buf[1] = 0x11;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
+#endif // WAKEUP_GESTURE
+
+ /* release all touches */
+#if MT_PROTOCOL_B
+ for (i = 0; i < ts->max_touch_num; i++) {
+ input_mt_slot(ts->input_dev, i);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
+ input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
+ }
+#endif
+ input_report_key(ts->input_dev, BTN_TOUCH, 0);
+#if !MT_PROTOCOL_B
+ input_mt_sync(ts->input_dev);
+#endif
+ input_sync(ts->input_dev);
+
+ msleep(50);
+
+ mutex_unlock(&ts->lock);
+
+ NVT_LOG("end\n");
+
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen driver resume function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t nvt_ts_resume(struct device *dev)
+{
+ int res = 0;
+
+ if (bTouchIsAwake) {
+ NVT_LOG("Touch is already resume\n");
+ return 0;
+ }
+
+ msleep(10);
+
+ mutex_lock(&ts->lock);
+
+ NVT_LOG("start\n");
+ // please make sure display reset(RESX) sequence and mipi dsi cmds sent before this
+#if NVT_TOUCH_SUPPORT_HW_RST
+ gpio_set_value(ts->reset_gpio, 1);
+#endif
+ nvt_bootloader_reset();
+ res = nvt_check_fw_reset_state(RESET_STATE_REK);
+
+ NVT_ERR("xlixiang---enter-%s-----res=%d\n", __func__, res);
+
+#if !WAKEUP_GESTURE
+ enable_irq(ts->client->irq);
+#endif
+
+#if NVT_TOUCH_ESD_PROTECT
+ queue_delayed_work(nvt_esd_check_wq, &nvt_esd_check_work,
+ msecs_to_jiffies(NVT_TOUCH_ESD_CHECK_PERIOD));
+#endif
+ bTouchIsAwake = 1;
+#if NVT_TOUCH_FW
+ ts->suspended = 0;
+#endif
+
+ mutex_unlock(&ts->lock);
+
+ NVT_LOG("end\n");
+
+ return 0;
+}
+
+
+#if defined(CONFIG_FB)
+static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int *blank;
+ struct nvt_ts_data *ts =
+ container_of(self, struct nvt_ts_data, fb_notif);
+
+ if (evdata && evdata->data && event == FB_EARLY_EVENT_BLANK) {
+ blank = evdata->data;
+ if (*blank == FB_BLANK_POWERDOWN) {
+ nvt_ts_suspend(&ts->client->dev);
+ }
+ } else if (evdata && evdata->data && event == FB_EVENT_BLANK) {
+ blank = evdata->data;
+ if (*blank == FB_BLANK_UNBLANK ||
+ (*blank == FB_BLANK_NORMAL && 0 == bTouchIsAwake)) {
+ nvt_ts_resume(&ts->client->dev);
+ }
+ }
+
+ return 0;
+}
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+/*******************************************************
+Description:
+ Novatek touchscreen driver early suspend function.
+
+return:
+ n.a.
+*******************************************************/
+static void nvt_ts_early_suspend(struct early_suspend *h)
+{
+ nvt_ts_suspend(ts->client, PMSG_SUSPEND);
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen driver late resume function.
+
+return:
+ n.a.
+*******************************************************/
+static void nvt_ts_late_resume(struct early_suspend *h)
+{
+ nvt_ts_resume(ts->client);
+}
+#endif
+
+#if 0
+static const struct dev_pm_ops nvt_ts_dev_pm_ops = {
+ .suspend = nvt_ts_suspend,
+ .resume = nvt_ts_resume,
+};
+#endif
+
+static const struct i2c_device_id nvt_ts_id[] = {
+ { NVT_I2C_NAME, 0 },
+ { }
+};
+
+#ifdef CONFIG_OF
+static struct of_device_id nvt_match_table[] = {
+ { .compatible = "novatek,NVT-ts",},
+ { },
+};
+#endif
+/*
+static struct i2c_board_info __initdata nvt_i2c_boardinfo[] = {
+ {
+ I2C_BOARD_INFO(NVT_I2C_NAME, I2C_FW_Address),
+ },
+};
+*/
+
+static struct i2c_driver nvt_i2c_driver = {
+ .probe = nvt_ts_probe,
+ .remove = nvt_ts_remove,
+// .suspend = nvt_ts_suspend,
+// .resume = nvt_ts_resume,
+ .id_table = nvt_ts_id,
+ .driver = {
+ .name = NVT_I2C_NAME,
+ .owner = THIS_MODULE,
+#if 0
+#ifdef CONFIG_PM
+ .pm = &nvt_ts_dev_pm_ops,
+#endif
+#endif
+#ifdef CONFIG_OF
+ .of_match_table = nvt_match_table,
+#endif
+ },
+};
+
+/*******************************************************
+Description:
+ Driver Install function.
+
+return:
+ Executive Outcomes. 0---succeed. not 0---failed.
+********************************************************/
+static int32_t __init nvt_driver_init(void)
+{
+ int32_t ret = 0;
+
+ NVT_LOG("start\n");
+ //---add i2c driver---
+ ret = i2c_add_driver(&nvt_i2c_driver);
+ if (ret) {
+ pr_err("%s: failed to add i2c driver", __func__);
+ goto err_driver;
+ }
+
+ pr_info("%s: finished\n", __func__);
+
+err_driver:
+ return ret;
+}
+
+/*******************************************************
+Description:
+ Driver uninstall function.
+
+return:
+ n.a.
+********************************************************/
+static void __exit nvt_driver_exit(void)
+{
+ i2c_del_driver(&nvt_i2c_driver);
+
+ if (nvt_wq)
+ destroy_workqueue(nvt_wq);
+
+#if BOOT_UPDATE_FIRMWARE
+ if (nvt_fwu_wq)
+ destroy_workqueue(nvt_fwu_wq);
+#endif
+#if NVT_TOUCH_ESD_PROTECT
+ if (nvt_esd_check_wq)
+ destroy_workqueue(nvt_esd_check_wq);
+#endif
+
+}
+
+//late_initcall(nvt_driver_init);
+module_init(nvt_driver_init);
+module_exit(nvt_driver_exit);
+
+MODULE_DESCRIPTION("Novatek Touchscreen Driver");
+MODULE_LICENSE("GPL");
--- /dev/null
+/*
+ * Copyright (C) 2010 - 2017 Novatek, Inc.
+ *
+ * $Revision: 22971 $
+ * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+#ifndef _LINUX_NVT_TOUCH_H
+#define _LINUX_NVT_TOUCH_H
+
+#include <linux/i2c.h>
+#include <linux/input.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "nt36xxx_mem_map.h"
+
+#define NVT_DEBUG 1
+
+//---GPIO number---
+#define NVTTOUCH_RST_PIN 980
+#define NVTTOUCH_INT_PIN 943
+
+
+//---INT trigger mode---
+//#define IRQ_TYPE_EDGE_RISING 1
+//#define IRQ_TYPE_EDGE_FALLING 2
+#define INT_TRIGGER_TYPE IRQ_TYPE_EDGE_RISING
+
+
+//---I2C driver info.---
+#define NVT_I2C_NAME "NVT-ts"
+#define I2C_BLDR_Address 0x01
+#define I2C_FW_Address 0x01
+#define I2C_HW_Address 0x62
+
+#if NVT_DEBUG
+#define NVT_LOG(fmt, args...) pr_err("[%s] %s %d: " fmt, NVT_I2C_NAME, __func__, __LINE__, ##args)
+#else
+#define NVT_LOG(fmt, args...) pr_info("[%s] %s %d: " fmt, NVT_I2C_NAME, __func__, __LINE__, ##args)
+#endif
+#define NVT_ERR(fmt, args...) pr_err("[%s] %s %d: " fmt, NVT_I2C_NAME, __func__, __LINE__, ##args)
+
+//---Input device info.---
+#define NVT_TS_NAME "NVTCapacitiveTouchScreen"
+
+
+//---Touch info.---
+#define TOUCH_DEFAULT_MAX_WIDTH 1080
+#define TOUCH_DEFAULT_MAX_HEIGHT 2246
+#define TOUCH_MAX_FINGER_NUM 10
+#define TOUCH_KEY_NUM 0
+#if TOUCH_KEY_NUM > 0
+extern const uint16_t touch_key_array[TOUCH_KEY_NUM];
+#endif
+#define TOUCH_FORCE_NUM 1000
+
+/* Enable only when module have tp reset pin and connected to host */
+#define NVT_TOUCH_SUPPORT_HW_RST 1
+
+//---Customerized func.---
+#define NVT_TOUCH_PROC 1
+#define NVT_TOUCH_EXT_PROC 1
+#define NVT_TOUCH_FW 1
+#define NVT_TOUCH_MP 1
+#define NVT_TOUCH_MP_LENOVO 1
+#define MT_PROTOCOL_B 1
+#define WAKEUP_GESTURE 0
+#if WAKEUP_GESTURE
+extern const uint16_t gesture_key_array[];
+#endif
+#define BOOT_UPDATE_FIRMWARE 0
+#define BOOT_UPDATE_FIRMWARE_NAME "novatek_ts_fw.bin"
+/* ---ESD Protect.--- */
+#define NVT_TOUCH_ESD_PROTECT 1
+#define NVT_TOUCH_ESD_CHECK_PERIOD 2000 /* ms */
+
+struct nvt_ts_data {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct work_struct nvt_work;
+ struct delayed_work nvt_fwu_work;
+ uint16_t addr;
+ int8_t phys[32];
+#if defined(CONFIG_FB)
+ struct notifier_block fb_notif;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ struct early_suspend early_suspend;
+#endif
+ uint8_t fw_ver;
+ uint8_t x_num;
+ uint8_t y_num;
+ uint16_t abs_x_max;
+ uint16_t abs_y_max;
+ uint8_t max_touch_num;
+ uint8_t max_button_num;
+ uint32_t int_trigger_type;
+ int32_t irq_gpio;
+ uint32_t irq_flags;
+ int32_t reset_gpio;
+ uint32_t reset_flags;
+ struct mutex lock;
+ const struct nvt_ts_mem_map *mmap;
+ uint8_t carrier_system;
+ uint16_t nvt_pid;
+#if NVT_TOUCH_FW
+ int8_t product_id[10];
+ uint8_t suspended;
+ uint8_t force_reflash;
+ uint8_t loading_fw;
+#endif
+};
+
+#if NVT_TOUCH_FW
+#define FW_NAME_MAX_LEN 80
+#define VENDOR_NAME "novatek_ts"
+#endif
+
+#if NVT_TOUCH_PROC
+struct nvt_flash_data{
+ rwlock_t lock;
+ struct i2c_client *client;
+};
+#endif
+
+typedef enum {
+ RESET_STATE_INIT = 0xA0,// IC reset
+ RESET_STATE_REK, // ReK baseline
+ RESET_STATE_REK_FINISH, // baseline is ready
+ RESET_STATE_NORMAL_RUN,
+ RESET_STATE_MAX = 0xAF
+} RST_COMPLETE_STATE;
+
+typedef enum {
+ EVENT_MAP_HOST_CMD = 0x50,
+ EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE = 0x51,
+ EVENT_MAP_RESET_COMPLETE = 0x60,
+ EVENT_MAP_FWINFO = 0x78,
+ EVENT_MAP_PROJECTID = 0x9A,
+ EVENT_MAP_FWDATE = 0x9C,
+} I2C_EVENT_MAP;
+
+#if NVT_TOUCH_MP_LENOVO
+typedef enum {
+ MP_RESULT_SHIFT_SHORT = 0x00,
+ MP_RESULT_SHIFT_SHORT_DIFF,
+ MP_RESULT_SHIFT_SHORT_BASE,
+ MP_RESULT_SHIFT_OPEN,
+ MP_RESULT_SHIFT_RAWDATA,
+ MP_RESULT_SHIFT_CC,
+ MP_RESULT_SHIFT_CC_I,
+ MP_RESULT_SHIFT_CC_Q,
+ MP_RESULT_SHIFT_NOISE,
+ MP_RESULT_SHIFT_DIFF_MAX,
+ MP_RESULT_SHIFT_DIFF_MIN,
+/* MP_RESULT_SHIFT_READFAIL,*/
+} MP_TEST_RESULT;
+#endif
+
+//---extern structures---
+extern struct nvt_ts_data *ts;
+
+//---extern functions---
+extern int32_t CTP_I2C_READ(struct i2c_client *client, uint16_t address, uint8_t *buf, uint16_t len);
+extern int32_t CTP_I2C_WRITE(struct i2c_client *client, uint16_t address, uint8_t *buf, uint16_t len);
+extern void nvt_bootloader_reset(void);
+extern void nvt_sw_reset_idle(void);
+extern int32_t nvt_check_fw_reset_state(RST_COMPLETE_STATE check_reset_state);
+extern int32_t nvt_get_fw_info(void);
+extern int32_t nvt_clear_fw_status(void);
+extern int32_t nvt_check_fw_status(void);
+
+#if NVT_TOUCH_ESD_PROTECT
+extern void nvt_esd_check_enable(uint8_t enable);
+#endif
+extern void nvt_stop_crc_reboot(void);
+
+#endif /* _LINUX_NVT_TOUCH_H */
--- /dev/null
+/*
+ * Copyright (C) 2010 - 2017 Novatek, Inc.
+ *
+ * $Revision: 22971 $
+ * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/delay.h>
+
+#include "nt36xxx.h"
+
+#if NVT_TOUCH_EXT_PROC
+#define NVT_FW_VERSION "nvt_fw_version"
+#define NVT_BASELINE "nvt_baseline"
+#define NVT_RAW "nvt_raw"
+#define NVT_DIFF "nvt_diff"
+
+#define I2C_TANSFER_LENGTH 64
+
+#define NORMAL_MODE 0x00
+#define TEST_MODE_1 0x21
+#define TEST_MODE_2 0x22
+#define HANDSHAKING_HOST_READY 0xBB
+
+#define XDATA_SECTOR_SIZE 256
+#define XDATA_BUF_SIZE 2048
+
+static uint8_t xdata_tmp[XDATA_BUF_SIZE] = {0};
+static int32_t xdata[XDATA_BUF_SIZE] = {0};
+static int32_t xdata_i[XDATA_BUF_SIZE] = {0};
+static int32_t xdata_q[XDATA_BUF_SIZE] = {0};
+
+static struct proc_dir_entry *NVT_proc_fw_version_entry;
+static struct proc_dir_entry *NVT_proc_baseline_entry;
+static struct proc_dir_entry *NVT_proc_raw_entry;
+static struct proc_dir_entry *NVT_proc_diff_entry;
+
+/*******************************************************
+Description:
+ Novatek touchscreen change mode function.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_change_mode(uint8_t mode)
+{
+ uint8_t buf[8] = {0};
+
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---set mode---
+ buf[0] = EVENT_MAP_HOST_CMD;
+ buf[1] = mode;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
+
+ if (mode == NORMAL_MODE) {
+ buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
+ buf[1] = HANDSHAKING_HOST_READY;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
+ msleep(20);
+ }
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen get firmware pipe function.
+
+return:
+ Executive outcomes. 0---pipe 0. 1---pipe 1.
+*******************************************************/
+uint8_t nvt_get_fw_pipe(void)
+{
+ uint8_t buf[8]= {0};
+
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---read fw status---
+ buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
+ buf[1] = 0x00;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
+
+ //NVT_LOG("FW pipe=%d, buf[1]=0x%02X\n", (buf[1]&0x01), buf[1]);
+
+ return (buf[1] & 0x01);
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen read mass data function.
+
+return:
+ n.a.
+*******************************************************/
+int32_t nvt_read_mass_data(uint8_t i2c_addr, uint8_t *temp_buf, uint32_t count)
+{
+ int32_t i = 0;
+ int32_t j = 0;
+ int32_t k = 0;
+ uint8_t i2c_buf[I2C_TANSFER_LENGTH + 1] = {0};
+ uint32_t xdata_addr = 0;
+ uint32_t head_addr = 0;
+ int32_t dummy_len = 0;
+ int32_t data_len = 0;
+ int32_t residual_len = 0;
+
+ xdata_addr = (temp_buf[3] << 24) + (temp_buf[4] << 16) + (temp_buf[5] << 8) + temp_buf[6];
+ head_addr = xdata_addr - (xdata_addr % XDATA_SECTOR_SIZE);
+ dummy_len = xdata_addr - head_addr;
+ data_len = (int32_t)((temp_buf[1] << 8) + temp_buf[2]);
+ residual_len = (head_addr + dummy_len + data_len) % XDATA_SECTOR_SIZE;
+
+ if (data_len > XDATA_BUF_SIZE)
+ return -EINVAL;
+
+ for (i = 0; i < ((dummy_len + data_len) / XDATA_SECTOR_SIZE); i++) {
+ i2c_buf[0] = 0xFF;
+ i2c_buf[1] = ((head_addr + XDATA_SECTOR_SIZE * i) >> 16) & 0xFF;
+ i2c_buf[2] = ((head_addr + XDATA_SECTOR_SIZE * i) >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, (uint16_t)i2c_addr, i2c_buf, 3);
+ for (j = 0; j < (XDATA_SECTOR_SIZE / I2C_TANSFER_LENGTH); j++) {
+ i2c_buf[0] = I2C_TANSFER_LENGTH * j;
+ CTP_I2C_READ(ts->client, (uint16_t)i2c_addr, i2c_buf, I2C_TANSFER_LENGTH + 1);
+ for (k = 0; k < I2C_TANSFER_LENGTH; k++) {
+ xdata_tmp[XDATA_SECTOR_SIZE * i + I2C_TANSFER_LENGTH * j + k] = i2c_buf[k + 1];
+ }
+ }
+ }
+
+ if (residual_len != 0) {
+ i2c_buf[0] = 0xFF;
+ i2c_buf[1] = ((xdata_addr + data_len - residual_len) >> 16) & 0xFF;
+ i2c_buf[2] = ((xdata_addr + data_len - residual_len) >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, (uint16_t)i2c_addr, i2c_buf, 3);
+ for (j = 0; j < (residual_len / I2C_TANSFER_LENGTH + 1); j++) {
+ i2c_buf[0] = I2C_TANSFER_LENGTH * j;
+ CTP_I2C_READ(ts->client, (uint16_t)i2c_addr, i2c_buf, I2C_TANSFER_LENGTH + 1);
+ for (k = 0; k < I2C_TANSFER_LENGTH; k++) {
+ xdata_tmp[(dummy_len + data_len - residual_len) + I2C_TANSFER_LENGTH * j + k] = i2c_buf[k + 1];
+ }
+ }
+ }
+
+ i2c_buf[0] = 0xFF;
+ i2c_buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ i2c_buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, (uint16_t)i2c_addr, i2c_buf, 3);
+
+ for (i = 0; i < data_len; i++) {
+ *(temp_buf + i) = xdata_tmp[dummy_len + i];
+ }
+
+ return data_len;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen read meta data function.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_read_mdata(uint32_t xdata_addr, uint32_t xdata_btn_addr)
+{
+ int32_t i = 0;
+ int32_t j = 0;
+ int32_t k = 0;
+ uint8_t buf[I2C_TANSFER_LENGTH + 1] = {0};
+ uint32_t head_addr = 0;
+ int32_t dummy_len = 0;
+ int32_t data_len = 0;
+ int32_t residual_len = 0;
+
+ //---set xdata sector address & length---
+ head_addr = xdata_addr - (xdata_addr % XDATA_SECTOR_SIZE);
+ dummy_len = xdata_addr - head_addr;
+ data_len = ts->x_num * ts->y_num * 2;
+ residual_len = (head_addr + dummy_len + data_len) % XDATA_SECTOR_SIZE;
+
+ //printk("head_addr=0x%05X, dummy_len=0x%05X, data_len=0x%05X, residual_len=0x%05X\n", head_addr, dummy_len, data_len, residual_len);
+
+ //read xdata : step 1
+ for (i = 0; i < ((dummy_len + data_len) / XDATA_SECTOR_SIZE); i++) {
+ //---change xdata index---
+ buf[0] = 0xFF;
+ buf[1] = ((head_addr + XDATA_SECTOR_SIZE * i) >> 16) & 0xFF;
+ buf[2] = ((head_addr + XDATA_SECTOR_SIZE * i) >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---read xdata by I2C_TANSFER_LENGTH
+ for (j = 0; j < (XDATA_SECTOR_SIZE / I2C_TANSFER_LENGTH); j++) {
+ //---read data---
+ buf[0] = I2C_TANSFER_LENGTH * j;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, I2C_TANSFER_LENGTH + 1);
+
+ //---copy buf to xdata_tmp---
+ for (k = 0; k < I2C_TANSFER_LENGTH; k++) {
+ xdata_tmp[XDATA_SECTOR_SIZE * i + I2C_TANSFER_LENGTH * j + k] = buf[k + 1];
+ //printk("0x%02X, 0x%04X\n", buf[k+1], (XDATA_SECTOR_SIZE*i + I2C_TANSFER_LENGTH*j + k));
+ }
+ }
+ //printk("addr=0x%05X\n", (head_addr+XDATA_SECTOR_SIZE*i));
+ }
+
+ //read xdata : step2
+ if (residual_len != 0) {
+ //---change xdata index---
+ buf[0] = 0xFF;
+ buf[1] = ((xdata_addr + data_len - residual_len) >> 16) & 0xFF;
+ buf[2] = ((xdata_addr + data_len - residual_len) >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---read xdata by I2C_TANSFER_LENGTH
+ for (j = 0; j < (residual_len / I2C_TANSFER_LENGTH + 1); j++) {
+ //---read data---
+ buf[0] = I2C_TANSFER_LENGTH * j;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, I2C_TANSFER_LENGTH + 1);
+
+ //---copy buf to xdata_tmp---
+ for (k = 0; k < I2C_TANSFER_LENGTH; k++) {
+ xdata_tmp[(dummy_len + data_len - residual_len) + I2C_TANSFER_LENGTH * j + k] = buf[k + 1];
+ //printk("0x%02X, 0x%04x\n", buf[k+1], ((dummy_len+data_len-residual_len) + I2C_TANSFER_LENGTH*j + k));
+ }
+ }
+ //printk("addr=0x%05X\n", (xdata_addr+data_len-residual_len));
+ }
+
+ //---remove dummy data and 2bytes-to-1data---
+ for (i = 0; i < (data_len / 2); i++) {
+ xdata[i] = (int16_t)(xdata_tmp[dummy_len + i * 2] + 256 * xdata_tmp[dummy_len + i * 2 + 1]);
+ }
+
+#if TOUCH_KEY_NUM > 0
+ //read button xdata : step3
+ //---change xdata index---
+ buf[0] = 0xFF;
+ buf[1] = (xdata_btn_addr >> 16) & 0xFF;
+ buf[2] = ((xdata_btn_addr >> 8) & 0xFF);
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---read data---
+ buf[0] = (xdata_btn_addr & 0xFF);
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, (TOUCH_KEY_NUM * 2 + 1));
+
+ //---2bytes-to-1data---
+ for (i = 0; i < TOUCH_KEY_NUM; i++) {
+ xdata[ts->x_num * ts->y_num + i] = (int16_t)(buf[1 + i * 2] + 256 * buf[1 + i * 2 + 1]);
+ }
+#endif
+
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen read meta data from IQ to rss function.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_read_mdata_rss(uint32_t xdata_i_addr, uint32_t xdata_q_addr, uint32_t xdata_btn_i_addr, uint32_t xdata_btn_q_addr)
+{
+ int i = 0;
+
+ nvt_read_mdata(xdata_i_addr, xdata_btn_i_addr);
+ memcpy(xdata_i, xdata, ((ts->x_num * ts->y_num + TOUCH_KEY_NUM) * sizeof(int32_t)));
+
+ nvt_read_mdata(xdata_q_addr, xdata_btn_q_addr);
+ memcpy(xdata_q, xdata, ((ts->x_num * ts->y_num + TOUCH_KEY_NUM) * sizeof(int32_t)));
+
+ for (i = 0; i < (ts->x_num * ts->y_num + TOUCH_KEY_NUM); i++) {
+ xdata[i] = (int32_t)int_sqrt((unsigned long)(xdata_i[i] * xdata_i[i]) + (unsigned long)(xdata_q[i] * xdata_q[i]));
+ }
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen get meta data function.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_get_mdata(int32_t *buf, uint8_t *m_x_num, uint8_t *m_y_num)
+{
+ *m_x_num = ts->x_num;
+ *m_y_num = ts->y_num;
+ memcpy(buf, xdata, ((ts->x_num * ts->y_num + TOUCH_KEY_NUM) * sizeof(int32_t)));
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen firmware version show function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t c_fw_version_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "fw_ver=%d, x_num=%d, y_num=%d, button_num=%d\n", ts->fw_ver, ts->x_num, ts->y_num, ts->max_button_num);
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen xdata sequence print show
+ function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t c_show(struct seq_file *m, void *v)
+{
+ int32_t i = 0;
+ int32_t j = 0;
+
+ for (i = 0; i < ts->y_num; i++) {
+ for (j = 0; j < ts->x_num; j++) {
+ seq_printf(m, "%5d, ", xdata[i * ts->x_num + j]);
+ }
+ seq_puts(m, "\n");
+ }
+
+#if TOUCH_KEY_NUM > 0
+ for (i = 0; i < TOUCH_KEY_NUM; i++) {
+ seq_printf(m, "%5d, ", xdata[ts->x_num * ts->y_num + i]);
+ }
+ seq_puts(m, "\n");
+#endif
+
+ seq_printf(m, "\n\n");
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen xdata sequence print start
+ function.
+
+return:
+ Executive outcomes. 1---call next function.
+ NULL---not call next function and sequence loop
+ stop.
+*******************************************************/
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < 1 ? (void *)1 : NULL;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen xdata sequence print next
+ function.
+
+return:
+ Executive outcomes. NULL---no next and call sequence
+ stop function.
+*******************************************************/
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return NULL;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen xdata sequence print stop
+ function.
+
+return:
+ n.a.
+*******************************************************/
+static void c_stop(struct seq_file *m, void *v)
+{
+ return;
+}
+
+const struct seq_operations nvt_fw_version_seq_ops = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = c_fw_version_show
+};
+
+const struct seq_operations nvt_seq_ops = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = c_show
+};
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/nvt_fw_version open
+ function.
+
+return:
+ n.a.
+*******************************************************/
+static int32_t nvt_info_open(struct inode *inode, struct file *file)
+{
+ if (mutex_lock_interruptible(&ts->lock)) {
+ return -ERESTARTSYS;
+ }
+
+ NVT_LOG("++\n");
+#if NVT_TOUCH_ESD_PROTECT
+ nvt_esd_check_enable(false);
+#endif
+ if (nvt_get_fw_info()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ mutex_unlock(&ts->lock);
+
+ NVT_LOG("--\n");
+
+ return seq_open(file, &nvt_fw_version_seq_ops);
+}
+
+static const struct file_operations nvt_info_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = nvt_info_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int32_t nvt_fw_version_open(struct inode *inode, struct file *file)
+{
+ if (mutex_lock_interruptible(&ts->lock)) {
+ return -ERESTARTSYS;
+ }
+
+ NVT_LOG("++\n");
+#if NVT_TOUCH_ESD_PROTECT
+ nvt_esd_check_enable(false);
+#endif
+ if (nvt_get_fw_info()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ mutex_unlock(&ts->lock);
+
+ NVT_LOG("--\n");
+
+ return seq_open(file, &nvt_fw_version_seq_ops);
+}
+
+static const struct file_operations nvt_fw_version_fops = {
+ .owner = THIS_MODULE,
+ .open = nvt_fw_version_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/nvt_baseline open function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t nvt_baseline_open(struct inode *inode, struct file *file)
+{
+ if (mutex_lock_interruptible(&ts->lock)) {
+ return -ERESTARTSYS;
+ }
+
+ NVT_LOG("++\n");
+#if NVT_TOUCH_ESD_PROTECT
+ nvt_esd_check_enable(false);
+#endif
+ if (nvt_clear_fw_status()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ nvt_change_mode(TEST_MODE_2);
+
+ if (nvt_check_fw_status()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ if (nvt_get_fw_info()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ if (ts->carrier_system) {
+ nvt_read_mdata_rss(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_Q_ADDR,
+ ts->mmap->BASELINE_BTN_ADDR, ts->mmap->BASELINE_BTN_Q_ADDR);
+ } else {
+ nvt_read_mdata(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_BTN_ADDR);
+ }
+
+ nvt_change_mode(NORMAL_MODE);
+
+ mutex_unlock(&ts->lock);
+
+ NVT_LOG("--\n");
+
+ return seq_open(file, &nvt_seq_ops);
+}
+
+static const struct file_operations nvt_baseline_fops = {
+ .owner = THIS_MODULE,
+ .open = nvt_baseline_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/nvt_raw open function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t nvt_raw_open(struct inode *inode, struct file *file)
+{
+ if (mutex_lock_interruptible(&ts->lock)) {
+ return -ERESTARTSYS;
+ }
+
+ NVT_LOG("++\n");
+#if NVT_TOUCH_ESD_PROTECT
+ nvt_esd_check_enable(false);
+#endif
+ if (nvt_clear_fw_status()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ nvt_change_mode(TEST_MODE_2);
+
+ if (nvt_check_fw_status()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ if (nvt_get_fw_info()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ if (ts->carrier_system) {
+ if (nvt_get_fw_pipe() == 0)
+ nvt_read_mdata_rss(ts->mmap->RAW_PIPE0_ADDR, ts->mmap->RAW_PIPE0_Q_ADDR,
+ ts->mmap->RAW_BTN_PIPE0_ADDR, ts->mmap->RAW_BTN_PIPE0_Q_ADDR);
+ else
+ nvt_read_mdata_rss(ts->mmap->RAW_PIPE1_ADDR, ts->mmap->RAW_PIPE1_Q_ADDR,
+ ts->mmap->RAW_BTN_PIPE1_ADDR, ts->mmap->RAW_BTN_PIPE1_Q_ADDR);
+ } else {
+ if (nvt_get_fw_pipe() == 0)
+ nvt_read_mdata(ts->mmap->RAW_PIPE0_ADDR, ts->mmap->RAW_BTN_PIPE0_ADDR);
+ else
+ nvt_read_mdata(ts->mmap->RAW_PIPE1_ADDR, ts->mmap->RAW_BTN_PIPE1_ADDR);
+ }
+
+ nvt_change_mode(NORMAL_MODE);
+
+ mutex_unlock(&ts->lock);
+
+ NVT_LOG("--\n");
+
+ return seq_open(file, &nvt_seq_ops);
+}
+
+static const struct file_operations nvt_raw_fops = {
+ .owner = THIS_MODULE,
+ .open = nvt_raw_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/nvt_diff open function.
+
+return:
+ Executive outcomes. 0---succeed. negative---failed.
+*******************************************************/
+static int32_t nvt_diff_open(struct inode *inode, struct file *file)
+{
+ if (mutex_lock_interruptible(&ts->lock)) {
+ return -ERESTARTSYS;
+ }
+
+ NVT_LOG("++\n");
+#if NVT_TOUCH_ESD_PROTECT
+ nvt_esd_check_enable(false);
+#endif
+ if (nvt_clear_fw_status()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ nvt_change_mode(TEST_MODE_2);
+
+ if (nvt_check_fw_status()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ if (nvt_get_fw_info()) {
+ mutex_unlock(&ts->lock);
+ return -EAGAIN;
+ }
+
+ if (ts->carrier_system) {
+ if (nvt_get_fw_pipe() == 0)
+ nvt_read_mdata_rss(ts->mmap->DIFF_PIPE0_ADDR, ts->mmap->DIFF_PIPE0_Q_ADDR,
+ ts->mmap->DIFF_BTN_PIPE0_ADDR, ts->mmap->DIFF_BTN_PIPE0_Q_ADDR);
+ else
+ nvt_read_mdata_rss(ts->mmap->DIFF_PIPE1_ADDR, ts->mmap->DIFF_PIPE1_Q_ADDR,
+ ts->mmap->DIFF_BTN_PIPE1_ADDR, ts->mmap->DIFF_BTN_PIPE1_Q_ADDR);
+ } else {
+ if (nvt_get_fw_pipe() == 0)
+ nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, ts->mmap->DIFF_BTN_PIPE0_ADDR);
+ else
+ nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, ts->mmap->DIFF_BTN_PIPE1_ADDR);
+ }
+
+ nvt_change_mode(NORMAL_MODE);
+
+ mutex_unlock(&ts->lock);
+
+ NVT_LOG("--\n");
+
+ return seq_open(file, &nvt_seq_ops);
+}
+
+static const struct file_operations nvt_diff_fops = {
+ .owner = THIS_MODULE,
+ .open = nvt_diff_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+/*******************************************************
+Description:
+ Novatek touchscreen extra function proc. file node
+ initial function.
+
+return:
+ Executive outcomes. 0---succeed. -12---failed.
+*******************************************************/
+int32_t nvt_extra_proc_init(void)
+{
+ NVT_proc_fw_version_entry = proc_create(NVT_FW_VERSION, 0444, NULL,&nvt_fw_version_fops);
+ if (NVT_proc_fw_version_entry == NULL) {
+ NVT_ERR("create proc/nvt_fw_version Failed!\n");
+ return -ENOMEM;
+ } else {
+ NVT_LOG("create proc/nvt_fw_version Succeeded!\n");
+ }
+
+ NVT_proc_baseline_entry = proc_create(NVT_BASELINE, 0444, NULL,&nvt_baseline_fops);
+ if (NVT_proc_baseline_entry == NULL) {
+ NVT_ERR("create proc/nvt_baseline Failed!\n");
+ return -ENOMEM;
+ } else {
+ NVT_LOG("create proc/nvt_baseline Succeeded!\n");
+ }
+
+ NVT_proc_raw_entry = proc_create(NVT_RAW, 0444, NULL,&nvt_raw_fops);
+ if (NVT_proc_raw_entry == NULL) {
+ NVT_ERR("create proc/nvt_raw Failed!\n");
+ return -ENOMEM;
+ } else {
+ NVT_LOG("create proc/nvt_raw Succeeded!\n");
+ }
+
+ NVT_proc_diff_entry = proc_create(NVT_DIFF, 0444, NULL,&nvt_diff_fops);
+ if (NVT_proc_diff_entry == NULL) {
+ NVT_ERR("create proc/nvt_diff Failed!\n");
+ return -ENOMEM;
+ } else {
+ NVT_LOG("create proc/nvt_diff Succeeded!\n");
+ }
+
+ return 0;
+}
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2010 - 2017 Novatek, Inc.
+ *
+ * $Revision: 22971 $
+ * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/firmware.h>
+
+#include "nt36xxx.h"
+
+#if (BOOT_UPDATE_FIRMWARE || NVT_TOUCH_FW)
+
+#define FW_BIN_SIZE_116KB 118784
+#define FW_BIN_SIZE FW_BIN_SIZE_116KB
+#define FW_BIN_VER_OFFSET 0x1A000
+#define FW_BIN_VER_BAR_OFFSET 0x1A001
+#define FLASH_SECTOR_SIZE 4096
+#define SIZE_64KB 65536
+#define BLOCK_64KB_NUM 4
+
+const struct firmware *fw_entry = NULL;
+
+/*******************************************************
+Description:
+ Novatek touchscreen request update firmware function.
+
+return:
+ Executive outcomes. 0---succeed. -1,-22---failed.
+*******************************************************/
+int32_t update_firmware_request(char *filename)
+{
+ int32_t ret = 0;
+
+ if (NULL == filename) {
+ return -1;
+ }
+
+ NVT_LOG("filename is %s\n", filename);
+
+ ret = request_firmware(&fw_entry, filename, &ts->client->dev);
+ if (ret) {
+ NVT_ERR("firmware load failed, ret=%d\n", ret);
+ return ret;
+ }
+
+ // check bin file size (116kb)
+ if (fw_entry->size != FW_BIN_SIZE) {
+ NVT_ERR("bin file size not match. (%zu)\n", fw_entry->size);
+ return -EINVAL;
+ }
+
+ // check if FW version add FW version bar equals 0xFF
+ if (*(fw_entry->data + FW_BIN_VER_OFFSET) + *(fw_entry->data + FW_BIN_VER_BAR_OFFSET) != 0xFF) {
+ NVT_ERR("bin file FW_VER + FW_VER_BAR should be 0xFF!\n");
+ NVT_ERR("FW_VER=0x%02X, FW_VER_BAR=0x%02X\n", *(fw_entry->data+FW_BIN_VER_OFFSET), *(fw_entry->data+FW_BIN_VER_BAR_OFFSET));
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen release update firmware function.
+
+return:
+ n.a.
+*******************************************************/
+void update_firmware_release(void)
+{
+ if (fw_entry) {
+ release_firmware(fw_entry);
+ }
+ fw_entry=NULL;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen check firmware version function.
+
+return:
+ Executive outcomes. 0---need update. 1---need not
+ update.
+*******************************************************/
+int32_t Check_FW_Ver(void)
+{
+ uint8_t buf[16] = {0};
+ int32_t ret = 0;
+
+ //write i2c index to EVENT BUF ADDR
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("i2c write error!(%d)\n", ret);
+ return ret;
+ }
+
+ //read Firmware Version
+ buf[0] = EVENT_MAP_FWINFO;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("i2c read error!(%d)\n", ret);
+ return ret;
+ }
+
+ NVT_LOG("IC FW Ver = 0x%02X, FW Ver Bar = 0x%02X\n", buf[1], buf[2]);
+ NVT_LOG("Bin FW Ver = 0x%02X, FW ver Bar = 0x%02X\n",
+ fw_entry->data[FW_BIN_VER_OFFSET], fw_entry->data[FW_BIN_VER_BAR_OFFSET]);
+
+ // check IC FW_VER + FW_VER_BAR equals 0xFF or not, need to update if not
+ if ((buf[1] + buf[2]) != 0xFF) {
+ NVT_ERR("IC FW_VER + FW_VER_BAR not equals to 0xFF!\n");
+ return 0;
+ }
+
+ // compare IC and binary FW version
+ if (buf[1] > fw_entry->data[FW_BIN_VER_OFFSET])
+ return 1;
+ else
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen resume from deep power down function.
+
+return:
+ Executive outcomes. 0---succeed. negative---failed.
+*******************************************************/
+int32_t Resume_PD(void)
+{
+ uint8_t buf[8] = {0};
+ int32_t ret = 0;
+ int32_t retry = 0;
+
+ // Resume Command
+ buf[0] = 0x00;
+ buf[1] = 0xAB;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Write Enable error!!(%d)\n", ret);
+ return ret;
+ }
+
+ // Check 0xAA (Resume Command)
+ retry = 0;
+ while(1) {
+ msleep(1);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Resume Command) error!!(%d)\n", ret);
+ return ret;
+ }
+ if (buf[1] == 0xAA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 20)) {
+ NVT_ERR("Check 0xAA (Resume Command) error!! status=0x%02X\n", buf[1]);
+ return -1;
+ }
+ }
+ msleep(10);
+
+ NVT_LOG("Resume PD OK\n");
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen check firmware checksum function.
+
+return:
+ Executive outcomes. 0---checksum not match.
+ 1---checksum match. -1--- checksum read failed.
+*******************************************************/
+int32_t Check_CheckSum(void)
+{
+ uint8_t buf[64] = {0};
+ uint32_t XDATA_Addr = ts->mmap->READ_FLASH_CHECKSUM_ADDR;
+ int32_t ret = 0;
+ int32_t i = 0;
+ int32_t k = 0;
+ uint16_t WR_Filechksum[BLOCK_64KB_NUM] = {0};
+ uint16_t RD_Filechksum[BLOCK_64KB_NUM] = {0};
+ size_t fw_bin_size = 0;
+ size_t len_in_blk = 0;
+ int32_t retry = 0;
+
+ if (Resume_PD()) {
+ NVT_ERR("Resume PD error!!\n");
+ return -1;
+ }
+
+ fw_bin_size = fw_entry->size;
+
+ for (i = 0; i < BLOCK_64KB_NUM; i++) {
+ if (fw_bin_size > (i * SIZE_64KB)) {
+ // Calculate WR_Filechksum of each 64KB block
+ len_in_blk = min(fw_bin_size - i * SIZE_64KB, (size_t)SIZE_64KB);
+ WR_Filechksum[i] = i + 0x00 + 0x00 + (((len_in_blk - 1) >> 8) & 0xFF) + ((len_in_blk - 1) & 0xFF);
+ for (k = 0; k < len_in_blk; k++) {
+ WR_Filechksum[i] += fw_entry->data[k + i * SIZE_64KB];
+ }
+ WR_Filechksum[i] = 65535 - WR_Filechksum[i] + 1;
+
+ // Fast Read Command
+ buf[0] = 0x00;
+ buf[1] = 0x07;
+ buf[2] = i;
+ buf[3] = 0x00;
+ buf[4] = 0x00;
+ buf[5] = ((len_in_blk - 1) >> 8) & 0xFF;
+ buf[6] = (len_in_blk - 1) & 0xFF;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 7);
+ if (ret < 0) {
+ NVT_ERR("Fast Read Command error!!(%d)\n", ret);
+ return ret;
+ }
+ // Check 0xAA (Fast Read Command)
+ retry = 0;
+ while (1) {
+ msleep(80);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Fast Read Command) error!!(%d)\n", ret);
+ return ret;
+ }
+ if (buf[1] == 0xAA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 5)) {
+ NVT_ERR("Check 0xAA (Fast Read Command) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
+ return -1;
+ }
+ }
+ // Read Checksum (write addr high byte & middle byte)
+ buf[0] = 0xFF;
+ buf[1] = XDATA_Addr >> 16;
+ buf[2] = (XDATA_Addr >> 8) & 0xFF;
+ ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("Read Checksum (write addr high byte & middle byte) error!!(%d)\n", ret);
+ return ret;
+ }
+ // Read Checksum
+ buf[0] = (XDATA_Addr) & 0xFF;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("Read Checksum error!!(%d)\n", ret);
+ return ret;
+ }
+
+ RD_Filechksum[i] = (uint16_t)((buf[2] << 8) | buf[1]);
+ if (WR_Filechksum[i] != RD_Filechksum[i]) {
+ NVT_ERR("RD_Filechksum[%d]=0x%04X, WR_Filechksum[%d]=0x%04X\n", i, RD_Filechksum[i], i, WR_Filechksum[i]);
+ NVT_ERR("firmware checksum not match!!\n");
+ return 0;
+ }
+ }
+ }
+
+ NVT_LOG("firmware checksum match\n");
+ return 1;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen initial bootloader and flash
+ block function.
+
+return:
+ Executive outcomes. 0---succeed. negative---failed.
+*******************************************************/
+int32_t Init_BootLoader(void)
+{
+ uint8_t buf[64] = {0};
+ int32_t ret = 0;
+ int32_t retry = 0;
+
+ // SW Reset & Idle
+ nvt_sw_reset_idle();
+
+ // Initiate Flash Block
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ buf[2] = I2C_FW_Address;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("Inittial Flash Block error!!(%d)\n", ret);
+ return ret;
+ }
+
+ // Check 0xAA (Initiate Flash Block)
+ retry = 0;
+ while(1) {
+ msleep(1);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Inittial Flash Block) error!!(%d)\n", ret);
+ return ret;
+ }
+ if (buf[1] == 0xAA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 20)) {
+ NVT_ERR("Check 0xAA (Inittial Flash Block) error!! status=0x%02X\n", buf[1]);
+ return -1;
+ }
+ }
+
+ NVT_LOG("Init OK \n");
+ msleep(20);
+
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen erase flash sectors function.
+
+return:
+ Executive outcomes. 0---succeed. negative---failed.
+*******************************************************/
+int32_t Erase_Flash(void)
+{
+ uint8_t buf[64] = {0};
+ int32_t ret = 0;
+ int32_t count = 0;
+ int32_t i = 0;
+ int32_t Flash_Address = 0;
+ int32_t retry = 0;
+
+ // Write Enable
+ buf[0] = 0x00;
+ buf[1] = 0x06;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Write Enable (for Write Status Register) error!!(%d)\n", ret);
+ return ret;
+ }
+ // Check 0xAA (Write Enable)
+ retry = 0;
+ while (1) {
+ mdelay(1);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Write Enable for Write Status Register) error!!(%d)\n", ret);
+ return ret;
+ }
+ if (buf[1] == 0xAA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 20)) {
+ NVT_ERR("Check 0xAA (Write Enable for Write Status Register) error!! status=0x%02X\n", buf[1]);
+ return -1;
+ }
+ }
+
+ // Write Status Register
+ buf[0] = 0x00;
+ buf[1] = 0x01;
+ buf[2] = 0x00;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("Write Status Register error!!(%d)\n", ret);
+ return ret;
+ }
+ // Check 0xAA (Write Status Register)
+ retry = 0;
+ while (1) {
+ mdelay(1);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Write Status Register) error!!(%d)\n", ret);
+ return ret;
+ }
+ if (buf[1] == 0xAA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 20)) {
+ NVT_ERR("Check 0xAA (Write Status Register) error!! status=0x%02X\n", buf[1]);
+ return -1;
+ }
+ }
+
+ // Read Status
+ retry = 0;
+ while (1) {
+ mdelay(5);
+ buf[0] = 0x00;
+ buf[1] = 0x05;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Read Status (for Write Status Register) error!!(%d)\n", ret);
+ return ret;
+ }
+
+ // Check 0xAA (Read Status)
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Read Status for Write Status Register) error!!(%d)\n", ret);
+ return ret;
+ }
+ if ((buf[1] == 0xAA) && (buf[2] == 0x00)) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 100)) {
+ NVT_ERR("Check 0xAA (Read Status for Write Status Register) failed, buf[1]=0x%02X, buf[2]=0x%02X, retry=%d\n", buf[1], buf[2], retry);
+ return -1;
+ }
+ }
+
+ if (fw_entry->size % FLASH_SECTOR_SIZE)
+ count = fw_entry->size / FLASH_SECTOR_SIZE + 1;
+ else
+ count = fw_entry->size / FLASH_SECTOR_SIZE;
+
+ for(i = 0; i < count; i++) {
+ // Write Enable
+ buf[0] = 0x00;
+ buf[1] = 0x06;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Write Enable error!!(%d,%d)\n", ret, i);
+ return ret;
+ }
+ // Check 0xAA (Write Enable)
+ retry = 0;
+ while (1) {
+ mdelay(1);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Write Enable) error!!(%d,%d)\n", ret, i);
+ return ret;
+ }
+ if (buf[1] == 0xAA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 20)) {
+ NVT_ERR("Check 0xAA (Write Enable) error!! status=0x%02X\n", buf[1]);
+ return -1;
+ }
+ }
+
+ Flash_Address = i * FLASH_SECTOR_SIZE;
+
+ // Sector Erase
+ buf[0] = 0x00;
+ buf[1] = 0x20; // Command : Sector Erase
+ buf[2] = ((Flash_Address >> 16) & 0xFF);
+ buf[3] = ((Flash_Address >> 8) & 0xFF);
+ buf[4] = (Flash_Address & 0xFF);
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 5);
+ if (ret < 0) {
+ NVT_ERR("Sector Erase error!!(%d,%d)\n", ret, i);
+ return ret;
+ }
+ // Check 0xAA (Sector Erase)
+ retry = 0;
+ while (1) {
+ mdelay(1);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Sector Erase) error!!(%d,%d)\n", ret, i);
+ return ret;
+ }
+ if (buf[1] == 0xAA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 20)) {
+ NVT_ERR("Check 0xAA (Sector Erase) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
+ return -1;
+ }
+ }
+
+ // Read Status
+ retry = 0;
+ while (1) {
+ mdelay(5);
+ buf[0] = 0x00;
+ buf[1] = 0x05;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Read Status error!!(%d,%d)\n", ret, i);
+ return ret;
+ }
+
+ // Check 0xAA (Read Status)
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Read Status) error!!(%d,%d)\n", ret, i);
+ return ret;
+ }
+ if ((buf[1] == 0xAA) && (buf[2] == 0x00)) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 100)) {
+ NVT_ERR("Check 0xAA (Read Status) failed, buf[1]=0x%02X, buf[2]=0x%02X, retry=%d\n", buf[1], buf[2], retry);
+ return -1;
+ }
+ }
+ }
+
+ NVT_LOG("Erase OK \n");
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen write flash sectors function.
+
+return:
+ Executive outcomes. 0---succeed. negative---failed.
+*******************************************************/
+int32_t Write_Flash(void)
+{
+ uint8_t buf[64] = {0};
+ uint32_t XDATA_Addr = ts->mmap->RW_FLASH_DATA_ADDR;
+ uint32_t Flash_Address = 0;
+ int32_t i = 0, j = 0, k = 0;
+ uint8_t tmpvalue = 0;
+ int32_t count = 0;
+ int32_t ret = 0;
+ int32_t retry = 0;
+
+ // change I2C buffer index
+ buf[0] = 0xFF;
+ buf[1] = XDATA_Addr >> 16;
+ buf[2] = (XDATA_Addr >> 8) & 0xFF;
+ ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("change I2C buffer index error!!(%d)\n", ret);
+ return ret;
+ }
+
+ if (fw_entry->size % 256)
+ count = fw_entry->size / 256 + 1;
+ else
+ count = fw_entry->size / 256;
+
+ for (i = 0; i < count; i++) {
+ Flash_Address = i * 256;
+
+ // Write Enable
+ buf[0] = 0x00;
+ buf[1] = 0x06;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Write Enable error!!(%d)\n", ret);
+ return ret;
+ }
+ // Check 0xAA (Write Enable)
+ retry = 0;
+ while (1) {
+ udelay(100);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Write Enable) error!!(%d,%d)\n", ret, i);
+ return ret;
+ }
+ if (buf[1] == 0xAA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 20)) {
+ NVT_ERR("Check 0xAA (Write Enable) error!! status=0x%02X\n", buf[1]);
+ return -1;
+ }
+ }
+
+ // Write Page : 256 bytes
+ for (j = 0; j < min(fw_entry->size - i * 256, (size_t)256); j += 32) {
+ buf[0] = (XDATA_Addr + j) & 0xFF;
+ for (k = 0; k < 32; k++) {
+ buf[1 + k] = fw_entry->data[Flash_Address + j + k];
+ }
+ ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 33);
+ if (ret < 0) {
+ NVT_ERR("Write Page error!!(%d), j=%d\n", ret, j);
+ return ret;
+ }
+ }
+ if (fw_entry->size - Flash_Address >= 256)
+ tmpvalue=(Flash_Address >> 16) + ((Flash_Address >> 8) & 0xFF) + (Flash_Address & 0xFF) + 0x00 + (255);
+ else
+ tmpvalue=(Flash_Address >> 16) + ((Flash_Address >> 8) & 0xFF) + (Flash_Address & 0xFF) + 0x00 + (fw_entry->size - Flash_Address - 1);
+
+ for (k = 0;k < min(fw_entry->size - Flash_Address,(size_t)256); k++)
+ tmpvalue += fw_entry->data[Flash_Address + k];
+
+ tmpvalue = 255 - tmpvalue + 1;
+
+ // Page Program
+ buf[0] = 0x00;
+ buf[1] = 0x02;
+ buf[2] = ((Flash_Address >> 16) & 0xFF);
+ buf[3] = ((Flash_Address >> 8) & 0xFF);
+ buf[4] = (Flash_Address & 0xFF);
+ buf[5] = 0x00;
+ buf[6] = min(fw_entry->size - Flash_Address,(size_t)256) - 1;
+ buf[7] = tmpvalue;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 8);
+ if (ret < 0) {
+ NVT_ERR("Page Program error!!(%d), i=%d\n", ret, i);
+ return ret;
+ }
+ // Check 0xAA (Page Program)
+ retry = 0;
+ while (1) {
+ mdelay(1);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Page Program error!!(%d)\n", ret);
+ return ret;
+ }
+ if (buf[1] == 0xAA || buf[1] == 0xEA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 20)) {
+ NVT_ERR("Check 0xAA (Page Program) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
+ return -1;
+ }
+ }
+ if (buf[1] == 0xEA) {
+ NVT_ERR("Page Program error!! i=%d\n", i);
+ return -3;
+ }
+
+ // Read Status
+ retry = 0;
+ while (1) {
+ mdelay(5);
+ buf[0] = 0x00;
+ buf[1] = 0x05;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Read Status error!!(%d)\n", ret);
+ return ret;
+ }
+
+ // Check 0xAA (Read Status)
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Read Status) error!!(%d)\n", ret);
+ return ret;
+ }
+ if (((buf[1] == 0xAA) && (buf[2] == 0x00)) || (buf[1] == 0xEA)) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 100)) {
+ NVT_ERR("Check 0xAA (Read Status) failed, buf[1]=0x%02X, buf[2]=0x%02X, retry=%d\n", buf[1], buf[2], retry);
+ return -1;
+ }
+ }
+ if (buf[1] == 0xEA) {
+ NVT_ERR("Page Program error!! i=%d\n", i);
+ return -4;
+ }
+
+ NVT_LOG("Programming...%2d%%\r", ((i * 100) / count));
+ }
+
+ NVT_LOG("Programming...%2d%%\r", 100);
+ NVT_LOG("Program OK \n");
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen verify checksum of written
+ flash function.
+
+return:
+ Executive outcomes. 0---succeed. negative---failed.
+*******************************************************/
+int32_t Verify_Flash(void)
+{
+ uint8_t buf[64] = {0};
+ uint32_t XDATA_Addr = ts->mmap->READ_FLASH_CHECKSUM_ADDR;
+ int32_t ret = 0;
+ int32_t i = 0;
+ int32_t k = 0;
+ uint16_t WR_Filechksum[BLOCK_64KB_NUM] = {0};
+ uint16_t RD_Filechksum[BLOCK_64KB_NUM] = {0};
+ size_t fw_bin_size = 0;
+ size_t len_in_blk = 0;
+ int32_t retry = 0;
+
+ fw_bin_size = fw_entry->size;
+
+ for (i = 0; i < BLOCK_64KB_NUM; i++) {
+ if (fw_bin_size > (i * SIZE_64KB)) {
+ // Calculate WR_Filechksum of each 64KB block
+ len_in_blk = min(fw_bin_size - i * SIZE_64KB, (size_t)SIZE_64KB);
+ WR_Filechksum[i] = i + 0x00 + 0x00 + (((len_in_blk - 1) >> 8) & 0xFF) + ((len_in_blk - 1) & 0xFF);
+ for (k = 0; k < len_in_blk; k++) {
+ WR_Filechksum[i] += fw_entry->data[k + i * SIZE_64KB];
+ }
+ WR_Filechksum[i] = 65535 - WR_Filechksum[i] + 1;
+
+ // Fast Read Command
+ buf[0] = 0x00;
+ buf[1] = 0x07;
+ buf[2] = i;
+ buf[3] = 0x00;
+ buf[4] = 0x00;
+ buf[5] = ((len_in_blk - 1) >> 8) & 0xFF;
+ buf[6] = (len_in_blk - 1) & 0xFF;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 7);
+ if (ret < 0) {
+ NVT_ERR("Fast Read Command error!!(%d)\n", ret);
+ return ret;
+ }
+ // Check 0xAA (Fast Read Command)
+ retry = 0;
+ while (1) {
+ msleep(80);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Fast Read Command) error!!(%d)\n", ret);
+ return ret;
+ }
+ if (buf[1] == 0xAA) {
+ break;
+ }
+ retry++;
+ if (unlikely(retry > 5)) {
+ NVT_ERR("Check 0xAA (Fast Read Command) failed, buf[1]=0x%02X, retry=%d\n", buf[1], retry);
+ return -1;
+ }
+ }
+ // Read Checksum (write addr high byte & middle byte)
+ buf[0] = 0xFF;
+ buf[1] = XDATA_Addr >> 16;
+ buf[2] = (XDATA_Addr >> 8) & 0xFF;
+ ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("Read Checksum (write addr high byte & middle byte) error!!(%d)\n", ret);
+ return ret;
+ }
+ // Read Checksum
+ buf[0] = (XDATA_Addr) & 0xFF;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("Read Checksum error!!(%d)\n", ret);
+ return ret;
+ }
+
+ RD_Filechksum[i] = (uint16_t)((buf[2] << 8) | buf[1]);
+ if (WR_Filechksum[i] != RD_Filechksum[i]) {
+ NVT_ERR("Verify Fail%d!!\n", i);
+ NVT_ERR("RD_Filechksum[%d]=0x%04X, WR_Filechksum[%d]=0x%04X\n", i, RD_Filechksum[i], i, WR_Filechksum[i]);
+ return -1;
+ }
+ }
+ }
+
+ NVT_LOG("Verify OK \n");
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen update firmware function.
+
+return:
+ Executive outcomes. 0---succeed. negative---failed.
+*******************************************************/
+int32_t Update_Firmware(void)
+{
+ int32_t ret = 0;
+
+ //---Stop CRC check to prevent IC auto reboot---
+ nvt_stop_crc_reboot();
+
+ // Step 1 : initial bootloader
+ ret = Init_BootLoader();
+ if (ret) {
+ return ret;
+ }
+
+ // Step 2 : Resume PD
+ ret = Resume_PD();
+ if (ret) {
+ return ret;
+ }
+
+ // Step 3 : Erase
+ ret = Erase_Flash();
+ if (ret) {
+ return ret;
+ }
+
+ // Step 4 : Program
+ ret = Write_Flash();
+ if (ret) {
+ return ret;
+ }
+
+ // Step 5 : Verify
+ ret = Verify_Flash();
+ if (ret) {
+ return ret;
+ }
+
+ //Step 6 : Bootloader Reset
+ nvt_bootloader_reset();
+ nvt_check_fw_reset_state(RESET_STATE_INIT);
+
+ return ret;
+}
+/*******************************************************
+Description:
+ Novatek touchscreen check flash end flag function.
+
+return:
+ Executive outcomes. 0---succeed. 1,negative---failed.
+*******************************************************/
+#define NVT_FLASH_END_FLAG_LEN 3
+#define NVT_FLASH_END_FLAG_ADDR 0x1AFFD
+int32_t nvt_check_flash_end_flag(void)
+{
+ uint8_t buf[8] = {0};
+ uint8_t nvt_end_flag[NVT_FLASH_END_FLAG_LEN + 1] = {0};
+ int32_t ret = 0;
+
+ // Step 1 : initial bootloader
+ ret = Init_BootLoader();
+ if (ret) {
+ return ret;
+ }
+
+ // Step 2 : Resume PD
+ ret = Resume_PD();
+ if (ret) {
+ return ret;
+ }
+
+ // Step 3 : unlock
+ buf[0] = 0x00;
+ buf[1] = 0x35;
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("write unlock error!!(%d)\n", ret);
+ return ret;
+ }
+ msleep(10);
+
+ //Step 4 : Flash Read Command
+ buf[0] = 0x00;
+ buf[1] = 0x03;
+ buf[2] = (NVT_FLASH_END_FLAG_ADDR >> 16) & 0xFF; //Addr_H
+ buf[3] = (NVT_FLASH_END_FLAG_ADDR >> 8) & 0xFF; //Addr_M
+ buf[4] = NVT_FLASH_END_FLAG_ADDR & 0xFF; //Addr_L
+ buf[5] = (NVT_FLASH_END_FLAG_LEN >> 8) & 0xFF; //Len_H
+ buf[6] = NVT_FLASH_END_FLAG_LEN & 0xFF; //Len_L
+ ret = CTP_I2C_WRITE(ts->client, I2C_HW_Address, buf, 7);
+ if (ret < 0) {
+ NVT_ERR("write Read Command error!!(%d)\n", ret);
+ return ret;
+ }
+ msleep(10);
+
+ // Check 0xAA (Read Command)
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ ret = CTP_I2C_READ(ts->client, I2C_HW_Address, buf, 2);
+ if (ret < 0) {
+ NVT_ERR("Check 0xAA (Read Command) error!!(%d)\n", ret);
+ return ret;
+ }
+ if (buf[1] != 0xAA) {
+ NVT_ERR("Check 0xAA (Read Command) error!! status=0x%02X\n", buf[1]);
+ return -1;
+ }
+
+ msleep(10);
+
+ //Step 5 : Read Flash Data
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->READ_FLASH_CHECKSUM_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->READ_FLASH_CHECKSUM_ADDR >> 8) & 0xFF;
+ ret = CTP_I2C_WRITE(ts->client, I2C_BLDR_Address, buf, 3);
+ if (ret < 0) {
+ NVT_ERR("change index error!! (%d)\n", ret);
+ return ret;
+ }
+ msleep(10);
+
+ // Read Back
+ buf[0] = ts->mmap->READ_FLASH_CHECKSUM_ADDR & 0xFF;
+ ret = CTP_I2C_READ(ts->client, I2C_BLDR_Address, buf, 6);
+ if (ret < 0) {
+ NVT_ERR("Read Back error!! (%d)\n", ret);
+ return ret;
+ }
+
+ //buf[3:5] => NVT End Flag
+ strncpy(nvt_end_flag, &buf[3], NVT_FLASH_END_FLAG_LEN);
+ NVT_LOG("nvt_end_flag=%s (%02X %02X %02X)\n", nvt_end_flag, buf[3], buf[4], buf[5]);
+
+ if (strncmp(nvt_end_flag, "NVT", 3) == 0) {
+ return 0;
+ } else {
+ NVT_ERR("\"NVT\" end flag not found!\n");
+ return 1;
+ }
+}
+#endif
+
+#if BOOT_UPDATE_FIRMWARE
+/*******************************************************
+Description:
+ Novatek touchscreen update firmware when booting
+ function.
+
+return:
+ n.a.
+*******************************************************/
+void Boot_Update_Firmware(struct work_struct *work)
+{
+ int32_t ret = 0;
+
+ char firmware_name[256] = "";
+ sprintf(firmware_name, BOOT_UPDATE_FIRMWARE_NAME);
+
+ // request bin file in "/etc/firmware"
+ ret = update_firmware_request(firmware_name);
+ if (ret) {
+ NVT_ERR("update_firmware_request failed. (%d)\n", ret);
+ return;
+ }
+
+ mutex_lock(&ts->lock);
+#if NVT_TOUCH_ESD_PROTECT
+ nvt_esd_check_enable(false);
+#endif
+#if NVT_TOUCH_FW
+ ts->loading_fw = 1;
+#endif
+ nvt_sw_reset_idle();
+
+ ret = Check_CheckSum();
+
+ if (ret < 0) { // read firmware checksum failed
+ NVT_ERR("read firmware checksum failed\n");
+ Update_Firmware();
+ } else if ((ret == 0) && (Check_FW_Ver() == 0)) { // (fw checksum not match) && (bin fw version >= ic fw version)
+ NVT_LOG("firmware version not match\n");
+ Update_Firmware();
+ } else if (nvt_check_flash_end_flag()) {
+ NVT_LOG("check flash end flag failed\n");
+ Update_Firmware();
+ } else {
+ // Bootloader Reset
+ nvt_bootloader_reset();
+ nvt_check_fw_reset_state(RESET_STATE_INIT);
+ }
+
+#if NVT_TOUCH_FW
+ ts->loading_fw = 0;
+#endif
+ mutex_unlock(&ts->lock);
+
+ update_firmware_release();
+}
+#endif /* BOOT_UPDATE_FIRMWARE */
+
+#if NVT_TOUCH_FW
+static ssize_t nvt_poweron_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ bool val;
+
+ mutex_lock(&ts->lock);
+ val = ts->suspended;
+ mutex_unlock(&ts->lock);
+
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ val == 0);
+}
+
+static DEVICE_ATTR(poweron, 0444, nvt_poweron_show, NULL);
+
+static ssize_t nvt_ic_ver_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "[FW]%02x,[IC]NT36525\n",
+ ts->fw_ver);
+}
+
+static DEVICE_ATTR(ic_ver, 0444, nvt_ic_ver_show, NULL);
+
+static ssize_t nvt_productinfo_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+/* Update script use as $touch_product_id in fw name ==> (chip id from Lenovo&script) OR (vendor name from Focaltech) OR (project ID from Longcheer&Himax)
+ Project ID ?? ( - Jeter - Hannah)
+ Chip ID ?? (NVT-ts or NVTCapacitiveTouchScreen or NT36xxx) */
+ return scnprintf(buf, PAGE_SIZE, "%s\n",
+ ts->product_id);
+}
+
+static DEVICE_ATTR(productinfo, 0444, nvt_productinfo_show, NULL);
+
+static ssize_t nvt_force_reflash_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned int input;
+
+ if (sscanf(buf, "%u", &input) != 1)
+ return -EINVAL;
+
+ ts->force_reflash = (input == 0) ? false : true;
+
+ return count;
+}
+
+static DEVICE_ATTR(forcereflash, 0220, NULL, nvt_force_reflash_store);
+
+static ssize_t nvt_flashprog_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ (ts->loading_fw) ? 1 : 0);
+}
+
+static DEVICE_ATTR(flashprog, 0444, nvt_flashprog_show, NULL);
+
+static ssize_t nvt_do_reflash_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int retval;
+ char prefix[FW_NAME_MAX_LEN] = VENDOR_NAME;
+ char template[FW_NAME_MAX_LEN];
+ char firmware_name[256] = "";
+
+ if (count > FW_NAME_MAX_LEN) {
+ NVT_ERR("FW filename is too long\n");
+ retval = -EINVAL;
+ goto exit;
+ }
+
+ if (ts->suspended) {
+ NVT_ERR("In suspend state, try again later\n");
+ retval = -EINVAL;
+ goto exit;
+ }
+
+ if (ts->loading_fw) {
+ NVT_ERR("In FW flashing state, try again later\n");
+ retval = -EINVAL;
+ goto exit;
+ }
+
+ if (!ts->force_reflash) {
+ if (strncmp(buf, prefix,
+ strnlen(prefix, sizeof(prefix)))) {
+ NVT_ERR("FW does not belong to Novatek\n");
+ retval = -EINVAL;
+ goto exit;
+ }
+
+ snprintf(template, sizeof(template), "-%s-",
+ ts->product_id);
+ if (!strnstr(buf + strnlen(prefix, sizeof(prefix)), template,
+ count)) {
+ NVT_ERR("FW does not belong to %s\n", ts->product_id);
+ retval = -EINVAL;
+ goto exit;
+ }
+ }
+
+ strlcpy(firmware_name, buf, count);
+ NVT_LOG("FW filename: %s\n", firmware_name);
+
+ retval = update_firmware_request(firmware_name);
+ if (retval) {
+ NVT_ERR("update_firmware_request failed. (%d)\n", retval);
+ goto exit;
+ }
+
+ mutex_lock(&ts->lock);
+#if NVT_TOUCH_ESD_PROTECT
+ nvt_esd_check_enable(false);
+#endif
+ ts->loading_fw = 1;
+ nvt_sw_reset_idle();
+
+ retval = Check_CheckSum();
+
+ if (retval < 0) {
+ NVT_ERR("read firmware checksum failed\n");
+ Update_Firmware();
+ } else if ((retval == 0) && (Check_FW_Ver() == 0)) {
+ NVT_LOG("firmware version not match\n");
+ Update_Firmware();
+ } else if (nvt_check_flash_end_flag()) {
+ NVT_LOG("check flash end flag failed\n");
+ Update_Firmware();
+ } else {
+ /* Bootloader Reset */
+ nvt_bootloader_reset();
+ nvt_check_fw_reset_state(RESET_STATE_INIT);
+ }
+
+ ts->loading_fw = 0;
+ mutex_unlock(&ts->lock);
+
+ update_firmware_release();
+
+ retval = count;
+exit:
+ return retval;
+}
+
+static DEVICE_ATTR(doreflash, 0220, NULL, nvt_do_reflash_store);
+
+static ssize_t nvt_build_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+/* Update script use for comparing $str_cfg_id_latest in fw name */
+ uint8_t tmp_buf[4] = {0};
+ uint8_t fw_version = 0;
+ uint8_t date_Y = 0;
+ uint8_t date_M = 0;
+ uint8_t date_D = 0;
+
+ tmp_buf[0] = 0xFF;
+ tmp_buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ tmp_buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, tmp_buf, 3);
+
+ tmp_buf[0] = EVENT_MAP_FWINFO;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, tmp_buf, 2);
+ fw_version = tmp_buf[1];
+
+ tmp_buf[0] = EVENT_MAP_FWDATE;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, tmp_buf, 4);
+ date_Y = tmp_buf[1];
+ date_M = tmp_buf[2];
+ date_D = tmp_buf[3];
+
+ return scnprintf(buf, PAGE_SIZE, "%02x-%02d%02d%02d\n",
+ fw_version, date_Y, date_M, date_D);
+}
+
+static DEVICE_ATTR(buildid, 0444, nvt_build_id_show, NULL);
+
+
+#include <linux/slab.h>
+#include <linux/major.h>
+#include <linux/kdev_t.h>
+
+/* Attribute: path (RO) */
+static ssize_t path_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t blen;
+ const char *path;
+
+ path = kobject_get_path(&ts->client->dev.kobj, GFP_KERNEL);
+ blen = scnprintf(buf, PAGE_SIZE, "%s", path ? path : "na");
+ kfree(path);
+ return blen;
+}
+
+/* Attribute: vendor (RO) */
+static ssize_t vendor_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return scnprintf(buf, PAGE_SIZE, VENDOR_NAME);
+}
+
+static struct device_attribute touchscreen_attributes[] = {
+ __ATTR_RO(path),
+ __ATTR_RO(vendor),
+ __ATTR_NULL
+};
+
+#define TSDEV_MINOR_BASE 128
+#define TSDEV_MINOR_MAX 32
+
+/*******************************************************
+Description:
+ Novatek touchscreen FW function class. file node
+ initial function.
+
+return:
+ Executive outcomes. 0---succeed. -1---failed.
+*******************************************************/
+int32_t nvt_fw_class_init(bool create)
+{
+ struct device_attribute *attrs = touchscreen_attributes;
+ int i, error = 0;
+ static struct class *touchscreen_class;
+ static struct device *ts_class_dev;
+ static int minor;
+
+ if (create) {
+ minor = input_get_new_minor(ts->client->addr,
+ 1, false);
+ if (minor < 0)
+ minor = input_get_new_minor(TSDEV_MINOR_BASE,
+ TSDEV_MINOR_MAX, true);
+ NVT_LOG("assigned minor %d\n", minor);
+
+ touchscreen_class = class_create(THIS_MODULE, "touchscreen");
+ if (IS_ERR(touchscreen_class)) {
+ error = PTR_ERR(touchscreen_class);
+ touchscreen_class = NULL;
+ return error;
+ }
+
+ ts_class_dev = device_create(touchscreen_class, NULL,
+ MKDEV(INPUT_MAJOR, minor),
+ ts, NVT_I2C_NAME);
+ if (IS_ERR(ts_class_dev)) {
+ error = PTR_ERR(ts_class_dev);
+ ts_class_dev = NULL;
+ return error;
+ }
+
+ for (i = 0; attrs[i].attr.name != NULL; ++i) {
+ error = device_create_file(ts_class_dev, &attrs[i]);
+ if (error)
+ break;
+ }
+
+ if (error)
+ goto device_destroy;
+ else
+ NVT_LOG("create /sys/class/touchscreen/%s Succeeded!\n", NVT_I2C_NAME);
+ } else {
+ if (!touchscreen_class || !ts_class_dev)
+ return -ENODEV;
+
+ for (i = 0; attrs[i].attr.name != NULL; ++i)
+ device_remove_file(ts_class_dev, &attrs[i]);
+
+ device_unregister(ts_class_dev);
+ class_unregister(touchscreen_class);
+ }
+
+ return 0;
+
+device_destroy:
+ for (--i; i >= 0; --i)
+ device_remove_file(ts_class_dev, &attrs[i]);
+ device_destroy(touchscreen_class, MKDEV(INPUT_MAJOR, minor));
+ ts_class_dev = NULL;
+ class_unregister(touchscreen_class);
+ NVT_ERR("error creating touchscreen class\n");
+
+ return -ENODEV;
+}
+
+int nvt_fw_sysfs_init(void)
+{
+ int ret;
+ struct i2c_client *client = ts->client;
+
+ ret = nvt_fw_class_init(true);
+ if (ret != 0) {
+ NVT_ERR("fw class init failed. ret=%d\n", ret);
+ return ret;
+ }
+
+ ret = device_create_file(&client->dev, &dev_attr_forcereflash);
+ if (ret) {
+ NVT_ERR("create_file dev_attr_forcereflash failed\n");
+ return ret;
+ }
+
+ ret = device_create_file(&client->dev, &dev_attr_flashprog);
+ if (ret) {
+ NVT_ERR("create_file dev_attr_flashprog failed\n");
+ return ret;
+ }
+ ret = device_create_file(&client->dev, &dev_attr_doreflash);
+ if (ret) {
+ NVT_ERR("create_file dev_attr_doreflash failed\n");
+ return ret;
+ }
+
+ ret = device_create_file(&client->dev, &dev_attr_buildid);
+ if (ret) {
+ NVT_ERR("create_file dev_attr_buildid failed\n");
+ return ret;
+ }
+
+ ret = device_create_file(&client->dev, &dev_attr_productinfo);
+ if (ret) {
+ NVT_ERR("create_file dev_attr_productinfo failed\n");
+ return ret;
+ }
+
+ ret = device_create_file(&client->dev, &dev_attr_poweron);
+ if (ret) {
+ NVT_ERR("create_file dev_attr_poweron failed\n");
+ return ret;
+ }
+
+ ret = device_create_file(&client->dev, &dev_attr_ic_ver);
+ if (ret) {
+ NVT_ERR("create_file dev_attr_ic_ver failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+void nvt_fw_sysfs_deinit(void)
+{
+ struct i2c_client *client = ts->client;
+ device_remove_file(&client->dev, &dev_attr_forcereflash);
+ device_remove_file(&client->dev, &dev_attr_flashprog);
+ device_remove_file(&client->dev, &dev_attr_doreflash);
+ device_remove_file(&client->dev, &dev_attr_buildid);
+ device_remove_file(&client->dev, &dev_attr_productinfo);
+ device_remove_file(&client->dev, &dev_attr_poweron);
+ device_remove_file(&client->dev, &dev_attr_ic_ver);
+ nvt_fw_class_init(false);
+}
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2010 - 2017 Novatek, Inc.
+ *
+ * $Revision: 22971 $
+ * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+struct nvt_ts_mem_map {
+ uint32_t EVENT_BUF_ADDR;
+ uint32_t RAW_PIPE0_ADDR;
+ uint32_t RAW_PIPE0_Q_ADDR;
+ uint32_t RAW_PIPE1_ADDR;
+ uint32_t RAW_PIPE1_Q_ADDR;
+ uint32_t BASELINE_ADDR;
+ uint32_t BASELINE_Q_ADDR;
+ uint32_t BASELINE_BTN_ADDR;
+ uint32_t BASELINE_BTN_Q_ADDR;
+ uint32_t DIFF_PIPE0_ADDR;
+ uint32_t DIFF_PIPE0_Q_ADDR;
+ uint32_t DIFF_PIPE1_ADDR;
+ uint32_t DIFF_PIPE1_Q_ADDR;
+ uint32_t RAW_BTN_PIPE0_ADDR;
+ uint32_t RAW_BTN_PIPE0_Q_ADDR;
+ uint32_t RAW_BTN_PIPE1_ADDR;
+ uint32_t RAW_BTN_PIPE1_Q_ADDR;
+ uint32_t DIFF_BTN_PIPE0_ADDR;
+ uint32_t DIFF_BTN_PIPE0_Q_ADDR;
+ uint32_t DIFF_BTN_PIPE1_ADDR;
+ uint32_t DIFF_BTN_PIPE1_Q_ADDR;
+ uint32_t READ_FLASH_CHECKSUM_ADDR;
+ uint32_t RW_FLASH_DATA_ADDR;
+};
+
+static const struct nvt_ts_mem_map NT36672A_memory_map = {
+ .EVENT_BUF_ADDR = 0x21C00,
+ .RAW_PIPE0_ADDR = 0x20000,
+ .RAW_PIPE0_Q_ADDR = 0,
+ .RAW_PIPE1_ADDR = 0x23000,
+ .RAW_PIPE1_Q_ADDR = 0,
+ .BASELINE_ADDR = 0x20BFC,
+ .BASELINE_Q_ADDR = 0,
+ .BASELINE_BTN_ADDR = 0x23BFC,
+ .BASELINE_BTN_Q_ADDR = 0,
+ .DIFF_PIPE0_ADDR = 0x206DC,
+ .DIFF_PIPE0_Q_ADDR = 0,
+ .DIFF_PIPE1_ADDR = 0x236DC,
+ .DIFF_PIPE1_Q_ADDR = 0,
+ .RAW_BTN_PIPE0_ADDR = 0x20510,
+ .RAW_BTN_PIPE0_Q_ADDR = 0,
+ .RAW_BTN_PIPE1_ADDR = 0x23510,
+ .RAW_BTN_PIPE1_Q_ADDR = 0,
+ .DIFF_BTN_PIPE0_ADDR = 0x20BF0,
+ .DIFF_BTN_PIPE0_Q_ADDR = 0,
+ .DIFF_BTN_PIPE1_ADDR = 0x23BF0,
+ .DIFF_BTN_PIPE1_Q_ADDR = 0,
+ .READ_FLASH_CHECKSUM_ADDR = 0x24000,
+ .RW_FLASH_DATA_ADDR = 0x24002,
+};
+
+static const struct nvt_ts_mem_map NT36772_memory_map = {
+ .EVENT_BUF_ADDR = 0x11E00,
+ .RAW_PIPE0_ADDR = 0x10000,
+ .RAW_PIPE0_Q_ADDR = 0,
+ .RAW_PIPE1_ADDR = 0x12000,
+ .RAW_PIPE1_Q_ADDR = 0,
+ .BASELINE_ADDR = 0x10E70,
+ .BASELINE_Q_ADDR = 0,
+ .BASELINE_BTN_ADDR = 0x12E70,
+ .BASELINE_BTN_Q_ADDR = 0,
+ .DIFF_PIPE0_ADDR = 0x10830,
+ .DIFF_PIPE0_Q_ADDR = 0,
+ .DIFF_PIPE1_ADDR = 0x12830,
+ .DIFF_PIPE1_Q_ADDR = 0,
+ .RAW_BTN_PIPE0_ADDR = 0x10E60,
+ .RAW_BTN_PIPE0_Q_ADDR = 0,
+ .RAW_BTN_PIPE1_ADDR = 0x12E60,
+ .RAW_BTN_PIPE1_Q_ADDR = 0,
+ .DIFF_BTN_PIPE0_ADDR = 0x10E68,
+ .DIFF_BTN_PIPE0_Q_ADDR = 0,
+ .DIFF_BTN_PIPE1_ADDR = 0x12E68,
+ .DIFF_BTN_PIPE1_Q_ADDR = 0,
+ .READ_FLASH_CHECKSUM_ADDR = 0x14000,
+ .RW_FLASH_DATA_ADDR = 0x14002,
+};
+
+static const struct nvt_ts_mem_map NT36525_memory_map = {
+ .EVENT_BUF_ADDR = 0x11A00,
+ .RAW_PIPE0_ADDR = 0x10000,
+ .RAW_PIPE0_Q_ADDR = 0,
+ .RAW_PIPE1_ADDR = 0x12000,
+ .RAW_PIPE1_Q_ADDR = 0,
+ .BASELINE_ADDR = 0x10B08,
+ .BASELINE_Q_ADDR = 0,
+ .BASELINE_BTN_ADDR = 0x12B08,
+ .BASELINE_BTN_Q_ADDR = 0,
+ .DIFF_PIPE0_ADDR = 0x1064C,
+ .DIFF_PIPE0_Q_ADDR = 0,
+ .DIFF_PIPE1_ADDR = 0x1264C,
+ .DIFF_PIPE1_Q_ADDR = 0,
+ .RAW_BTN_PIPE0_ADDR = 0x10634,
+ .RAW_BTN_PIPE0_Q_ADDR = 0,
+ .RAW_BTN_PIPE1_ADDR = 0x12634,
+ .RAW_BTN_PIPE1_Q_ADDR = 0,
+ .DIFF_BTN_PIPE0_ADDR = 0x10AFC,
+ .DIFF_BTN_PIPE0_Q_ADDR = 0,
+ .DIFF_BTN_PIPE1_ADDR = 0x12AFC,
+ .DIFF_BTN_PIPE1_Q_ADDR = 0,
+ .READ_FLASH_CHECKSUM_ADDR = 0x14000,
+ .RW_FLASH_DATA_ADDR = 0x14002,
+};
+
+static const struct nvt_ts_mem_map NT36870_memory_map = {
+ .EVENT_BUF_ADDR = 0x25000,
+ .RAW_PIPE0_ADDR = 0x20000,
+ .RAW_PIPE0_Q_ADDR = 0x204C8,
+ .RAW_PIPE1_ADDR = 0x23000,
+ .RAW_PIPE1_Q_ADDR = 0x234C8,
+ .BASELINE_ADDR = 0x21350,
+ .BASELINE_Q_ADDR = 0x21818,
+ .BASELINE_BTN_ADDR = 0x24350,
+ .BASELINE_BTN_Q_ADDR = 0x24358,
+ .DIFF_PIPE0_ADDR = 0x209B0,
+ .DIFF_PIPE0_Q_ADDR = 0x20E78,
+ .DIFF_PIPE1_ADDR = 0x239B0,
+ .DIFF_PIPE1_Q_ADDR = 0x23E78,
+ .RAW_BTN_PIPE0_ADDR = 0x20990,
+ .RAW_BTN_PIPE0_Q_ADDR = 0x20998,
+ .RAW_BTN_PIPE1_ADDR = 0x23990,
+ .RAW_BTN_PIPE1_Q_ADDR = 0x23998,
+ .DIFF_BTN_PIPE0_ADDR = 0x21340,
+ .DIFF_BTN_PIPE0_Q_ADDR = 0x21348,
+ .DIFF_BTN_PIPE1_ADDR = 0x24340,
+ .DIFF_BTN_PIPE1_Q_ADDR = 0x24348,
+ .READ_FLASH_CHECKSUM_ADDR = 0x24000,
+ .RW_FLASH_DATA_ADDR = 0x24002,
+};
+
+static const struct nvt_ts_mem_map NT36676F_memory_map = {
+ .EVENT_BUF_ADDR = 0x11A00,
+ .RAW_PIPE0_ADDR = 0x10000,
+ .RAW_PIPE0_Q_ADDR = 0,
+ .RAW_PIPE1_ADDR = 0x12000,
+ .RAW_PIPE1_Q_ADDR = 0,
+ .BASELINE_ADDR = 0x10B08,
+ .BASELINE_Q_ADDR = 0,
+ .BASELINE_BTN_ADDR = 0x12B08,
+ .BASELINE_BTN_Q_ADDR = 0,
+ .DIFF_PIPE0_ADDR = 0x1064C,
+ .DIFF_PIPE0_Q_ADDR = 0,
+ .DIFF_PIPE1_ADDR = 0x1264C,
+ .DIFF_PIPE1_Q_ADDR = 0,
+ .RAW_BTN_PIPE0_ADDR = 0x10634,
+ .RAW_BTN_PIPE0_Q_ADDR = 0,
+ .RAW_BTN_PIPE1_ADDR = 0x12634,
+ .RAW_BTN_PIPE1_Q_ADDR = 0,
+ .DIFF_BTN_PIPE0_ADDR = 0x10AFC,
+ .DIFF_BTN_PIPE0_Q_ADDR = 0,
+ .DIFF_BTN_PIPE1_ADDR = 0x12AFC,
+ .DIFF_BTN_PIPE1_Q_ADDR = 0,
+ .READ_FLASH_CHECKSUM_ADDR = 0x14000,
+ .RW_FLASH_DATA_ADDR = 0x14002,
+};
+
+#define NVT_ID_BYTE_MAX 6
+struct nvt_ts_trim_id_table {
+ uint8_t id[NVT_ID_BYTE_MAX];
+ uint8_t mask[NVT_ID_BYTE_MAX];
+ const struct nvt_ts_mem_map *mmap;
+ uint8_t carrier_system;
+};
+
+static const struct nvt_ts_trim_id_table trim_id_table[] = {
+ {.id = {0x0A, 0xFF, 0xFF, 0x72, 0x66, 0x03}, .mask = {1, 0, 0, 1, 1, 1},
+ .mmap = &NT36672A_memory_map, .carrier_system = 0},
+ {.id = {0x55, 0x00, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1},
+ .mmap = &NT36772_memory_map, .carrier_system = 0},
+ {.id = {0x55, 0x72, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1},
+ .mmap = &NT36772_memory_map, .carrier_system = 0},
+ {.id = {0xAA, 0x00, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1},
+ .mmap = &NT36772_memory_map, .carrier_system = 0},
+ {.id = {0xAA, 0x72, 0xFF, 0x00, 0x00, 0x00}, .mask = {1, 1, 0, 1, 1, 1},
+ .mmap = &NT36772_memory_map, .carrier_system = 0},
+ {.id = {0xFF, 0xFF, 0xFF, 0x72, 0x67, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
+ .mmap = &NT36772_memory_map, .carrier_system = 0},
+ {.id = {0xFF, 0xFF, 0xFF, 0x70, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
+ .mmap = &NT36772_memory_map, .carrier_system = 0},
+ {.id = {0xFF, 0xFF, 0xFF, 0x70, 0x67, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
+ .mmap = &NT36772_memory_map, .carrier_system = 0},
+ {.id = {0xFF, 0xFF, 0xFF, 0x72, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
+ .mmap = &NT36772_memory_map, .carrier_system = 0},
+ {.id = {0xFF, 0xFF, 0xFF, 0x25, 0x65, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
+ .mmap = &NT36525_memory_map, .carrier_system = 0},
+ {.id = {0xFF, 0xFF, 0xFF, 0x70, 0x68, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
+ .mmap = &NT36870_memory_map, .carrier_system = 1},
+ {.id = {0xFF, 0xFF, 0xFF, 0x76, 0x66, 0x03}, .mask = {0, 0, 0, 1, 1, 1},
+ .mmap = &NT36676F_memory_map, .carrier_system = 0}
+};
--- /dev/null
+/*
+ * Copyright (C) 2010 - 2017 Novatek, Inc.
+ *
+ * $Revision: 23067 $
+ * $Date: 2018-02-09 11:39:27 +0800 (ι±δΊ, 09 δΊζ 2018) $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+
+#include "nt36xxx.h"
+#include "nt36xxx_mp_ctrlram.h"
+
+#if NVT_TOUCH_MP
+
+#define NORMAL_MODE 0x00
+#define TEST_MODE_1 0x21
+#define TEST_MODE_2 0x22
+#define MP_MODE_CC 0x41
+#define FREQ_HOP_DISABLE 0x66
+#define FREQ_HOP_ENABLE 0x65
+
+#define SHORT_TEST_CSV_FILE "/data/local/tmp/ShortTest.csv"
+#define OPEN_TEST_CSV_FILE "/data/local/tmp/OpenTest.csv"
+#define FW_RAWDATA_CSV_FILE "/data/local/tmp/FWMutualTest.csv"
+#define FW_CC_CSV_FILE "/data/local/tmp/FWCCTest.csv"
+#define NOISE_TEST_CSV_FILE "/data/local/tmp/NoiseTest.csv"
+
+#define nvt_mp_seq_printf(m, fmt, args...) do { \
+ seq_printf(m, fmt, ##args); \
+ if (!nvt_mp_test_result_printed) \
+ printk(fmt, ##args); \
+} while (0)
+
+static uint8_t *RecordResult_Short = NULL;
+static uint8_t *RecordResult_Short_Diff = NULL;
+static uint8_t *RecordResult_Short_Base = NULL;
+static uint8_t *RecordResult_Open = NULL;
+static uint8_t *RecordResult_FWMutual = NULL;
+static uint8_t *RecordResult_FW_CC = NULL;
+static uint8_t *RecordResult_FW_CC_I = NULL;
+static uint8_t *RecordResult_FW_CC_Q = NULL;
+static uint8_t *RecordResult_FW_DiffMax = NULL;
+static uint8_t *RecordResult_FW_DiffMin = NULL;
+
+static int32_t TestResult_Short = 0;
+static int32_t TestResult_Short_Diff = 0;
+static int32_t TestResult_Short_Base = 0;
+static int32_t TestResult_Open = 0;
+static int32_t TestResult_FW_Rawdata = 0;
+static int32_t TestResult_FWMutual = 0;
+static int32_t TestResult_FW_CC = 0;
+static int32_t TestResult_FW_CC_I = 0;
+static int32_t TestResult_FW_CC_Q = 0;
+static int32_t TestResult_Noise = 0;
+static int32_t TestResult_FW_DiffMax = 0;
+static int32_t TestResult_FW_DiffMin = 0;
+
+static int32_t *RawData_Short = NULL;
+static int32_t *RawData_Short_Diff = NULL;
+static int32_t *RawData_Short_Base = NULL;
+static int32_t *RawData_Open = NULL;
+static int32_t *RawData_Diff = NULL;
+static int32_t *RawData_Diff_Min = NULL;
+static int32_t *RawData_Diff_Max = NULL;
+static int32_t *RawData_FWMutual = NULL;
+static int32_t *RawData_FW_CC = NULL;
+static int32_t *RawData_FW_CC_I = NULL;
+static int32_t *RawData_FW_CC_Q = NULL;
+
+static struct proc_dir_entry *NVT_proc_selftest_entry = NULL;
+#if NVT_TOUCH_MP_LENOVO
+static struct proc_dir_entry *NVT_proc_selftest_read_data = NULL;
+#endif
+static int8_t nvt_mp_test_result_printed = 0;
+
+extern void nvt_change_mode(uint8_t mode);
+extern uint8_t nvt_get_fw_pipe(void);
+extern void nvt_read_mdata(uint32_t xdata_addr, uint32_t xdata_btn_addr);
+extern void nvt_get_mdata(int32_t *buf, uint8_t *m_x_num, uint8_t *m_y_num);
+void nvt_mp_parse_dt(struct device_node *root, const char *node_compatible);
+extern int32_t nvt_read_mass_data(uint32_t xdata_addr, uint8_t *temp_buf, uint32_t len);
+
+/*******************************************************
+Description:
+ Novatek touchscreen allocate buffer for mp selftest.
+
+return:
+ Executive outcomes. 0---succeed. -12---Out of memory
+*******************************************************/
+static int nvt_mp_buffer_init(void)
+{
+ size_t RecordResult_BufSize = IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE;
+ size_t RawData_BufSize = (IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE) * sizeof(int32_t);
+
+ RecordResult_Short = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
+ if (!RecordResult_Short) {
+ NVT_ERR("kzalloc for RecordResult_Short failed!\n");
+ return -ENOMEM;
+ }
+
+ RecordResult_Short_Diff = RecordResult_Short;
+
+ RecordResult_Short_Base = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
+ if (!RecordResult_Short_Base) {
+ NVT_ERR("kzalloc for RecordResult_Short_Base failed!\n");
+ return -ENOMEM;
+ }
+
+ RecordResult_Open = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
+ if (!RecordResult_Open) {
+ NVT_ERR("kzalloc for RecordResult_Open failed!\n");
+ return -ENOMEM;
+ }
+
+ RecordResult_FWMutual = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
+ if (!RecordResult_FWMutual) {
+ NVT_ERR("kzalloc for RecordResult_FWMutual failed!\n");
+ return -ENOMEM;
+ }
+
+ RecordResult_FW_CC = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
+ if (!RecordResult_FW_CC) {
+ NVT_ERR("kzalloc for RecordResult_FW_CC failed!\n");
+ return -ENOMEM;
+ }
+
+ RecordResult_FW_CC_I = RecordResult_FW_CC;
+
+ RecordResult_FW_CC_Q = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
+ if (!RecordResult_FW_CC_Q) {
+ NVT_ERR("kzalloc for RecordResult_FW_CC_Q failed!\n");
+ return -ENOMEM;
+ }
+
+ RecordResult_FW_DiffMax = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
+ if (!RecordResult_FW_DiffMax) {
+ NVT_ERR("kzalloc for RecordResult_FW_DiffMax failed!\n");
+ return -ENOMEM;
+ }
+
+ RecordResult_FW_DiffMin = (uint8_t *)kzalloc(RecordResult_BufSize, GFP_KERNEL);
+ if (!RecordResult_FW_DiffMin) {
+ NVT_ERR("kzalloc for RecordResult_FW_DiffMin failed!\n");
+ return -ENOMEM;
+ }
+
+ RawData_Short = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
+ if (!RawData_Short) {
+ NVT_ERR("kzalloc for RawData_Short failed!\n");
+ return -ENOMEM;
+ }
+
+ RawData_Short_Diff = RawData_Short;
+
+ RawData_Short_Base = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
+ if (!RawData_Short_Base) {
+ NVT_ERR("kzalloc for RawData_Short_Base failed!\n");
+ return -ENOMEM;
+ }
+
+ RawData_Open = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
+ if (!RawData_Open) {
+ NVT_ERR("kzalloc for RawData_Open failed!\n");
+ return -ENOMEM;
+ }
+
+ RawData_Diff = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
+ if (!RawData_Diff) {
+ NVT_ERR("kzalloc for RawData_Diff failed!\n");
+ return -ENOMEM;
+ }
+
+ RawData_Diff_Min = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
+ if (!RawData_Diff_Min) {
+ NVT_ERR("kzalloc for RawData_Diff_Min failed!\n");
+ return -ENOMEM;
+ }
+
+ RawData_Diff_Max = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
+ if (!RawData_Diff_Max) {
+ NVT_ERR("kzalloc for RawData_Diff_Max failed!\n");
+ return -ENOMEM;
+ }
+
+ RawData_FWMutual = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
+ if (!RawData_FWMutual) {
+ NVT_ERR("kzalloc for RawData_FWMutual failed!\n");
+ return -ENOMEM;
+ }
+
+ RawData_FW_CC = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
+ if (!RawData_FW_CC) {
+ NVT_ERR("kzalloc for RawData_FW_CC failed!\n");
+ return -ENOMEM;
+ }
+
+ RawData_FW_CC_I = RawData_FW_CC;
+
+ RawData_FW_CC_Q = (int32_t *)kzalloc(RawData_BufSize, GFP_KERNEL);
+ if (!RawData_FW_CC_Q) {
+ NVT_ERR("kzalloc for RawData_FW_CC_Q failed!\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen self-test criteria print function.
+
+return:
+ n.a.
+*******************************************************/
+static void nvt_print_lmt_array(int32_t *array, int32_t x_ch, int32_t y_ch)
+{
+ int32_t i = 0;
+ int32_t j = 0;
+#if TOUCH_KEY_NUM > 0
+ int32_t k = 0;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ for (j = 0; j < y_ch; j++) {
+ for(i = 0; i < x_ch; i++) {
+ printk("%5d, ", array[j * x_ch + i]);
+ }
+ printk("\n");
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ printk("%5d, ", array[y_ch * x_ch + k]);
+ }
+ printk("\n");
+#endif /* #if TOUCH_KEY_NUM > 0 */
+}
+
+static void nvt_print_criteria(void)
+{
+ NVT_LOG("++\n");
+
+ if (ts->carrier_system) {
+ //---PS_Config_Lmt_Short_Diff---
+ printk("PS_Config_Lmt_Short_Diff_P:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_Short_Diff_P, X_Channel, Y_Channel);
+ printk("PS_Config_Lmt_Short_Diff_N:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_Short_Diff_N, X_Channel, Y_Channel);
+ //---PS_Config_Lmt_Short_Base---
+ printk("PS_Config_Lmt_Short_Base_P:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_Short_Base_P, X_Channel, Y_Channel);
+ printk("PS_Config_Lmt_Short_Base_N:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_Short_Base_N, X_Channel, Y_Channel);
+ } else {
+ //---PS_Config_Lmt_Short_Rawdata---
+ printk("PS_Config_Lmt_Short_Rawdata_P:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_Short_Rawdata_P, X_Channel, Y_Channel);
+ printk("PS_Config_Lmt_Short_Rawdata_N:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_Short_Rawdata_N, X_Channel, Y_Channel);
+ }
+
+ //---PS_Config_Lmt_Open_Rawdata---
+ printk("PS_Config_Lmt_Open_Rawdata_P:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_Open_Rawdata_P, X_Channel, Y_Channel);
+ printk("PS_Config_Lmt_Open_Rawdata_N:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_Open_Rawdata_N, X_Channel, Y_Channel);
+
+ //---PS_Config_Lmt_FW_Rawdata---
+ printk("PS_Config_Lmt_FW_Rawdata_P:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_Rawdata_P, X_Channel, Y_Channel);
+ printk("PS_Config_Lmt_FW_Rawdata_N:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_Rawdata_N, X_Channel, Y_Channel);
+
+ if (ts->carrier_system) {
+ //---PS_Config_Lmt_FW_CC_I---
+ printk("PS_Config_Lmt_FW_CC_I_P:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_CC_I_P, X_Channel, Y_Channel);
+ printk("PS_Config_Lmt_FW_CC_I_N:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_CC_I_N, X_Channel, Y_Channel);
+ //---PS_Config_Lmt_FW_CC_Q---
+ printk("PS_Config_Lmt_FW_CC_Q_P:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_CC_Q_P, X_Channel, Y_Channel);
+ printk("PS_Config_Lmt_FW_CC_Q_N:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_CC_Q_N, X_Channel, Y_Channel);
+ } else {
+ //---PS_Config_Lmt_FW_CC---
+ printk("PS_Config_Lmt_FW_CC_P:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_CC_P, X_Channel, Y_Channel);
+ printk("PS_Config_Lmt_FW_CC_N:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_CC_N, X_Channel, Y_Channel);
+ }
+
+ //---PS_Config_Lmt_FW_Diff---
+ printk("PS_Config_Lmt_FW_Diff_P:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_Diff_P, X_Channel, Y_Channel);
+ printk("PS_Config_Lmt_FW_Diff_N:\n");
+ nvt_print_lmt_array(PS_Config_Lmt_FW_Diff_N, X_Channel, Y_Channel);
+
+ NVT_LOG("--\n");
+}
+
+static int32_t nvt_save_rawdata_to_csv(int32_t *rawdata, uint8_t x_ch, uint8_t y_ch, const char *file_path, uint32_t offset)
+{
+ int32_t x = 0;
+ int32_t y = 0;
+ int32_t iArrayIndex = 0;
+#if TOUCH_KEY_NUM > 0
+ int32_t k = 0;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ printk("%s:++%s\n", __func__, file_path);
+
+ for (y = 0; y < y_ch; y++) {
+ for (x = 0; x < x_ch; x++) {
+ iArrayIndex = y * x_ch + x;
+ printk("%5d, ", rawdata[iArrayIndex]);
+ }
+ printk("\n");
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = y_ch * x_ch + k;
+ printk("%5d, ", rawdata[iArrayIndex]);
+ }
+ printk("\n");
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ printk("%s:--\n", __func__);
+
+ return 0;
+}
+
+static int32_t nvt_polling_hand_shake_status(void)
+{
+ uint8_t buf[8] = {0};
+ int32_t i = 0;
+ const int32_t retry = 50;
+
+ for (i = 0; i < retry; i++) {
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---read fw status---
+ buf[0] = EVENT_MAP_HANDSHAKING_or_SUB_CMD_BYTE;
+ buf[1] = 0x00;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
+
+ if ((buf[1] == 0xA0) || (buf[1] == 0xA1))
+ break;
+
+ msleep(10);
+ }
+
+ if (i >= retry) {
+ NVT_ERR("polling hand shake status failed, buf[1]=0x%02X\n", buf[1]);
+
+ // Read back 5 bytes from offset EVENT_MAP_HOST_CMD for debug check
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ buf[0] = EVENT_MAP_HOST_CMD;
+ buf[1] = 0x00;
+ buf[2] = 0x00;
+ buf[3] = 0x00;
+ buf[4] = 0x00;
+ buf[5] = 0x00;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 6);
+ NVT_ERR("Read back 5 bytes from offset EVENT_MAP_HOST_CMD: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", buf[1], buf[2], buf[3], buf[4], buf[5]);
+
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+static int8_t nvt_switch_FreqHopEnDis(uint8_t FreqHopEnDis)
+{
+ uint8_t buf[8] = {0};
+ uint8_t retry = 0;
+ int8_t ret = 0;
+
+ NVT_LOG("++\n");
+
+ for (retry = 0; retry < 20; retry++) {
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---switch FreqHopEnDis---
+ buf[0] = EVENT_MAP_HOST_CMD;
+ buf[1] = FreqHopEnDis;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 2);
+
+ msleep(35);
+
+ buf[0] = EVENT_MAP_HOST_CMD;
+ buf[1] = 0xFF;
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, 2);
+
+ if (buf[1] == 0x00)
+ break;
+ }
+
+ if (unlikely(retry == 20)) {
+ NVT_ERR("switch FreqHopEnDis 0x%02X failed, buf[1]=0x%02X\n", FreqHopEnDis, buf[1]);
+ ret = -1;
+ }
+
+ NVT_LOG("--\n");
+
+ return ret;
+}
+
+static int32_t nvt_read_baseline(int32_t *xdata)
+{
+ uint8_t x_num = 0;
+ uint8_t y_num = 0;
+ uint32_t x = 0;
+ uint32_t y = 0;
+ int32_t iArrayIndex = 0;
+#if TOUCH_KEY_NUM > 0
+ int32_t k = 0;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ NVT_LOG("++\n");
+
+ nvt_read_mdata(ts->mmap->BASELINE_ADDR, ts->mmap->BASELINE_BTN_ADDR);
+
+ nvt_get_mdata(xdata, &x_num, &y_num);
+
+ for (y = 0; y < y_num; y++) {
+ for (x = 0; x < x_num; x++) {
+ iArrayIndex = y * x_num + x;
+ if (ts->carrier_system) {
+ xdata[iArrayIndex] = (uint16_t)xdata[iArrayIndex];
+ } else {
+ xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex];
+ }
+ }
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = Y_Channel * X_Channel + k;
+ if (ts->carrier_system) {
+ xdata[iArrayIndex] = (uint16_t)xdata[iArrayIndex];
+ } else {
+ xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex];
+ }
+ }
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ printk("%s:\n", __func__);
+ // Save Rawdata to CSV file
+ if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, FW_RAWDATA_CSV_FILE, 0) < 0) {
+ NVT_ERR("save rawdata to CSV file failed\n");
+ return -EAGAIN;
+ }
+
+ NVT_LOG("--\n");
+
+ return 0;
+}
+
+static int32_t nvt_read_CC(int32_t *xdata)
+{
+ uint8_t x_num = 0;
+ uint8_t y_num = 0;
+ uint32_t x = 0;
+ uint32_t y = 0;
+ int32_t iArrayIndex = 0;
+ int32_t xdata_tmp = 0;
+#if TOUCH_KEY_NUM > 0
+ int32_t k = 0;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ uint32_t rawdata_cc_q_offset = 0;
+
+ NVT_LOG("++\n");
+
+ if (nvt_get_fw_pipe() == 0)
+ nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, ts->mmap->DIFF_BTN_PIPE1_ADDR);
+ else
+ nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, ts->mmap->DIFF_BTN_PIPE0_ADDR);
+
+ nvt_get_mdata(xdata, &x_num, &y_num);
+
+ for (y = 0; y < y_num; y++) {
+ for (x = 0; x < x_num; x++) {
+ iArrayIndex = y * x_num + x;
+ if (ts->carrier_system) {
+ xdata_tmp = xdata[iArrayIndex];
+ RawData_FW_CC_I[iArrayIndex] = (uint8_t)(xdata_tmp & 0xFF);
+ RawData_FW_CC_Q[iArrayIndex] = (uint8_t)((xdata_tmp >> 8) & 0xFF);
+ } else {
+ xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex];
+ }
+ }
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = Y_Channel * X_Channel + k;
+ if (ts->carrier_system) {
+ xdata_tmp = xdata[iArrayIndex];
+ RawData_FW_CC_I[iArrayIndex] = (uint8_t)(xdata_tmp & 0xFF);
+ RawData_FW_CC_Q[iArrayIndex] = (uint8_t)((xdata_tmp >> 8) & 0xFF);
+ } else {
+ xdata[iArrayIndex] = (int16_t)xdata[iArrayIndex];
+ }
+ }
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ printk("%s:\n", __func__);
+ if (ts->carrier_system) {
+ printk("%s:RawData_CC_I:\n", __func__);
+ // Save Rawdata to CSV file
+ if (nvt_save_rawdata_to_csv(RawData_FW_CC_I, X_Channel, Y_Channel, FW_CC_CSV_FILE, 0) < 0) {
+ NVT_ERR("save rawdata to CSV file failed\n");
+ return -EAGAIN;
+ }
+#if TOUCH_KEY_NUM > 0
+ rawdata_cc_q_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2 + Key_Channel * 7 + 2;
+#else
+ rawdata_cc_q_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ printk("%s:RawData_CC_Q:\n", __func__);
+ // Save Rawdata to CSV file
+ if (nvt_save_rawdata_to_csv(RawData_FW_CC_Q, X_Channel, Y_Channel, FW_CC_CSV_FILE, rawdata_cc_q_offset) < 0) {
+ NVT_ERR("save rawdata to CSV file failed\n");
+ return -EAGAIN;
+ }
+ } else {
+ // Save Rawdata to CSV file
+ if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, FW_CC_CSV_FILE, 0) < 0) {
+ NVT_ERR("save rawdata to CSV file failed\n");
+ return -EAGAIN;
+ }
+ }
+
+ NVT_LOG("--\n");
+
+ return 0;
+}
+
+static void nvt_enable_noise_collect(int32_t frame_num)
+{
+ uint8_t buf[8] = {0};
+
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---enable noise collect---
+ buf[0] = EVENT_MAP_HOST_CMD;
+ buf[1] = 0x47;
+ buf[2] = 0xAA;
+ buf[3] = frame_num;
+ buf[4] = 0x00;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 5);
+}
+
+static int32_t nvt_read_fw_noise(int32_t *xdata)
+{
+ uint8_t x_num = 0;
+ uint8_t y_num = 0;
+ uint32_t x = 0;
+ uint32_t y = 0;
+ int32_t iArrayIndex = 0;
+ int32_t frame_num = 0;
+ uint32_t rawdata_diff_min_offset = 0;
+#if TOUCH_KEY_NUM > 0
+ int32_t k = 0;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ NVT_LOG("++\n");
+
+ //---Enter Test Mode---
+ if (nvt_clear_fw_status()) {
+ return -EAGAIN;
+ }
+
+ frame_num = PS_Config_Diff_Test_Frame / 10;
+ if (frame_num <= 0)
+ frame_num = 1;
+ printk("%s: frame_num=%d\n", __func__, frame_num);
+ nvt_enable_noise_collect(frame_num);
+ // need wait PS_Config_Diff_Test_Frame * 8.3ms
+ msleep(frame_num * 83);
+
+ if (nvt_polling_hand_shake_status()) {
+ return -EAGAIN;
+ }
+
+ if (nvt_get_fw_info()) {
+ return -EAGAIN;
+ }
+
+ if (nvt_get_fw_pipe() == 0)
+ nvt_read_mdata(ts->mmap->DIFF_PIPE0_ADDR, ts->mmap->DIFF_BTN_PIPE0_ADDR);
+ else
+ nvt_read_mdata(ts->mmap->DIFF_PIPE1_ADDR, ts->mmap->DIFF_BTN_PIPE1_ADDR);
+
+ nvt_get_mdata(xdata, &x_num, &y_num);
+
+ for (y = 0; y < y_num; y++) {
+ for (x = 0; x < x_num; x++) {
+ iArrayIndex = y * x_num + x;
+ if (ts->carrier_system) {
+ RawData_Diff_Max[iArrayIndex] = (uint16_t)xdata[iArrayIndex];
+ RawData_Diff_Min[iArrayIndex] = 0;
+ } else {
+ RawData_Diff_Max[iArrayIndex] = (int8_t)((xdata[iArrayIndex] >> 8) & 0xFF);
+ RawData_Diff_Min[iArrayIndex] = (int8_t)(xdata[iArrayIndex] & 0xFF);
+ }
+ }
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = Y_Channel * X_Channel + k;
+ if (ts->carrier_system) {
+ RawData_Diff_Max[iArrayIndex] = (uint16_t)xdata[iArrayIndex];
+ RawData_Diff_Min[iArrayIndex] = 0;
+ } else {
+ RawData_Diff_Max[iArrayIndex] = (int8_t)((xdata[iArrayIndex] >> 8) & 0xFF);
+ RawData_Diff_Min[iArrayIndex] = (int8_t)(xdata[iArrayIndex] & 0xFF);
+ }
+ }
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ //---Leave Test Mode---
+ nvt_change_mode(NORMAL_MODE);
+
+ printk("%s:RawData_Diff_Max:\n", __func__);
+ // Save Rawdata to CSV file
+ if (nvt_save_rawdata_to_csv(RawData_Diff_Max, X_Channel, Y_Channel, NOISE_TEST_CSV_FILE, 0) < 0) {
+ NVT_ERR("save rawdata to CSV file failed\n");
+ return -EAGAIN;
+ }
+
+ if (!ts->carrier_system) {
+#if TOUCH_KEY_NUM > 0
+ rawdata_diff_min_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2 + Key_Channel * 7 + 2;
+#else
+ rawdata_diff_min_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ printk("%s:RawData_Diff_Min:\n", __func__);
+ // Save Rawdata to CSV file
+ if (nvt_save_rawdata_to_csv(RawData_Diff_Min, X_Channel, Y_Channel, NOISE_TEST_CSV_FILE, rawdata_diff_min_offset) < 0) {
+ NVT_ERR("save rawdata to CSV file failed\n");
+ return -EAGAIN;
+ }
+ }
+
+ NVT_LOG("--\n");
+
+ return 0;
+}
+
+static void nvt_enable_open_test(void)
+{
+ uint8_t buf[8] = {0};
+
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---enable open test---
+ buf[0] = EVENT_MAP_HOST_CMD;
+ buf[1] = 0x45;
+ buf[2] = 0xAA;
+ buf[3] = 0x02;
+ buf[4] = 0x00;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 5);
+}
+
+static void nvt_enable_short_test(void)
+{
+ uint8_t buf[8] = {0};
+
+ //---set xdata index to EVENT BUF ADDR---
+ buf[0] = 0xFF;
+ buf[1] = (ts->mmap->EVENT_BUF_ADDR >> 16) & 0xFF;
+ buf[2] = (ts->mmap->EVENT_BUF_ADDR >> 8) & 0xFF;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+
+ //---enable short test---
+ buf[0] = EVENT_MAP_HOST_CMD;
+ buf[1] = 0x43;
+ buf[2] = 0xAA;
+ buf[3] = 0x02;
+ buf[4] = 0x00;
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 5);
+}
+
+static int32_t nvt_read_fw_open(int32_t *xdata)
+{
+ uint32_t raw_pipe_addr = 0;
+ uint8_t *rawdata_buf = NULL;
+ uint32_t x = 0;
+ uint32_t y = 0;
+ uint8_t buf[128] = {0};
+#if TOUCH_KEY_NUM > 0
+ uint32_t raw_btn_pipe_addr = 0;
+ int32_t k = 0;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ NVT_LOG("++\n");
+
+ //---Enter Test Mode---
+ if (nvt_clear_fw_status()) {
+ return -EAGAIN;
+ }
+
+ nvt_enable_open_test();
+
+ if (nvt_polling_hand_shake_status()) {
+ return -EAGAIN;
+ }
+
+#if TOUCH_KEY_NUM > 0
+ rawdata_buf = (uint8_t *)kzalloc((IC_X_CFG_SIZE * IC_Y_CFG_SIZE + IC_KEY_CFG_SIZE) * 2, GFP_KERNEL);
+#else
+ rawdata_buf = (uint8_t *)kzalloc(IC_X_CFG_SIZE * IC_Y_CFG_SIZE * 2, GFP_KERNEL);
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ if (!rawdata_buf) {
+ NVT_ERR("kzalloc for rawdata_buf failed!\n");
+ return -ENOMEM;
+ }
+
+ if (nvt_get_fw_pipe() == 0)
+ raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR;
+ else
+ raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR;
+
+ for (y = 0; y < IC_Y_CFG_SIZE; y++) {
+ //---change xdata index---
+ buf[0] = 0xFF;
+ buf[1] = (uint8_t)(((raw_pipe_addr + y * IC_X_CFG_SIZE * 2) >> 16) & 0xFF);
+ buf[2] = (uint8_t)(((raw_pipe_addr + y * IC_X_CFG_SIZE * 2) >> 8) & 0xFF);
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+ buf[0] = (uint8_t)((raw_pipe_addr + y * IC_X_CFG_SIZE * 2) & 0xFF);
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, IC_X_CFG_SIZE * 2 + 1);
+ memcpy(rawdata_buf + y * IC_X_CFG_SIZE * 2, buf + 1, IC_X_CFG_SIZE * 2);
+ }
+#if TOUCH_KEY_NUM > 0
+ if (nvt_get_fw_pipe() == 0)
+ raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE0_ADDR;
+ else
+ raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE1_ADDR;
+
+ //---change xdata index---
+ buf[0] = 0xFF;
+ buf[1] = (uint8_t)((raw_btn_pipe_addr >> 16) & 0xFF);
+ buf[2] = (uint8_t)((raw_btn_pipe_addr >> 8) & 0xFF);
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+ buf[0] = (uint8_t)(raw_btn_pipe_addr & 0xFF);
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, IC_KEY_CFG_SIZE * 2 + 1);
+ memcpy(rawdata_buf + IC_Y_CFG_SIZE * IC_X_CFG_SIZE * 2, buf + 1, IC_KEY_CFG_SIZE * 2);
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ for (y = 0; y < IC_Y_CFG_SIZE; y++) {
+ for (x = 0; x < IC_X_CFG_SIZE; x++) {
+ if ((AIN_Y[y] != 0xFF) && (AIN_X[x] != 0xFF)) {
+ xdata[AIN_Y[y] * X_Channel + AIN_X[x]] = (int16_t)((rawdata_buf[(y * IC_X_CFG_SIZE + x) * 2] + 256 * rawdata_buf[(y * IC_X_CFG_SIZE + x) * 2 + 1]));
+ }
+ }
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < IC_KEY_CFG_SIZE; k++) {
+ if (AIN_KEY[k] != 0xFF)
+ xdata[Y_Channel * X_Channel + AIN_KEY[k]] = (int16_t)(rawdata_buf[(IC_Y_CFG_SIZE * IC_X_CFG_SIZE + k) * 2] + 256 * rawdata_buf[(IC_Y_CFG_SIZE * IC_X_CFG_SIZE + k) * 2 + 1]);
+ }
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ if (rawdata_buf) {
+ kfree(rawdata_buf);
+ rawdata_buf = NULL;
+ }
+
+ //---Leave Test Mode---
+ nvt_change_mode(NORMAL_MODE);
+
+
+ printk("%s:RawData_Open\n", __func__);
+ // Save RawData to CSV file
+ if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, OPEN_TEST_CSV_FILE, 0) < 0) {
+ NVT_ERR("save rawdata to CSV file failed\n");
+ return -EAGAIN;
+ }
+
+ NVT_LOG("--\n");
+
+ return 0;
+}
+
+static int32_t nvt_read_fw_short(int32_t *xdata)
+{
+ uint32_t raw_pipe_addr = 0;
+ uint8_t *rawdata_buf = NULL;
+ uint32_t x = 0;
+ uint32_t y = 0;
+ uint8_t buf[128] = {0};
+ int32_t iArrayIndex = 0;
+#if TOUCH_KEY_NUM > 0
+ uint32_t raw_btn_pipe_addr = 0;
+ int32_t k = 0;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ uint32_t rawdata_short_base_offset = 0;
+
+ NVT_LOG("++\n");
+
+ //---Enter Test Mode---
+ if (nvt_clear_fw_status()) {
+ return -EAGAIN;
+ }
+
+ nvt_enable_short_test();
+
+ if (nvt_polling_hand_shake_status()) {
+ return -EAGAIN;
+ }
+
+#if TOUCH_KEY_NUM > 0
+ rawdata_buf = (uint8_t *)kzalloc((X_Channel * Y_Channel + Key_Channel) * 2, GFP_KERNEL);
+#else
+ rawdata_buf = (uint8_t *)kzalloc(X_Channel * Y_Channel * 2, GFP_KERNEL);
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ if (!rawdata_buf) {
+ NVT_ERR("kzalloc for rawdata_buf failed!\n");
+ return -ENOMEM;
+ }
+
+ if (ts->carrier_system) {
+ // to get short diff rawdata at pipe0
+ raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR;
+ } else {
+ if (nvt_get_fw_pipe() == 0)
+ raw_pipe_addr = ts->mmap->RAW_PIPE0_ADDR;
+ else
+ raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR;
+ }
+
+ for (y = 0; y < Y_Channel; y++) {
+ //---change xdata index---
+ buf[0] = 0xFF;
+ buf[1] = (uint8_t)(((raw_pipe_addr + y * X_Channel * 2) >> 16) & 0xFF);
+ buf[2] = (uint8_t)(((raw_pipe_addr + y * X_Channel * 2) >> 8) & 0xFF);
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+ buf[0] = (uint8_t)((raw_pipe_addr + y * X_Channel * 2) & 0xFF);
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, X_Channel * 2 + 1);
+ memcpy(rawdata_buf + y * X_Channel * 2, buf + 1, X_Channel * 2);
+ }
+#if TOUCH_KEY_NUM > 0
+ if (ts->carrier_system) {
+ // to get button short diff rawdata at pipe0
+ raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE0_ADDR;
+ } else {
+ if (nvt_get_fw_pipe() == 0)
+ raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE0_ADDR;
+ else
+ raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE1_ADDR;
+ }
+
+ //---change xdata index---
+ buf[0] = 0xFF;
+ buf[1] = (uint8_t)((raw_btn_pipe_addr >> 16) & 0xFF);
+ buf[2] = (uint8_t)((raw_btn_pipe_addr >> 8) & 0xFF);
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+ buf[0] = (uint8_t)(raw_btn_pipe_addr & 0xFF);
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, Key_Channel * 2 + 1);
+ memcpy(rawdata_buf + Y_Channel * X_Channel * 2, buf + 1, Key_Channel * 2);
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ for (y = 0; y < Y_Channel; y++) {
+ for (x = 0; x < X_Channel; x++) {
+ iArrayIndex = y * X_Channel + x;
+ xdata[iArrayIndex] = (int16_t)(rawdata_buf[iArrayIndex * 2] + 256 * rawdata_buf[iArrayIndex * 2 + 1]);
+ }
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = Y_Channel * X_Channel + k;
+ xdata[iArrayIndex] = (int16_t)(rawdata_buf[iArrayIndex * 2] + 256 * rawdata_buf[iArrayIndex * 2 + 1]);
+ }
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ // for carrier sensing system to get short baseline rawdata
+ if (ts->carrier_system) {
+ // to get short baseline rawdata at pipe1
+ raw_pipe_addr = ts->mmap->RAW_PIPE1_ADDR;
+
+ for (y = 0; y < Y_Channel; y++) {
+ //---change xdata index---
+ buf[0] = 0xFF;
+ buf[1] = (uint8_t)(((raw_pipe_addr + y * X_Channel * 2) >> 16) & 0xFF);
+ buf[2] = (uint8_t)(((raw_pipe_addr + y * X_Channel * 2) >> 8) & 0xFF);
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+ buf[0] = (uint8_t)((raw_pipe_addr + y * X_Channel * 2) & 0xFF);
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, X_Channel * 2 + 1);
+ memcpy(rawdata_buf + y * X_Channel * 2, buf + 1, X_Channel * 2);
+ }
+#if TOUCH_KEY_NUM > 0
+ // to get button short baseline rawdata at pipe1
+ raw_btn_pipe_addr = ts->mmap->RAW_BTN_PIPE1_ADDR;
+
+ //---change xdata index---
+ buf[0] = 0xFF;
+ buf[1] = (uint8_t)((raw_btn_pipe_addr >> 16) & 0xFF);
+ buf[2] = (uint8_t)((raw_btn_pipe_addr >> 8) & 0xFF);
+ CTP_I2C_WRITE(ts->client, I2C_FW_Address, buf, 3);
+ buf[0] = (uint8_t)(raw_btn_pipe_addr & 0xFF);
+ CTP_I2C_READ(ts->client, I2C_FW_Address, buf, Key_Channel * 2 + 1);
+ memcpy(rawdata_buf + Y_Channel * X_Channel * 2, buf + 1, Key_Channel * 2);
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ for (y = 0; y < Y_Channel; y++) {
+ for (x = 0; x < X_Channel; x++) {
+ iArrayIndex = y * X_Channel + x;
+ RawData_Short_Base[iArrayIndex] = (int16_t)(rawdata_buf[iArrayIndex * 2] + 256 * rawdata_buf[iArrayIndex * 2 + 1]);
+ }
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = Y_Channel * X_Channel + k;
+ RawData_Short_Base[iArrayIndex] = (int16_t)(rawdata_buf[iArrayIndex * 2] + 256 * rawdata_buf[iArrayIndex * 2 + 1]);
+ }
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ }
+
+ if (rawdata_buf) {
+ kfree(rawdata_buf);
+ rawdata_buf = NULL;
+ }
+
+ //---Leave Test Mode---
+ nvt_change_mode(NORMAL_MODE);
+
+ if (ts->carrier_system)
+ printk("%s:RawData_Short_Diff:\n", __func__);
+ else
+ printk("%s:RawData_Short\n", __func__);
+ // Save Rawdata to CSV file
+ if (nvt_save_rawdata_to_csv(xdata, X_Channel, Y_Channel, SHORT_TEST_CSV_FILE, 0) < 0) {
+ NVT_ERR("save rawdata to CSV file failed\n");
+ return -EAGAIN;
+ }
+ if (ts->carrier_system) {
+#if TOUCH_KEY_NUM > 0
+ rawdata_short_base_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2 + Key_Channel * 7 + 2;
+#else
+ rawdata_short_base_offset = Y_Channel * X_Channel * 7 + Y_Channel * 2;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ printk("%s:RawData_Short_Base:\n", __func__);
+ // Save Rawdata to CSV file
+ if (nvt_save_rawdata_to_csv(RawData_Short_Base, X_Channel, Y_Channel, SHORT_TEST_CSV_FILE, rawdata_short_base_offset) < 0) {
+ NVT_ERR("save rawdata to CSV file failed\n");
+ return -EAGAIN;
+ }
+ }
+
+ NVT_LOG("--\n");
+
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen raw data test for each single point function.
+
+return:
+ Executive outcomes. 0---passed. negative---failed.
+*******************************************************/
+static int32_t RawDataTest_SinglePoint_Sub(int32_t rawdata[], uint8_t RecordResult[], uint8_t x_ch, uint8_t y_ch, int32_t Rawdata_Limit_Postive[], int32_t Rawdata_Limit_Negative[])
+{
+ int32_t i = 0;
+ int32_t j = 0;
+#if TOUCH_KEY_NUM > 0
+ int32_t k = 0;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ int32_t iArrayIndex = 0;
+ bool isPass = true;
+
+ for (j = 0; j < y_ch; j++) {
+ for (i = 0; i < x_ch; i++) {
+ iArrayIndex = j * x_ch + i;
+
+ RecordResult[iArrayIndex] = 0x00; // default value for PASS
+
+ if(rawdata[iArrayIndex] > Rawdata_Limit_Postive[iArrayIndex])
+ RecordResult[iArrayIndex] |= 0x01;
+
+ if(rawdata[iArrayIndex] < Rawdata_Limit_Negative[iArrayIndex])
+ RecordResult[iArrayIndex] |= 0x02;
+ }
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = y_ch * x_ch + k;
+
+ RecordResult[iArrayIndex] = 0x00; // default value for PASS
+
+ if(rawdata[iArrayIndex] > Rawdata_Limit_Postive[iArrayIndex])
+ RecordResult[iArrayIndex] |= 0x01;
+
+ if(rawdata[iArrayIndex] < Rawdata_Limit_Negative[iArrayIndex])
+ RecordResult[iArrayIndex] |= 0x02;
+ }
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ //---Check RecordResult---
+ for (j = 0; j < y_ch; j++) {
+ for (i = 0; i < x_ch; i++) {
+ if (RecordResult[j * x_ch + i] != 0) {
+ isPass = false;
+ break;
+ }
+ }
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = y_ch * x_ch + k;
+ if (RecordResult[iArrayIndex] != 0) {
+ isPass = false;
+ break;
+ }
+ }
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ if (isPass == false) {
+ return -1; // FAIL
+ } else {
+ return 0; // PASS
+ }
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen print self-test result function.
+
+return:
+ n.a.
+*******************************************************/
+void print_selftest_result(struct seq_file *m, int32_t TestResult, uint8_t RecordResult[], int32_t rawdata[], uint8_t x_len, uint8_t y_len)
+{
+ int32_t i = 0;
+ int32_t j = 0;
+ int32_t iArrayIndex = 0;
+#if TOUCH_KEY_NUM > 0
+ int32_t k = 0;
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+ switch (TestResult) {
+ case 0:
+ nvt_mp_seq_printf(m, " PASS!\n");
+ break;
+
+ case 1:
+ nvt_mp_seq_printf(m, " ERROR! Read Data FAIL!\n");
+ break;
+
+ case -1:
+ nvt_mp_seq_printf(m, " FAIL!\n");
+ nvt_mp_seq_printf(m, "RecordResult:\n");
+ for (i = 0; i < y_len; i++) {
+ for (j = 0; j < x_len; j++) {
+ iArrayIndex = i * x_len + j;
+ nvt_mp_seq_printf(m, "0x%02X, ", RecordResult[iArrayIndex]);
+ }
+ nvt_mp_seq_printf(m, "\n");
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = y_len * x_len + k;
+ nvt_mp_seq_printf(m, "0x%02X, ", RecordResult[iArrayIndex]);
+ }
+ nvt_mp_seq_printf(m, "\n");
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ nvt_mp_seq_printf(m, "ReadData:\n");
+ for (i = 0; i < y_len; i++) {
+ for (j = 0; j < x_len; j++) {
+ iArrayIndex = i * x_len + j;
+ nvt_mp_seq_printf(m, "%5d, ", rawdata[iArrayIndex]);
+ }
+ nvt_mp_seq_printf(m, "\n");
+ }
+#if TOUCH_KEY_NUM > 0
+ for (k = 0; k < Key_Channel; k++) {
+ iArrayIndex = y_len * x_len + k;
+ nvt_mp_seq_printf(m, "%5d, ", rawdata[iArrayIndex]);
+ }
+ nvt_mp_seq_printf(m, "\n");
+#endif /* #if TOUCH_KEY_NUM > 0 */
+ break;
+ }
+ nvt_mp_seq_printf(m, "\n");
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen self-test sequence print show
+ function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t c_show_selftest(struct seq_file *m, void *v)
+{
+#if NVT_TOUCH_MP_LENOVO
+ MP_TEST_RESULT mp_result = 0;
+#endif
+
+ NVT_LOG("++\n");
+#if !NVT_TOUCH_MP_LENOVO
+ nvt_mp_seq_printf(m, "FW Version: %d\n\n", ts->fw_ver);
+
+ nvt_mp_seq_printf(m, "Short Test");
+ if ((TestResult_Short == 0) || (TestResult_Short == 1)) {
+ print_selftest_result(m, TestResult_Short, RecordResult_Short, RawData_Short, X_Channel, Y_Channel);
+ } else { // TestResult_Short is -1
+ if (ts->carrier_system) {
+ nvt_mp_seq_printf(m, " FAIL!\n");
+ if (TestResult_Short_Diff == -1) {
+ nvt_mp_seq_printf(m, "Short Diff");
+ print_selftest_result(m, TestResult_Short_Diff, RecordResult_Short_Diff, RawData_Short_Diff, X_Channel, Y_Channel);
+ }
+ if (TestResult_Short_Base == -1) {
+ nvt_mp_seq_printf(m, "Short Base");
+ print_selftest_result(m, TestResult_Short_Base, RecordResult_Short_Base, RawData_Short_Base, X_Channel, Y_Channel);
+ }
+ } else {
+ print_selftest_result(m, TestResult_Short, RecordResult_Short, RawData_Short, X_Channel, Y_Channel);
+ }
+ }
+
+ nvt_mp_seq_printf(m, "Open Test");
+ print_selftest_result(m, TestResult_Open, RecordResult_Open, RawData_Open, X_Channel, Y_Channel);
+
+ nvt_mp_seq_printf(m, "FW Rawdata Test");
+ if ((TestResult_FW_Rawdata == 0) || (TestResult_FW_Rawdata == 1)) {
+ print_selftest_result(m, TestResult_FWMutual, RecordResult_FWMutual, RawData_FWMutual, X_Channel, Y_Channel);
+ } else { // TestResult_FW_Rawdata is -1
+ nvt_mp_seq_printf(m, " FAIL!\n");
+ if (TestResult_FWMutual == -1) {
+ nvt_mp_seq_printf(m, "FW Mutual");
+ print_selftest_result(m, TestResult_FWMutual, RecordResult_FWMutual, RawData_FWMutual, X_Channel, Y_Channel);
+ }
+ if (TestResult_FW_CC == -1) {
+ if (ts->carrier_system) {
+ if (TestResult_FW_CC_I == -1) {
+ nvt_mp_seq_printf(m, "FW CC_I");
+ print_selftest_result(m, TestResult_FW_CC_I, RecordResult_FW_CC_I, RawData_FW_CC_I, X_Channel, Y_Channel);
+ }
+ if (TestResult_FW_CC_Q == -1) {
+ nvt_mp_seq_printf(m, "FW CC_Q");
+ print_selftest_result(m, TestResult_FW_CC_Q, RecordResult_FW_CC_Q, RawData_FW_CC_Q, X_Channel, Y_Channel);
+ }
+ } else {
+ nvt_mp_seq_printf(m, "FW CC");
+ print_selftest_result(m, TestResult_FW_CC, RecordResult_FW_CC, RawData_FW_CC, X_Channel, Y_Channel);
+ }
+ }
+ }
+
+ nvt_mp_seq_printf(m, "Noise Test");
+ if ((TestResult_Noise == 0) || (TestResult_Noise == 1)) {
+ print_selftest_result(m, TestResult_FW_DiffMax, RecordResult_FW_DiffMax, RawData_Diff_Max, X_Channel, Y_Channel);
+ } else { // TestResult_Noise is -1
+ nvt_mp_seq_printf(m, " FAIL!\n");
+
+ if (TestResult_FW_DiffMax == -1) {
+ nvt_mp_seq_printf(m, "FW Diff Max");
+ print_selftest_result(m, TestResult_FW_DiffMax, RecordResult_FW_DiffMax, RawData_Diff_Max, X_Channel, Y_Channel);
+ }
+ if (TestResult_FW_DiffMin == -1) {
+ nvt_mp_seq_printf(m, "FW Diff Min");
+ print_selftest_result(m, TestResult_FW_DiffMin, RecordResult_FW_DiffMin, RawData_Diff_Min, X_Channel, Y_Channel);
+ }
+ }
+#else
+ /* short */
+ if (TestResult_Short >= 0)
+ mp_result |= (!!TestResult_Short << MP_RESULT_SHIFT_SHORT);
+ else {
+ if (ts->carrier_system) {
+ mp_result |= (!!TestResult_Short_Diff << MP_RESULT_SHIFT_SHORT_DIFF);
+ mp_result |= (!!TestResult_Short_Base << MP_RESULT_SHIFT_SHORT_BASE);
+ } else {
+ mp_result |= (!!TestResult_Short << MP_RESULT_SHIFT_SHORT);
+ }
+ }
+
+ /* open */
+ mp_result |= (!!TestResult_Open << MP_RESULT_SHIFT_OPEN);
+
+ /* raw data & cc */
+ if (TestResult_FW_Rawdata >= 0)
+ mp_result |= (!!TestResult_FWMutual << MP_RESULT_SHIFT_RAWDATA);
+ else {
+ if (TestResult_FWMutual == -1) {
+ mp_result |= (!!TestResult_FWMutual << MP_RESULT_SHIFT_RAWDATA);
+ }
+ if (TestResult_FW_CC == -1) {
+ if (ts->carrier_system) {
+ mp_result |= (!!TestResult_FW_CC_I << MP_RESULT_SHIFT_CC_I);
+ mp_result |= (!!TestResult_FW_CC_Q << MP_RESULT_SHIFT_CC_Q);
+ } else {
+ mp_result |= (!!TestResult_FW_CC << MP_RESULT_SHIFT_CC);
+ }
+ }
+ }
+
+ /* noise */
+ if (TestResult_Noise >= 0)
+ mp_result |= (!!TestResult_FW_DiffMax << MP_RESULT_SHIFT_DIFF_MAX);
+ else {
+ if (TestResult_FW_DiffMax == -1) {
+ mp_result |= (!!TestResult_FW_DiffMax << MP_RESULT_SHIFT_DIFF_MAX);
+ }
+ if (TestResult_FW_DiffMin == -1) {
+ mp_result |= (!!TestResult_FW_DiffMin << MP_RESULT_SHIFT_DIFF_MIN);
+ }
+ }
+
+ nvt_mp_seq_printf(m, "%d", mp_result);
+#endif
+ nvt_mp_test_result_printed = 1;
+
+ NVT_LOG("--\n");
+
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen self-test sequence print start
+ function.
+
+return:
+ Executive outcomes. 1---call next function.
+ NULL---not call next function and sequence loop
+ stop.
+*******************************************************/
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < 1 ? (void *)1 : NULL;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen self-test sequence print next
+ function.
+
+return:
+ Executive outcomes. NULL---no next and call sequence
+ stop function.
+*******************************************************/
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return NULL;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen self-test sequence print stop
+ function.
+
+return:
+ n.a.
+*******************************************************/
+static void c_stop(struct seq_file *m, void *v)
+{
+ return;
+}
+
+const struct seq_operations nvt_selftest_seq_ops = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = c_show_selftest
+};
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/nvt_selftest open function.
+
+return:
+ Executive outcomes. 0---succeed. negative---failed.
+*******************************************************/
+static int32_t nvt_selftest_open(struct inode *inode, struct file *file)
+{
+ struct device_node *np = ts->client->dev.of_node;
+ unsigned char mpcriteria[32] = {0}; //novatek-mp-criteria-default
+
+ TestResult_Short = 0;
+ TestResult_Short_Diff = 0;
+ TestResult_Short_Base = 0;
+ TestResult_Open = 0;
+ TestResult_FW_Rawdata = 0;
+ TestResult_FWMutual = 0;
+ TestResult_FW_CC = 0;
+ TestResult_FW_CC_I = 0;
+ TestResult_FW_CC_Q = 0;
+ TestResult_Noise = 0;
+ TestResult_FW_DiffMax = 0;
+ TestResult_FW_DiffMin = 0;
+
+ NVT_LOG("++\n");
+
+ if (mutex_lock_interruptible(&ts->lock)) {
+ return -ERESTARTSYS;
+ }
+#if NVT_TOUCH_ESD_PROTECT
+ nvt_esd_check_enable(false);
+#endif
+
+ if (nvt_get_fw_info()) {
+ mutex_unlock(&ts->lock);
+ NVT_ERR("get fw info failed!\n");
+ return -EAGAIN;
+ }
+
+ /* Parsing criteria from dts */
+ if(of_property_read_bool(np, "novatek,mp-support-dt")) {
+ /*
+ * Parsing Criteria by Novatek PID
+ * The string rule is "novatek-mp-criteria-<nvt_pid>"
+ * nvt_pid is 2 bytes (show hex).
+ *
+ * Ex. nvt_pid = 500A
+ * mpcriteria = "novatek-mp-criteria-500A"
+ */
+ snprintf(mpcriteria, PAGE_SIZE, "novatek-mp-criteria-%04X", ts->nvt_pid);
+
+ nvt_mp_parse_dt(np, mpcriteria);
+ } else {
+ NVT_LOG("Not found novatek,mp-support-dt, use default setting\n");
+ //---Print Test Criteria---
+ nvt_print_criteria();
+ }
+
+ if (nvt_switch_FreqHopEnDis(FREQ_HOP_DISABLE)) {
+ mutex_unlock(&ts->lock);
+ NVT_ERR("switch frequency hopping disable failed!\n");
+ return -EAGAIN;
+ }
+
+ if (nvt_check_fw_reset_state(RESET_STATE_NORMAL_RUN)) {
+ mutex_unlock(&ts->lock);
+ NVT_ERR("check fw reset state failed!\n");
+ return -EAGAIN;
+ }
+
+ msleep(100);
+
+ //---Enter Test Mode---
+ if (nvt_clear_fw_status()) {
+ mutex_unlock(&ts->lock);
+ NVT_ERR("clear fw status failed!\n");
+ return -EAGAIN;
+ }
+
+ nvt_change_mode(MP_MODE_CC);
+
+ if (nvt_check_fw_status()) {
+ mutex_unlock(&ts->lock);
+ NVT_ERR("check fw status failed!\n");
+ return -EAGAIN;
+ }
+
+ //---FW Rawdata Test---
+ if (nvt_read_baseline(RawData_FWMutual) != 0) {
+ TestResult_FWMutual = 1;
+ } else {
+ TestResult_FWMutual = RawDataTest_SinglePoint_Sub(RawData_FWMutual, RecordResult_FWMutual, X_Channel, Y_Channel,
+ PS_Config_Lmt_FW_Rawdata_P, PS_Config_Lmt_FW_Rawdata_N);
+ }
+ if (nvt_read_CC(RawData_FW_CC) != 0) {
+ TestResult_FW_CC = 1;
+ if (ts->carrier_system) {
+ TestResult_FW_CC_I = 1;
+ TestResult_FW_CC_Q = 1;
+ }
+ } else {
+ if (ts->carrier_system) {
+ TestResult_FW_CC_I = RawDataTest_SinglePoint_Sub(RawData_FW_CC_I, RecordResult_FW_CC_I, X_Channel, Y_Channel,
+ PS_Config_Lmt_FW_CC_I_P, PS_Config_Lmt_FW_CC_I_N);
+ TestResult_FW_CC_Q = RawDataTest_SinglePoint_Sub(RawData_FW_CC_Q, RecordResult_FW_CC_Q, X_Channel, Y_Channel,
+ PS_Config_Lmt_FW_CC_Q_P, PS_Config_Lmt_FW_CC_Q_N);
+ if ((TestResult_FW_CC_I == -1) || (TestResult_FW_CC_Q == -1))
+ TestResult_FW_CC = -1;
+ else
+ TestResult_FW_CC = 0;
+ } else {
+ TestResult_FW_CC = RawDataTest_SinglePoint_Sub(RawData_FW_CC, RecordResult_FW_CC, X_Channel, Y_Channel,
+ PS_Config_Lmt_FW_CC_P, PS_Config_Lmt_FW_CC_N);
+ }
+ }
+
+ if ((TestResult_FWMutual == 1) || (TestResult_FW_CC == 1)) {
+ TestResult_FW_Rawdata = 1;
+ } else {
+ if ((TestResult_FWMutual == -1) || (TestResult_FW_CC == -1))
+ TestResult_FW_Rawdata = -1;
+ else
+ TestResult_FW_Rawdata = 0;
+ }
+
+ //---Leave Test Mode---
+ nvt_change_mode(NORMAL_MODE);
+
+ //---Noise Test---
+ if (nvt_read_fw_noise(RawData_Diff) != 0) {
+ TestResult_Noise = 1; // 1: ERROR
+ TestResult_FW_DiffMax = 1;
+ TestResult_FW_DiffMin = 1;
+ } else {
+ TestResult_FW_DiffMax = RawDataTest_SinglePoint_Sub(RawData_Diff_Max, RecordResult_FW_DiffMax, X_Channel, Y_Channel,
+ PS_Config_Lmt_FW_Diff_P, PS_Config_Lmt_FW_Diff_N);
+
+ // for carrier sensing system, only positive noise data
+ if (ts->carrier_system) {
+ TestResult_FW_DiffMin = 0;
+ } else {
+ TestResult_FW_DiffMin = RawDataTest_SinglePoint_Sub(RawData_Diff_Min, RecordResult_FW_DiffMin, X_Channel, Y_Channel,
+ PS_Config_Lmt_FW_Diff_P, PS_Config_Lmt_FW_Diff_N);
+ }
+
+ if ((TestResult_FW_DiffMax == -1) || (TestResult_FW_DiffMin == -1))
+ TestResult_Noise = -1;
+ else
+ TestResult_Noise = 0;
+ }
+
+ //--Short Test---
+ if (nvt_read_fw_short(RawData_Short) != 0) {
+ TestResult_Short = 1; // 1:ERROR
+ if (ts->carrier_system) {
+ TestResult_Short_Diff = 1;
+ TestResult_Short_Base = 1;
+ }
+ } else {
+ //---Self Test Check --- // 0:PASS, -1:FAIL
+ if (ts->carrier_system) {
+ TestResult_Short_Diff = RawDataTest_SinglePoint_Sub(RawData_Short_Diff, RecordResult_Short_Diff, X_Channel, Y_Channel,
+ PS_Config_Lmt_Short_Diff_P, PS_Config_Lmt_Short_Diff_N);
+ TestResult_Short_Base = RawDataTest_SinglePoint_Sub(RawData_Short_Base, RecordResult_Short_Base, X_Channel, Y_Channel,
+ PS_Config_Lmt_Short_Base_P, PS_Config_Lmt_Short_Base_N);
+
+ if ((TestResult_Short_Diff == -1) || (TestResult_Short_Base == -1))
+ TestResult_Short = -1;
+ else
+ TestResult_Short = 0;
+ } else {
+ TestResult_Short = RawDataTest_SinglePoint_Sub(RawData_Short, RecordResult_Short, X_Channel, Y_Channel,
+ PS_Config_Lmt_Short_Rawdata_P, PS_Config_Lmt_Short_Rawdata_N);
+ }
+ }
+
+ //---Open Test---
+ if (nvt_read_fw_open(RawData_Open) != 0) {
+ TestResult_Open = 1; // 1:ERROR
+ } else {
+ //---Self Test Check --- // 0:PASS, -1:FAIL
+ TestResult_Open = RawDataTest_SinglePoint_Sub(RawData_Open, RecordResult_Open, X_Channel, Y_Channel,
+ PS_Config_Lmt_Open_Rawdata_P, PS_Config_Lmt_Open_Rawdata_N);
+ }
+
+ //---Reset IC---
+ nvt_bootloader_reset();
+
+ mutex_unlock(&ts->lock);
+
+ NVT_LOG("--\n");
+
+ nvt_mp_test_result_printed = 0;
+
+ return seq_open(file, &nvt_selftest_seq_ops);
+}
+
+static const struct file_operations nvt_selftest_fops = {
+ .owner = THIS_MODULE,
+ .open = nvt_selftest_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+#if NVT_TOUCH_MP_LENOVO
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/NVTflash read function.
+
+return:
+ Executive outcomes. 2---succeed. -5,-14---failed.
+*******************************************************/
+static ssize_t nvt_data_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
+{
+ uint8_t *str;
+ int32_t ret = -1;
+ int32_t retries = 0;
+ int8_t i2c_wr = 0;
+ uint8_t i2c_addr = 0;
+ uint32_t data_len = 0;
+
+ NVT_LOG("++\n");
+
+ if (count > (40 * (40 + 4) * 2 + 7)) {
+ NVT_ERR("error count=%zu\n", count);
+ return -EFAULT;
+ }
+
+ str = kmalloc(40 * (40 + 4) * 2 + 7, GFP_KERNEL);
+ if (str == NULL) {
+ NVT_ERR("failed to allocated memory for input data\n");
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(str, buff, count)) {
+ NVT_ERR("copy from user error\n");
+ return -EFAULT;
+ }
+
+#if NVT_TOUCH_ESD_PROTECT
+ nvt_esd_check_enable(false);
+#endif
+
+ i2c_wr = str[0] >> 7;
+ i2c_addr = str[0] & 0x7F;
+ data_len = (int32_t)((str[1] << 8) + str[2]);
+
+ if (i2c_wr == 0) {
+ return -ENOTSUPP;
+ } else if (i2c_wr == 1) {
+ while (retries < 20) {
+ ret = nvt_read_mass_data(i2c_addr, str, data_len);
+ if (ret == data_len)
+ break;
+ else
+ NVT_ERR("error, retries=%d, ret=%d, data_len=%d\n", retries, ret, data_len);
+
+ retries++;
+ }
+
+ if (retries < 20) {
+ ret = copy_to_user(buff, str, data_len);
+ if (ret) {
+ NVT_ERR("error, copy_to_user, ret=%d, data_len=%d\n", ret, data_len);
+ return -EFAULT;
+ }
+ }
+
+ if (unlikely(retries == 20)) {
+ NVT_ERR("error, ret = %d\n", ret);
+ return -EIO;
+ }
+ } else {
+ NVT_ERR("Call error, str[0]=%d\n", str[0]);
+ return -EFAULT;
+ }
+
+ kfree(str);
+ NVT_LOG("--\n");
+ return ret;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/NVTflash open function.
+
+return:
+ Executive outcomes. 0---succeed. -12---failed.
+*******************************************************/
+static int32_t nvt_data_open(struct inode *inode, struct file *file)
+{
+ struct nvt_flash_data *dev;
+
+ dev = kmalloc(sizeof(struct nvt_flash_data), GFP_KERNEL);
+ if (dev == NULL) {
+ NVT_ERR("Failed to allocate memory for nvt flash data\n");
+ return -ENOMEM;
+ }
+
+ rwlock_init(&dev->lock);
+ file->private_data = dev;
+
+ return 0;
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen /proc/NVTflash close function.
+
+return:
+ Executive outcomes. 0---succeed.
+*******************************************************/
+static int32_t nvt_data_close(struct inode *inode, struct file *file)
+{
+ struct nvt_flash_data *dev = file->private_data;
+
+ if (dev)
+ kfree(dev);
+
+ return 0;
+}
+
+static const struct file_operations nvt_read_data_fops = {
+ .owner = THIS_MODULE,
+ .open = nvt_data_open,
+ .release = nvt_data_close,
+ .read = nvt_data_read,
+};
+#endif
+
+#ifdef CONFIG_OF
+/*******************************************************
+Description:
+ Novatek touchscreen parse AIN setting for array type.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_mp_parse_ain(struct device_node *np, const char *name, uint8_t *array, int32_t size)
+{
+ struct property *data;
+ int32_t len, ret;
+ int32_t tmp[40];
+ int32_t i;
+
+ data = of_find_property(np, name, &len);
+ len /= sizeof(u32);
+
+ if ((!data) || (!len) || (len != size)) {
+ NVT_ERR("error find %s. len=%d\n", name, len);
+ } else {
+ NVT_LOG("%s. len=%d\n", name, len);
+ ret = of_property_read_u32_array(np, name, tmp, len);
+ if (ret) {
+ NVT_ERR("error reading %s. ret=%d\n", name, ret);
+ return;
+ }
+
+ for (i = 0; i < len; i++)
+ array[i] = tmp[i];
+
+#if NVT_DEBUG
+ printk("[NVT-ts] %s = ", name);
+ for (i = 0; i < len; i++) {
+ printk("%02d ", array[i]);
+ }
+ printk("\n");
+#endif
+ }
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen parse criterion for u32 type.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_mp_parse_u32(struct device_node *np, const char *name, int32_t *para)
+{
+ int32_t ret;
+
+ ret = of_property_read_u32(np, name, para);
+ if (ret)
+ NVT_ERR("error reading %s. ret=%d\n", name, ret);
+ else {
+#if NVT_DEBUG
+ NVT_LOG("%s=%d\n", name, *para);
+#endif
+ }
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen parse criterion for array type.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_mp_parse_array(struct device_node *np, const char *name, int32_t *array,
+ int32_t size)
+{
+ struct property *data;
+ int32_t len, ret;
+#if NVT_DEBUG
+ int32_t i, j, iArrayIndex = 0;
+#endif
+
+ data = of_find_property(np, name, &len);
+ len /= sizeof(u32);
+ if ((!data) || (!len) || (len < size)) {
+ NVT_ERR("error find %s. len=%d\n", name, len);
+ } else {
+ NVT_LOG("%s. len=%d\n", name, len);
+ ret = of_property_read_u32_array(np, name, array, len);
+ if (ret) {
+ NVT_ERR("error reading %s. ret=%d\n", name, ret);
+ return;
+ }
+
+#if NVT_DEBUG
+ NVT_LOG("%s =\n", name);
+ for (j = 0; j < Y_Channel; j++) {
+ printk("[NVT-ts] ");
+ for (i = 0; i < X_Channel; i++) {
+ iArrayIndex = j * X_Channel + i;
+ printk("%5d, ", array[iArrayIndex]);
+ }
+ printk("\n");
+ }
+#if TOUCH_KEY_NUM > 0
+ printk("[NVT-ts] ");
+ for (i = 0; i < Key_Channel; i++) {
+ iArrayIndex++;
+ printk("%5d, ", array[iArrayIndex]);
+ }
+ printk("\n");
+#endif
+#endif
+ }
+}
+
+/*******************************************************
+Description:
+ Novatek touchscreen parse device tree mp function.
+
+return:
+ n.a.
+*******************************************************/
+void nvt_mp_parse_dt(struct device_node *root, const char *node_compatible)
+{
+ struct device_node *np = root;
+ struct device_node *child = NULL;
+
+ NVT_LOG("Parse mp criteria for node %s\n", node_compatible);
+
+ /* find each MP sub-nodes */
+ for_each_child_of_node(root, child) {
+ /* find the specified node */
+ if (of_device_is_compatible(child, node_compatible)) {
+ NVT_LOG("found child node %s\n", node_compatible);
+ np = child;
+ break;
+ }
+ }
+ if (child == NULL) {
+ NVT_ERR("Not found compatible node %s, use default setting!\n", node_compatible);
+ return;
+ }
+
+ /* MP Config*/
+ nvt_mp_parse_u32(np, "IC_X_CFG_SIZE", &IC_X_CFG_SIZE);
+
+ nvt_mp_parse_u32(np, "IC_Y_CFG_SIZE", &IC_Y_CFG_SIZE);
+
+#if TOUCH_KEY_NUM > 0
+ nvt_mp_parse_u32(np, "IC_KEY_CFG_SIZE", &IC_KEY_CFG_SIZE);
+#endif
+
+ nvt_mp_parse_u32(np, "X_Channel", &X_Channel);
+
+ nvt_mp_parse_u32(np, "Y_Channel", &Y_Channel);
+
+ nvt_mp_parse_ain(np, "AIN_X", AIN_X, IC_X_CFG_SIZE);
+
+ nvt_mp_parse_ain(np, "AIN_Y", AIN_Y, IC_Y_CFG_SIZE);
+
+#if TOUCH_KEY_NUM > 0
+ nvt_mp_parse_ain(np, "AIN_KEY", AIN_KEY, IC_KEY_CFG_SIZE);
+#endif
+
+ /* MP Criteria */
+ if (ts->carrier_system) {
+ nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Diff_P", PS_Config_Lmt_Short_Diff_P,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Diff_N", PS_Config_Lmt_Short_Diff_N,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Base_P", PS_Config_Lmt_Short_Base_P,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Base_N", PS_Config_Lmt_Short_Base_N,
+ X_Channel * Y_Channel + Key_Channel);
+ } else {
+ nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Rawdata_P", PS_Config_Lmt_Short_Rawdata_P,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_Short_Rawdata_N", PS_Config_Lmt_Short_Rawdata_N,
+ X_Channel * Y_Channel + Key_Channel);
+ }
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_Open_Rawdata_P", PS_Config_Lmt_Open_Rawdata_P,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_Open_Rawdata_N", PS_Config_Lmt_Open_Rawdata_N,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Rawdata_P", PS_Config_Lmt_FW_Rawdata_P,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Rawdata_N", PS_Config_Lmt_FW_Rawdata_N,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_P", PS_Config_Lmt_FW_CC_P,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_N", PS_Config_Lmt_FW_CC_N,
+ X_Channel * Y_Channel + Key_Channel);
+
+ if (ts->carrier_system) {
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_I_P", PS_Config_Lmt_FW_CC_I_P,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_I_N", PS_Config_Lmt_FW_CC_I_N,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_Q_P", PS_Config_Lmt_FW_CC_Q_P,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_CC_Q_N", PS_Config_Lmt_FW_CC_Q_N,
+ X_Channel * Y_Channel + Key_Channel);
+ }
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Diff_P", PS_Config_Lmt_FW_Diff_P,
+ X_Channel * Y_Channel + Key_Channel);
+
+ nvt_mp_parse_array(np, "PS_Config_Lmt_FW_Diff_N", PS_Config_Lmt_FW_Diff_N,
+ X_Channel * Y_Channel + Key_Channel);
+ nvt_mp_parse_u32(np, "PS_Config_Diff_Test_Frame", &PS_Config_Diff_Test_Frame);
+
+ NVT_LOG("Parse mp criteria done!\n");
+}
+#endif
+
+/*******************************************************
+Description:
+ Novatek touchscreen MP function proc. file node
+ initial function.
+
+return:
+ Executive outcomes. 0---succeed. -1---failed.
+*******************************************************/
+int32_t nvt_mp_proc_init(void)
+{
+ int32_t ret = 0;
+
+ NVT_proc_selftest_entry = proc_create("nvt_selftest", 0444, NULL, &nvt_selftest_fops);
+ if (NVT_proc_selftest_entry == NULL) {
+ NVT_ERR("create /proc/nvt_selftest Failed!\n");
+ ret = -1;
+ } else {
+ if(nvt_mp_buffer_init()) {
+ NVT_ERR("Allocate mp memory failed\n");
+ ret = -1;
+ }
+ else {
+ NVT_LOG("create /proc/nvt_selftest Succeeded!\n");
+ }
+ ret = 0;
+ }
+#if NVT_TOUCH_MP_LENOVO
+ if (ret == 0) {
+ NVT_proc_selftest_read_data = proc_create("nvt_read_data", 0444, NULL, &nvt_read_data_fops);
+ if (NVT_proc_selftest_read_data == NULL) {
+ NVT_ERR("create /proc/nvt_read_data Failed!\n");
+ ret = -1;
+ } else {
+ NVT_LOG("create /proc/nvt_read_data Succeeded!\n");
+ }
+ }
+#endif
+ return ret;
+}
+
+#endif /* #if NVT_TOUCH_MP */
--- /dev/null
+/*
+ * Copyright (C) 2010 - 2017 Novatek, Inc.
+ *
+ * $Revision: 22971 $
+ * $Date: 2018-02-08 16:05:40 +0800 (ι±ε, 08 δΊζ 2018) $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#if NVT_TOUCH_MP
+
+static uint32_t IC_X_CFG_SIZE = 18;
+static uint32_t IC_Y_CFG_SIZE = 36;
+static uint32_t IC_KEY_CFG_SIZE = 4;
+static uint32_t X_Channel = 18;
+static uint32_t Y_Channel = 34;
+static uint32_t Key_Channel = TOUCH_KEY_NUM;
+static uint8_t AIN_X[40] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
+static uint8_t AIN_Y[40] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 0xFF, 0xFF};
+#if TOUCH_KEY_NUM > 0
+static uint8_t AIN_KEY[8] = {0, 1, 2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+#endif /* #if TOUCH_KEY_NUM > 0 */
+
+static int32_t PS_Config_Lmt_Short_Rawdata_P[40 * 40] = {
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+ 6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,6500,
+#if TOUCH_KEY_NUM > 0
+ 20000,20000,20000,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_Short_Rawdata_N[40 * 40] = {
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+ 4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,4500,
+#if TOUCH_KEY_NUM > 0
+ 11550,11550,11550,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_Short_Diff_P[40 * 40] = {
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+ 6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,6300,
+#if TOUCH_KEY_NUM > 0
+ 6300,6300,6300,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_Short_Diff_N[40 * 40] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+#if TOUCH_KEY_NUM > 0
+ 0,0,0,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_Short_Base_P[40 * 40] = {
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+ 2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,2000,
+#if TOUCH_KEY_NUM > 0
+ 2000,2000,2000,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_Short_Base_N[40 * 40] = {
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+ -2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,-2000,
+#if TOUCH_KEY_NUM > 0
+ -2000,-2000,-2000,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_Open_Rawdata_P[40 * 40] = {
+ 5830,2470,3134,2675,6215, 590, 616, 542, 600,2505,2447,2511,2488,6273,4533,3227,2617,6119,
+ 2967,3669,3098,6069,5039,4702,4552,4654,4525,2545,2653,2584,2695,3051,3680,5123,5934,3186,
+ 2831,3440,2926,3081,2920,3067,2910,3055,2916,2883,3046,2916,3049,2907,3448,2893,3039,2908,
+ 2762,3353,2877,3020,2873,3008,2865,2999,2872,2813,2961,2871,2990,2862,3389,2846,2979,2861,
+ 2815,3410,2895,3040,2892,3031,2886,3023,2891,2863,3015,2890,3012,2881,3408,2865,3000,2881,
+ 2773,3357,2846,2980,2844,2974,2840,2967,2846,2817,2958,2843,2952,2832,3347,2816,2942,2838,
+ 2775,3362,2822,2953,2846,2975,2846,2970,2851,2825,2966,2823,2929,2838,3353,2823,2943,2838,
+ 2730,3176,2803,2925,2797,2898,2800,2914,2807,2778,2906,2804,2901,2787,3160,2772,2879,2788,
+ 2741,2939,2813,2938,2807,2909,2814,2930,2817,2791,2922,2815,2914,2798,2913,2784,2893,2801,
+ 2691,2875,2761,2878,2758,2849,2767,2869,2765,2756,2857,2764,2863,2745,2849,2734,2830,2748,
+ 2684,2861,2750,2862,2724,2812,2758,2859,2757,2750,2843,2759,2855,2714,2809,2726,2821,2743,
+ 2714,2871,2768,2868,2771,2852,2785,2881,2788,2787,2867,2786,2866,2759,2844,2743,2830,2768,
+ 2725,2885,2781,2884,2781,2871,2803,2901,2799,2804,2881,2798,2877,2770,2863,2755,2849,2780,
+ 2554,2710,2612,2700,2616,2690,2607,2683,2624,2629,2676,2623,2693,2604,2680,2569,2649,2614,
+ 2558,2712,2615,2703,2620,2697,2638,2717,2629,2634,2683,2627,2694,2607,2684,2598,2688,2621,
+ 2487,2628,2541,2619,2548,2616,2567,2626,2554,2560,2605,2553,2607,2534,2599,2525,2611,2548,
+ 2492,2625,2538,2616,2545,2617,2567,2618,2531,2561,2605,2552,2605,2531,2598,2524,2615,2527,
+ 2399,2515,2447,2508,2450,2506,2476,2508,2461,2466,2499,2461,2494,2437,2491,2433,2508,2457,
+ 2393,2510,2442,2501,2446,2503,2471,2502,2469,2465,2507,2458,2489,2433,2489,2430,2513,2450,
+ 2316,2419,2363,2414,2372,2418,2394,2413,2387,2386,2414,2377,2399,2354,2399,2352,2432,2370,
+ 2287,2391,2354,2404,2369,2415,2387,2407,2373,2360,2374,2365,2389,2344,2391,2342,2431,2363,
+ 2214,2303,2260,2294,2276,2306,2296,2295,2278,2286,2300,2272,2276,2251,2284,2252,2316,2270,
+ 2283,2365,2323,2419,2345,2376,2370,2379,2355,2360,2374,2341,2338,2316,2349,2317,2447,2344,
+ 2225,2304,2245,2634,2280,2300,2303,2304,2284,2278,2285,2254,2257,2247,2265,2262,2684,2285,
+ 2099,2175,2147,2528,2158,2167,2175,2165,2146,2149,2154,2145,2143,2128,2141,2145,2553,2157,
+ 2005,2144,2065,2312,2074,2119,2085,2137,2057,2055,2112,2055,2113,2044,2112,2059,2337,2060,
+ 1970,2107,2031,2273,2042,2082,2052,2081,2028,2018,2074,2021,2072,2011,2072,2029,2301,2026,
+ 1894,2019,1958,2188,1958,1983,1977,1992,1954,1938,1978,1940,1980,1924,1971,1954,2213,1948,
+ 1840,1957,1908,2127,1918,1929,1925,1929,1895,1888,1917,1891,1919,1886,1925,1907,2154,1896,
+ 1767,1872,1837,2045,1846,1845,1854,1844,1822,1813,1827,1815,1834,1814,1842,1836,2067,1818,
+ 1726,1830,1800,2004,1810,1802,1813,1791,1784,1772,1779,1776,1791,1776,1798,1796,2021,1777,
+ 1658,1750,1733,1929,1741,1722,1750,1719,1709,1701,1695,1704,1713,1709,1724,1737,1948,1706,
+ 1499,2086,1889,1954,1768,1745,1774,1735,1732,1720,1710,1724,1735,1732,1748,1762,1975,1461,
+ 3326,3789,3764,1741,1713,1721,1704,1695,1703,1796,1816,1835,1821,1834,2028,1708,1674,1383,
+#if TOUCH_KEY_NUM > 0
+ 13000,13000,13000,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_Open_Rawdata_N[40 * 40] = {
+ 3139,1330,1688,1440,3346, 317, 332, 292, 323,1349,1318,1352,1340,3378,2441,1738,1409,3295,
+ 1597,1975,1668,3268,2714,2532,2451,2506,2437,1371,1428,1391,1451,1643,1981,2759,3195,1715,
+ 1525,1852,1575,1659,1572,1652,1567,1645,1570,1552,1640,1570,1642,1565,1857,1558,1636,1566,
+ 1487,1806,1549,1626,1547,1620,1543,1615,1547,1514,1595,1546,1610,1541,1825,1532,1604,1541,
+ 1516,1836,1559,1637,1557,1632,1554,1628,1557,1541,1623,1556,1622,1551,1835,1543,1616,1551,
+ 1493,1808,1532,1605,1531,1601,1529,1597,1532,1517,1593,1531,1590,1525,1802,1516,1584,1528,
+ 1494,1810,1520,1590,1532,1602,1533,1599,1535,1521,1597,1520,1577,1528,1805,1520,1585,1528,
+ 1470,1710,1509,1575,1506,1560,1508,1569,1511,1496,1565,1510,1562,1501,1702,1493,1550,1501,
+ 1476,1583,1515,1582,1512,1567,1515,1578,1517,1503,1573,1516,1569,1507,1568,1499,1558,1508,
+ 1449,1548,1487,1550,1485,1534,1490,1545,1489,1484,1539,1489,1542,1478,1534,1472,1524,1480,
+ 1445,1541,1481,1541,1467,1514,1485,1539,1485,1481,1531,1485,1537,1461,1513,1468,1519,1477,
+ 1461,1546,1490,1544,1492,1536,1499,1551,1501,1501,1544,1500,1543,1486,1532,1477,1524,1491,
+ 1467,1553,1498,1553,1498,1546,1509,1562,1507,1510,1551,1507,1549,1492,1541,1483,1534,1497,
+ 1375,1459,1406,1454,1409,1448,1404,1445,1413,1416,1441,1413,1450,1402,1443,1383,1426,1407,
+ 1378,1460,1408,1455,1411,1452,1420,1463,1416,1418,1445,1414,1451,1404,1445,1399,1448,1411,
+ 1339,1415,1368,1410,1372,1409,1382,1414,1375,1379,1403,1375,1404,1365,1399,1360,1406,1372,
+ 1342,1414,1367,1408,1370,1409,1382,1410,1363,1379,1402,1374,1403,1363,1399,1359,1408,1361,
+ 1292,1354,1318,1350,1319,1349,1333,1350,1325,1328,1346,1325,1343,1312,1341,1310,1351,1323,
+ 1289,1351,1315,1347,1317,1348,1330,1347,1329,1327,1350,1324,1340,1310,1340,1308,1353,1319,
+ 1247,1302,1272,1300,1277,1302,1289,1299,1285,1285,1300,1280,1292,1267,1292,1266,1309,1276,
+ 1232,1288,1267,1295,1276,1300,1286,1296,1278,1271,1278,1274,1286,1262,1287,1261,1309,1272,
+ 1192,1240,1217,1235,1225,1242,1236,1236,1226,1231,1239,1224,1226,1212,1230,1213,1247,1222,
+ 1229,1273,1251,1302,1263,1279,1276,1281,1268,1271,1278,1261,1259,1247,1265,1248,1318,1262,
+ 1198,1241,1209,1418,1228,1239,1240,1241,1230,1227,1230,1214,1215,1210,1220,1218,1445,1231,
+ 1130,1171,1156,1361,1162,1167,1171,1166,1155,1157,1160,1155,1154,1146,1153,1155,1375,1161,
+ 1080,1155,1112,1245,1117,1141,1123,1151,1108,1107,1137,1107,1138,1100,1137,1109,1258,1109,
+ 1061,1134,1093,1224,1099,1121,1105,1120,1092,1087,1117,1088,1116,1083,1116,1093,1239,1091,
+ 1020,1087,1054,1178,1054,1068,1065,1072,1052,1044,1065,1044,1066,1036,1061,1052,1191,1049,
+ 991,1054,1028,1145,1033,1039,1036,1038,1020,1016,1032,1018,1033,1015,1037,1027,1160,1021,
+ 952,1008, 989,1101, 994, 993, 998, 993, 981, 976, 984, 977, 988, 977, 992, 989,1113, 979,
+ 929, 985, 969,1079, 975, 970, 976, 965, 960, 954, 958, 956, 964, 956, 968, 967,1088, 957,
+ 893, 942, 933,1039, 938, 927, 942, 926, 920, 916, 912, 918, 922, 920, 928, 935,1049, 918,
+ 807,1123,1017,1052, 952, 940, 955, 934, 932, 926, 921, 928, 934, 933, 941, 949,1063, 787,
+ 1791,2040,2027, 937, 922, 927, 918, 913, 917, 967, 978, 988, 981, 987,1092, 920, 901, 745,
+#if TOUCH_KEY_NUM > 0
+ 6500,6500,6500,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_Rawdata_P[40 * 40] = {
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+ 1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,1700,
+#if TOUCH_KEY_NUM > 0
+ 2000,2000,2000,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_Rawdata_N[40 * 40] = {
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+ 700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+#if TOUCH_KEY_NUM > 0
+ 400,400,400,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_CC_P[40 * 40] = {
+ 116,114,119,109,112,106,104,106,103,108,110,108,110,117,113,115,111,113,
+ 117,115,118,111,113,111,114,114,109,110,115,114,112,113,112,118,116,119,
+ 115,113,116,110,112,109,108,108,107,108,113,111,110,111,110,116,111,115,
+ 116,114,117,112,114,110,109,110,108,109,114,111,111,112,111,117,113,116,
+ 115,113,116,111,113,110,108,109,107,108,112,111,110,112,111,117,112,116,
+ 116,115,118,112,114,111,110,110,108,109,114,112,112,113,112,118,114,117,
+ 114,112,115,110,112,108,107,108,106,107,111,110,110,111,110,116,111,115,
+ 115,114,117,112,113,110,109,109,108,109,113,111,111,112,111,117,113,116,
+ 115,113,116,111,113,110,109,109,108,109,113,111,111,112,111,117,112,116,
+ 117,115,118,113,115,112,111,111,110,112,115,112,112,114,113,118,114,117,
+ 114,112,115,110,112,109,109,109,107,113,112,110,110,112,110,117,112,115,
+ 115,112,116,111,113,110,109,109,108,114,112,110,111,112,111,117,112,115,
+ 117,115,118,113,115,112,111,113,110,118,113,112,113,115,113,119,115,118,
+ 114,112,116,110,113,110,109,112,108,115,110,110,111,112,111,117,112,115,
+ 116,113,117,112,114,111,111,113,109,117,112,111,112,114,112,118,114,117,
+ 116,113,117,112,114,111,110,112,109,116,112,111,111,114,112,118,113,116,
+ 117,114,119,113,115,112,111,113,110,117,114,112,112,115,113,119,115,117,
+ 115,112,116,110,112,110,109,110,108,114,111,109,110,112,111,116,112,114,
+ 116,113,118,112,114,111,111,112,110,116,113,111,112,114,112,118,114,116,
+ 116,113,117,112,114,111,111,111,110,115,113,111,111,114,112,117,113,115,
+ 118,115,119,114,115,113,113,113,111,117,114,112,113,115,113,119,115,117,
+ 116,112,117,111,113,110,110,111,109,114,112,110,111,113,112,117,113,115,
+ 117,113,118,112,114,111,111,112,109,115,112,111,111,114,112,117,114,116,
+ 119,115,120,114,116,114,113,115,111,115,113,113,114,117,115,120,116,118,
+ 117,113,118,112,114,112,112,113,110,112,111,111,111,115,113,118,114,116,
+ 119,114,119,113,114,113,112,115,111,112,112,112,112,115,114,119,116,119,
+ 119,114,118,113,114,112,112,114,110,111,111,111,112,114,114,119,115,119,
+ 121,116,120,114,116,114,114,116,112,113,113,113,114,116,115,121,117,120,
+ 118,113,117,112,113,111,111,113,109,110,110,110,111,114,113,119,115,118,
+ 120,115,119,114,115,113,113,115,111,112,112,112,113,116,114,120,117,119,
+ 119,115,119,113,114,113,114,115,111,111,112,111,113,115,114,120,117,119,
+ 121,116,121,115,116,114,116,117,113,113,114,113,114,117,115,122,119,121,
+ 115,112,116,113,114,112,115,114,110,111,111,111,112,115,113,120,116,118,
+ 115,114,120,114,115,112,110,111,110,107,113,113,110,111,111,120,116,118,
+#if TOUCH_KEY_NUM > 0
+ 38,38,38,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_CC_N[40 * 40] = {
+ 63,61,64,59,60,57,56,57,55,58,59,58,59,63,61,62,60,61,
+ 63,62,63,60,61,60,61,61,59,59,62,61,60,61,60,64,62,64,
+ 62,61,62,59,60,59,58,58,58,58,61,60,59,60,59,62,60,62,
+ 62,61,63,60,61,59,59,59,58,58,61,60,60,61,60,63,61,63,
+ 62,61,63,60,61,59,58,59,58,58,60,60,59,60,60,63,60,62,
+ 63,62,63,60,61,60,59,59,58,59,61,60,60,61,60,64,61,63,
+ 61,60,62,59,60,58,58,58,57,58,60,59,59,60,59,62,60,62,
+ 62,61,63,60,61,59,59,59,58,59,61,60,60,60,60,63,61,63,
+ 62,61,63,60,61,59,59,59,58,58,61,60,60,60,60,63,61,62,
+ 63,62,63,61,62,60,60,60,59,61,62,60,61,61,61,64,61,63,
+ 62,60,62,59,60,59,58,59,58,61,60,59,59,60,59,63,60,62,
+ 62,61,62,60,61,59,59,59,58,61,60,59,60,60,60,63,60,62,
+ 63,62,64,61,62,60,60,61,59,63,61,60,61,62,61,64,62,63,
+ 61,60,62,59,61,59,59,60,58,62,59,59,60,60,60,63,60,62,
+ 62,61,63,60,61,60,60,61,59,63,60,60,60,61,60,63,61,63,
+ 62,61,63,60,61,60,59,60,59,62,60,60,60,61,60,63,61,62,
+ 63,62,64,61,62,60,60,61,59,63,61,60,61,62,61,64,62,63,
+ 62,60,63,59,61,59,59,59,58,61,60,59,59,60,60,63,60,61,
+ 63,61,63,60,61,60,60,60,59,63,61,60,60,61,60,63,61,62,
+ 63,61,63,60,61,60,60,60,59,62,61,60,60,61,61,63,61,62,
+ 64,62,64,61,62,61,61,61,60,63,61,60,61,62,61,64,62,63,
+ 62,60,63,60,61,59,59,60,58,62,61,59,60,61,60,63,61,62,
+ 63,61,63,60,61,60,60,61,59,62,60,60,60,61,60,63,61,62,
+ 64,62,65,61,62,61,61,62,60,62,61,61,61,63,62,65,63,64,
+ 63,61,63,60,61,60,60,61,59,60,60,60,60,62,61,63,62,63,
+ 64,61,64,61,61,61,61,62,60,60,60,60,61,62,61,64,62,64,
+ 64,61,64,61,61,60,61,61,59,60,60,60,60,62,61,64,62,64,
+ 65,62,65,62,62,61,61,62,60,61,61,61,61,63,62,65,63,65,
+ 64,61,63,60,61,60,60,61,59,59,59,59,60,61,61,64,62,63,
+ 64,62,64,61,62,61,61,62,60,60,60,60,61,62,62,65,63,64,
+ 64,62,64,61,62,61,61,62,60,60,60,60,61,62,61,65,63,64,
+ 65,62,65,62,63,62,63,63,61,61,61,61,61,63,62,66,64,65,
+ 62,60,62,61,61,60,62,61,59,60,60,60,60,62,61,64,63,64,
+ 62,61,64,61,62,60,59,60,59,58,61,61,59,60,60,65,62,63,
+#if TOUCH_KEY_NUM > 0
+ 9,9,9,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_CC_I_P[40 * 40] = {
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+#if TOUCH_KEY_NUM > 0
+ 25,25,25,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_CC_I_N[40 * 40] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+#if TOUCH_KEY_NUM > 0
+ 0,0,0,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_CC_Q_P[40 * 40] = {
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+ 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+#if TOUCH_KEY_NUM > 0
+ 25,25,25,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_CC_Q_N[40 * 40] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+#if TOUCH_KEY_NUM > 0
+ 0,0,0,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_Diff_P[40 * 40] = {
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+ 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+#if TOUCH_KEY_NUM > 0
+ 35,35,35,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Lmt_FW_Diff_N[40 *40] = {
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+ -50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,-50,
+#if TOUCH_KEY_NUM > 0
+ -35,-35,-35,
+#endif /* #if TOUCH_KEY_NUM > 0 */
+};
+
+static int32_t PS_Config_Diff_Test_Frame = 50;
+
+#endif /* #if NVT_TOUCH_MP */