mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
TP bring up[1/4]
touch IC is synaptics Change-Id: I5cc6c211d1a157967666c2d9bf910b0bde0d3541 Reviewed-on: https://gerrit.mot.com/2267911 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Reviewed-by: Wei Deng <dengwei1@motorola.com> Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com> Reviewed-by: <hqjiangy@motorola.com> Tested-by: Jira Key Submit-Approved: Jira Key
This commit is contained in:
parent
0769972de6
commit
9293c0bd41
27 changed files with 21416 additions and 0 deletions
33
drivers/input/touchscreen/synaptics_tcm2_mmi/Android.mk
Normal file
33
drivers/input/touchscreen/synaptics_tcm2_mmi/Android.mk
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
DLKM_DIR := motorola/kernel/modules
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
|
||||
ifeq ($(DRM_PANEL_NOTIFICATIONS),true)
|
||||
KBUILD_OPTIONS += CONFIG_DRM_PANEL_NOTIFICATIONS=y
|
||||
endif
|
||||
|
||||
ifeq ($(TOUCHSCREEN_SYNA_TCM2_SYSFS),true)
|
||||
KBUILD_OPTIONS += CONFIG_TOUCHSCREEN_SYNA_TCM2_SYSFS=y
|
||||
endif
|
||||
|
||||
ifeq ($(TOUCHSCREEN_SYNA_TCM2_TESTING),true)
|
||||
KBUILD_OPTIONS += CONFIG_TOUCHSCREEN_SYNA_TCM2_TESTING=y
|
||||
endif
|
||||
|
||||
ifneq ($(findstring touchscreen_mmi.ko,$(BOARD_VENDOR_KERNEL_MODULES)),)
|
||||
KBUILD_OPTIONS += CONFIG_INPUT_TOUCHSCREEN_MMI=y
|
||||
endif
|
||||
|
||||
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := synaptics_v2_mmi.ko
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES += $(KERNEL_MODULES_OUT)/mmi_info.ko
|
||||
ifneq ($(findstring touchscreen_mmi.ko,$(BOARD_VENDOR_KERNEL_MODULES)),)
|
||||
KBUILD_OPTIONS += CONFIG_INPUT_TOUCHSCREEN_MMI=y
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES += $(KERNEL_MODULES_OUT)/touchscreen_mmi.ko
|
||||
endif
|
||||
KBUILD_OPTIONS_GKI += GKI_OBJ_MODULE_DIR=gki
|
||||
include $(DLKM_DIR)/AndroidKernelModule.mk
|
||||
43
drivers/input/touchscreen/synaptics_tcm2_mmi/Kbuild
Normal file
43
drivers/input/touchscreen/synaptics_tcm2_mmi/Kbuild
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# add -Wall to try to catch everything we can.
|
||||
EXTRA_CFLAGS += -Wall
|
||||
EXTRA_CFLAGS += \
|
||||
-I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include \
|
||||
-I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/drivers/input/touchscreen/synaptics_tcm2_mmi \
|
||||
-I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/drivers/input/touchscreen/synaptics_tcm2_mmi/tcm
|
||||
|
||||
obj-m := synaptics_v2_mmi.o
|
||||
synaptics_v2_mmi-objs := \
|
||||
syna_tcm2.o \
|
||||
syna_tcm2_testing.o \
|
||||
syna_tcm2_sysfs.o \
|
||||
syna_tcm2_platform_spi.o \
|
||||
tcm/synaptics_touchcom_core_v1.o \
|
||||
tcm/synaptics_touchcom_core_v2.o \
|
||||
tcm/synaptics_touchcom_func_base.o \
|
||||
tcm/synaptics_touchcom_func_reflash.o \
|
||||
tcm/synaptics_touchcom_func_touch.o
|
||||
|
||||
|
||||
|
||||
|
||||
ifneq ($(filter m y, $(CONFIG_DRM_PANEL_NOTIFICATIONS)),)
|
||||
EXTRA_CFLAGS += -DCONFIG_DRM_PANEL_NOTIFICATIONS
|
||||
endif
|
||||
|
||||
ifneq ($(filter m y,$(CONFIG_TOUCHSCREEN_SYNA_TCM2_SYSFS)),)
|
||||
EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_SYNA_TCM2_SYSFS
|
||||
endif
|
||||
|
||||
ifneq ($(filter m y,$(CONFIG_TOUCHSCREEN_SYNA_TCM2_TESTING)),)
|
||||
EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_SYNA_TCM2_TESTING
|
||||
endif
|
||||
|
||||
ifneq ($(filter m y,$(CONFIG_INPUT_TOUCHSCREEN_MMI)),)
|
||||
KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../touchscreen_mmi/$(GKI_OBJ_MODULE_DIR)/Module.symvers
|
||||
EXTRA_CFLAGS += -DCONFIG_INPUT_TOUCHSCREEN_MMI
|
||||
synaptics_v2_mmi-objs += syna_ts_mmi.o
|
||||
endif
|
||||
|
||||
|
||||
KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../touchscreen_mmi/$(GKI_OBJ_MODULE_DIR)/Module.symvers
|
||||
KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../../../mmi_info/$(GKI_OBJ_MODULE_DIR)/Module.symvers
|
||||
60
drivers/input/touchscreen/synaptics_tcm2_mmi/Kconfig
Normal file
60
drivers/input/touchscreen/synaptics_tcm2_mmi/Kconfig
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#
|
||||
# Synaptics TCM touchscreen driver configuration
|
||||
#
|
||||
menuconfig TOUCHSCREEN_SYNA_TCM2
|
||||
tristate "Synaptics TCM touchscreen"
|
||||
default y
|
||||
help
|
||||
Say Y here if you have a Synaptics TCM touchscreen connected
|
||||
to your system.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
||||
if TOUCHSCREEN_SYNA_TCM2
|
||||
|
||||
choice
|
||||
default TOUCHSCREEN_SYNA_TCM2_I2C
|
||||
prompt "Synaptics TCM bus module"
|
||||
config TOUCHSCREEN_SYNA_TCM2_I2C
|
||||
bool "I2C"
|
||||
depends on I2C
|
||||
config TOUCHSCREEN_SYNA_TCM2_SPI
|
||||
bool "SPI"
|
||||
depends on SPI_MASTER
|
||||
endchoice
|
||||
|
||||
config TOUCHSCREEN_SYNA_TCM2_SYSFS
|
||||
bool "Synaptics TCM device sysfs module"
|
||||
depends on TOUCHSCREEN_SYNA_TCM2
|
||||
help
|
||||
Say Y here to enable support for the sysfs interface.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config TOUCHSCREEN_SYNA_TCM2_REFLASH
|
||||
bool "Synaptics TCM reflash module"
|
||||
depends on TOUCHSCREEN_SYNA_TCM2
|
||||
help
|
||||
Say Y here to enable support for the reflashing.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config TOUCHSCREEN_SYNA_TCM2_TESTING
|
||||
bool "Synaptics TCM testing module"
|
||||
depends on TOUCHSCREEN_SYNA_TCM2
|
||||
help
|
||||
Say Y here to enable support for the production test.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config TOUCHSCREEN_SYNA_TCM2_ROMBOOT
|
||||
bool "Synaptics TCM rom-bootloader module"
|
||||
depends on TOUCHSCREEN_SYNA_TCM2
|
||||
help
|
||||
Say Y here to enable support for the rom-boot access.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
endif
|
||||
10
drivers/input/touchscreen/synaptics_tcm2_mmi/Makefile
Normal file
10
drivers/input/touchscreen/synaptics_tcm2_mmi/Makefile
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
|
||||
|
||||
modules_install:
|
||||
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
|
||||
1929
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2.c
Normal file
1929
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2.c
Normal file
File diff suppressed because it is too large
Load diff
472
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2.h
Normal file
472
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2.h
Normal file
|
|
@ -0,0 +1,472 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file syna_tcm2.h
|
||||
*
|
||||
* The header file is used for the Synaptics TouchComm reference driver.
|
||||
* Platform-specific functions and included headers are implemented in
|
||||
* syna_touchcom_platform.h and syna_touchcom_runtime.h.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TCM2_DRIVER_H_
|
||||
#define _SYNAPTICS_TCM2_DRIVER_H_
|
||||
|
||||
#include "syna_tcm2_platform.h"
|
||||
#include "synaptics_touchcom_core_dev.h"
|
||||
#include "synaptics_touchcom_func_touch.h"
|
||||
|
||||
#define PLATFORM_DRIVER_NAME "synaptics_tcm"
|
||||
|
||||
#define TOUCH_INPUT_NAME "synaptics_tcm_touch"
|
||||
#define TOUCH_INPUT_PHYS_PATH "synaptics_tcm/touch_input"
|
||||
|
||||
#define CHAR_DEVICE_NAME "tcm"
|
||||
#define CHAR_DEVICE_MODE (0x0600)
|
||||
|
||||
#define SYNAPTICS_TCM_DRIVER_ID (1 << 0)
|
||||
#define SYNAPTICS_TCM_DRIVER_VERSION 1
|
||||
#define SYNAPTICS_TCM_DRIVER_SUBVER "3.0"
|
||||
|
||||
#define FILE_NAME_LENGTH 128
|
||||
|
||||
#define IS_NOT_FW_MODE(mode) \
|
||||
((mode != MODE_APPLICATION_FIRMWARE) && (mode != MODE_HOSTDOWNLOAD_FIRMWARE))
|
||||
|
||||
#define IS_FW_MODE(mode) \
|
||||
((mode == MODE_APPLICATION_FIRMWARE) || (mode == MODE_HOSTDOWNLOAD_FIRMWARE))
|
||||
|
||||
/**
|
||||
* @section: Driver Configurations
|
||||
*
|
||||
* The macros in the driver files below are used for doing compile time
|
||||
* configuration of the driver.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief: HAS_SYSFS_INTERFACE
|
||||
* Open to enable the sysfs interface
|
||||
*
|
||||
* @brief: HAS_REFLASH_FEATURE
|
||||
* Open to enable firmware reflash features
|
||||
*
|
||||
* @brief: HAS_ROMBOOT_REFLASH_FEATURE
|
||||
* Open to enable ROMBOOT reflash features
|
||||
*
|
||||
* @brief: HAS_TESTING_FEATURE
|
||||
* Open to enable testing features
|
||||
*/
|
||||
#if defined(CONFIG_TOUCHSCREEN_SYNA_TCM2_SYSFS)
|
||||
#define HAS_SYSFS_INTERFACE
|
||||
#endif
|
||||
#if defined(CONFIG_TOUCHSCREEN_SYNA_TCM2_REFLASH)
|
||||
#define HAS_REFLASH_FEATURE
|
||||
#endif
|
||||
#if defined(CONFIG_TOUCHSCREEN_SYNA_TCM2_ROMBOOT)
|
||||
#define HAS_ROMBOOT_REFLASH_FEATURE
|
||||
#endif
|
||||
#if defined(CONFIG_TOUCHSCREEN_SYNA_TCM2_TESTING)
|
||||
#define HAS_TESTING_FEATURE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief: TYPE_B_PROTOCOL
|
||||
* Open to enable the multi-touch (MT) protocol
|
||||
*/
|
||||
#define TYPE_B_PROTOCOL
|
||||
|
||||
/**
|
||||
* @brief: RESET_ON_RESUME
|
||||
* Open if willing to issue a reset to the touch controller
|
||||
* from suspend.
|
||||
* Set "disable" in default.
|
||||
*/
|
||||
/* #define RESET_ON_RESUME */
|
||||
|
||||
/**
|
||||
* @brief ENABLE_WAKEUP_GESTURE
|
||||
* Open if having wake-up gesture support.
|
||||
*/
|
||||
/* #define ENABLE_WAKEUP_GESTURE */
|
||||
|
||||
/**
|
||||
* @brief REPORT_SWAP_XY
|
||||
* Open if trying to swap x and y position coordinate reported.
|
||||
* @brief REPORT_FLIP_X
|
||||
* Open if trying to flip x position coordinate reported.
|
||||
* @brief REPORT_FLIP_Y
|
||||
* Open if trying to flip x position coordinate reported.
|
||||
*/
|
||||
/* #define REPORT_SWAP_XY */
|
||||
/* #define REPORT_FLIP_X */
|
||||
/* #define REPORT_FLIP_Y */
|
||||
|
||||
/**
|
||||
* @brief REPORT_TOUCH_WIDTH
|
||||
* Open if willing to add the width data to the input event.
|
||||
*/
|
||||
#define REPORT_TOUCH_WIDTH
|
||||
|
||||
/**
|
||||
* @brief USE_CUSTOM_TOUCH_REPORT_CONFIG
|
||||
* Open if willing to set up the format of touch report.
|
||||
* The custom_touch_format[] array in syna_tcm2.c can be used
|
||||
* to describe the customized report format.
|
||||
*/
|
||||
/* #define USE_CUSTOM_TOUCH_REPORT_CONFIG */
|
||||
|
||||
/**
|
||||
* @brief STARTUP_REFLASH
|
||||
* Open if willing to do fw checking and update at startup.
|
||||
* The firmware image will be obtained by request_firmware() API,
|
||||
* so please ensure the image is built-in or included properly.
|
||||
*
|
||||
* This property is available only when SYNA_TCM2_REFLASH
|
||||
* feature is enabled.
|
||||
*/
|
||||
#if defined(HAS_REFLASH_FEATURE) || defined(HAS_ROMBOOT_REFLASH_FEATURE)
|
||||
#define STARTUP_REFLASH
|
||||
#endif
|
||||
/**
|
||||
* @brief MULTICHIP_DUT_REFLASH
|
||||
* Open if willing to do fw update and the DUT belongs to multi-chip
|
||||
* product. This property dependent on STARTUP_REFLASH property.
|
||||
*
|
||||
* Set "disable" in default.
|
||||
*/
|
||||
#if defined(HAS_ROMBOOT_REFLASH_FEATURE) && defined(STARTUP_REFLASH)
|
||||
/* #define MULTICHIP_DUT_REFLASH */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ENABLE_DISP_NOTIFIER
|
||||
* Open if having display notification event and willing to listen
|
||||
* the event from display driver.
|
||||
*
|
||||
* Set "disable" in default due to no generic notifier for DRM
|
||||
*/
|
||||
#if defined(CONFIG_FB) || defined(CONFIG_DRM_PANEL)
|
||||
/* #define ENABLE_DISP_NOTIFIER */
|
||||
#endif
|
||||
/**
|
||||
* @brief RESUME_EARLY_UNBLANK
|
||||
* Open if willing to resume in early un-blanking state.
|
||||
*
|
||||
* This property is available only when ENABLE_DISP_NOTIFIER
|
||||
* feature is enabled.
|
||||
*/
|
||||
#ifdef ENABLE_DISP_NOTIFIER
|
||||
/* #define RESUME_EARLY_UNBLANK */
|
||||
#endif
|
||||
/**
|
||||
* @brief USE_DRM_PANEL_NOTIFIER
|
||||
* Open if willing to listen the notification event from
|
||||
* DRM_PANEL. Please be noted that 'struct drm_panel_notifier'
|
||||
* must be implemented in the target BSP.
|
||||
*
|
||||
* This property is available only when ENABLE_DISP_NOTIFIER
|
||||
* feature is enabled.
|
||||
*
|
||||
* Set "disable" in default due to no generic notifier for DRM
|
||||
*/
|
||||
#if defined(ENABLE_DISP_NOTIFIER) && defined(CONFIG_DRM_PANEL)
|
||||
#define USE_DRM_PANEL_NOTIFIER
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ENABLE_EXTERNAL_FRAME_PROCESS
|
||||
* Open if having external frame process to the userspace application.
|
||||
*
|
||||
* Set "enable" in default
|
||||
*
|
||||
* @brief REPORT_TYPES
|
||||
* Total types of report being used for external frame process.
|
||||
*
|
||||
* @brief EFP_ENABLE / EFP_DISABLE
|
||||
* Specific value to label whether the report is required to be
|
||||
* process or not.
|
||||
*
|
||||
* @brief REPORT_CONCURRENTLY
|
||||
* Open if willing to concurrently handle reports for both kernel
|
||||
* and userspace application.
|
||||
*
|
||||
* Set "disable" in default
|
||||
*/
|
||||
#define ENABLE_EXTERNAL_FRAME_PROCESS
|
||||
#define REPORT_TYPES (256)
|
||||
#define EFP_ENABLE (1)
|
||||
#define EFP_DISABLE (0)
|
||||
/* #define REPORT_CONCURRENTLY */
|
||||
|
||||
/**
|
||||
* @brief TCM_CONNECT_IN_PROBE
|
||||
* Open if willing to detect and connect to TouchComm device at
|
||||
* probe function; otherwise, please invoke connect() manually.
|
||||
*
|
||||
* Set "enable" in default
|
||||
*/
|
||||
#define TCM_CONNECT_IN_PROBE
|
||||
|
||||
/**
|
||||
* @brief FORCE_CONNECTION
|
||||
* Open if willing to connect to TouchComm device w/o error outs.
|
||||
*
|
||||
* Set "disable" in default
|
||||
*/
|
||||
/* #define FORCE_CONNECTION */
|
||||
|
||||
/**
|
||||
* @brief ENABLE_CUSTOM_TOUCH_ENTITY
|
||||
* Open if having custom requirements to parse the custom code
|
||||
* entity in the touch report.
|
||||
*
|
||||
* Set "disable" in default
|
||||
*/
|
||||
/* #define ENABLE_CUSTOM_TOUCH_ENTITY */
|
||||
|
||||
/**
|
||||
* @brief ENABLE_HELPER
|
||||
* Open if willing to do additional handling upon helper wokqueue
|
||||
*
|
||||
* Set "disable" in default
|
||||
*/
|
||||
/* #define ENABLE_HELPER */
|
||||
|
||||
/**
|
||||
* @brief: Power States
|
||||
*
|
||||
* Enumerate the power states of device
|
||||
*/
|
||||
enum power_state {
|
||||
PWR_OFF = 0,
|
||||
PWR_ON,
|
||||
LOW_PWR,
|
||||
};
|
||||
|
||||
#if defined(ENABLE_HELPER)
|
||||
/**
|
||||
* @brief: Tasks for helper
|
||||
*
|
||||
* Tasks being supported in the helper thread and the structure
|
||||
*/
|
||||
enum helper_task {
|
||||
HELP_NONE = 0,
|
||||
HELP_RESET_DETECTED,
|
||||
};
|
||||
|
||||
struct syna_tcm_helper {
|
||||
syna_pal_atomic_t task;
|
||||
struct work_struct work;
|
||||
struct workqueue_struct *workqueue;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief: context of the synaptics linux-based driver
|
||||
*
|
||||
* The structure defines the kernel specific data in linux-based driver
|
||||
*/
|
||||
struct syna_tcm {
|
||||
|
||||
/* TouchComm device core context */
|
||||
struct tcm_dev *tcm_dev;
|
||||
|
||||
/* PLatform device driver */
|
||||
struct platform_device *pdev;
|
||||
|
||||
/* Generic touched data generated by tcm core lib */
|
||||
struct tcm_touch_data_blob tp_data;
|
||||
|
||||
syna_pal_mutex_t tp_event_mutex;
|
||||
|
||||
unsigned char prev_obj_status[MAX_NUM_OBJECTS];
|
||||
|
||||
/* Buffer stored the irq event data */
|
||||
struct tcm_buffer event_data;
|
||||
|
||||
/* Hardware interface layer */
|
||||
struct syna_hw_interface *hw_if;
|
||||
|
||||
/* ISR-related variables */
|
||||
pid_t isr_pid;
|
||||
bool irq_wake;
|
||||
|
||||
/* cdev and sysfs nodes creation */
|
||||
struct cdev char_dev;
|
||||
dev_t char_dev_num;
|
||||
int char_dev_ref_count;
|
||||
|
||||
struct class *device_class;
|
||||
struct device *device;
|
||||
|
||||
struct kobject *sysfs_dir;
|
||||
|
||||
/* Input device registration */
|
||||
struct input_dev *input_dev;
|
||||
struct input_params {
|
||||
unsigned int max_x;
|
||||
unsigned int max_y;
|
||||
unsigned int max_objects;
|
||||
} input_dev_params;
|
||||
|
||||
/* Workqueue used for fw update */
|
||||
struct delayed_work reflash_work;
|
||||
struct workqueue_struct *reflash_workqueue;
|
||||
|
||||
/* IOCTL-related variables */
|
||||
pid_t proc_pid;
|
||||
struct task_struct *proc_task;
|
||||
|
||||
/* flags */
|
||||
int pwr_state;
|
||||
bool slept_in_early_suspend;
|
||||
bool lpwg_enabled;
|
||||
bool is_attn_redirecting;
|
||||
unsigned char fb_ready;
|
||||
bool is_connected;
|
||||
char fw_name[FILE_NAME_LENGTH];
|
||||
|
||||
/* framebuffer callbacks notifier */
|
||||
#if defined(ENABLE_DISP_NOTIFIER)
|
||||
struct notifier_block fb_notifier;
|
||||
#endif
|
||||
|
||||
/* fifo to pass the data to userspace */
|
||||
unsigned int fifo_remaining_frame;
|
||||
struct list_head frame_fifo_queue;
|
||||
wait_queue_head_t wait_frame;
|
||||
unsigned char report_to_queue[REPORT_TYPES];
|
||||
|
||||
#if defined(ENABLE_HELPER)
|
||||
/* helper workqueue */
|
||||
struct syna_tcm_helper helper;
|
||||
#endif
|
||||
|
||||
/* Specific function pointer to do device connection.
|
||||
*
|
||||
* This function will power on and identify the connected device.
|
||||
* At the end of function, the ISR will be registered as well.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
int (*dev_connect)(struct syna_tcm *tcm);
|
||||
|
||||
/* Specific function pointer to disconnect the device
|
||||
*
|
||||
* This function will power off the connected device.
|
||||
* Then, all the allocated resource will be released.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
int (*dev_disconnect)(struct syna_tcm *tcm);
|
||||
|
||||
/* Specific function pointer to set up app fw firmware
|
||||
*
|
||||
* This function should be called whenever the device initially
|
||||
* powers up, resets, or firmware update.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
int (*dev_set_up_app_fw)(struct syna_tcm *tcm);
|
||||
|
||||
/* Specific function pointer to resume the device from suspend state.
|
||||
*
|
||||
* @param
|
||||
* [ in] dev: an instance of device
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
int (*dev_resume)(struct device *dev);
|
||||
|
||||
/* Specific function pointer to put device into suspend state.
|
||||
*
|
||||
* @param
|
||||
* [ in] dev: an instance of device
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
int (*dev_suspend)(struct device *dev);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief: Helpers for cdevice nodes and sysfs nodes creation
|
||||
*
|
||||
* These functions are implemented in syna_touchcom_sysfs.c
|
||||
* and available only when HAS_SYSFS_INTERFACE is enabled.
|
||||
*/
|
||||
#ifdef HAS_SYSFS_INTERFACE
|
||||
|
||||
int syna_cdev_create_sysfs(struct syna_tcm *ptcm,
|
||||
struct platform_device *pdev);
|
||||
|
||||
void syna_cdev_remove_sysfs(struct syna_tcm *ptcm);
|
||||
|
||||
void syna_cdev_redirect_attn(struct syna_tcm *ptcm);
|
||||
|
||||
#ifdef ENABLE_EXTERNAL_FRAME_PROCESS
|
||||
void syna_cdev_update_report_queue(struct syna_tcm *tcm,
|
||||
unsigned char code, struct tcm_buffer *pevent_data);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* end of _SYNAPTICS_TCM2_DRIVER_H_ */
|
||||
|
||||
/**
|
||||
* @section: STARTUP_REFLASH_DELAY_TIME_MS
|
||||
* The delayed time to start fw update during the startup time.
|
||||
* This configuration depends on STARTUP_REFLASH.
|
||||
*/
|
||||
|
||||
#ifdef STARTUP_REFLASH
|
||||
#define STARTUP_REFLASH_DELAY_TIME_MS (200)
|
||||
#define FW_IMAGE_NAME "synaptics/firmware.img"
|
||||
void syna_dev_reflash_startup_work(struct work_struct *work);
|
||||
#endif
|
||||
|
||||
int syna_set_fw_name(struct syna_tcm *tcm, char *name);
|
||||
int syna_reflash_do_reflash(struct syna_tcm *tcm, char *fwname);
|
||||
//int syna_dev_early_suspend(struct device *dev);
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: syna_tcm2_platform.h
|
||||
*
|
||||
* This file declares the platform-specific or hardware relevant data.
|
||||
*
|
||||
* The main structure, syna_hw_interface, abstracts the bus transferred,
|
||||
* ATTN signal, RST_N pin, and power control operations.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TCM2_PLATFORM_H_
|
||||
#define _SYNAPTICS_TCM2_PLATFORM_H_
|
||||
|
||||
#include "syna_tcm2_runtime.h"
|
||||
|
||||
/**
|
||||
* @section: The capability of bus transferred
|
||||
*
|
||||
* Declare read/write capability in bytes (0 = unlimited)
|
||||
*/
|
||||
#define RD_CHUNK_SIZE (512)
|
||||
#define WR_CHUNK_SIZE (512)
|
||||
|
||||
/**
|
||||
* @section: Type of power supply
|
||||
*
|
||||
* The below enumerates the type of power supply
|
||||
*/
|
||||
enum power_supply {
|
||||
PSU_REGULATOR = 0,
|
||||
PSU_GPIO,
|
||||
};
|
||||
|
||||
/**
|
||||
* @section: Defined Hardware-Specific Data
|
||||
*
|
||||
* @brief: syna_hw_bus_data
|
||||
* Hardware Data for bus transferred
|
||||
*
|
||||
* @brief: syna_hw_attn_data
|
||||
* Hardware Data for ATTN signal
|
||||
*
|
||||
* @brief: syna_hw_rst_data
|
||||
* Hardware Data for RST_N pin
|
||||
*
|
||||
* @brief: syna_hw_pwr_data
|
||||
* Hardware Data for power control
|
||||
*
|
||||
* @brief: syna_hw_interface
|
||||
* Contain all above hardware data and abstract the
|
||||
* hardware operations
|
||||
*/
|
||||
|
||||
/* The hardware data especially for bus transferred */
|
||||
struct syna_hw_bus_data {
|
||||
unsigned char type;
|
||||
/* capability of i/o chunk */
|
||||
unsigned int rd_chunk_size;
|
||||
unsigned int wr_chunk_size;
|
||||
/* clock frequency in hz */
|
||||
unsigned int frequency_hz;
|
||||
/* parameters for i2c */
|
||||
unsigned int i2c_addr;
|
||||
/* parameters for spi */
|
||||
unsigned int spi_mode;
|
||||
unsigned int spi_byte_delay_us;
|
||||
unsigned int spi_block_delay_us;
|
||||
/* mutex to protect the i/o, if needed */
|
||||
syna_pal_mutex_t io_mutex;
|
||||
/* parameters for io switch, if needed */
|
||||
int switch_gpio;
|
||||
int switch_state;
|
||||
};
|
||||
|
||||
/* The hardware data especially for ATTN signal */
|
||||
struct syna_hw_attn_data {
|
||||
/* parameters */
|
||||
int irq_gpio;
|
||||
int irq_on_state;
|
||||
unsigned long irq_flags;
|
||||
int irq_id;
|
||||
bool irq_enabled;
|
||||
/* mutex to protect the irq control, if needed */
|
||||
syna_pal_mutex_t irq_en_mutex;
|
||||
};
|
||||
|
||||
/* The hardware data especially for RST_N pin */
|
||||
struct syna_hw_rst_data {
|
||||
/* parameters */
|
||||
int reset_gpio;
|
||||
int reset_on_state;
|
||||
unsigned int reset_delay_ms;
|
||||
unsigned int reset_active_ms;
|
||||
};
|
||||
|
||||
/* The hardware data especially for power control */
|
||||
struct syna_hw_pwr_data {
|
||||
int psu;
|
||||
/* parameters */
|
||||
int vdd_gpio;
|
||||
int avdd_gpio;
|
||||
int power_on_state;
|
||||
unsigned int power_on_delay_ms;
|
||||
/* voltage */
|
||||
unsigned int vdd;
|
||||
unsigned int vled;
|
||||
unsigned int vio;
|
||||
unsigned int vddtx;
|
||||
/* regulators */
|
||||
const char *vdd_reg_name;
|
||||
void *vdd_reg_dev;
|
||||
const char *avdd_reg_name;
|
||||
void *avdd_reg_dev;
|
||||
};
|
||||
|
||||
/**
|
||||
* @section: Hardware Interface Abstraction Layer
|
||||
*
|
||||
* The structure contains the hardware-specific implementations
|
||||
* on the target platform.
|
||||
*/
|
||||
struct syna_hw_interface {
|
||||
/* The handle of hardware device */
|
||||
void *pdev;
|
||||
|
||||
/* Hardware specific data */
|
||||
struct syna_hw_bus_data bdata_io;
|
||||
struct syna_hw_attn_data bdata_attn;
|
||||
struct syna_hw_rst_data bdata_rst;
|
||||
struct syna_hw_pwr_data bdata_pwr;
|
||||
|
||||
/* Operation to do power on/off, if supported
|
||||
*
|
||||
* This is an optional operation.
|
||||
*
|
||||
* Implementation should request that the power device be
|
||||
* enabled with the output at the proper voltage.
|
||||
*
|
||||
* Assign the pointer NULL if power supply module is not controllable.
|
||||
*
|
||||
* @param
|
||||
* [ in] hw_if: the handle of hw interface
|
||||
* [ in] en: '1' for powering on, and '0' for powering off
|
||||
*
|
||||
* @return
|
||||
* 0 on success; otherwise, on error.
|
||||
*/
|
||||
int (*ops_power_on)(struct syna_hw_interface *hw_if,
|
||||
bool en);
|
||||
|
||||
/* Operation to perform the hardware reset, if supported
|
||||
*
|
||||
* This is an optional operation.
|
||||
*
|
||||
* The actual reset waveform should be reference to the device spec.
|
||||
*
|
||||
* Assign the pointer NULL if RST_N pin is not controllable.
|
||||
*
|
||||
* @param
|
||||
* [ in] hw_if: the handle of hw interface
|
||||
*
|
||||
* @return
|
||||
* 0 on success; otherwise, on error.
|
||||
*/
|
||||
void (*ops_hw_reset)(struct syna_hw_interface *hw_if);
|
||||
|
||||
/* Operation to set up the bus connection
|
||||
*
|
||||
* This is an optional operation to add in the extra configuration
|
||||
* before doing connection.
|
||||
*
|
||||
* Assign the pointer NULL if this operation is not required.
|
||||
*
|
||||
* @param
|
||||
* [ in] hw_if: the handle of hw interface
|
||||
* [ in] config: parameters to change
|
||||
*
|
||||
* @return
|
||||
* 0 or positive value on success; otherwise, on error.
|
||||
*/
|
||||
int (*ops_bus_setup)(struct syna_hw_interface *hw_if,
|
||||
struct syna_hw_bus_data *config);
|
||||
|
||||
/* Operation to read the bare data from bus
|
||||
*
|
||||
* This is an essential operation; otherwise, the communication
|
||||
* will not be created.
|
||||
*
|
||||
* @param
|
||||
* [ in] hw_if: the handle of hw interface
|
||||
* [out] rd_data: buffer for storing data retrieved
|
||||
* [ in] rd_len: length of reading data in bytes
|
||||
*
|
||||
* @return
|
||||
* 0 or positive value on success; otherwise, on error.
|
||||
*/
|
||||
int (*ops_read_data)(struct syna_hw_interface *hw_if,
|
||||
unsigned char *rd_data, unsigned int rd_len);
|
||||
|
||||
/* Operation to write the bare data to bus
|
||||
*
|
||||
* This is an essential operation; otherwise, the communication
|
||||
* will not be created.
|
||||
*
|
||||
* @param
|
||||
* [ in] hw_if: the handle of hw interface
|
||||
* [ in] wr_data: written data
|
||||
* [ in] wr_len: length of written data in bytes
|
||||
*
|
||||
* @return
|
||||
* 0 or positive value on success; otherwise, on error.
|
||||
*/
|
||||
int (*ops_write_data)(struct syna_hw_interface *hw_if,
|
||||
unsigned char *wr_data, unsigned int wr_len);
|
||||
|
||||
/* Operation to enable/disable the irq, if supported
|
||||
*
|
||||
* This is an optional operation. Providing this operation could
|
||||
* minimize the frequency of ISR being called.
|
||||
*
|
||||
* Once disabled, ISR will not be invoked even ATTN is asserted.
|
||||
*
|
||||
* Assign the pointer NULL if irq is not controllable.
|
||||
*
|
||||
* @param
|
||||
* [ in] hw_if: the handle of hw interface
|
||||
* [ in] en: '1' for enabling, and '0' for disabling
|
||||
*
|
||||
* @return
|
||||
* 0 on success; otherwise, on error.
|
||||
*/
|
||||
int (*ops_enable_irq)(struct syna_hw_interface *hw_if,
|
||||
bool en);
|
||||
|
||||
/* Operation to wait for the signal of interrupt, if supported
|
||||
*
|
||||
* This is an optional operation to help for creating the
|
||||
* custom interrupt handler. Besides, the recommendation is to
|
||||
* implement in one-shot approach if possible.
|
||||
*
|
||||
* Implementation should return control if ATTN is asserted or
|
||||
* specified timeout expire. If timeout is 0, should check the
|
||||
* state of the ATTN signal and return control immediately.
|
||||
*
|
||||
* Assign the pointer NULL if customized ISR is not required.
|
||||
*
|
||||
* @param
|
||||
* [ in] hw_if: the handle of hw interface
|
||||
* [ in] timeout_ms: time frame in milliseconds
|
||||
*
|
||||
* @return
|
||||
* 0 on success; otherwise, on error.
|
||||
*/
|
||||
int (*ops_wait_irq)(struct syna_hw_interface *hw_if,
|
||||
unsigned int timeout_ms);
|
||||
|
||||
};
|
||||
/* end of structure syna_hw_interface */
|
||||
|
||||
|
||||
/**
|
||||
* syna_hw_interface_init()
|
||||
*
|
||||
* Initialize the lower-level hardware interface module.
|
||||
* After returning, the handle of hw interface should be ready.
|
||||
*
|
||||
* @param
|
||||
* void
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_hw_interface_init(void);
|
||||
|
||||
/**
|
||||
* syna_hw_interface_exit()
|
||||
*
|
||||
* Delete the lower-level hardware interface module.
|
||||
*
|
||||
* @param
|
||||
* void
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
void syna_hw_interface_exit(void);
|
||||
|
||||
|
||||
#endif /* end of _SYNAPTICS_TCM2_PLATFORM_H_ */
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
753
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2_runtime.h
Normal file
753
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2_runtime.h
Normal file
|
|
@ -0,0 +1,753 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file syna_tcm2_runtime.h
|
||||
*
|
||||
* This file abstracts platform-specific headers and C runtime APIs being used
|
||||
* on the target platform.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TCM2_C_RUNTIME_H_
|
||||
#define _SYNAPTICS_TCM2_C_RUNTIME_H_
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/firmware.h>
|
||||
#ifdef CONFIG_DRM_PANEL
|
||||
#include <drm/drm_panel.h>
|
||||
#elif CONFIG_FB
|
||||
#include <linux/fb.h>
|
||||
#include <linux/notifier.h>
|
||||
#endif
|
||||
#include <linux/fs.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
/**
|
||||
* @brief: DEV_MANAGED_API
|
||||
*
|
||||
* For linux kernel, managed interface was created for resources commonly
|
||||
* used by device drivers using devres.
|
||||
*
|
||||
* Open if willing to use managed-APIs rather than legacy APIs.
|
||||
*/
|
||||
#define DEV_MANAGED_API
|
||||
|
||||
#if defined(DEV_MANAGED_API) || defined(USE_DRM_PANEL_NOTIFIER)
|
||||
extern struct device *syna_request_managed_device(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @section: Log helpers
|
||||
*
|
||||
* @brief: LOGD
|
||||
* Output the debug message
|
||||
*
|
||||
* @brief: LOGI
|
||||
* Output the info message
|
||||
*
|
||||
* @brief: LOGN
|
||||
* Output the notice message
|
||||
*
|
||||
* @brief: LOGW
|
||||
* Output the warning message
|
||||
*
|
||||
* @brief: LOGE
|
||||
* Output the error message
|
||||
*/
|
||||
#define LOGD(log, ...) \
|
||||
pr_debug("[SYNA-debug] %s: " log, __func__, ##__VA_ARGS__)
|
||||
#define LOGI(log, ...) \
|
||||
pr_info("[SYNA-info] %s: " log, __func__, ##__VA_ARGS__)
|
||||
#define LOGN(log, ...) \
|
||||
pr_notice("[SYNA-info] %s: " log, __func__, ##__VA_ARGS__)
|
||||
#define LOGW(log, ...) \
|
||||
pr_warn("[SYNA-warning] %s: " log, __func__, ##__VA_ARGS__)
|
||||
#define LOGE(log, ...) \
|
||||
pr_err("[SYNA-error] %s: " log, __func__, ##__VA_ARGS__)
|
||||
|
||||
|
||||
/**
|
||||
* @section: Error Codes returned
|
||||
* Functions usually return 0 or positive value on success.
|
||||
* Thus, please defines negative value here.
|
||||
*/
|
||||
#define _EIO (-EIO) /* I/O errors */
|
||||
#define _ENOMEM (-ENOMEM) /* Out of memory */
|
||||
#define _EINVAL (-EINVAL) /* Invalid parameters */
|
||||
#define _ENODEV (-ENODEV) /* No such device */
|
||||
#define _ETIMEDOUT (-ETIMEDOUT) /* execution timeout */
|
||||
|
||||
|
||||
/**
|
||||
* @section: Data Comparison helpers
|
||||
*
|
||||
* @brief: MAX
|
||||
* Find the maximum value between
|
||||
*
|
||||
* @brief: MIN:
|
||||
* Find the minimum value between
|
||||
*
|
||||
* @brief: GET_BIT
|
||||
* Return the value of target bit
|
||||
*/
|
||||
#define MAX(a, b) \
|
||||
({__typeof__(a) _a = (a); \
|
||||
__typeof__(b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
#define MIN(a, b) \
|
||||
({__typeof__(a) _a = (a); \
|
||||
__typeof__(b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
#define GET_BIT(var, pos) \
|
||||
(((var) & (1 << (pos))) >> (pos))
|
||||
|
||||
|
||||
/**
|
||||
* @section: C Atomic operations
|
||||
*
|
||||
* @brief: ATOMIC_SET
|
||||
* Set an atomic data
|
||||
*
|
||||
* @brief: ATOMIC_GET:
|
||||
* Get an atomic data
|
||||
*/
|
||||
typedef atomic_t syna_pal_atomic_t;
|
||||
|
||||
#define ATOMIC_SET(atomic, value) \
|
||||
atomic_set(&atomic, value)
|
||||
|
||||
#define ATOMIC_GET(atomic) \
|
||||
atomic_read(&atomic)
|
||||
|
||||
|
||||
/**
|
||||
* @section: C Integer Calculation helpers
|
||||
*
|
||||
* @brief: syna_pal_le2_to_uint
|
||||
* Convert 2-byte data to an unsigned integer
|
||||
*
|
||||
* @brief: syna_pal_le4_to_uint
|
||||
* Convert 4-byte data to an unsigned integer
|
||||
*
|
||||
* @brief: syna_pal_ceil_div
|
||||
* Calculate the ceiling of the integer division
|
||||
*/
|
||||
|
||||
/**
|
||||
* syna_pal_le2_to_uint()
|
||||
*
|
||||
* Convert 2-byte data in little-endianness to an unsigned integer
|
||||
*
|
||||
* @param
|
||||
* [ in] src: 2-byte data in little-endianness
|
||||
*
|
||||
* @return
|
||||
* an unsigned integer converted
|
||||
*/
|
||||
static inline unsigned int syna_pal_le2_to_uint(const unsigned char *src)
|
||||
{
|
||||
return (unsigned int)src[0] +
|
||||
(unsigned int)src[1] * 0x100;
|
||||
}
|
||||
/**
|
||||
* syna_pal_le4_to_uint()
|
||||
*
|
||||
* Convert 4-byte data in little-endianness to an unsigned integer
|
||||
*
|
||||
* @param
|
||||
* [ in] src: 4-byte data in little-endianness
|
||||
*
|
||||
* @return
|
||||
* an unsigned integer converted
|
||||
*/
|
||||
static inline unsigned int syna_pal_le4_to_uint(const unsigned char *src)
|
||||
{
|
||||
return (unsigned int)src[0] +
|
||||
(unsigned int)src[1] * 0x100 +
|
||||
(unsigned int)src[2] * 0x10000 +
|
||||
(unsigned int)src[3] * 0x1000000;
|
||||
}
|
||||
/**
|
||||
* syna_pal_ceil_div()
|
||||
*
|
||||
* Calculate the ceiling of the integer division
|
||||
*
|
||||
* @param
|
||||
* [ in] dividend: the dividend value
|
||||
* [ in] divisor: the divisor value
|
||||
*
|
||||
* @return
|
||||
* the ceiling of the integer division
|
||||
*/
|
||||
static inline unsigned int syna_pal_ceil_div(unsigned int dividend,
|
||||
unsigned int divisor)
|
||||
{
|
||||
return (dividend + divisor - 1) / divisor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @section: C Runtime for Memory Management helpers
|
||||
*
|
||||
* @brief: syna_pal_mem_calloc
|
||||
* Allocate a block of memory space
|
||||
*
|
||||
* @brief: syna_pal_mem_free
|
||||
* Deallocate a block of memory previously allocated
|
||||
*
|
||||
* @brief: syna_pal_mem_set
|
||||
* Fill memory with a constant byte
|
||||
*
|
||||
* @brief: syna_pal_mem_cpy
|
||||
* Ensure the safe size before doing memory copy
|
||||
*/
|
||||
|
||||
/**
|
||||
* syna_pal_mem_calloc()
|
||||
*
|
||||
* Allocates a block of memory for an array of 'num' elements,
|
||||
* each of them has 'size' bytes long, and initializes all its bits to zero.
|
||||
*
|
||||
* @param
|
||||
* [ in] num: number of elements for an array
|
||||
* [ in] size: number of bytes for each elements
|
||||
*
|
||||
* @return
|
||||
* On success, a pointer to the memory block allocated by the function.
|
||||
*/
|
||||
static inline void *syna_pal_mem_alloc(unsigned int num, unsigned int size)
|
||||
{
|
||||
#ifdef DEV_MANAGED_API
|
||||
struct device *dev = syna_request_managed_device();
|
||||
|
||||
if (!dev) {
|
||||
LOGE("Invalid managed device\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((int)(num * size) <= 0) {
|
||||
LOGE("Invalid parameter\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEV_MANAGED_API
|
||||
return devm_kcalloc(dev, num, size, GFP_KERNEL);
|
||||
#else /* Legacy API */
|
||||
return kcalloc(num, size, GFP_KERNEL);
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* syna_pal_mem_free()
|
||||
*
|
||||
* Deallocate a block of memory previously allocated.
|
||||
*
|
||||
* @param
|
||||
* [ in] ptr: a memory block previously allocated
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_mem_free(void *ptr)
|
||||
{
|
||||
#ifdef DEV_MANAGED_API
|
||||
struct device *dev = syna_request_managed_device();
|
||||
|
||||
if (!dev) {
|
||||
LOGE("Invalid managed device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr)
|
||||
devm_kfree(dev, ptr);
|
||||
#else /* Legacy API */
|
||||
kfree(ptr);
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* syna_pal_mem_set()
|
||||
*
|
||||
* Fill memory with a constant byte
|
||||
*
|
||||
* @param
|
||||
* [ in] ptr: pointer to a memory block
|
||||
* [ in] c: the constant value
|
||||
* [ in] n: number of byte being set
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_mem_set(void *ptr, int c, unsigned int n)
|
||||
{
|
||||
memset(ptr, c, n);
|
||||
}
|
||||
/**
|
||||
* syna_pal_mem_cpy()
|
||||
*
|
||||
* Ensure the safe size before copying the values of num bytes from the
|
||||
* location to the memory block pointed to by destination.
|
||||
*
|
||||
* @param
|
||||
* [out] dest: pointer to the destination space
|
||||
* [ in] dest_size: size of destination array
|
||||
* [ in] src: pointer to the source of data to be copied
|
||||
* [ in] src_size: size of source array
|
||||
* [ in] num: number of bytes to copy
|
||||
*
|
||||
* @return
|
||||
* 0 on success; otherwise, on error.
|
||||
*/
|
||||
static inline int syna_pal_mem_cpy(void *dest, unsigned int dest_size,
|
||||
const void *src, unsigned int src_size, unsigned int num)
|
||||
{
|
||||
if (dest == NULL || src == NULL)
|
||||
return -1;
|
||||
|
||||
if (num > dest_size || num > src_size) {
|
||||
LOGE("Invalid size. src:%d, dest:%d, num:%d\n",
|
||||
src_size, dest_size, num);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy((void *)dest, (const void *)src, num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @section: C Runtime for Muxtex Control helpers
|
||||
*
|
||||
* @brief: syna_pal_mutex_alloc
|
||||
* Create a mutex object
|
||||
*
|
||||
* @brief: syna_pal_mutex_free
|
||||
* Release the mutex object previously allocated
|
||||
*
|
||||
* @brief: syna_pal_mutex_lock
|
||||
* Lock the mutex
|
||||
*
|
||||
* @brief: syna_pal_mutex_unlock
|
||||
* Unlock the mutex previously locked
|
||||
*/
|
||||
|
||||
typedef struct mutex syna_pal_mutex_t;
|
||||
|
||||
/**
|
||||
* syna_pal_mutex_alloc()
|
||||
*
|
||||
* Create a mutex object.
|
||||
*
|
||||
* @param
|
||||
* [out] ptr: pointer to the mutex handle being allocated
|
||||
*
|
||||
* @return
|
||||
* 0 on success; otherwise, on error.
|
||||
*/
|
||||
static inline int syna_pal_mutex_alloc(syna_pal_mutex_t *ptr)
|
||||
{
|
||||
mutex_init((struct mutex *)ptr);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* syna_pal_mutex_free()
|
||||
*
|
||||
* Release the mutex object previously allocated.
|
||||
*
|
||||
* @param
|
||||
* [ in] ptr: mutex handle previously allocated
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_mutex_free(syna_pal_mutex_t *ptr)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
/**
|
||||
* syna_pal_mutex_lock()
|
||||
*
|
||||
* Acquire/lock the mutex.
|
||||
*
|
||||
* @param
|
||||
* [ in] ptr: a mutex handle
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_mutex_lock(syna_pal_mutex_t *ptr)
|
||||
{
|
||||
mutex_lock((struct mutex *)ptr);
|
||||
}
|
||||
/**
|
||||
* syna_pal_mutex_unlock()
|
||||
*
|
||||
* Unlock the locked mutex.
|
||||
*
|
||||
* @param
|
||||
* [ in] ptr: a mutex handle
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_mutex_unlock(syna_pal_mutex_t *ptr)
|
||||
{
|
||||
mutex_unlock((struct mutex *)ptr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @section: C Runtime for Completion Event
|
||||
*
|
||||
* @brief: syna_pal_completion_alloc
|
||||
* Allocate a completion event
|
||||
*
|
||||
* @brief: syna_pal_completion_free
|
||||
* Release the completion event previously allocated
|
||||
*
|
||||
* @brief: syna_pal_completion_complete
|
||||
* Complete the completion event being waiting for
|
||||
*
|
||||
* @brief: syna_pal_completion_reset
|
||||
* Reset or reinitialize the completion event
|
||||
*
|
||||
* @brief: syna_pal_completion_wait_for
|
||||
* Wait for the completion event
|
||||
*/
|
||||
|
||||
typedef struct completion syna_pal_completion_t;
|
||||
|
||||
/**
|
||||
* syna_pal_completion_alloc()
|
||||
*
|
||||
* Allocate a completion event, and the default state is not set.
|
||||
* Caller must reset the event before each use.
|
||||
*
|
||||
* @param
|
||||
* [out] ptr: pointer to the completion handle being allocated
|
||||
*
|
||||
* @return
|
||||
* 0 on success; otherwise, on error.
|
||||
*/
|
||||
static inline int syna_pal_completion_alloc(syna_pal_completion_t *ptr)
|
||||
{
|
||||
init_completion((struct completion *)ptr);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* syna_pal_completion_free()
|
||||
*
|
||||
* Release the completion event previously allocated
|
||||
*
|
||||
* @param
|
||||
* [ in] ptr: the completion event previously allocated
|
||||
event
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_completion_free(syna_pal_completion_t *ptr)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
/**
|
||||
* syna_pal_completion_complete()
|
||||
*
|
||||
* Complete the completion event being waiting for
|
||||
*
|
||||
* @param
|
||||
* [ in] ptr: the completion event
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_completion_complete(syna_pal_completion_t *ptr)
|
||||
{
|
||||
complete((struct completion *)ptr);
|
||||
}
|
||||
/**
|
||||
* syna_pal_completion_reset()
|
||||
*
|
||||
* Reset or reinitialize the completion event
|
||||
*
|
||||
* @param
|
||||
* [ in] ptr: the completion event
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_completion_reset(syna_pal_completion_t *ptr)
|
||||
{
|
||||
#if (KERNEL_VERSION(3, 13, 0) > LINUX_VERSION_CODE)
|
||||
init_completion((struct completion *)ptr);
|
||||
#else
|
||||
reinit_completion((struct completion *)ptr);
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* syna_pal_completion_wait_for()
|
||||
*
|
||||
* Wait for the completion event during the given time slot
|
||||
*
|
||||
* @param
|
||||
* [ in] ptr: the completion event
|
||||
* [ in] timeout_ms: time frame in milliseconds
|
||||
*
|
||||
* @return
|
||||
* 0 if a signal is received; otherwise, on timeout or error occurs.
|
||||
*/
|
||||
static inline int syna_pal_completion_wait_for(syna_pal_completion_t *ptr,
|
||||
unsigned int timeout_ms)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = wait_for_completion_timeout((struct completion *)ptr,
|
||||
msecs_to_jiffies(timeout_ms));
|
||||
if (retval == 0) /* timeout occurs */
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @section: C Runtime to Pause the Execution
|
||||
*
|
||||
* @brief: syna_pal_sleep_ms
|
||||
* Sleep for a fixed amount of time in milliseconds
|
||||
*
|
||||
* @brief: syna_pal_sleep_us
|
||||
* Sleep for a range of time in microseconds
|
||||
*
|
||||
* @brief: syna_pal_busy_delay_ms
|
||||
* Busy wait for a fixed amount of time in milliseconds
|
||||
*/
|
||||
|
||||
/**
|
||||
* syna_pal_sleep_ms()
|
||||
*
|
||||
* Sleep for a fixed amount of time in milliseconds
|
||||
*
|
||||
* @param
|
||||
* [ in] time_ms: time frame in milliseconds
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_sleep_ms(int time_ms)
|
||||
{
|
||||
msleep(time_ms);
|
||||
}
|
||||
/**
|
||||
* syna_pal_sleep_us()
|
||||
*
|
||||
* Sleep for a range of time in microseconds
|
||||
*
|
||||
* @param
|
||||
* [ in] time_us_min: the min. time frame in microseconds
|
||||
* [ in] time_us_max: the max. time frame in microseconds
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_sleep_us(int time_us_min, int time_us_max)
|
||||
{
|
||||
usleep_range(time_us_min, time_us_max);
|
||||
}
|
||||
/**
|
||||
* syna_pal_busy_delay_ms()
|
||||
*
|
||||
* Busy wait for a fixed amount of time in milliseconds
|
||||
*
|
||||
* @param
|
||||
* [ in] time_ms: time frame in milliseconds
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
static inline void syna_pal_busy_delay_ms(int time_ms)
|
||||
{
|
||||
mdelay(time_ms);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @section: C Runtime for String operations
|
||||
*
|
||||
* @brief: syna_pal_str_len
|
||||
* Return the length of C string
|
||||
*
|
||||
* @brief: syna_pal_str_cpy:
|
||||
* Ensure the safe size before doing C string copy
|
||||
*
|
||||
* @brief: syna_pal_str_cmp:
|
||||
* Compare whether the given C strings are equal or not
|
||||
*/
|
||||
|
||||
/**
|
||||
* syna_pal_str_len()
|
||||
*
|
||||
* Return the length of C string
|
||||
*
|
||||
* @param
|
||||
* [ in] str: an array of characters
|
||||
*
|
||||
* @return
|
||||
* the length of given string
|
||||
*/
|
||||
static inline unsigned int syna_pal_str_len(const char *str)
|
||||
{
|
||||
return (unsigned int)strlen(str);
|
||||
}
|
||||
/**
|
||||
* syna_pal_str_cpy()
|
||||
*
|
||||
* Copy the C string pointed by source into the array pointed by destination.
|
||||
*
|
||||
* @param
|
||||
* [ in] dest: pointer to the destination C string
|
||||
* [ in] dest_size: size of destination C string
|
||||
* [out] src: pointer to the source of C string to be copied
|
||||
* [ in] src_size: size of source C string
|
||||
* [ in] num: number of bytes to copy
|
||||
*
|
||||
* @return
|
||||
* 0 on success; otherwise, on error.
|
||||
*/
|
||||
static inline int syna_pal_str_cpy(char *dest, unsigned int dest_size,
|
||||
const char *src, unsigned int src_size, unsigned int num)
|
||||
{
|
||||
if (dest == NULL || src == NULL)
|
||||
return -1;
|
||||
|
||||
if (num > dest_size || num > src_size) {
|
||||
LOGE("Invalid size. src:%d, dest:%d, num:%d\n",
|
||||
src_size, dest_size, num);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(dest, src, num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* syna_pal_str_cmp()
|
||||
*
|
||||
* Compares up to num characters of the C string str1 to those of the
|
||||
* C string str2.
|
||||
*
|
||||
* @param
|
||||
* [ in] str1: C string to be compared
|
||||
* [ in] str2: C string to be compared
|
||||
* [ in] num: number of characters to compare
|
||||
*
|
||||
* @return
|
||||
* 0 if both strings are equal; otherwise, not equal.
|
||||
*/
|
||||
static inline int syna_pal_str_cmp(const char *str1, const char *str2,
|
||||
unsigned int num)
|
||||
{
|
||||
return strncmp(str1, str2, num);
|
||||
}
|
||||
/**
|
||||
* syna_pal_hex_to_uint()
|
||||
*
|
||||
* Convert the given string in hex to an integer returned
|
||||
*
|
||||
* @param
|
||||
* [ in] str: C string to be converted
|
||||
* [ in] length: target length
|
||||
*
|
||||
* @return
|
||||
* An integer converted
|
||||
*/
|
||||
static inline unsigned int syna_pal_hex_to_uint(char *str, int length)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
char *ptr = NULL;
|
||||
|
||||
for (ptr = str; ptr != str + length; ++ptr) {
|
||||
result <<= 4;
|
||||
if (*ptr >= 'A')
|
||||
result += *ptr - 'A' + 10;
|
||||
else
|
||||
result += *ptr - '0';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @section: C Runtime for Checksum Calculation
|
||||
*
|
||||
* @brief: syna_pal_crc32
|
||||
* Calculates the CRC32 value
|
||||
*/
|
||||
|
||||
/**
|
||||
* syna_pal_crc32()
|
||||
*
|
||||
* Calculates the CRC32 value of the data
|
||||
*
|
||||
* @param
|
||||
* [ in] seed: the previous crc32 value
|
||||
* [ in] data: byte data for the calculation
|
||||
* [ in] len: the byte length of the data.
|
||||
*
|
||||
* @return
|
||||
* 0 if both strings are equal; otherwise, not equal.
|
||||
*/
|
||||
static inline unsigned int syna_pal_crc32(unsigned int seed,
|
||||
const char *data, unsigned int len)
|
||||
{
|
||||
return crc32(seed, data, len);
|
||||
}
|
||||
|
||||
#endif /* end of _SYNAPTICS_TCM2_C_RUNTIME_H_ */
|
||||
2290
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2_sysfs.c
Normal file
2290
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2_sysfs.c
Normal file
File diff suppressed because it is too large
Load diff
660
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2_testing.c
Normal file
660
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_tcm2_testing.c
Normal file
|
|
@ -0,0 +1,660 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file syna_tcm2_testing.c
|
||||
*
|
||||
* This file implements the sample code to perform chip testing.
|
||||
*/
|
||||
#include "syna_tcm2_testing.h"
|
||||
#include "syna_tcm2_testing_limits.h"
|
||||
#include "synaptics_touchcom_core_dev.h"
|
||||
#include "synaptics_touchcom_func_base.h"
|
||||
|
||||
/* g_testing_dir represents the root folder of testing sysfs
|
||||
*/
|
||||
static struct kobject *g_testing_dir;
|
||||
static struct syna_tcm *g_tcm_ptr;
|
||||
|
||||
|
||||
/**
|
||||
* syna_testing_compare_byte_vector()
|
||||
*
|
||||
* Sample code to compare the test result with limits
|
||||
* by byte vector
|
||||
*
|
||||
* @param
|
||||
* [ in] data: target test data
|
||||
* [ in] data_size: size of test data
|
||||
* [ in] limit: test limit value to be compared with
|
||||
* [ in] limit_size: size of test limit
|
||||
*
|
||||
* @return
|
||||
* on success, true; otherwise, return false
|
||||
*/
|
||||
static bool syna_testing_compare_byte_vector(unsigned char *data,
|
||||
unsigned int data_size, const unsigned char *limit,
|
||||
unsigned int limit_size)
|
||||
{
|
||||
bool result = false;
|
||||
unsigned char tmp;
|
||||
unsigned char p, l;
|
||||
int i, j;
|
||||
|
||||
if (!data || (data_size == 0)) {
|
||||
LOGE("Invalid test data\n");
|
||||
return false;
|
||||
}
|
||||
if (!limit || (limit_size == 0)) {
|
||||
LOGE("Invalid limits\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (limit_size < data_size) {
|
||||
LOGE("Limit size mismatched, data size: %d, limits: %d\n",
|
||||
data_size, limit_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = true;
|
||||
for (i = 0; i < data_size; i++) {
|
||||
tmp = data[i];
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
p = GET_BIT(tmp, j);
|
||||
l = GET_BIT(limit[i], j);
|
||||
if (p != l) {
|
||||
LOGE("Fail on TRX-%03d (data:%X, limit:%X)\n",
|
||||
(i*8 + j), p, l);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_testing_compare_frame()
|
||||
*
|
||||
* Sample code to compare the test result with limits
|
||||
* by a lower-bound frame
|
||||
*
|
||||
* @param
|
||||
* [ in] data: target test data
|
||||
* [ in] data_size: size of test data
|
||||
* [ in] rows: the number of rows
|
||||
* [ in] cols: the number of column
|
||||
* [ in] limits_hi: upper-bound test limit
|
||||
* [ in] limits_lo: lower-bound test limit
|
||||
*
|
||||
* @return
|
||||
* on success, true; otherwise, return false
|
||||
*/
|
||||
static bool syna_testing_compare_frame(unsigned char *data,
|
||||
unsigned int data_size, int rows, int cols,
|
||||
const short *limits_hi, const short *limits_lo)
|
||||
{
|
||||
bool result = false;
|
||||
short *data_ptr = NULL;
|
||||
short limit;
|
||||
int i, j;
|
||||
|
||||
if (!data || (data_size == 0)) {
|
||||
LOGE("Invalid test data\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data_size < (2 * rows * cols)) {
|
||||
LOGE("Size mismatched, data:%d (exppected:%d)\n",
|
||||
data_size, (2 * rows * cols));
|
||||
result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rows > LIMIT_BOUNDARY) {
|
||||
LOGE("Rows mismatched, rows:%d (exppected:%d)\n",
|
||||
rows, LIMIT_BOUNDARY);
|
||||
result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cols > LIMIT_BOUNDARY) {
|
||||
LOGE("Columns mismatched, cols: %d (exppected:%d)\n",
|
||||
cols, LIMIT_BOUNDARY);
|
||||
result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
result = true;
|
||||
|
||||
if (!limits_hi)
|
||||
goto end_of_upper_bound_limit;
|
||||
|
||||
data_ptr = (short *)&data[0];
|
||||
for (i = 0; i < rows; i++) {
|
||||
for (j = 0; j < cols; j++) {
|
||||
limit = limits_hi[i * LIMIT_BOUNDARY + j];
|
||||
if (*data_ptr > limit) {
|
||||
LOGE("Fail on (%2d,%2d)=%5d, limits_hi:%4d\n",
|
||||
i, j, *data_ptr, limit);
|
||||
result = false;
|
||||
}
|
||||
data_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
end_of_upper_bound_limit:
|
||||
|
||||
if (!limits_lo)
|
||||
goto end_of_lower_bound_limit;
|
||||
|
||||
data_ptr = (short *)&data[0];
|
||||
for (i = 0; i < rows; i++) {
|
||||
for (j = 0; j < cols; j++) {
|
||||
limit = limits_lo[i * LIMIT_BOUNDARY + j];
|
||||
if (*data_ptr < limit) {
|
||||
LOGE("Fail on (%2d,%2d)=%5d, limits_lo:%4d\n",
|
||||
i, j, *data_ptr, limit);
|
||||
result = false;
|
||||
}
|
||||
data_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
end_of_lower_bound_limit:
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_testing_device_id()
|
||||
*
|
||||
* Sample code to ensure the device id is expected
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
static int syna_testing_device_id(struct syna_tcm *tcm)
|
||||
{
|
||||
int retval;
|
||||
bool result;
|
||||
struct tcm_identification_info info;
|
||||
char *strptr = NULL;
|
||||
|
||||
LOGI("Start testing\n");
|
||||
|
||||
retval = syna_tcm_identify(tcm->tcm_dev, &info);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get identification\n");
|
||||
result = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
strptr = strnstr(info.part_number,
|
||||
device_id_limit,
|
||||
strlen(info.part_number));
|
||||
if (strptr != NULL)
|
||||
result = true;
|
||||
else {
|
||||
LOGE("Device ID mismatched, FW: %s (limit: %s)\n",
|
||||
info.part_number, device_id_limit);
|
||||
result = false;
|
||||
}
|
||||
|
||||
exit:
|
||||
LOGI("Result = %s\n", (result)?"pass":"fail");
|
||||
|
||||
return ((result) ? 0 : -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_testing_config_id()
|
||||
*
|
||||
* Sample code to ensure the config id is expected
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
static int syna_testing_config_id(struct syna_tcm *tcm)
|
||||
{
|
||||
int retval;
|
||||
bool result;
|
||||
struct tcm_application_info info;
|
||||
int idx;
|
||||
|
||||
LOGI("Start testing\n");
|
||||
|
||||
retval = syna_tcm_get_app_info(tcm->tcm_dev, &info);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get app info\n");
|
||||
result = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
result = true;
|
||||
for (idx = 0; idx < sizeof(config_id_limit); idx++) {
|
||||
if (config_id_limit[idx] != info.customer_config_id[idx]) {
|
||||
LOGE("Fail on byte.%d (data: %02X, limit: %02X)\n",
|
||||
idx, info.customer_config_id[idx],
|
||||
config_id_limit[idx]);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
LOGI("Result = %s\n", (result)?"pass":"fail");
|
||||
|
||||
return ((result) ? 0 : -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_testing_check_id_show()
|
||||
*
|
||||
* Attribute to show the result of ID comparsion to the console.
|
||||
*
|
||||
* @param
|
||||
* [ in] kobj: an instance of kobj
|
||||
* [ in] attr: an instance of kobj attribute structure
|
||||
* [out] buf: string buffer shown on console
|
||||
*
|
||||
* @return
|
||||
* on success, number of characters being output;
|
||||
* otherwise, negative value on error.
|
||||
*/
|
||||
static ssize_t syna_testing_check_id_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int retval;
|
||||
unsigned int count = 0;
|
||||
struct syna_tcm *tcm = g_tcm_ptr;
|
||||
|
||||
if (!tcm->is_connected) {
|
||||
retval = snprintf(buf, PAGE_SIZE,
|
||||
"Device is NOT connected\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
||||
retval = syna_testing_device_id(tcm);
|
||||
|
||||
retval = snprintf(buf, PAGE_SIZE - count,
|
||||
"Device ID check: %s\n",
|
||||
(retval < 0) ? "fail" : "pass");
|
||||
|
||||
buf += retval;
|
||||
count += retval;
|
||||
|
||||
retval = syna_testing_config_id(tcm);
|
||||
|
||||
retval = snprintf(buf, PAGE_SIZE - count,
|
||||
"Config ID check: %s\n",
|
||||
(retval < 0) ? "fail" : "pass");
|
||||
|
||||
buf += retval;
|
||||
count += retval;
|
||||
|
||||
retval = count;
|
||||
exit:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct kobj_attribute kobj_attr_check_id =
|
||||
__ATTR(check_id, 0444, syna_testing_check_id_show, NULL);
|
||||
|
||||
/**
|
||||
* syna_testing_pt01()
|
||||
*
|
||||
* Sample code to perform PT01 testing
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
static int syna_testing_pt01(struct syna_tcm *tcm)
|
||||
{
|
||||
int retval;
|
||||
bool result = false;
|
||||
struct tcm_buffer test_data;
|
||||
|
||||
syna_tcm_buf_init(&test_data);
|
||||
|
||||
LOGI("Start testing\n");
|
||||
|
||||
retval = syna_tcm_run_production_test(tcm->tcm_dev,
|
||||
TEST_PID01_TRX_TRX_SHORTS,
|
||||
&test_data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to run test %d\n", TEST_PID01_TRX_TRX_SHORTS);
|
||||
result = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
result = syna_testing_compare_byte_vector(test_data.buf,
|
||||
test_data.data_length,
|
||||
pt01_limits,
|
||||
ARRAY_SIZE(pt01_limits));
|
||||
|
||||
exit:
|
||||
LOGI("Result = %s\n", (result)?"pass":"fail");
|
||||
|
||||
syna_tcm_buf_release(&test_data);
|
||||
|
||||
return ((result) ? 0 : -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_testing_pt01_show()
|
||||
*
|
||||
* Attribute to show the result of PT01 test to the console.
|
||||
*
|
||||
* @param
|
||||
* [ in] kobj: an instance of kobj
|
||||
* [ in] attr: an instance of kobj attribute structure
|
||||
* [out] buf: string buffer shown on console
|
||||
*
|
||||
* @return
|
||||
* on success, number of characters being output;
|
||||
* otherwise, negative value on error.
|
||||
*/
|
||||
static ssize_t syna_testing_pt01_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int retval;
|
||||
unsigned int count = 0;
|
||||
struct syna_tcm *tcm = g_tcm_ptr;
|
||||
|
||||
if (!tcm->is_connected) {
|
||||
count = snprintf(buf, PAGE_SIZE,
|
||||
"Device is NOT connected\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
retval = syna_testing_pt01(tcm);
|
||||
|
||||
count = snprintf(buf, PAGE_SIZE,
|
||||
"TEST PT$01: %s\n",
|
||||
(retval < 0) ? "fail" : "pass");
|
||||
|
||||
exit:
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct kobj_attribute kobj_attr_pt01 =
|
||||
__ATTR(pt01, 0444, syna_testing_pt01_show, NULL);
|
||||
|
||||
/**
|
||||
* syna_testing_pt05()
|
||||
*
|
||||
* Sample code to perform PT05 testing
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
static int syna_testing_pt05(struct syna_tcm *tcm)
|
||||
{
|
||||
int retval;
|
||||
bool result = false;
|
||||
struct tcm_buffer test_data;
|
||||
|
||||
syna_tcm_buf_init(&test_data);
|
||||
|
||||
LOGI("Start testing\n");
|
||||
|
||||
retval = syna_tcm_run_production_test(tcm->tcm_dev,
|
||||
TEST_PID05_FULL_RAW_CAP,
|
||||
&test_data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to run test %d\n", TEST_PID05_FULL_RAW_CAP);
|
||||
result = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
result = syna_testing_compare_frame(test_data.buf,
|
||||
test_data.data_length,
|
||||
tcm->tcm_dev->rows,
|
||||
tcm->tcm_dev->cols,
|
||||
(const short *)&pt05_hi_limits[0],
|
||||
(const short *)&pt05_lo_limits[0]);
|
||||
|
||||
exit:
|
||||
LOGI("Result = %s\n", (result)?"pass":"fail");
|
||||
|
||||
syna_tcm_buf_release(&test_data);
|
||||
|
||||
return ((result) ? 0 : -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_testing_pt05_show()
|
||||
*
|
||||
* Attribute to show the result of PT05 test to the console.
|
||||
*
|
||||
* @param
|
||||
* [ in] kobj: an instance of kobj
|
||||
* [ in] attr: an instance of kobj attribute structure
|
||||
* [out] buf: string buffer shown on console
|
||||
*
|
||||
* @return
|
||||
* on success, number of characters being output;
|
||||
* otherwise, negative value on error.
|
||||
*/
|
||||
static ssize_t syna_testing_pt05_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int retval;
|
||||
unsigned int count = 0;
|
||||
struct syna_tcm *tcm = g_tcm_ptr;
|
||||
|
||||
if (!tcm->is_connected) {
|
||||
count = snprintf(buf, PAGE_SIZE,
|
||||
"Device is NOT connected\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
retval = syna_testing_pt05(tcm);
|
||||
|
||||
count = snprintf(buf, PAGE_SIZE,
|
||||
"TEST PT$05: %s\n", (retval < 0) ? "fail" : "pass");
|
||||
|
||||
exit:
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct kobj_attribute kobj_attr_pt05 =
|
||||
__ATTR(pt05, 0444, syna_testing_pt05_show, NULL);
|
||||
|
||||
/**
|
||||
* syna_testing_pt0a()
|
||||
*
|
||||
* Sample code to perform PT0A testing
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
static int syna_testing_pt0a(struct syna_tcm *tcm)
|
||||
{
|
||||
int retval;
|
||||
bool result = false;
|
||||
struct tcm_buffer test_data;
|
||||
|
||||
syna_tcm_buf_init(&test_data);
|
||||
|
||||
LOGI("Start testing\n");
|
||||
|
||||
retval = syna_tcm_run_production_test(tcm->tcm_dev,
|
||||
TEST_PID10_DELTA_NOISE,
|
||||
&test_data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to run test %d\n", TEST_PID10_DELTA_NOISE);
|
||||
result = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
result = syna_testing_compare_frame(test_data.buf,
|
||||
test_data.data_length,
|
||||
tcm->tcm_dev->rows,
|
||||
tcm->tcm_dev->cols,
|
||||
(const short *)&pt0a_hi_limits[0],
|
||||
(const short *)&pt0a_lo_limits[0]);
|
||||
|
||||
exit:
|
||||
LOGI("Result = %s\n", (result)?"pass":"fail");
|
||||
|
||||
syna_tcm_buf_release(&test_data);
|
||||
|
||||
return ((result) ? 0 : -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_testing_pt0a_show()
|
||||
*
|
||||
* Attribute to show the result of PT0A test to the console.
|
||||
*
|
||||
* @param
|
||||
* [ in] kobj: an instance of kobj
|
||||
* [ in] attr: an instance of kobj attribute structure
|
||||
* [out] buf: string buffer shown on console
|
||||
*
|
||||
* @return
|
||||
* on success, number of characters being output;
|
||||
* otherwise, negative value on error.
|
||||
*/
|
||||
static ssize_t syna_testing_pt0a_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int retval;
|
||||
unsigned int count = 0;
|
||||
struct syna_tcm *tcm = g_tcm_ptr;
|
||||
|
||||
if (!tcm->is_connected) {
|
||||
count = snprintf(buf, PAGE_SIZE,
|
||||
"Device is NOT connected\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
retval = syna_testing_pt0a(tcm);
|
||||
|
||||
count = snprintf(buf, PAGE_SIZE,
|
||||
"TEST PT$0A: %s\n", (retval < 0) ? "fail" : "pass");
|
||||
|
||||
exit:
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct kobj_attribute kobj_attr_pt0a =
|
||||
__ATTR(pt0a, 0444, syna_testing_pt0a_show, NULL);
|
||||
|
||||
/*
|
||||
* declaration of sysfs attributes
|
||||
*/
|
||||
static struct attribute *attrs[] = {
|
||||
&kobj_attr_check_id.attr,
|
||||
&kobj_attr_pt01.attr,
|
||||
&kobj_attr_pt05.attr,
|
||||
&kobj_attr_pt0a.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group attr_testing_group = {
|
||||
.attrs = attrs,
|
||||
};
|
||||
|
||||
/**
|
||||
* syna_testing_create_dir()
|
||||
*
|
||||
* Create a directory and register it with sysfs.
|
||||
* Then, create all defined sysfs files.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
* [ in] sysfs_dir: root directory of sysfs nodes
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_testing_create_dir(struct syna_tcm *tcm,
|
||||
struct kobject *sysfs_dir)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
g_testing_dir = kobject_create_and_add("testing",
|
||||
sysfs_dir);
|
||||
if (!g_testing_dir) {
|
||||
LOGE("Fail to create testing directory\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
retval = sysfs_create_group(g_testing_dir, &attr_testing_group);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to create sysfs group\n");
|
||||
|
||||
kobject_put(g_testing_dir);
|
||||
return retval;
|
||||
}
|
||||
|
||||
g_tcm_ptr = tcm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
*syna_testing_remove_dir()
|
||||
*
|
||||
* Remove the allocate sysfs directory
|
||||
*
|
||||
* @param
|
||||
* none
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
void syna_testing_remove_dir(void)
|
||||
{
|
||||
if (g_testing_dir) {
|
||||
sysfs_remove_group(g_testing_dir, &attr_testing_group);
|
||||
|
||||
kobject_put(g_testing_dir);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2018 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TCM2_TESTING_H_
|
||||
#define _SYNAPTICS_TCM2_TESTING_H_
|
||||
|
||||
#include "syna_tcm2.h"
|
||||
|
||||
/**
|
||||
* syna_testing_create_dir()
|
||||
*
|
||||
* Create a directory and register it with sysfs.
|
||||
* Then, create all defined sysfs files.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm: the driver handle
|
||||
* [ in] sysfs_dir: root directory of sysfs nodes
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_testing_create_dir(struct syna_tcm *tcm,
|
||||
struct kobject *sysfs_dir);
|
||||
/**
|
||||
*syna_testing_remove_dir()
|
||||
*
|
||||
* Remove the allocate sysfs directory
|
||||
*
|
||||
* @param
|
||||
* none
|
||||
*
|
||||
* @return
|
||||
* on success, 0; otherwise, negative value on error.
|
||||
*/
|
||||
void syna_testing_remove_dir(void);
|
||||
|
||||
|
||||
#endif /* end of _SYNAPTICS_TCM2_TESTING_H_ */
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2018 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TCM2_TESTING_LIMITS_H_
|
||||
#define _SYNAPTICS_TCM2_TESTING_LIMITS_H_
|
||||
|
||||
#define LIMIT_BOUNDARY (40)
|
||||
|
||||
/* test limit for the device id checking */
|
||||
static const char *device_id_limit = "3908";
|
||||
|
||||
/* test limit for the config id checking */
|
||||
static const unsigned char config_id_limit[16] = {
|
||||
0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/**
|
||||
* @section test limit for PT01 testing
|
||||
*/
|
||||
static const unsigned char pt01_limits[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/**
|
||||
* @section test limit for the PT05 testing
|
||||
*/
|
||||
static const short pt05_hi_limits[LIMIT_BOUNDARY * LIMIT_BOUNDARY] = {
|
||||
/* 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 */
|
||||
/* 00 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 01 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 02 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 03 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 04 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 05 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 06 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 07 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 08 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 09 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 10 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 11 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 12 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 13 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 14 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 15 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 16 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 17 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 18 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 19 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 20 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 21 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 22 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 23 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 24 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 25 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 26 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 27 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 28 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 29 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 30 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 31 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 32 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 33 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 34 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 35 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 36 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 37 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 38 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
/* 39 */ 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,
|
||||
};
|
||||
|
||||
static const short pt05_lo_limits[LIMIT_BOUNDARY * LIMIT_BOUNDARY] = {
|
||||
/* 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 */
|
||||
/* 00 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 01 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 02 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 03 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 04 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 05 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 06 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 07 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 08 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 09 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 10 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 11 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 12 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 13 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 14 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 15 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 16 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 17 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 18 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 19 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 20 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 21 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 22 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 23 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 24 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 25 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 26 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 27 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 28 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 29 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 30 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 31 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 32 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 33 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 34 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 35 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 36 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 37 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 38 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
/* 39 */ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
|
||||
};
|
||||
|
||||
/**
|
||||
* @section test limit for the PT0A testing
|
||||
*/
|
||||
static const short pt0a_hi_limits[LIMIT_BOUNDARY * LIMIT_BOUNDARY] = {
|
||||
/* 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 */
|
||||
/* 00 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 01 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 02 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 03 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 04 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 05 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 06 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 07 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 08 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 09 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 10 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 11 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 12 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 13 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 14 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 15 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 16 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 17 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 18 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 19 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 20 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 21 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 22 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 23 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 24 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 25 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 26 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 27 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 28 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 29 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 30 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 31 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 32 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 33 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 34 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 35 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 36 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 37 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 38 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
/* 39 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
};
|
||||
|
||||
static const short pt0a_lo_limits[LIMIT_BOUNDARY * LIMIT_BOUNDARY] = {
|
||||
/* 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 */
|
||||
/* 00 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 01 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 02 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 03 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 04 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 05 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 06 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 07 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 08 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 09 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 10 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 11 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 12 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 13 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 14 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 15 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 16 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 17 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 18 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 19 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 20 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 21 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 22 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 23 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 24 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 25 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 26 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 27 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 28 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 29 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 30 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 31 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 32 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 33 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 34 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 35 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 36 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 37 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 38 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
/* 39 */ -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, -20,
|
||||
};
|
||||
|
||||
#endif /* end of _SYNAPTICS_TCM2_TESTING_LIMITS_H_ */
|
||||
456
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_ts_mmi.c
Normal file
456
drivers/input/touchscreen/synaptics_tcm2_mmi/syna_ts_mmi.c
Normal file
|
|
@ -0,0 +1,456 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Motorola Mobility LLC
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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/gpio.h>
|
||||
#include <linux/touchscreen_mmi.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include "syna_tcm2_runtime.h"
|
||||
#include "syna_tcm2_platform.h"
|
||||
#include "syna_tcm2.h"
|
||||
#include "synaptics_touchcom_func_base.h"
|
||||
#include "synaptics_touchcom_func_reflash.h"
|
||||
|
||||
static int syna_ts_mmi_methods_get_vendor(struct device *dev, void *cdata)
|
||||
{
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "%s", "synaptics");
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_get_productinfo(struct device *dev, void *cdata)
|
||||
{
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if(!dev){
|
||||
LOGE("dev is null");
|
||||
}
|
||||
if(!dev->p){
|
||||
LOGE("dev->p is null");
|
||||
}
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
return scnprintf(TO_CHARP(cdata), 6, "%s", tcm->tcm_dev->id_info.part_number);
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_get_config_id(struct device *dev, void *cdata)
|
||||
{
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
unsigned int buildid;
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
buildid = tcm->tcm_dev->packrat_number;
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, "%d", buildid);
|
||||
}
|
||||
|
||||
/*return firmware version*/
|
||||
static int syna_ts_mmi_methods_get_build_id(struct device *dev, void *cdata)
|
||||
{
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, "%s", tcm->tcm_dev->app_info.customer_config_id);
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_get_bus_type(struct device *dev, void *idata)
|
||||
{
|
||||
const struct syna_hw_interface *hw_if;
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
hw_if = tcm->hw_if;
|
||||
if (!hw_if) {
|
||||
LOGE("Hardware interface not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
TO_INT(idata) = hw_if->bdata_io.type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_get_irq_status(struct device *dev, void *idata)
|
||||
{
|
||||
struct syna_hw_interface *hw_if;
|
||||
struct syna_hw_attn_data *attn;
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
hw_if = tcm->hw_if;
|
||||
if (!hw_if) {
|
||||
LOGE("Hardware interface not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
attn = &hw_if->bdata_attn;
|
||||
if (!attn) {
|
||||
LOGE("Failed to get ts attn");
|
||||
return -ENODEV;
|
||||
}
|
||||
TO_INT(idata) = gpio_get_value(attn->irq_gpio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_get_drv_irq(struct device *dev, void *idata)
|
||||
{
|
||||
struct syna_hw_attn_data *attn;
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
attn = &tcm->hw_if->bdata_attn;
|
||||
if (!attn) {
|
||||
LOGE("Failed to get ts attn");
|
||||
return -ENODEV;
|
||||
}
|
||||
TO_INT(idata) = attn->irq_enabled ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_get_poweron(struct device *dev, void *idata)
|
||||
{
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
TO_INT(idata) = tcm->pwr_state ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_get_flashprog(struct device *dev, void *idata)
|
||||
{
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
int app_status;
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
app_status = syna_pal_le2_to_uint(tcm->tcm_dev->app_info.status);
|
||||
if (IS_NOT_FW_MODE(tcm->tcm_dev->id_info.mode) ||
|
||||
app_status != APP_STATUS_OK)
|
||||
TO_INT(idata) = 1;
|
||||
else
|
||||
TO_INT(idata) = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_drv_irq(struct device *dev, int state)
|
||||
{
|
||||
int retval;
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
mutex_lock(&tcm->tp_event_mutex);
|
||||
if (state == 0) {
|
||||
retval = tcm->hw_if->ops_enable_irq(tcm->hw_if, false);
|
||||
goto exit;
|
||||
} else if (state == 1) {
|
||||
retval = tcm->hw_if->ops_enable_irq(tcm->hw_if, true);
|
||||
if (retval < 0) {
|
||||
LOGE("Failed to enable interrupt\n");
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
retval = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&tcm->tp_event_mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_reset(struct device *dev, int type)
|
||||
{
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (tcm->hw_if->ops_hw_reset)
|
||||
{
|
||||
tcm->hw_if->ops_hw_reset(tcm->hw_if);
|
||||
return 0;
|
||||
}
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static int syna_ts_firmware_update(struct device *dev, char *fwname) {
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
int retval;
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
LOGI("HW request update fw");
|
||||
|
||||
retval = syna_set_fw_name(tcm, fwname);
|
||||
if (retval < 0)
|
||||
{
|
||||
LOGE("Failed to set fw_name");
|
||||
return -EFAULT;
|
||||
}
|
||||
retval = syna_reflash_do_reflash(tcm, fwname);
|
||||
if (retval < 0)
|
||||
{
|
||||
LOGE("Failed to do reflash");
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_methods_power(struct device *dev, int on)
|
||||
{
|
||||
int retval;
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!on) {
|
||||
retval = 0;
|
||||
goto disable_pwr_reg;
|
||||
}
|
||||
|
||||
if (tcm->hw_if->bdata_pwr.vdd_reg_dev) {
|
||||
retval = regulator_enable(tcm->hw_if->bdata_pwr.vdd_reg_dev);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to enable vdd regulator\n");
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (tcm->hw_if->bdata_pwr.avdd_reg_dev) {
|
||||
retval = regulator_enable(tcm->hw_if->bdata_pwr.avdd_reg_dev);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to enable avdd regulator\n");
|
||||
goto disable_bus_reg;
|
||||
}
|
||||
syna_pal_sleep_ms(tcm->hw_if->bdata_pwr.power_on_delay_ms);
|
||||
}
|
||||
return 0;
|
||||
|
||||
disable_pwr_reg:
|
||||
if (tcm->hw_if->bdata_pwr.avdd_reg_dev)
|
||||
retval = regulator_enable(tcm->hw_if->bdata_pwr.avdd_reg_dev);
|
||||
disable_bus_reg:
|
||||
if (tcm->hw_if->bdata_pwr.vdd_reg_dev)
|
||||
retval = regulator_enable(tcm->hw_if->bdata_pwr.vdd_reg_dev);
|
||||
exit:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_pre_resume(struct device *dev)
|
||||
{
|
||||
int retval;
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
return -ENODEV;
|
||||
}
|
||||
if (tcm->pwr_state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
retval = syna_tcm_sleep(tcm->tcm_dev, false);
|
||||
if (retval < 0) {
|
||||
LOGE("Failed to exit deep sleep\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tcm->dev_resume(&tcm->pdev->dev);
|
||||
tcm->pwr_state = true;
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
tcm->pwr_state = false;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_post_suspend(struct device *dev)
|
||||
{
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!tcm->pwr_state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tcm->dev_suspend(&tcm->pdev->dev);
|
||||
|
||||
tcm->pwr_state = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int syna_ts_mmi_pre_suspend(struct device *dev)
|
||||
{
|
||||
struct syna_tcm *tcm;
|
||||
struct platform_device *pdev = dev_get_drvdata(dev);
|
||||
// int retval = 0;
|
||||
|
||||
if (!pdev) {
|
||||
LOGE("Failed to get platform device");
|
||||
return -ENODEV;
|
||||
}
|
||||
tcm = platform_get_drvdata(pdev);
|
||||
if (!tcm) {
|
||||
LOGE("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!tcm->pwr_state)
|
||||
return 0;
|
||||
|
||||
// retval = syna_dev_early_suspend(&tcm->pdev->dev);
|
||||
// if (retval < 0)
|
||||
// LOGE("early suspend fail");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ts_mmi_methods syna_ts_mmi_methods = {
|
||||
.get_vendor = syna_ts_mmi_methods_get_vendor,
|
||||
.get_productinfo = syna_ts_mmi_methods_get_productinfo,
|
||||
.get_build_id = syna_ts_mmi_methods_get_build_id,
|
||||
.get_config_id = syna_ts_mmi_methods_get_config_id,
|
||||
.get_bus_type = syna_ts_mmi_methods_get_bus_type,
|
||||
.get_irq_status = syna_ts_mmi_methods_get_irq_status,
|
||||
.get_drv_irq = syna_ts_mmi_methods_get_drv_irq,
|
||||
.get_flashprog = syna_ts_mmi_methods_get_flashprog,
|
||||
.get_poweron = syna_ts_mmi_methods_get_poweron,
|
||||
/* SET methods */
|
||||
.reset = syna_ts_mmi_methods_reset,
|
||||
.drv_irq = syna_ts_mmi_methods_drv_irq,
|
||||
.power = syna_ts_mmi_methods_power,
|
||||
/* Firmware */
|
||||
.firmware_update = syna_ts_firmware_update,
|
||||
/* PM callback */
|
||||
.pre_resume = syna_ts_mmi_pre_resume,
|
||||
.pre_suspend = syna_ts_mmi_pre_suspend,
|
||||
.post_suspend = syna_ts_mmi_post_suspend,
|
||||
};
|
||||
|
||||
int syna_ts_mmi_dev_register(struct syna_tcm *tcm) {
|
||||
int ret;
|
||||
ret = ts_mmi_dev_register(tcm->pdev->dev.parent, &syna_ts_mmi_methods);
|
||||
if (ret) {
|
||||
LOGE("Failed to register ts mmi ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void syna_ts_mmi_dev_unregister(struct syna_tcm *tcm) {
|
||||
ts_mmi_dev_unregister(tcm->pdev->dev.parent);
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,460 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file synaptics_touchcom_func_base.h
|
||||
*
|
||||
* This file declares generic and foundational APIs being used to communicate
|
||||
* with Synaptics touch controller through TouchComm communication protocol.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TOUCHCOM_BASE_FUNCS_H_
|
||||
#define _SYNAPTICS_TOUCHCOM_BASE_FUNCS_H_
|
||||
|
||||
#include "synaptics_touchcom_core_dev.h"
|
||||
|
||||
/**
|
||||
* syna_tcm_allocate_device()
|
||||
*
|
||||
* Create the TouchCom core device handle.
|
||||
* This function must be called in order to allocate the main device handle,
|
||||
* structure syna_tcm_dev, which will be passed to all other operations and
|
||||
* functions within the entire source code.
|
||||
*
|
||||
* Meanwhile, caller has to prepare specific syna_tcm_hw_interface structure,
|
||||
* so that all the implemented functions can access hardware components
|
||||
* through syna_tcm_hw_interface.
|
||||
*
|
||||
* @param
|
||||
* [out] ptcm_dev_ptr: a pointer to the device handle returned
|
||||
* [ in] hw_if: hardware-specific data on target platform
|
||||
* [ in] resp_reading: default resp reading method
|
||||
* set 'RESP_IN_ATTN' to apply ATTN-driven method;
|
||||
* set 'RESP_IN_POLLING' to read in resp by polling
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_allocate_device(struct tcm_dev **ptcm_dev_ptr,
|
||||
struct syna_hw_interface *hw_if, unsigned int resp_reading);
|
||||
|
||||
/**
|
||||
* syna_tcm_remove_device()
|
||||
*
|
||||
* Remove the TouchCom core device handle.
|
||||
* This function must be invoked when the device is no longer needed.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
*
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
void syna_tcm_remove_device(struct tcm_dev *tcm_dev);
|
||||
|
||||
/**
|
||||
* syna_tcm_detect_device()
|
||||
*
|
||||
* Determine the type of device being connected and distinguish which
|
||||
* version of TouchCom firmware running on the device.
|
||||
* This function should be called before using this TouchComm core library.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
*
|
||||
* @return
|
||||
* on success, the current mode running on the device is returned;
|
||||
* otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_detect_device(struct tcm_dev *tcm_dev);
|
||||
|
||||
/**
|
||||
* syna_tcm_get_event_data()
|
||||
*
|
||||
* Helper to read TouchComm messages when ATTN signal is asserted.
|
||||
* After returning, the ATTN signal should be no longer asserted.
|
||||
*
|
||||
* The 'code' returned will guide the caller on the next action.
|
||||
* For example, do touch reporting once returned code is equal to REPORT_TOUCH.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [out] code: received report code
|
||||
* [out] report: report data returned
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_get_event_data(struct tcm_dev *tcm_dev,
|
||||
unsigned char *code,
|
||||
struct tcm_buffer *report);
|
||||
|
||||
/**
|
||||
* syna_tcm_change_resp_read()
|
||||
*
|
||||
* Helper to change the default resp reading method, which was previously set
|
||||
* when calling syna_tcm_allocate_device
|
||||
*
|
||||
* @param
|
||||
* [in] tcm_dev: the device handle
|
||||
* [in] request: resp reading method to change
|
||||
* set '0' or 'RESP_IN_ATTN' for ATTN-driven; otherwise,
|
||||
* assign a positive value standing for the polling time
|
||||
* @return
|
||||
* none.
|
||||
*/
|
||||
void syna_tcm_change_resp_read(struct tcm_dev *tcm_dev, unsigned int request);
|
||||
|
||||
/**
|
||||
* syna_tcm_identify()
|
||||
*
|
||||
* Implement the standard command code, which is used to request
|
||||
* an IDENTIFY report packet
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [out] id_info: the identification info packet returned
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_identify(struct tcm_dev *tcm_dev,
|
||||
struct tcm_identification_info *id_info);
|
||||
|
||||
/**
|
||||
* syna_tcm_reset()
|
||||
*
|
||||
* Implement the standard command code, which is used to perform a sw reset
|
||||
* immediately. After a successful reset, an IDENTIFY report to indicate that
|
||||
* device is ready.
|
||||
*
|
||||
* Caller shall be aware that the firmware will be reloaded after reset.
|
||||
* Therefore, if expecting that a different firmware version is loaded, please
|
||||
* do app firmware setup after reset.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_reset(struct tcm_dev *tcm_dev);
|
||||
|
||||
/**
|
||||
* syna_tcm_enable_report()
|
||||
*
|
||||
* Implement the application fw command code to enable or disable a report.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] report_code: the requested report code being generated
|
||||
* [ in] en: '1' for enabling; '0' for disabling
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_enable_report(struct tcm_dev *tcm_dev,
|
||||
unsigned char report_code, bool en);
|
||||
|
||||
/**
|
||||
* syna_tcm_switch_fw_mode()
|
||||
*
|
||||
* Implement the command code to switch the firmware mode.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] mode: target firmware mode
|
||||
* [ in] fw_switch_delay: delay time for fw mode switching.
|
||||
* a positive value presents the time for polling;
|
||||
* or, set '0' or 'RESP_IN_ATTN' for ATTN driven
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_switch_fw_mode(struct tcm_dev *tcm_dev,
|
||||
unsigned char mode, unsigned int fw_switch_delay);
|
||||
|
||||
/**
|
||||
* syna_tcm_get_boot_info()
|
||||
*
|
||||
* Implement the bootloader command code, which is used to request a
|
||||
* boot information packet.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [out] boot_info: the boot info packet returned
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_get_boot_info(struct tcm_dev *tcm_dev,
|
||||
struct tcm_boot_info *boot_info);
|
||||
|
||||
/**
|
||||
* syna_tcm_get_app_info()
|
||||
*
|
||||
* Implement the application fw command code to request an application
|
||||
* info packet from device
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [out] app_info: the application info packet returned
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_get_app_info(struct tcm_dev *tcm_dev,
|
||||
struct tcm_application_info *app_info);
|
||||
|
||||
/**
|
||||
* syna_tcm_get_static_config()
|
||||
*
|
||||
* Implement the application fw command code to retrieve the contents of
|
||||
* the static configuration.
|
||||
*
|
||||
* The size of static configuration is available in app info packet.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [out] buf: buffer stored the static configuration
|
||||
* [ in] buf_size: the size of given buffer
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_get_static_config(struct tcm_dev *tcm_dev,
|
||||
unsigned char *buf, unsigned int buf_size);
|
||||
|
||||
/**
|
||||
* syna_tcm_set_static_config()
|
||||
*
|
||||
* Implement the application fw command code to set the contents of
|
||||
* the static configuration. When the write is completed, the device will
|
||||
* restart touch sensing with the new settings
|
||||
*
|
||||
* The size of static configuration is available in app info packet.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] config_data: the data of static configuration
|
||||
* [ in] config_data_size: the size of given data
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_static_config(struct tcm_dev *tcm_dev,
|
||||
unsigned char *config_data, unsigned int config_data_size);
|
||||
|
||||
/**
|
||||
* syna_tcm_get_dynamic_config()
|
||||
*
|
||||
* Implement the application fw command code to get the value from the a single
|
||||
* field of the dynamic configuration
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] id: target field id
|
||||
* [out] value: the value returned
|
||||
* [ in] delay_ms_resp: delay time for response reading.
|
||||
* a positive value presents the time for polling;
|
||||
* or, set '0' or 'RESP_IN_ATTN' for ATTN driven
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_get_dynamic_config(struct tcm_dev *tcm_dev,
|
||||
unsigned char id, unsigned short *value,
|
||||
unsigned int delay_ms_resp);
|
||||
|
||||
/**
|
||||
* syna_tcm_set_dynamic_config()
|
||||
*
|
||||
* Implement the application fw command code to set the specified value to
|
||||
* the selected field of the dynamic configuration
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] id: target field id
|
||||
* [ in] value: the value to the selected field
|
||||
* [ in] delay_ms_resp: delay time for response reading.
|
||||
* a positive value presents the time for polling;
|
||||
* or, set '0' or 'RESP_IN_ATTN' for ATTN driven
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_dynamic_config(struct tcm_dev *tcm_dev,
|
||||
unsigned char id, unsigned short value,
|
||||
unsigned int delay_ms_resp);
|
||||
|
||||
/**
|
||||
* syna_tcm_rezero()
|
||||
*
|
||||
* Implement the application fw command code to force the device to rezero its
|
||||
* baseline estimate.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_rezero(struct tcm_dev *tcm_dev);
|
||||
|
||||
/**
|
||||
* syna_tcm_set_config_id()
|
||||
*
|
||||
* Implement the application fw command code to set the 16-byte config id,
|
||||
* which can be read in the app info packet.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] config_id: config id to be set
|
||||
* [ in] size: size of input data
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_config_id(struct tcm_dev *tcm_dev,
|
||||
unsigned char *config_id, unsigned int size);
|
||||
|
||||
/**
|
||||
* syna_tcm_sleep()
|
||||
*
|
||||
* Implement the application fw command code to put the device into low power
|
||||
* deep sleep mode or set to normal active mode
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] en: '1' to low power deep sleep mode; '0' to active mode
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_sleep(struct tcm_dev *tcm_dev, bool en);
|
||||
|
||||
/**
|
||||
* syna_tcm_get_features()
|
||||
*
|
||||
* Implement the application fw command code to query the supported features.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [out] info: the features description packet returned
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_get_features(struct tcm_dev *tcm_dev,
|
||||
struct tcm_features_info *info);
|
||||
|
||||
/**
|
||||
* syna_tcm_run_production_test()
|
||||
*
|
||||
* Implement the appplication fw command code to request the device to run
|
||||
* the production test.
|
||||
*
|
||||
* Production tests are listed at enum test_code (PID$).
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] test_item: the requested testing item
|
||||
* [out] tdata: testing data returned
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_run_production_test(struct tcm_dev *tcm_dev,
|
||||
unsigned char test_item, struct tcm_buffer *tdata);
|
||||
|
||||
/**
|
||||
* syna_tcm_send_command()
|
||||
*
|
||||
* Helper to forward the custom commnd to the device
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] command: TouchComm command
|
||||
* [ in] payload: data payload, if any
|
||||
* [ in] payload_length: length of data payload, if any
|
||||
* [out] resp_code: response code returned
|
||||
* [out] resp: buffer to store the response data
|
||||
* [ in] delay_ms_resp: delay time for response reading.
|
||||
* a positive value presents the time for polling;
|
||||
* or, set '0' or 'RESP_IN_ATTN' for ATTN driven
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_send_command(struct tcm_dev *tcm_dev,
|
||||
unsigned char command, unsigned char *payload,
|
||||
unsigned int payload_length, unsigned char *resp_code,
|
||||
struct tcm_buffer *resp, unsigned int delay_ms_resp);
|
||||
|
||||
/**
|
||||
* syna_tcm_enable_predict_reading()
|
||||
*
|
||||
* predict reading aims to retrieve all data in one transfer;
|
||||
* while, standard reads will read 4-byte header and payload data separately
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] en: '1' to low power deep sleep mode; '0' to active mode
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_enable_predict_reading(struct tcm_dev *tcm_dev, bool en);
|
||||
/**
|
||||
* syna_tcm_get_message_crc()
|
||||
*
|
||||
* this function is used to return the crc of message retrieved previously
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
*
|
||||
* @return
|
||||
* 2 bytes crc value
|
||||
*/
|
||||
unsigned short syna_tcm_get_message_crc(struct tcm_dev *tcm_dev);
|
||||
/**
|
||||
* syna_tcm_set_reset_occurrence_callback()
|
||||
*
|
||||
* Set up callback function once an unexpected reset received
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] p_cb: the pointer of callback function
|
||||
* [ in] p_cbdata: pointer to caller data
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_reset_occurrence_callback(struct tcm_dev *tcm_dev,
|
||||
tcm_reset_occurrence_callback_t p_cb, void *p_cbdata);
|
||||
|
||||
|
||||
#endif /* end of _SYNAPTICS_TOUCHCOM_BASE_FUNCS_H_ */
|
||||
|
|
@ -0,0 +1,569 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file synaptics_touchcom_func_base_flash.h
|
||||
*
|
||||
* This file declares the common functions and structures being used in relevant
|
||||
* functions of fw update.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TOUCHCOM_PARSE_FW_FILES_H_
|
||||
#define _SYNAPTICS_TOUCHCOM_PARSE_FW_FILES_H_
|
||||
|
||||
#include "synaptics_touchcom_core_dev.h"
|
||||
|
||||
/**
|
||||
* @section: Some specific definition in the firmware file
|
||||
*/
|
||||
#define ID_STRING_SIZE (32)
|
||||
|
||||
#define SIZE_WORDS (8)
|
||||
|
||||
#define IHEX_RECORD_SIZE (14)
|
||||
|
||||
#define IHEX_MAX_BLOCKS (64)
|
||||
|
||||
#define IMAGE_FILE_MAGIC_VALUE (0x4818472b)
|
||||
|
||||
#define FLASH_AREA_MAGIC_VALUE (0x7c05e516)
|
||||
|
||||
|
||||
/**
|
||||
* @section: Helper macros for firmware file parsing
|
||||
*/
|
||||
#define CRC32(data, length) \
|
||||
(syna_pal_crc32(~0, data, length) ^ ~0)
|
||||
|
||||
#define VALUE(value) \
|
||||
(syna_pal_le2_to_uint(value))
|
||||
|
||||
#define AREA_ID_STR(area) \
|
||||
(syna_tcm_get_flash_area_string(area))
|
||||
|
||||
|
||||
/**
|
||||
* @section: Area Partitions in firmware
|
||||
*/
|
||||
enum flash_area {
|
||||
AREA_NONE = 0,
|
||||
/* please add the declarations below */
|
||||
|
||||
AREA_BOOT_CODE,
|
||||
AREA_BOOT_CONFIG,
|
||||
AREA_APP_CODE,
|
||||
AREA_APP_CODE_COPRO,
|
||||
AREA_APP_CONFIG,
|
||||
AREA_PROD_TEST,
|
||||
AREA_DISP_CONFIG,
|
||||
AREA_F35_APP_CODE,
|
||||
AREA_FORCE_TUNING,
|
||||
AREA_GAMMA_TUNING,
|
||||
AREA_TEMPERATURE_GAMM_TUNING,
|
||||
AREA_CUSTOM_LCM,
|
||||
AREA_LOOKUP,
|
||||
AREA_CUSTOM_OEM,
|
||||
AREA_OPEN_SHORT_TUNING,
|
||||
AREA_CUSTOM_OTP,
|
||||
AREA_PPDT,
|
||||
AREA_ROMBOOT_APP_CODE,
|
||||
AREA_TOOL_BOOT_CONFIG,
|
||||
|
||||
/* please add the declarations above */
|
||||
AREA_MAX,
|
||||
};
|
||||
/**
|
||||
* @section: String of Area Partitions in firmware
|
||||
*/
|
||||
static char *flash_area_str[] = {
|
||||
NULL,
|
||||
/* please add the declarations below */
|
||||
|
||||
"BOOT_CODE", /* AREA_BOOT_CODE */
|
||||
"BOOT_CONFIG", /* AREA_BOOT_CONFIG */
|
||||
"APP_CODE", /* AREA_APP_CODE */
|
||||
"APP_CODE_COPRO", /* AREA_APP_CODE_COPRO */
|
||||
"APP_CONFIG", /* AREA_APP_CONFIG */
|
||||
"APP_PROD_TEST", /* AREA_PROD_TEST */
|
||||
"DISPLAY", /* AREA_DISP_CONFIG */
|
||||
"F35_APP_CODE", /* AREA_F35_APP_CODE */
|
||||
"FORCE", /* AREA_FORCE_TUNING */
|
||||
"GAMMA", /* AREA_GAMMA_TUNING */
|
||||
"TEMPERATURE_GAMM",/* AREA_TEMPERATURE_GAMM_TUNING */
|
||||
"LCM", /* AREA_CUSTOM_LCM */
|
||||
"LOOKUP", /* AREA_LOOKUP */
|
||||
"OEM", /* AREA_CUSTOM_OEM */
|
||||
"OPEN_SHORT", /* AREA_OPEN_SHORT_TUNING */
|
||||
"OTP", /* AREA_CUSTOM_OTP */
|
||||
"PPDT", /* AREA_PPDT */
|
||||
"ROMBOOT_APP_CODE",/* AREA_ROMBOOT_APP_CODE */
|
||||
"TOOL_BOOT_CONFIG",/* AREA_TOOL_BOOT_CONFIG */
|
||||
|
||||
/* please add the declarations above */
|
||||
NULL
|
||||
};
|
||||
/**
|
||||
* @section: Header Content of app config defined
|
||||
* in firmware file
|
||||
*/
|
||||
struct app_config_header {
|
||||
unsigned short magic_value[4];
|
||||
unsigned char checksum[4];
|
||||
unsigned char length[2];
|
||||
unsigned char build_id[4];
|
||||
unsigned char customer_config_id[16];
|
||||
};
|
||||
/**
|
||||
* @section: The Partition Descriptor defined
|
||||
* in firmware file
|
||||
*/
|
||||
struct area_descriptor {
|
||||
unsigned char magic_value[4];
|
||||
unsigned char id_string[16];
|
||||
unsigned char flags[4];
|
||||
unsigned char flash_addr_words[4];
|
||||
unsigned char length[4];
|
||||
unsigned char checksum[4];
|
||||
};
|
||||
/**
|
||||
* @section: Structure for the Data Block defined
|
||||
* in firmware file
|
||||
*/
|
||||
struct block_data {
|
||||
bool available;
|
||||
const unsigned char *data;
|
||||
unsigned int size;
|
||||
unsigned int flash_addr;
|
||||
unsigned char id;
|
||||
};
|
||||
/**
|
||||
* @section: Structure for the Parsed Image File
|
||||
*/
|
||||
struct image_info {
|
||||
struct block_data data[AREA_MAX];
|
||||
};
|
||||
/**
|
||||
* @section: Header of Image File
|
||||
*
|
||||
* Define the header of firmware image file
|
||||
*/
|
||||
struct image_header {
|
||||
unsigned char magic_value[4];
|
||||
unsigned char num_of_areas[4];
|
||||
};
|
||||
/**
|
||||
* @section: Structure for the Parsed iHex File
|
||||
*/
|
||||
struct ihex_info {
|
||||
unsigned int records;
|
||||
unsigned char *bin;
|
||||
unsigned int bin_size;
|
||||
struct block_data block[IHEX_MAX_BLOCKS];
|
||||
};
|
||||
|
||||
/**
|
||||
* syna_tcm_get_flash_area_string()
|
||||
*
|
||||
* Return the string ID of target area in the flash memory
|
||||
*
|
||||
* @param
|
||||
* [ in] area: target flash area
|
||||
*
|
||||
* @return
|
||||
* the string ID
|
||||
*/
|
||||
static inline char *syna_tcm_get_flash_area_string(enum flash_area area)
|
||||
{
|
||||
if (area < AREA_MAX)
|
||||
return (char *)flash_area_str[area];
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_save_flash_block_data()
|
||||
*
|
||||
* Save the block data of flash memory to the corresponding structure.
|
||||
*
|
||||
* @param
|
||||
* [out] image_info: image info used for storing the block data
|
||||
* [ in] area: target area
|
||||
* [ in] content: content of data
|
||||
* [ in] flash_addr: offset of block data
|
||||
* [ in] size: size of block data
|
||||
* [ in] checksum: checksum of block data
|
||||
*
|
||||
* @return
|
||||
* on success, return 0; otherwise, negative value on error.
|
||||
*/
|
||||
static int syna_tcm_save_flash_block_data(struct image_info *image_info,
|
||||
enum flash_area area, const unsigned char *content,
|
||||
unsigned int offset, unsigned int size, unsigned int checksum)
|
||||
{
|
||||
if (!image_info) {
|
||||
LOGE("Invalid image_info\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (area >= AREA_MAX) {
|
||||
LOGE("Invalid flash area\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (checksum != CRC32((const char *)content, size)) {
|
||||
LOGE("%s checksum error, in image: 0x%x (0x%x)\n",
|
||||
AREA_ID_STR(area), checksum,
|
||||
CRC32((const char *)content, size));
|
||||
return _EINVAL;
|
||||
}
|
||||
image_info->data[area].size = size;
|
||||
image_info->data[area].data = content;
|
||||
image_info->data[area].flash_addr = offset;
|
||||
image_info->data[area].id = (unsigned char)area;
|
||||
image_info->data[area].available = true;
|
||||
|
||||
LOGI("%s area - address:0x%08x (%d), size:%d\n",
|
||||
AREA_ID_STR(area), offset, offset, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_get_flash_area_id()
|
||||
*
|
||||
* Return the corresponding ID of flash area based on the given string
|
||||
*
|
||||
* @param
|
||||
* [ in] str: string to look for
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* if matching, return the corresponding ID; otherwise, return AREA_MAX.
|
||||
*/
|
||||
static enum flash_area syna_tcm_get_flash_area_id(char *str)
|
||||
{
|
||||
int area;
|
||||
char *target;
|
||||
unsigned int len;
|
||||
|
||||
for (area = AREA_MAX - 1; area >= 0; area--) {
|
||||
target = AREA_ID_STR(area);
|
||||
len = syna_pal_str_len(target);
|
||||
|
||||
if (syna_pal_str_cmp(str, target, len) == 0)
|
||||
return area;
|
||||
}
|
||||
|
||||
LOGW("Un-defined area string, %s\n", str);
|
||||
return AREA_MAX;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_parse_fw_image()
|
||||
*
|
||||
* Parse and analyze the information of each areas from the given
|
||||
* firmware image.
|
||||
*
|
||||
* @param
|
||||
* [ in] image: image file given
|
||||
* [ in] image_info: data blob stored the parsed data from an image file
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
static inline int syna_tcm_parse_fw_image(const unsigned char *image,
|
||||
struct image_info *image_info)
|
||||
{
|
||||
int retval = 0;
|
||||
unsigned int idx;
|
||||
unsigned int addr;
|
||||
unsigned int offset;
|
||||
unsigned int length;
|
||||
unsigned int checksum;
|
||||
unsigned int flash_addr;
|
||||
unsigned int magic_value;
|
||||
unsigned int num_of_areas;
|
||||
struct image_header *header;
|
||||
struct area_descriptor *descriptor;
|
||||
const unsigned char *content;
|
||||
enum flash_area target_area;
|
||||
|
||||
if (!image) {
|
||||
LOGE("No image data\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (!image_info) {
|
||||
LOGE("Invalid image_info blob\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
syna_pal_mem_set(image_info, 0x00, sizeof(struct image_info));
|
||||
|
||||
header = (struct image_header *)image;
|
||||
|
||||
magic_value = syna_pal_le4_to_uint(header->magic_value);
|
||||
if (magic_value != IMAGE_FILE_MAGIC_VALUE) {
|
||||
LOGE("Invalid image file magic value\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
offset = sizeof(struct image_header);
|
||||
num_of_areas = syna_pal_le4_to_uint(header->num_of_areas);
|
||||
|
||||
for (idx = 0; idx < num_of_areas; idx++) {
|
||||
addr = syna_pal_le4_to_uint(image + offset);
|
||||
descriptor = (struct area_descriptor *)(image + addr);
|
||||
offset += 4;
|
||||
|
||||
magic_value = syna_pal_le4_to_uint(descriptor->magic_value);
|
||||
if (magic_value != FLASH_AREA_MAGIC_VALUE)
|
||||
continue;
|
||||
|
||||
length = syna_pal_le4_to_uint(descriptor->length);
|
||||
content = (unsigned char *)descriptor + sizeof(*descriptor);
|
||||
flash_addr = syna_pal_le4_to_uint(descriptor->flash_addr_words);
|
||||
flash_addr = flash_addr * 2;
|
||||
checksum = syna_pal_le4_to_uint(descriptor->checksum);
|
||||
|
||||
target_area = syna_tcm_get_flash_area_id(
|
||||
(char *)descriptor->id_string);
|
||||
|
||||
retval = syna_tcm_save_flash_block_data(image_info,
|
||||
target_area,
|
||||
content,
|
||||
flash_addr,
|
||||
length,
|
||||
checksum);
|
||||
if (retval < 0)
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* syna_tcm_parse_ihex_line()
|
||||
*
|
||||
* Parse a line in the ihex file and convert into an actual data
|
||||
*
|
||||
* @param
|
||||
* [ in] line: a line of string stored in the ihex file
|
||||
* [out] count: size of actual data
|
||||
* [out] addr: address of data located
|
||||
* [out] type: the type of data belonging
|
||||
* [out] buf: a buffer to store the converted data
|
||||
* [int] buf_size: size of buffer
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
static inline int syna_tcm_parse_ihex_line(char *line, unsigned int *count,
|
||||
unsigned int *addr, unsigned int *type, unsigned char *buf,
|
||||
unsigned int buf_size)
|
||||
{
|
||||
const int OFFSET_COUNT = 1;
|
||||
const int SIZE_COUNT = 2;
|
||||
const int OFFSET_ADDR = OFFSET_COUNT + SIZE_COUNT;
|
||||
const int SIZE_ADDR = 4;
|
||||
const int OFFSET_TYPE = OFFSET_ADDR + SIZE_ADDR;
|
||||
const int SIZE_TYPE = 2;
|
||||
const int OFFSET_DATA = OFFSET_TYPE + SIZE_TYPE;
|
||||
const int SIZE_DATA = 2;
|
||||
unsigned int pos;
|
||||
|
||||
if (!line) {
|
||||
LOGE("No string line\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if ((!buf) || (buf_size == 0)) {
|
||||
LOGE("Invalid temporary data buffer\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
*count = syna_pal_hex_to_uint(
|
||||
line + OFFSET_COUNT, 2);
|
||||
*addr = syna_pal_hex_to_uint(
|
||||
line + OFFSET_ADDR, SIZE_ADDR);
|
||||
*type = syna_pal_hex_to_uint(
|
||||
line + OFFSET_TYPE, SIZE_TYPE);
|
||||
|
||||
if (*count > buf_size) {
|
||||
LOGE("Data size mismatched, required:%d, given:%d\n",
|
||||
*count, buf_size);
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
for (pos = 0; pos < *count; pos++)
|
||||
buf[pos] = (unsigned char)syna_pal_hex_to_uint(
|
||||
line + (((int)(pos << 1)) + OFFSET_DATA),
|
||||
SIZE_DATA);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_parse_fw_ihex()
|
||||
*
|
||||
* Based on the firmware ihex file given , parse and convert into a binary
|
||||
* firmware data to update.
|
||||
*
|
||||
* @param
|
||||
* [ in] ihex: original ihex file
|
||||
* [ in] ihex_size: size of given file
|
||||
* [ in] ihex_info: data blob stored the parsed data from an ihex file.
|
||||
* assume the data buffer inside was allocated
|
||||
* [ in] len_per_line: length for a useful data in a line
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
static inline int syna_tcm_parse_fw_ihex(const char *ihex, int ihex_size,
|
||||
struct ihex_info *ihex_info, const unsigned int len_per_line)
|
||||
{
|
||||
int retval;
|
||||
unsigned int pos;
|
||||
unsigned int record;
|
||||
char *tmp = NULL;
|
||||
unsigned int count;
|
||||
unsigned int type;
|
||||
unsigned char data[32] = { 0 };
|
||||
unsigned int addr;
|
||||
unsigned int offset;
|
||||
unsigned int prev_addr;
|
||||
unsigned int block_idx = 0;
|
||||
|
||||
if (!ihex) {
|
||||
LOGE("No ihex data\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (!ihex_info) {
|
||||
LOGE("Invalid ihex_info blob\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if ((!ihex_info->bin) || (ihex_info->bin_size == 0)) {
|
||||
LOGE("Invalid ihex_info->data\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
tmp = syna_pal_mem_alloc(len_per_line + 1, sizeof(char));
|
||||
if (!tmp) {
|
||||
LOGE("Fail to allocate temporary buffer\n");
|
||||
return _ENOMEM;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
addr = 0;
|
||||
pos = 0;
|
||||
prev_addr = 0;
|
||||
|
||||
ihex_info->records = ihex_size / len_per_line;
|
||||
LOGD("records = %d\n", ihex_info->records);
|
||||
|
||||
for (record = 0; record < ihex_info->records; record++) {
|
||||
pos = record * len_per_line;
|
||||
if ((char)ihex[pos] != ':') {
|
||||
LOGE("Invalid string maker at pos %d, marker:%c\n",
|
||||
pos, (char)ihex[pos]);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
retval = syna_pal_mem_cpy(tmp, len_per_line,
|
||||
&ihex[pos], ihex_size - pos, len_per_line);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to copy a line at pos %d\n", pos);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
retval = syna_tcm_parse_ihex_line(tmp, &count, &addr, &type,
|
||||
data, sizeof(data));
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to parse line at pos %d\n", pos);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((((prev_addr + 2) & 0xFFFF) != addr) && (type == 0x00)) {
|
||||
block_idx = (record == 0) ? 0 : block_idx + 1;
|
||||
if (block_idx >= IHEX_MAX_BLOCKS) {
|
||||
LOGE("Invalid block index\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ihex_info->block[block_idx].flash_addr =
|
||||
addr + offset;
|
||||
ihex_info->block[block_idx].data =
|
||||
&ihex_info->bin[addr + offset];
|
||||
ihex_info->block[block_idx].available = true;
|
||||
}
|
||||
|
||||
if (type == 0x00) {
|
||||
|
||||
prev_addr = addr;
|
||||
addr += offset;
|
||||
|
||||
if (addr >= ihex_info->bin_size) {
|
||||
LOGE("No enough size for data0 addr:0x%x(%d)\n",
|
||||
addr, addr);
|
||||
goto exit;
|
||||
}
|
||||
ihex_info->bin[addr++] = data[0];
|
||||
|
||||
if (addr >= ihex_info->bin_size) {
|
||||
LOGE("No enough size for data1 addr:0x%x(%d)\n",
|
||||
addr, addr);
|
||||
goto exit;
|
||||
}
|
||||
ihex_info->bin[addr++] = data[1];
|
||||
|
||||
ihex_info->block[block_idx].size += 2;
|
||||
|
||||
} else if (type == 0x02) {
|
||||
offset = (data[0] << 8) + data[1];
|
||||
offset <<= 4;
|
||||
}
|
||||
}
|
||||
|
||||
ihex_info->bin_size = addr; /* the actual size after data reordering */
|
||||
LOGN("Size of firmware binary data = %d\n", ihex_info->bin_size);
|
||||
|
||||
exit:
|
||||
syna_pal_mem_free((void *)tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* end of _SYNAPTICS_TOUCHCOM_PARSE_FW_FILES_H_ */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,146 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file synaptics_touchcom_func_reflash.h
|
||||
*
|
||||
* This file declares relevant functions and structures for TouchBoot.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TOUCHCOM_REFLASH_FUNCS_H_
|
||||
#define _SYNAPTICS_TOUCHCOM_REFLASH_FUNCS_H_
|
||||
|
||||
#include "synaptics_touchcom_core_dev.h"
|
||||
#include "synaptics_touchcom_func_base_flash.h"
|
||||
|
||||
/**
|
||||
* @section: Blocks to be updated
|
||||
*/
|
||||
enum update_area {
|
||||
UPDATE_NONE = 0,
|
||||
UPDATE_FIRMWARE_CONFIG,
|
||||
UPDATE_CONFIG_ONLY,
|
||||
UPDATE_ALL_BLOCKS,
|
||||
};
|
||||
|
||||
/**
|
||||
* @section: Data Type in flash memory
|
||||
*/
|
||||
enum flash_data {
|
||||
FLASH_LCM_DATA = 1,
|
||||
FLASH_OEM_DATA,
|
||||
FLASH_PPDT_DATA,
|
||||
FLASH_FORCE_CALIB_DATA,
|
||||
FLASH_OPEN_SHORT_TUNING_DATA,
|
||||
};
|
||||
|
||||
/**
|
||||
* @section: Specific data blob for reflash
|
||||
*
|
||||
* The structure contains various parameters being used in reflash
|
||||
*/
|
||||
struct tcm_reflash_data_blob {
|
||||
/* binary data of an image file */
|
||||
const unsigned char *image;
|
||||
unsigned int image_size;
|
||||
/* parsed data based on given image file */
|
||||
struct image_info image_info;
|
||||
/* standard information for flash access */
|
||||
unsigned int page_size;
|
||||
unsigned int write_block_size;
|
||||
unsigned int max_write_payload_size;
|
||||
/* temporary buffer during the reflash */
|
||||
struct tcm_buffer out;
|
||||
struct syna_tcm *tcm;
|
||||
};
|
||||
|
||||
/**
|
||||
* syna_tcm_compare_image_id_info()
|
||||
*
|
||||
* Compare the ID information between device and the image file,
|
||||
* and determine the area to be updated.
|
||||
* The function should be called after parsing the image file.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] reflash_data: data blob for reflash
|
||||
*
|
||||
* @return
|
||||
* Comparison result
|
||||
*/
|
||||
int syna_tcm_compare_image_id_info(struct tcm_dev *tcm_dev,
|
||||
struct tcm_reflash_data_blob *reflash_data);
|
||||
|
||||
/**
|
||||
* syna_tcm_read_flash_area()
|
||||
*
|
||||
* Entry function to read in the data of specific area in the flash memory.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] area: flash area to read
|
||||
* [out] data: buffer storing the retrieved data
|
||||
* [ in] rd_delay_us: delay time in micro-sec to read words data from flash.
|
||||
* set '0' to use default time, which is 10 us;
|
||||
* set 'FORCE_ATTN_DRIVEN' to adopt ATTN-driven.
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_read_flash_area(struct tcm_dev *tcm_dev,
|
||||
enum flash_area area, struct tcm_buffer *rd_data,
|
||||
unsigned int rd_delay_us);
|
||||
|
||||
/**
|
||||
* syna_tcm_do_fw_update()
|
||||
*
|
||||
* The entry function to perform fw update upon TouchBoot.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] image: image file given
|
||||
* [ in] image_size: size of data array
|
||||
* [ in] wait_delay_ms: a short delay time in millisecond to wait for
|
||||
* the completion of flash access
|
||||
* for polling, set a value formatted with
|
||||
* [erase | write];
|
||||
* for ATTN-driven, set a '0' or 'RESP_IN_ATTN'
|
||||
* [ in] force_reflash: '1' to do reflash anyway
|
||||
* '0' to compare ID info before doing reflash.
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_do_fw_update(struct tcm_dev *tcm_dev,
|
||||
const unsigned char *image, unsigned int image_size,
|
||||
unsigned int wait_delay_ms, bool force_reflash);
|
||||
|
||||
#endif /* end of _SYNAPTICS_TOUCHCOM_REFLASH_FUNCS_H_ */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,155 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file synaptics_touchcom_func_romboot.h
|
||||
*
|
||||
* This file declares relevant functions and structures for ROM boot-loader.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TOUCHCOM_ROMBOOT_FUNCS_H_
|
||||
#define _SYNAPTICS_TOUCHCOM_ROMBOOT_FUNCS_H_
|
||||
|
||||
#include "synaptics_touchcom_core_dev.h"
|
||||
#include "synaptics_touchcom_func_base_flash.h"
|
||||
|
||||
|
||||
#define ROMBOOT_DELAY_MS (20)
|
||||
|
||||
/**
|
||||
* @section: Structure to assemble flash command
|
||||
*/
|
||||
struct flash_param {
|
||||
union {
|
||||
struct {
|
||||
unsigned char byte0;
|
||||
unsigned char byte1;
|
||||
unsigned char byte2;
|
||||
};
|
||||
struct {
|
||||
unsigned char spi_param;
|
||||
unsigned char clk_div;
|
||||
unsigned char mode;
|
||||
};
|
||||
};
|
||||
unsigned char read_size[2];
|
||||
unsigned char command;
|
||||
};
|
||||
|
||||
/**
|
||||
* @section: Specific data blob for romboot
|
||||
*
|
||||
* The structure contains various parameters being used in
|
||||
* ROM boot control
|
||||
*/
|
||||
struct tcm_romboot_data_blob {
|
||||
/* binary data to write */
|
||||
const unsigned char *bdata;
|
||||
unsigned int bdata_size;
|
||||
/* parsed data based on given binary data */
|
||||
struct ihex_info ihex_info;
|
||||
struct image_info image_info;
|
||||
/* standard information for flash access */
|
||||
unsigned int page_size;
|
||||
unsigned int write_block_size;
|
||||
unsigned int max_write_payload_size;
|
||||
/* temporary buffer during the reflash */
|
||||
struct tcm_buffer out;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* syna_tcm_romboot_do_ihex_update()
|
||||
*
|
||||
* The entry function to perform ihex update upon ROM Boot.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] ihex: ihex data to write
|
||||
* [ in] ihex_size: size of ihex data
|
||||
* [ in] flash_size: size for temporary buffer allocation, which used
|
||||
* to re-order the flash data.
|
||||
* in general, (ihex_size + 4K) is preferred size
|
||||
* [ in] len_per_line: length per line in the ihex file
|
||||
* [ in] delay_ms: a short delay time in millisecond to wait for
|
||||
* the completion of flash access
|
||||
* [ in] is_multichip: flag to indicate a multi-chip product used
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_romboot_do_ihex_update(struct tcm_dev *tcm_dev,
|
||||
const unsigned char *ihex, unsigned int ihex_size,
|
||||
unsigned int flash_size, unsigned int len_per_line,
|
||||
unsigned int delay_ms, bool is_multichip);
|
||||
|
||||
/**
|
||||
* syna_tcm_romboot_do_multichip_reflash()
|
||||
*
|
||||
* The entry function to perform fw update with multi-chip product.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] image: image file given
|
||||
* [ in] image_size: size of data array
|
||||
* [ in] wait_delay_ms: a short delay time in millisecond to wait for
|
||||
* the completion of flash access
|
||||
* set [erase_delay_ms | write_delay_ms] for setup;
|
||||
* set '0' to use default time;
|
||||
* set 'FORCE_ATTN_DRIVEN' to adopt ATTN-driven.
|
||||
* [ in] force_reflash: '1' to do reflash anyway
|
||||
* '0' to compare ID info before doing reflash.
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_romboot_do_multichip_reflash(struct tcm_dev *tcm_dev,
|
||||
const unsigned char *image, unsigned int image_size,
|
||||
unsigned int wait_delay_ms, bool force_reflash);
|
||||
|
||||
/**
|
||||
* syna_tcm_get_romboot_info()
|
||||
*
|
||||
* Implement the bootloader command code, which is used to request a
|
||||
* RomBoot information packet.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [out] rom_boot_info: the romboot info packet returned
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_get_romboot_info(struct tcm_dev *tcm_dev,
|
||||
struct tcm_romboot_info *rom_boot_info);
|
||||
|
||||
|
||||
#endif /* end of _SYNAPTICS_TOUCHCOM_ROMBOOT_FUNCS_H_ */
|
||||
|
|
@ -0,0 +1,877 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Synaptics TCM touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file synaptics_tcm2_func_touch.c
|
||||
*
|
||||
* This file implements the touch report handling functions.
|
||||
* The declarations are available in synaptics_touchcom_func_touch.h.
|
||||
*/
|
||||
|
||||
#include "synaptics_touchcom_func_touch.h"
|
||||
|
||||
/**
|
||||
* syna_tcm_get_touch_data()
|
||||
*
|
||||
* Get data entity from the received report according to bit offset and bit
|
||||
* length defined in the touch report configuration.
|
||||
*
|
||||
* @param
|
||||
* [ in] report: touch report generated by TouchComm device
|
||||
* [ in] report_size: size of given report
|
||||
* [ in] offset: bit offset in the report
|
||||
* [ in] bits: number of bits representing the data
|
||||
* [out] data: data parsed
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_get_touch_data(const unsigned char *report,
|
||||
unsigned int report_size, unsigned int offset,
|
||||
unsigned int bits, unsigned int *data)
|
||||
{
|
||||
unsigned char mask;
|
||||
unsigned char byte_data;
|
||||
unsigned int output_data;
|
||||
unsigned int bit_offset;
|
||||
unsigned int byte_offset;
|
||||
unsigned int data_bits;
|
||||
unsigned int available_bits;
|
||||
unsigned int remaining_bits;
|
||||
|
||||
if (bits == 0 || bits > 32) {
|
||||
LOGE("Invalid number of bits %d\n", bits);
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (!report) {
|
||||
LOGE("Invalid report data\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (offset + bits > report_size * 8) {
|
||||
*data = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
output_data = 0;
|
||||
remaining_bits = bits;
|
||||
|
||||
bit_offset = offset % 8;
|
||||
byte_offset = offset / 8;
|
||||
|
||||
while (remaining_bits) {
|
||||
byte_data = report[byte_offset];
|
||||
byte_data >>= bit_offset;
|
||||
|
||||
available_bits = 8 - bit_offset;
|
||||
data_bits = MIN(available_bits, remaining_bits);
|
||||
mask = 0xff >> (8 - data_bits);
|
||||
|
||||
byte_data &= mask;
|
||||
|
||||
output_data |= byte_data << (bits - remaining_bits);
|
||||
|
||||
bit_offset = 0;
|
||||
byte_offset += 1;
|
||||
remaining_bits -= data_bits;
|
||||
}
|
||||
|
||||
*data = output_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_get_gesture_data()
|
||||
*
|
||||
* The contents of the gesture data entity depend on which gesture
|
||||
* is detected. The default size of data is defined in 16-64 bits natively.
|
||||
*
|
||||
* @param
|
||||
* [ in] report: touch report generated by TouchComm device
|
||||
* [ in] report_size: size of given report
|
||||
* [ in] offset: bit offset in the report
|
||||
* [ in] bits: total bits representing the gesture data
|
||||
* [out] gesture_data: gesture data parsed
|
||||
* [ in] gesture_id: gesture id retrieved
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
static int syna_tcm_get_gesture_data(const unsigned char *report,
|
||||
unsigned int report_size, unsigned int offset,
|
||||
unsigned int bits, struct tcm_gesture_data_blob *gesture_data,
|
||||
unsigned int gesture_id)
|
||||
{
|
||||
int retval;
|
||||
unsigned int idx;
|
||||
unsigned int data;
|
||||
unsigned int size;
|
||||
unsigned int data_end;
|
||||
|
||||
if (!report) {
|
||||
LOGE("Invalid report data\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (offset + bits > report_size * 8)
|
||||
return 0;
|
||||
|
||||
data_end = offset + bits;
|
||||
|
||||
size = (sizeof(gesture_data->data) / sizeof(unsigned char));
|
||||
|
||||
idx = 0;
|
||||
while ((offset < data_end) && (idx < size)) {
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, 16, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object index\n");
|
||||
return retval;
|
||||
}
|
||||
gesture_data->data[idx++] = (unsigned char)(data & 0xff);
|
||||
gesture_data->data[idx++] = (unsigned char)((data >> 8) & 0xff);
|
||||
offset += 16;
|
||||
}
|
||||
|
||||
switch (gesture_id) {
|
||||
case GESTURE_ID_DOUBLE_TAP:
|
||||
case GESTURE_ID_ACTIVE_TAP_AND_HOLD:
|
||||
case GESTURE_ID_ACTIVE_SINGLE_TAP:
|
||||
LOGD("Tap info: (%d, %d)\n",
|
||||
syna_pal_le2_to_uint(gesture_data->tap_x),
|
||||
syna_pal_le2_to_uint(gesture_data->tap_y));
|
||||
break;
|
||||
case GESTURE_ID_SWIPE:
|
||||
LOGD("Swipe info: direction:%x (%d, %d)\n",
|
||||
syna_pal_le2_to_uint(gesture_data->swipe_direction),
|
||||
syna_pal_le2_to_uint(gesture_data->tap_x),
|
||||
syna_pal_le2_to_uint(gesture_data->tap_y));
|
||||
break;
|
||||
default:
|
||||
LOGW("Unknown gesture_id:%d\n", gesture_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_parse_touch_report()
|
||||
*
|
||||
* Traverse through touch report configuration and parse the contents of
|
||||
* report packet to get the exactly touched data entity from touch reports.
|
||||
*
|
||||
* At the end of function, the touched data will be parsed and stored at the
|
||||
* associated position in structure touch_data_blob.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] report: touch report generated by TouchComm device
|
||||
* [ in] report_size: size of given report
|
||||
* [out] touch_data: touch data generated
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_parse_touch_report(struct tcm_dev *tcm_dev,
|
||||
unsigned char *report, unsigned int report_size,
|
||||
struct tcm_touch_data_blob *touch_data)
|
||||
{
|
||||
int retval;
|
||||
bool active_only;
|
||||
bool num_of_active_objects;
|
||||
unsigned char code;
|
||||
unsigned int size;
|
||||
unsigned int idx;
|
||||
unsigned int obj;
|
||||
unsigned int next;
|
||||
unsigned int data;
|
||||
unsigned int bits;
|
||||
unsigned int offset;
|
||||
unsigned int objects;
|
||||
unsigned int active_objects;
|
||||
unsigned int config_size;
|
||||
unsigned char *config_data;
|
||||
struct tcm_objects_data_blob *object_data;
|
||||
static unsigned int end_of_foreach;
|
||||
|
||||
if (!tcm_dev) {
|
||||
LOGE("Invalid tcm device handle\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (!report) {
|
||||
LOGE("Invalid report data\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (report_size <= 0) {
|
||||
LOGE("Invalid report data length\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (!touch_data) {
|
||||
LOGE("Invalid touch data structure\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (tcm_dev->max_objects == 0) {
|
||||
LOGE("Invalid max_objects supported\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
object_data = touch_data->object_data;
|
||||
|
||||
if (!object_data) {
|
||||
LOGE("Invalid object_data\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
config_data = tcm_dev->touch_config.buf;
|
||||
config_size = tcm_dev->touch_config.data_length;
|
||||
|
||||
if ((!config_data) || (config_size == 0)) {
|
||||
LOGE("Invalid config_data\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
size = sizeof(touch_data->object_data);
|
||||
syna_pal_mem_set(touch_data->object_data, 0x00, size);
|
||||
|
||||
num_of_active_objects = false;
|
||||
|
||||
idx = 0;
|
||||
offset = 0;
|
||||
objects = 0;
|
||||
active_objects = 0;
|
||||
active_only = false;
|
||||
obj = 0;
|
||||
next = 0;
|
||||
|
||||
while (idx < config_size) {
|
||||
code = config_data[idx++];
|
||||
switch (code) {
|
||||
case TOUCH_REPORT_END:
|
||||
goto exit;
|
||||
case TOUCH_REPORT_FOREACH_ACTIVE_OBJECT:
|
||||
obj = 0;
|
||||
next = idx;
|
||||
active_only = true;
|
||||
break;
|
||||
case TOUCH_REPORT_FOREACH_OBJECT:
|
||||
obj = 0;
|
||||
next = idx;
|
||||
active_only = false;
|
||||
break;
|
||||
case TOUCH_REPORT_FOREACH_END:
|
||||
end_of_foreach = idx;
|
||||
if (active_only) {
|
||||
if (num_of_active_objects) {
|
||||
objects++;
|
||||
obj++;
|
||||
if (objects < active_objects)
|
||||
idx = next;
|
||||
} else if (offset < report_size * 8) {
|
||||
obj++;
|
||||
idx = next;
|
||||
}
|
||||
} else {
|
||||
obj++;
|
||||
if (obj < tcm_dev->max_objects)
|
||||
idx = next;
|
||||
}
|
||||
break;
|
||||
case TOUCH_REPORT_PAD_TO_NEXT_BYTE:
|
||||
offset = syna_pal_ceil_div(offset, 8) * 8;
|
||||
break;
|
||||
case TOUCH_REPORT_TIMESTAMP:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get time-stamp\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->timestamp = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_OBJECT_N_INDEX:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object index\n");
|
||||
return retval;
|
||||
}
|
||||
obj = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_OBJECT_N_CLASSIFICATION:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object classification\n");
|
||||
return retval;
|
||||
}
|
||||
object_data[obj].status = (unsigned char)data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_OBJECT_N_X_POSITION:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object x position\n");
|
||||
return retval;
|
||||
}
|
||||
object_data[obj].x_pos = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_OBJECT_N_Y_POSITION:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object y position\n");
|
||||
return retval;
|
||||
}
|
||||
object_data[obj].y_pos = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_OBJECT_N_Z:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object z\n");
|
||||
return retval;
|
||||
}
|
||||
object_data[obj].z = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_OBJECT_N_X_WIDTH:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object x width\n");
|
||||
return retval;
|
||||
}
|
||||
object_data[obj].x_width = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_OBJECT_N_Y_WIDTH:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object y width\n");
|
||||
return retval;
|
||||
}
|
||||
object_data[obj].y_width = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_OBJECT_N_TX_POSITION_TIXELS:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object tx position\n");
|
||||
return retval;
|
||||
}
|
||||
object_data[obj].tx_pos = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_OBJECT_N_RX_POSITION_TIXELS:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get object rx position\n");
|
||||
return retval;
|
||||
}
|
||||
object_data[obj].rx_pos = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_NUM_OF_ACTIVE_OBJECTS:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get number of active objects\n");
|
||||
return retval;
|
||||
}
|
||||
active_objects = data;
|
||||
num_of_active_objects = true;
|
||||
touch_data->num_of_active_objects = data;
|
||||
offset += bits;
|
||||
if (touch_data->num_of_active_objects == 0) {
|
||||
if (end_of_foreach == 0)
|
||||
return 0;
|
||||
|
||||
idx = end_of_foreach;
|
||||
}
|
||||
break;
|
||||
case TOUCH_REPORT_0D_BUTTONS_STATE:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get 0D buttons state\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->buttons_state = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_GESTURE_ID:
|
||||
if (tcm_dev->cb_custom_gesture) {
|
||||
retval = tcm_dev->cb_custom_gesture(
|
||||
TOUCH_REPORT_GESTURE_ID, config_data,
|
||||
&idx, report, &offset, report_size,
|
||||
tcm_dev->cbdata_gesture);
|
||||
} else {
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report,
|
||||
report_size, offset, bits, &data);
|
||||
touch_data->gesture_id = data;
|
||||
offset += bits;
|
||||
}
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get gesture id\n");
|
||||
return retval;
|
||||
}
|
||||
break;
|
||||
case TOUCH_REPORT_GESTURE_DATA:
|
||||
if (tcm_dev->cb_custom_gesture) {
|
||||
retval = tcm_dev->cb_custom_gesture(
|
||||
TOUCH_REPORT_GESTURE_DATA, config_data,
|
||||
&idx, report, &offset, report_size,
|
||||
tcm_dev->cbdata_gesture);
|
||||
} else {
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_gesture_data(report,
|
||||
report_size,
|
||||
offset, bits,
|
||||
&touch_data->gesture_data,
|
||||
touch_data->gesture_id);
|
||||
offset += bits;
|
||||
}
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get gesture data\n");
|
||||
return retval;
|
||||
}
|
||||
break;
|
||||
case TOUCH_REPORT_FRAME_RATE:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get frame rate\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->frame_rate = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_FORCE_MEASUREMENT:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get force measurement data\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->force_data = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_FINGERPRINT_AREA_MEET:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get data for fingerprint area\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->fingerprint_area_meet = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_POWER_IM:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get power IM\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->power_im = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_CID_IM:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get CID IM\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->cid_im = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_RAIL_IM:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get rail IM\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->rail_im = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_CID_VARIANCE_IM:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get CID variance IM\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->cid_variance_im = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_NSM_FREQUENCY_INDEX:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get NSM frequency\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->nsm_frequency = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_NSM_STATE:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get NSM state\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->nsm_state = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_CPU_CYCLES_USED_SINCE_LAST_FRAME:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get cpu cycles info\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->num_of_cpu_cycles = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_FACE_DETECT:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to detect face\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->fd_data = data;
|
||||
offset += bits;
|
||||
break;
|
||||
case TOUCH_REPORT_SENSING_MODE:
|
||||
bits = config_data[idx++];
|
||||
retval = syna_tcm_get_touch_data(report, report_size,
|
||||
offset, bits, &data);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to get sensing mode\n");
|
||||
return retval;
|
||||
}
|
||||
touch_data->sensing_mode = data;
|
||||
offset += bits;
|
||||
break;
|
||||
default:
|
||||
/* use custom parsing method, if registered */
|
||||
if (tcm_dev->cb_custom_touch_entity) {
|
||||
retval = tcm_dev->cb_custom_touch_entity(
|
||||
code, config_data, &idx, report,
|
||||
&offset, report_size,
|
||||
tcm_dev->cbdata_touch_entity);
|
||||
if (retval >= 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGW("Unknown touch config code:0x%02x (length:%d)\n",
|
||||
code, config_data[idx]);
|
||||
bits = config_data[idx++];
|
||||
offset += bits;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_set_touch_report_config()
|
||||
*
|
||||
* Setup the format and content of touch report if needed.
|
||||
*
|
||||
* TouchComm allows to set how touch reports are formatted and what items get
|
||||
* reported each time a touch report is generated.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] config: the customized report configuration
|
||||
* [ in] config_size: size of given config
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_touch_report_config(struct tcm_dev *tcm_dev,
|
||||
unsigned char *config, unsigned int config_size)
|
||||
{
|
||||
int retval = 0;
|
||||
unsigned char resp_code;
|
||||
unsigned int size;
|
||||
struct tcm_application_info *app_info;
|
||||
unsigned char *data;
|
||||
|
||||
if (!tcm_dev) {
|
||||
LOGE("Invalid tcm device handle\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if ((!config) || (config_size == 0)) {
|
||||
LOGE("Invalid given config data\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (IS_NOT_APP_FW_MODE(tcm_dev->dev_mode)) {
|
||||
LOGE("Not in application fw mode, mode: %d\n",
|
||||
tcm_dev->dev_mode);
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
app_info = &tcm_dev->app_info;
|
||||
size = syna_pal_le2_to_uint(app_info->max_touch_report_config_size);
|
||||
|
||||
if (config_size > size) {
|
||||
LOGE("Invalid config size: %d (max: %d)\n", config_size, size);
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
data = syna_pal_mem_alloc(size, sizeof(unsigned char));
|
||||
if (!data) {
|
||||
LOGE("Fail to allocate memory for touch config setting\n");
|
||||
return _ENOMEM;
|
||||
}
|
||||
|
||||
retval = syna_pal_mem_cpy(data,
|
||||
size,
|
||||
config,
|
||||
config_size,
|
||||
config_size);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to copy custom touch config\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
retval = tcm_dev->write_message(tcm_dev,
|
||||
CMD_SET_TOUCH_REPORT_CONFIG,
|
||||
data,
|
||||
size,
|
||||
&resp_code,
|
||||
tcm_dev->msg_data.default_resp_reading);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to write command CMD_SET_TOUCH_REPORT_CONFIG\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
LOGI("Set touch config done\n");
|
||||
|
||||
exit:
|
||||
if (data)
|
||||
syna_pal_mem_free((void *)data);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_preserve_touch_report_config()
|
||||
*
|
||||
* Retrieve and preserve the current touch report configuration.
|
||||
*
|
||||
* The retrieved configuration is stored in touch_config buffer defined
|
||||
* in structure syna_tcm_dev for later using of touch position parsing.
|
||||
*
|
||||
* The touch_config buffer will be allocated internally and its size will
|
||||
* be updated accordingly.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_preserve_touch_report_config(struct tcm_dev *tcm_dev)
|
||||
{
|
||||
int retval = 0;
|
||||
unsigned char resp_code;
|
||||
unsigned int size = 0;
|
||||
|
||||
if (!tcm_dev) {
|
||||
LOGE("Invalid tcm device handle\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
if (IS_NOT_APP_FW_MODE(tcm_dev->dev_mode)) {
|
||||
LOGE("Not in application fw mode, mode: %d\n",
|
||||
tcm_dev->dev_mode);
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
retval = tcm_dev->write_message(tcm_dev,
|
||||
CMD_GET_TOUCH_REPORT_CONFIG,
|
||||
NULL,
|
||||
0,
|
||||
&resp_code,
|
||||
tcm_dev->msg_data.default_resp_reading);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to write command CMD_GET_TOUCH_REPORT_CONFIG\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
syna_tcm_buf_lock(&tcm_dev->resp_buf);
|
||||
|
||||
size = tcm_dev->resp_buf.data_length;
|
||||
retval = syna_tcm_buf_alloc(&tcm_dev->touch_config,
|
||||
size);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to allocate memory for internal touch_config\n");
|
||||
syna_tcm_buf_unlock(&tcm_dev->resp_buf);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
syna_tcm_buf_lock(&tcm_dev->touch_config);
|
||||
|
||||
retval = syna_pal_mem_cpy(tcm_dev->touch_config.buf,
|
||||
tcm_dev->touch_config.buf_size,
|
||||
tcm_dev->resp_buf.buf,
|
||||
tcm_dev->resp_buf.buf_size,
|
||||
size);
|
||||
if (retval < 0) {
|
||||
LOGE("Fail to clone touch config\n");
|
||||
syna_tcm_buf_unlock(&tcm_dev->touch_config);
|
||||
syna_tcm_buf_unlock(&tcm_dev->resp_buf);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tcm_dev->touch_config.data_length = size;
|
||||
|
||||
syna_tcm_buf_unlock(&tcm_dev->touch_config);
|
||||
syna_tcm_buf_unlock(&tcm_dev->resp_buf);
|
||||
|
||||
exit:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_set_custom_touch_entity_callback()
|
||||
*
|
||||
* Set up callback function to handle custom touch data.
|
||||
*
|
||||
* Once finding the "new" custom entity in touch report, the core library will
|
||||
* invoke the custom parsing method to handle this "new" code entity.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] p_cb: the callback function pointer
|
||||
* [ in] p_cbdata: pointer to caller data
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_custom_touch_entity_callback(struct tcm_dev *tcm_dev,
|
||||
tcm_custom_touch_entity_callback_t p_cb, void *p_cbdata)
|
||||
{
|
||||
if (!tcm_dev) {
|
||||
LOGE("Invalid tcm device handle\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
tcm_dev->cb_custom_touch_entity = p_cb;
|
||||
tcm_dev->cbdata_touch_entity = p_cbdata;
|
||||
|
||||
LOGI("enabled\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* syna_tcm_set_custom_gesture_callback()
|
||||
*
|
||||
* Set up callback function to handle the gesture data defined as the
|
||||
* following code entities
|
||||
* - TOUCH_REPORT_GESTURE_ID
|
||||
* - TOUCH_REPORT_GESTURE_DATA
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] p_cb: the callback function pointer
|
||||
* [ in] p_cbdata: pointer to caller data passed to callback function
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_custom_gesture_callback(struct tcm_dev *tcm_dev,
|
||||
tcm_custom_gesture_callback_t p_cb, void *p_cbdata)
|
||||
{
|
||||
if (!tcm_dev) {
|
||||
LOGE("Invalid tcm device handle\n");
|
||||
return _EINVAL;
|
||||
}
|
||||
|
||||
tcm_dev->cb_custom_gesture = p_cb;
|
||||
tcm_dev->cbdata_gesture = p_cbdata;
|
||||
|
||||
LOGI("enabled\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Synaptics TouchCom touchscreen driver
|
||||
*
|
||||
* Copyright (C) 2017-2020 Synaptics Incorporated. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
|
||||
* EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
|
||||
* AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
|
||||
* IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
|
||||
* AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION DOES
|
||||
* NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS'
|
||||
* TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S.
|
||||
* DOLLARS.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file synaptics_tcm2_func_touch.h
|
||||
*
|
||||
* This file declares related APIs and definitions for touch report handling.
|
||||
*/
|
||||
|
||||
#ifndef _SYNAPTICS_TOUCHCOM_TOUCH_FUNCS_H_
|
||||
#define _SYNAPTICS_TOUCHCOM_TOUCH_FUNCS_H_
|
||||
|
||||
#include "synaptics_touchcom_core_dev.h"
|
||||
|
||||
/**
|
||||
* @section: Types of Object Reported
|
||||
*
|
||||
* List the object classifications
|
||||
*/
|
||||
enum object_classification {
|
||||
LIFT = 0,
|
||||
FINGER = 1,
|
||||
GLOVED_OBJECT = 2,
|
||||
STYLUS = 3,
|
||||
ERASER = 4,
|
||||
SMALL_OBJECT = 5,
|
||||
PALM = 6,
|
||||
EDGE_TOUCHED = 8,
|
||||
HOVER_OBJECT = 9,
|
||||
NOP = -1,
|
||||
};
|
||||
|
||||
/**
|
||||
* @section: Types of Gesture ID
|
||||
*
|
||||
* List the gesture ID assigned
|
||||
*/
|
||||
enum gesture_classification {
|
||||
GESTURE_ID_NONE = 0,
|
||||
GESTURE_ID_DOUBLE_TAP = 1,
|
||||
GESTURE_ID_SWIPE = 2,
|
||||
GESTURE_ID_ACTIVE_SINGLE_TAP = 6,
|
||||
GESTURE_ID_ACTIVE_TAP_AND_HOLD = 7,
|
||||
};
|
||||
|
||||
/**
|
||||
* @section: Codes for Touch Report Configuration
|
||||
*
|
||||
* Define the 8-bit codes for the touch report configuration
|
||||
*/
|
||||
enum touch_report_code {
|
||||
/* control flow codes */
|
||||
TOUCH_REPORT_END = 0x00,
|
||||
TOUCH_REPORT_FOREACH_ACTIVE_OBJECT = 0x01,
|
||||
TOUCH_REPORT_FOREACH_OBJECT = 0x02,
|
||||
TOUCH_REPORT_FOREACH_END = 0x03,
|
||||
TOUCH_REPORT_PAD_TO_NEXT_BYTE = 0x04,
|
||||
/* entity codes */
|
||||
TOUCH_REPORT_TIMESTAMP = 0x05,
|
||||
TOUCH_REPORT_OBJECT_N_INDEX = 0x06,
|
||||
TOUCH_REPORT_OBJECT_N_CLASSIFICATION = 0x07,
|
||||
TOUCH_REPORT_OBJECT_N_X_POSITION = 0x08,
|
||||
TOUCH_REPORT_OBJECT_N_Y_POSITION = 0x09,
|
||||
TOUCH_REPORT_OBJECT_N_Z = 0x0a,
|
||||
TOUCH_REPORT_OBJECT_N_X_WIDTH = 0x0b,
|
||||
TOUCH_REPORT_OBJECT_N_Y_WIDTH = 0x0c,
|
||||
TOUCH_REPORT_OBJECT_N_TX_POSITION_TIXELS = 0x0d,
|
||||
TOUCH_REPORT_OBJECT_N_RX_POSITION_TIXELS = 0x0e,
|
||||
TOUCH_REPORT_0D_BUTTONS_STATE = 0x0f,
|
||||
TOUCH_REPORT_GESTURE_ID = 0x10,
|
||||
TOUCH_REPORT_FRAME_RATE = 0x11,
|
||||
TOUCH_REPORT_POWER_IM = 0x12,
|
||||
TOUCH_REPORT_CID_IM = 0x13,
|
||||
TOUCH_REPORT_RAIL_IM = 0x14,
|
||||
TOUCH_REPORT_CID_VARIANCE_IM = 0x15,
|
||||
TOUCH_REPORT_NSM_FREQUENCY_INDEX = 0x16,
|
||||
TOUCH_REPORT_NSM_STATE = 0x17,
|
||||
TOUCH_REPORT_NUM_OF_ACTIVE_OBJECTS = 0x18,
|
||||
TOUCH_REPORT_CPU_CYCLES_USED_SINCE_LAST_FRAME = 0x19,
|
||||
TOUCH_REPORT_FACE_DETECT = 0x1a,
|
||||
TOUCH_REPORT_GESTURE_DATA = 0x1b,
|
||||
TOUCH_REPORT_FORCE_MEASUREMENT = 0x1c,
|
||||
TOUCH_REPORT_FINGERPRINT_AREA_MEET = 0x1d,
|
||||
TOUCH_REPORT_SENSING_MODE = 0x1e,
|
||||
TOUCH_REPORT_KNOB_DATA = 0x24,
|
||||
};
|
||||
|
||||
/**
|
||||
* syna_tcm_parse_touch_report()
|
||||
*
|
||||
* Traverse through touch report configuration and parse the contents of
|
||||
* report packet to get the exactly touched data entity from touch reports.
|
||||
*
|
||||
* At the end of function, the touched data will be parsed and stored at the
|
||||
* associated position in struct touch_data_blob.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] report: touch report generated by TouchComm device
|
||||
* [ in] report_size: size of given report
|
||||
* [out] touch_data: touch data generated
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_parse_touch_report(struct tcm_dev *tcm_dev,
|
||||
unsigned char *report, unsigned int report_size,
|
||||
struct tcm_touch_data_blob *touch_data);
|
||||
|
||||
/**
|
||||
* syna_tcm_set_touch_report_config()
|
||||
*
|
||||
* Setup the format and content of touch report if needed
|
||||
*
|
||||
* TouchComm allows to set how touch reports are formatted and what items get
|
||||
* reported each time a touch report is generated.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] config: the customized report configuration
|
||||
* [ in] config_size: size of given config
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_touch_report_config(struct tcm_dev *tcm_dev,
|
||||
unsigned char *config, unsigned int config_size);
|
||||
|
||||
/**
|
||||
* syna_tcm_preserve_touch_report_config()
|
||||
*
|
||||
* Retrieve and preserve the current touch report configuration.
|
||||
*
|
||||
* The retrieved configuration is stored in touch_config buffer defined
|
||||
* in struct syna_tcm_dev for later using of touch position parsing.
|
||||
*
|
||||
* The touch_config buffer will be allocated internally and its size will
|
||||
* be updated accordingly.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_preserve_touch_report_config(struct tcm_dev *tcm_dev);
|
||||
|
||||
|
||||
/**
|
||||
* syna_tcm_get_touch_data()
|
||||
*
|
||||
* Get data entity from the received report according to bit offset and bit
|
||||
* length defined in the touch report configuration.
|
||||
*
|
||||
* @param
|
||||
* [ in] report: touch report generated by TouchComm device
|
||||
* [ in] report_size: size of given report
|
||||
* [ in] offset: bit offset in the report
|
||||
* [ in] bits: number of bits representing the data
|
||||
* [out] data: data parsed
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_get_touch_data(const unsigned char *report,
|
||||
unsigned int report_size, unsigned int offset,
|
||||
unsigned int bits, unsigned int *data);
|
||||
|
||||
/**
|
||||
* syna_tcm_set_custom_touch_entity_callback()
|
||||
*
|
||||
* Set up callback function to handle custom touch data.
|
||||
*
|
||||
* Once finding the "new" custom entity in touch report, the core library will
|
||||
* invoke the custom parsing method to handle this "new" code entity.
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] p_cb: the callback function pointer
|
||||
* [ in] p_cbdata: pointer to caller data passed to callback function
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_custom_touch_entity_callback(struct tcm_dev *tcm_dev,
|
||||
tcm_custom_touch_entity_callback_t p_cb, void *p_cbdata);
|
||||
|
||||
/**
|
||||
* syna_tcm_set_custom_gesture_callback()
|
||||
*
|
||||
* Set up callback function to handle the gesture data defined as the following
|
||||
* code entities
|
||||
* - TOUCH_REPORT_GESTURE_ID
|
||||
* - TOUCH_REPORT_GESTURE_DATA
|
||||
*
|
||||
* @param
|
||||
* [ in] tcm_dev: the device handle
|
||||
* [ in] p_cb: the callback function pointer
|
||||
* [ in] p_cbdata: pointer to caller data passed to callback function
|
||||
*
|
||||
* @return
|
||||
* on success, 0 or positive value; otherwise, negative value on error.
|
||||
*/
|
||||
int syna_tcm_set_custom_gesture_callback(struct tcm_dev *tcm_dev,
|
||||
tcm_custom_gesture_callback_t p_cb, void *p_cbdata);
|
||||
|
||||
|
||||
#endif /* end of _SYNAPTICS_TOUCHCOM_TOUCH_FUNCS_H_ */
|
||||
Loading…
Reference in a new issue