mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
fts: initial STmicro touch driver code
Initial driver code v5.2.18 Change-Id: I1da8b0a36dbd147fee08e2ffba5d175113296c83 Signed-off-by: Konstantin Makariev <hcv867@motorola.com> Reviewed-on: https://gerrit.mot.com/1682343 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Konstantin Makariev <kmakariev@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
fea6809413
commit
366e3815d0
29 changed files with 38585 additions and 0 deletions
6
drivers/input/touchscreen/stmicro_mmi/Makefile
Normal file
6
drivers/input/touchscreen/stmicro_mmi/Makefile
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# Makefile for the touchscreen drivers.
|
||||
#
|
||||
|
||||
obj-y += fts.o fts_proc.o fts_lib/
|
||||
|
||||
4243
drivers/input/touchscreen/stmicro_mmi/fts.c
Normal file
4243
drivers/input/touchscreen/stmicro_mmi/fts.c
Normal file
File diff suppressed because it is too large
Load diff
355
drivers/input/touchscreen/stmicro_mmi/fts.h
Normal file
355
drivers/input/touchscreen/stmicro_mmi/fts.h
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* fts.c
|
||||
*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2017, STMicroelectronics
|
||||
* Authors: AMG(Analog Mems Group)
|
||||
*
|
||||
* marco.cali@st.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* THE PRESENT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
|
||||
* OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, FOR THE SOLE
|
||||
* PURPOSE TO SUPPORT YOUR APPLICATION DEVELOPMENT.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM
|
||||
*THE
|
||||
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file fts.h
|
||||
* \brief Contains all the definitions and structs used generally by the driver
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FTS_I2C_H_
|
||||
#define _LINUX_FTS_I2C_H_
|
||||
|
||||
#include <linux/device.h>
|
||||
#include "fts_lib/ftsSoftware.h"
|
||||
#include "fts_lib/ftsHardware.h"
|
||||
|
||||
|
||||
/****************** CONFIGURATION SECTION ******************/
|
||||
/** @defgroup conf_section Driver Configuration Section
|
||||
* Settings of the driver code in order to suit the HW set up and the
|
||||
*application behavior
|
||||
* @{
|
||||
*/
|
||||
/* **** CODE CONFIGURATION **** */
|
||||
#define FTS_TS_DRV_NAME "fts" /* /< driver name */
|
||||
#define FTS_TS_DRV_VERSION "5.2.18" /* /< driver version string format */
|
||||
#define FTS_TS_DRV_VER 0x05021200 /* driver version u32 format */
|
||||
|
||||
#define DEBUG /* /< define to print more logs in the kernel log and better
|
||||
* follow the code flow */
|
||||
|
||||
#define DRIVER_TEST /* /< if defined allow to use and test special functions
|
||||
* of the driver and fts_lib from comand shell (usefull
|
||||
* for enginering/debug operations) */
|
||||
|
||||
|
||||
/* If both COMPUTE_INIT_METHOD and PRE_SAVED_METHOD are not defined,
|
||||
* driver will be automatically configured as GOLDEN_VALUE_METHOD */
|
||||
/*#define COMPUTE_INIT_METHOD*/ /* Allow to compute init data on phone during
|
||||
production */
|
||||
#ifndef COMPUTE_INIT_METHOD
|
||||
#define PRE_SAVED_METHOD /* Pre-Saved Method used
|
||||
* during production */
|
||||
#endif
|
||||
|
||||
/* #define FW_H_FILE */ /* include the FW data as header file */
|
||||
#ifdef FW_H_FILE
|
||||
#define FW_SIZE_NAME myArray_size /* /< name of the variable in
|
||||
* the FW header file which
|
||||
* specified the dimension of
|
||||
* the FW data array */
|
||||
#define FW_ARRAY_NAME myArray /* /< name of the variable in the FW
|
||||
* header file which specified the FW
|
||||
* data array */
|
||||
/* #define FW_UPDATE_ON_PROBE */
|
||||
/* if defined the FW update will be execute on the probe, if not it will be
|
||||
* executed EXP_FN_WORK_DELAY_MS ms after the probe is completed */
|
||||
#endif
|
||||
|
||||
#ifndef FW_UPDATE_ON_PROBE
|
||||
/* #define LIMITS_H_FILE */
|
||||
/* include the Production Limit File as header file, can be commented to use a
|
||||
* .csv file instead */
|
||||
#ifdef LIMITS_H_FILE
|
||||
#define LIMITS_SIZE_NAME myArray2_size /* /< name of the
|
||||
* variable in the
|
||||
* limits header file
|
||||
* which specified the
|
||||
* dimension of the
|
||||
* limits data array */
|
||||
#define LIMITS_ARRAY_NAME myArray2 /* /< name of the
|
||||
* variable in the
|
||||
* limits header file
|
||||
* which specified the
|
||||
* limits data array */
|
||||
#endif
|
||||
#else
|
||||
/* if execute fw update in the probe the limit file must be a .h */
|
||||
#define LIMITS_H_FILE /* /< include the Production Limit File as header file,
|
||||
* DO NOT COMMENT! */
|
||||
#define LIMITS_SIZE_NAME myArray2_size /* /< name of the
|
||||
* variable in the
|
||||
* limits header file
|
||||
* which specified the
|
||||
* dimension of the
|
||||
* limits data array */
|
||||
#define LIMITS_ARRAY_NAME myArray2 /* /< name of the
|
||||
* variable in the
|
||||
* limits header file
|
||||
* which specified the
|
||||
* limits data array */
|
||||
#endif
|
||||
|
||||
#define USE_ONE_FILE_NODE
|
||||
/* allow to enable/disable all the features just using one file node */
|
||||
|
||||
#ifndef FW_UPDATE_ON_PROBE
|
||||
#define EXP_FN_WORK_DELAY_MS 1000 /* /< time in ms elapsed after the probe
|
||||
* to start the work which execute FW
|
||||
* update and the Initialization of the
|
||||
* IC */
|
||||
#endif
|
||||
|
||||
/* **** END **** */
|
||||
|
||||
|
||||
/* **** FEATURES USED IN THE IC **** */
|
||||
/* Enable the support of keys */
|
||||
/* #define PHONE_KEY */
|
||||
|
||||
#define GESTURE_MODE /* /< enable the support of the gestures */
|
||||
#ifdef GESTURE_MODE
|
||||
#define USE_GESTURE_MASK /* /< the gestures to select are
|
||||
* referred using a gesture bitmask
|
||||
* instead of their gesture IDs */
|
||||
#endif
|
||||
|
||||
|
||||
#define CHARGER_MODE /* /< enable the support to charger mode feature
|
||||
* (comment to disable) */
|
||||
|
||||
#define GLOVE_MODE /* /< enable the support to glove mode feature (comment
|
||||
* to disable) */
|
||||
|
||||
#define COVER_MODE /* /< enable the support to cover mode feature (comment
|
||||
* to disable) */
|
||||
|
||||
#define STYLUS_MODE /* /< enable the support to stylus mode feature (comment
|
||||
* to disable) */
|
||||
|
||||
#define GRIP_MODE /* /< enable the support to grip mode feature (comment
|
||||
* to disable) */
|
||||
|
||||
|
||||
/* **** END **** */
|
||||
|
||||
|
||||
/* **** PANEL SPECIFICATION **** */
|
||||
#define X_AXIS_MAX 1440 /* /< Max X coordinate of the display */
|
||||
#define X_AXIS_MIN 0 /* /< min X coordinate of the display */
|
||||
#define Y_AXIS_MAX 2959 /* /< Max Y coordinate of the display */
|
||||
#define Y_AXIS_MIN 0 /* /< min Y coordinate of the display */
|
||||
|
||||
#define PRESSURE_MIN 0 /* /< min value of pressure reported */
|
||||
#define PRESSURE_MAX 127 /* /< Max value of pressure reported */
|
||||
|
||||
#define DISTANCE_MIN 0 /* /< min distance between the tool and the
|
||||
* display */
|
||||
#define DISTANCE_MAX 127 /* /< Max distance between the tool and the
|
||||
* display */
|
||||
|
||||
#define TOUCH_ID_MAX 10 /* /< Max number of simoultaneous touches
|
||||
* reported */
|
||||
|
||||
#define AREA_MIN PRESSURE_MIN /* /< min value of Major/minor axis
|
||||
* reported */
|
||||
#define AREA_MAX PRESSURE_MAX /* /< Man value of Major/minor axis
|
||||
* reported */
|
||||
/* **** END **** */
|
||||
/**@}*/
|
||||
/*********************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* Configuration mode
|
||||
*
|
||||
* bitmask which can assume the value defined as features in ftsSoftware.h or
|
||||
* the following values
|
||||
*/
|
||||
|
||||
/** @defgroup mode_section IC Status Mode
|
||||
* Bitmask which keeps track of the features and working mode enabled in the
|
||||
* IC.
|
||||
* The meaning of the the LSB of the bitmask must be interpreted considering
|
||||
* that the value defined in @link feat_opt Feature Selection Option @endlink
|
||||
* correspond to the position of the corresponding bit in the mask
|
||||
* @{
|
||||
*/
|
||||
#define MODE_NOTHING 0x00000000 /* /< nothing enabled (sense off) */
|
||||
#define MODE_ACTIVE(_mask, _sett) (_mask |= (SCAN_MODE_ACTIVE << 24) | \
|
||||
(_sett << 16))
|
||||
/* /< store the status of scan mode active and its setting */
|
||||
#define MODE_LOW_POWER(_mask, _sett) (_mask |= (SCAN_MODE_LOW_POWER << 24) | \
|
||||
(_sett << 16))
|
||||
/* /< store the status of scan mode low power and its setting */
|
||||
#define IS_POWER_MODE(_mask, _mode) ((_mask&(_mode<<24)) != 0x00)
|
||||
/* /< check the current mode of the IC */
|
||||
|
||||
/** @}*/
|
||||
|
||||
#define CMD_STR_LEN 32 /* /< max number of parameters that can accept
|
||||
* the MP file node (stm_fts_cmd) */
|
||||
|
||||
#define TSP_BUF_SIZE PAGE_SIZE /* /< max number of bytes printable on
|
||||
* the shell in the normal file nodes */
|
||||
|
||||
|
||||
/**
|
||||
* Struct which contains information about the HW platform and set up
|
||||
*/
|
||||
struct fts_hw_platform_data {
|
||||
int (*power)(bool on);
|
||||
int irq_gpio; /* /< number of the gpio associated to the interrupt pin
|
||||
* */
|
||||
int reset_gpio; /* /< number of the gpio associated to the reset pin */
|
||||
const char *vdd_reg_name; /* /< name of the VDD regulator */
|
||||
const char *avdd_reg_name; /* /< name of the AVDD regulator */
|
||||
};
|
||||
|
||||
/*
|
||||
* Forward declaration
|
||||
*/
|
||||
struct fts_ts_info;
|
||||
extern char tag[8]; /* /< forward the definition of the label used
|
||||
* to print the log in the kernel log */
|
||||
|
||||
/*
|
||||
* Dispatch event handler
|
||||
*/
|
||||
typedef void (*event_dispatch_handler_t)
|
||||
(struct fts_ts_info *info, unsigned char *data);
|
||||
|
||||
/**
|
||||
* FTS capacitive touch screen device information
|
||||
* - dev Pointer to the structure device \n
|
||||
* - client client structure \n
|
||||
* - input_dev Input device structure \n
|
||||
* - work Work thread \n
|
||||
* - event_wq Event queue for work thread \n
|
||||
* - event_dispatch_table Event dispatch table handlers \n
|
||||
* - attrs SysFS attributes \n
|
||||
* - mode Device operating mode (bitmask) \n
|
||||
* - touch_id Bitmask for touch id (mapped to input slots) \n
|
||||
* - stylus_id Bitmask for tracking the stylus touches (mapped using the
|
||||
* touchId) \n
|
||||
* - timer Timer when operating in polling mode \n
|
||||
* - power Power on/off routine \n
|
||||
* - board HW info retrieved from device tree \n
|
||||
* - vdd_reg DVDD power regulator \n
|
||||
* - avdd_reg AVDD power regulator \n
|
||||
* - resume_bit Indicate if screen off/on \n
|
||||
* - fwupdate_stat Store the result of a fw update triggered by the host \n
|
||||
* - notifier Used for be notified from a suspend/resume event \n
|
||||
* - sensor_sleep true suspend was called, false resume was called \n
|
||||
* - wakesrc Wakeup Source struct \n
|
||||
* - input_report_mutex mutex for handling the pressure of keys \n
|
||||
* - series_of_switches to store the enabling status of a particular feature
|
||||
* from the host \n
|
||||
*/
|
||||
struct fts_ts_info {
|
||||
struct device *dev; /* /< Pointer to the structure device */
|
||||
#ifdef I2C_INTERFACE
|
||||
struct i2c_client *client; /* /< I2C client structure */
|
||||
#else
|
||||
struct spi_device *client; /* /< SPI client structure */
|
||||
#endif
|
||||
struct input_dev *input_dev; /* /< Input device structure */
|
||||
|
||||
struct work_struct work; /* /< Event work thread */
|
||||
struct work_struct suspend_work; /* /< Suspend work thread */
|
||||
struct work_struct resume_work; /* /< Resume work thread */
|
||||
struct workqueue_struct *event_wq; /* /< Workqueue used for event
|
||||
* handler, suspend and resume
|
||||
* work threads */
|
||||
|
||||
#ifndef FW_UPDATE_ON_PROBE
|
||||
struct delayed_work fwu_work; /* /< Delayed work thread for fw update
|
||||
* process */
|
||||
struct workqueue_struct *fwu_workqueue; /* /< Fw update work
|
||||
* queue */
|
||||
#endif
|
||||
event_dispatch_handler_t *event_dispatch_table; /* /< Event dispatch
|
||||
* table handlers */
|
||||
|
||||
struct attribute_group attrs; /* /< SysFS attributes */
|
||||
|
||||
unsigned int mode; /* /< Device operating mode (bitmask: msb
|
||||
* indicate if active or lpm) */
|
||||
unsigned long touch_id; /* /< Bitmask for touch id (mapped to input
|
||||
* slots) */
|
||||
#ifdef STYLUS_MODE
|
||||
unsigned long stylus_id; /* /< Bitmask for tracking the stylus
|
||||
* touches (mapped using the touchId) */
|
||||
#endif
|
||||
|
||||
|
||||
struct fts_hw_platform_data *board; /* /< HW info retrieved from
|
||||
* device tree */
|
||||
struct regulator *vdd_reg; /* /< DVDD power regulator */
|
||||
struct regulator *avdd_reg; /* /< AVDD power regulator */
|
||||
|
||||
|
||||
int resume_bit; /* /< Indicate if screen off/on */
|
||||
int fwupdate_stat; /* /< Store the result of a fw update triggered
|
||||
* by the host */
|
||||
|
||||
|
||||
struct notifier_block notifier; /* /< Used for be notified from a
|
||||
* suspend/resume event */
|
||||
bool sensor_sleep; /* /< if true suspend was called while if false
|
||||
* resume was called */
|
||||
struct wakeup_source wakesrc; /* Wake Lock struct */
|
||||
|
||||
/* input lock */
|
||||
struct mutex input_report_mutex; /* /< mutex for handling the report
|
||||
* of the pressure of keys */
|
||||
|
||||
/* switches for features */
|
||||
int gesture_enabled; /* /< if set, the gesture mode will be enabled
|
||||
* during the suspend */
|
||||
int glove_enabled; /* /< if set, the glove mode will be enabled
|
||||
* when allowed */
|
||||
int charger_enabled; /* /< if set, the charger mode will be enabled
|
||||
* when allowed */
|
||||
int stylus_enabled; /* /< if set, the stylus mode will be enabled
|
||||
* when allowed */
|
||||
int cover_enabled; /* /< if set, the cover mode will be enabled
|
||||
* when allowed */
|
||||
int grip_enabled; /* /< if set, the grip mode mode will be enabled
|
||||
* when allowed */
|
||||
};
|
||||
|
||||
|
||||
|
||||
int fts_chip_powercycle(struct fts_ts_info *info);
|
||||
extern int input_register_notifier_client(struct notifier_block *nb);
|
||||
extern int input_unregister_notifier_client(struct notifier_block *nb);
|
||||
|
||||
/* export declaration of functions in fts_proc.c */
|
||||
extern int fts_proc_init(void);
|
||||
extern int fts_proc_remove(void);
|
||||
|
||||
#endif
|
||||
12574
drivers/input/touchscreen/stmicro_mmi/fts_fw.h
Normal file
12574
drivers/input/touchscreen/stmicro_mmi/fts_fw.h
Normal file
File diff suppressed because it is too large
Load diff
7
drivers/input/touchscreen/stmicro_mmi/fts_lib/Makefile
Normal file
7
drivers/input/touchscreen/stmicro_mmi/fts_lib/Makefile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for the FTS touchscreen driver.
|
||||
#
|
||||
|
||||
|
||||
obj-y += ftsCompensation.o ftsCore.o ftsError.o ftsFrame.o ftsIO.o ftsTest.o ftsTime.o ftsTool.o ftsFlash.o ftsGesture.o
|
||||
|
||||
822
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCompensation.c
Normal file
822
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCompensation.c
Normal file
|
|
@ -0,0 +1,822 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS functions for getting Initialization Data *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
/*!
|
||||
* \file ftsCompensation.c
|
||||
* \brief Contains all the function to work with Initialization Data
|
||||
*/
|
||||
|
||||
#include "ftsCompensation.h"
|
||||
#include "ftsCore.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsFrame.h"
|
||||
#include "ftsHardware.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsTime.h"
|
||||
#include "ftsTool.h"
|
||||
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
|
||||
/**
|
||||
* Request to the FW to load the specified Initialization Data
|
||||
* @param type type of Initialization data to load @link load_opt Load Host
|
||||
* Data Option @endlink
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int requestCompensationData(u8 type)
|
||||
{
|
||||
int ret = ERROR_OP_NOT_ALLOW;
|
||||
int retry = 0;
|
||||
|
||||
logError(0, "%s %s: Requesting compensation data... attemp = %d\n", tag,
|
||||
__func__, retry + 1);
|
||||
while (retry < RETRY_COMP_DATA_READ) {
|
||||
ret = writeSysCmd(SYS_CMD_LOAD_DATA, &type, 1);
|
||||
/* send request to load in memory the Compensation Data */
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: failed at %d attemp!\n", tag,
|
||||
__func__, retry + 1);
|
||||
retry += 1;
|
||||
} else {
|
||||
logError(0,
|
||||
"%s %s: Request Compensation data FINISHED!\n",
|
||||
tag,
|
||||
__func__);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
logError(1, "%s %s: Requesting compensation data... ERROR %08X\n", tag,
|
||||
__func__, ret | ERROR_REQU_COMP_DATA);
|
||||
return ret | ERROR_REQU_COMP_DATA;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read Initialization Data Header and check that the type loaded match
|
||||
* with the one previously requested
|
||||
* @param type type of Initialization data requested @link load_opt Load Host
|
||||
* Data Option @endlink
|
||||
* @param header pointer to DataHeader variable which will contain the header
|
||||
* @param address pointer to a variable which will contain the updated address
|
||||
* to the next data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readCompensationDataHeader(u8 type, DataHeader *header, u64 *address)
|
||||
{
|
||||
u64 offset = ADDR_FRAMEBUFFER;
|
||||
u8 data[COMP_DATA_HEADER];
|
||||
int ret;
|
||||
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, offset, data,
|
||||
COMP_DATA_HEADER, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) { /* i2c function have already a retry mechanism */
|
||||
logError(1,
|
||||
"%s %s: error while reading data header ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
logError(0, "%s Read Data Header done!\n", tag);
|
||||
|
||||
if (data[0] != HEADER_SIGNATURE) {
|
||||
logError(1,
|
||||
"%s %s: The Header Signature was wrong! %02X != %02X ERROR %08X\n",
|
||||
tag, __func__, data[0], HEADER_SIGNATURE,
|
||||
ERROR_WRONG_DATA_SIGN);
|
||||
return ERROR_WRONG_DATA_SIGN;
|
||||
}
|
||||
|
||||
|
||||
if (data[1] != type) {
|
||||
logError(1, "%s %s: Wrong type found! %02X!=%02X ERROR %08X\n",
|
||||
tag, __func__, data[1], type, ERROR_DIFF_DATA_TYPE);
|
||||
return ERROR_DIFF_DATA_TYPE;
|
||||
}
|
||||
|
||||
logError(0, "%s Type = %02X of Compensation data OK!\n", tag, type);
|
||||
|
||||
header->type = type;
|
||||
|
||||
*address = offset + COMP_DATA_HEADER;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read MS Global Initialization data from the buffer such as Cx1
|
||||
* @param address pointer to a variable which contain the address from where
|
||||
* to read the data and will contain the updated address to the next data
|
||||
* @param global pointer to MutualSenseData variable which will contain the MS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readMutualSenseGlobalData(u64 *address, MutualSenseData *global)
|
||||
{
|
||||
u8 data[COMP_DATA_GLOBAL];
|
||||
int ret;
|
||||
|
||||
logError(0, "%s Address for Global data= %08llX\n", tag, *address);
|
||||
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, *address, data,
|
||||
COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: error while reading info data ERROR %08X\n",
|
||||
tag, __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
logError(0, "%s Global data Read !\n", tag);
|
||||
|
||||
global->header.force_node = data[0];
|
||||
global->header.sense_node = data[1];
|
||||
global->cx1 = data[2];
|
||||
/* all other bytes are reserved atm */
|
||||
|
||||
logError(0, "%s force_len = %d sense_len = %d CX1 = %d\n", tag,
|
||||
global->header.force_node, global->header.sense_node,
|
||||
global->cx1);
|
||||
|
||||
*address += COMP_DATA_GLOBAL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read MS Initialization data for each node from the buffer
|
||||
* @param address a variable which contain the address from where to read the
|
||||
* data
|
||||
* @param node pointer to MutualSenseData variable which will contain the MS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readMutualSenseNodeData(u64 address, MutualSenseData *node)
|
||||
{
|
||||
int ret;
|
||||
int size = node->header.force_node * node->header.sense_node;
|
||||
|
||||
logError(0, "%s Address for Node data = %08llX\n", tag, address);
|
||||
|
||||
node->node_data = (i8 *)kmalloc(size * (sizeof(i8)), GFP_KERNEL);
|
||||
|
||||
if (node->node_data == NULL) {
|
||||
logError(1, "%s %s: can not allocate node_data... ERROR %08X",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
logError(0, "%s Node Data to read %d bytes\n", tag, size);
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address,
|
||||
node->node_data, size, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while reading node data ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ret);
|
||||
kfree(node->node_data);
|
||||
return ret;
|
||||
}
|
||||
node->node_data_size = size;
|
||||
|
||||
logError(0, "%s Read node data OK!\n", tag);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform all the steps to read the necessary info for MS Initialization data
|
||||
* from the buffer and store it in a MutualSenseData variable
|
||||
* @param type type of MS Initialization data to read @link load_opt Load Host
|
||||
* Data Option @endlink
|
||||
* @param data pointer to MutualSenseData variable which will contain the MS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readMutualSenseCompensationData(u8 type, MutualSenseData *data)
|
||||
{
|
||||
int ret;
|
||||
u64 address;
|
||||
|
||||
data->node_data = NULL;
|
||||
|
||||
if (!(type == LOAD_CX_MS_TOUCH || type == LOAD_CX_MS_LOW_POWER ||
|
||||
type == LOAD_CX_MS_KEY || type == LOAD_CX_MS_FORCE)) {
|
||||
logError(1,
|
||||
"%s %s: Choose a MS type of compensation data ERROR %08X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = requestCompensationData(type);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_REQU_COMP_DATA);
|
||||
return ret | ERROR_REQU_COMP_DATA;
|
||||
}
|
||||
|
||||
ret = readCompensationDataHeader(type, &(data->header), &address);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_HEADER);
|
||||
return ret | ERROR_COMP_DATA_HEADER;
|
||||
}
|
||||
|
||||
ret = readMutualSenseGlobalData(&address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_GLOBAL);
|
||||
return ret | ERROR_COMP_DATA_GLOBAL;
|
||||
}
|
||||
|
||||
ret = readMutualSenseNodeData(address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_NODE);
|
||||
return ret | ERROR_COMP_DATA_NODE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read SS Global Initialization data from the buffer such as Ix1/Cx1 for force
|
||||
* and sense
|
||||
* @param address pointer to a variable which contain the address from where
|
||||
* to read the data and will contain the updated address to the next data
|
||||
* @param global pointer to MutualSenseData variable which will contain the SS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readSelfSenseGlobalData(u64 *address, SelfSenseData *global)
|
||||
{
|
||||
int ret;
|
||||
u8 data[COMP_DATA_GLOBAL];
|
||||
|
||||
logError(0, "%s Address for Global data= %08llX\n", tag, *address);
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, *address, data,
|
||||
COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while reading the data... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
logError(0, "%s Global data Read !\n", tag);
|
||||
|
||||
|
||||
global->header.force_node = data[0];
|
||||
global->header.sense_node = data[1];
|
||||
global->f_ix1 = data[2];
|
||||
global->s_ix1 = data[3];
|
||||
global->f_cx1 = (i8)data[4];
|
||||
global->s_cx1 = (i8)data[5];
|
||||
global->f_max_n = data[6];
|
||||
global->s_max_n = data[7];
|
||||
global->f_ix0 = data[8];
|
||||
global->s_ix0 = data[9];
|
||||
|
||||
logError(0,
|
||||
"%s force_len = %d sense_len = %d f_ix1 = %d s_ix1 = %d f_cx1 = %d s_cx1 = %d\n",
|
||||
tag, global->header.force_node, global->header.sense_node,
|
||||
global->f_ix1, global->s_ix1, global->f_cx1, global->s_cx1);
|
||||
logError(0, "%s max_n = %d s_max_n = %d f_ix0 = %d s_ix0 = %d\n",
|
||||
tag, global->f_max_n, global->s_max_n,
|
||||
global->f_ix0, global->s_ix0);
|
||||
|
||||
*address += COMP_DATA_GLOBAL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read SS Initialization data for each node of force and sense channels from
|
||||
* the buffer
|
||||
* @param address a variable which contain the address from where to read the
|
||||
* data
|
||||
* @param node pointer to SelfSenseData variable which will contain the SS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readSelfSenseNodeData(u64 address, SelfSenseData *node)
|
||||
{
|
||||
int size = node->header.force_node * 2 + node->header.sense_node * 2;
|
||||
u8 data[size];
|
||||
int ret;
|
||||
|
||||
node->ix2_fm = (u8 *)kmalloc(node->header.force_node * (sizeof(u8)),
|
||||
GFP_KERNEL);
|
||||
if (node->ix2_fm == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for ix2_fm... ERROR %08X",
|
||||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
node->cx2_fm = (i8 *)kmalloc(node->header.force_node * (sizeof(i8)),
|
||||
GFP_KERNEL);
|
||||
if (node->cx2_fm == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for cx2_fm ... ERROR %08X",
|
||||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix2_fm);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->ix2_sn = (u8 *)kmalloc(node->header.sense_node * (sizeof(u8)),
|
||||
GFP_KERNEL);
|
||||
if (node->ix2_sn == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for ix2_sn ERROR %08X",
|
||||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix2_fm);
|
||||
kfree(node->cx2_fm);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->cx2_sn = (i8 *)kmalloc(node->header.sense_node * (sizeof(i8)),
|
||||
GFP_KERNEL);
|
||||
if (node->cx2_sn == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for cx2_sn ERROR %08X",
|
||||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix2_fm);
|
||||
kfree(node->cx2_fm);
|
||||
kfree(node->ix2_sn);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
|
||||
logError(0, "%s Address for Node data = %08llX\n", tag, address);
|
||||
|
||||
logError(0, "%s Node Data to read %d bytes\n", tag, size);
|
||||
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, data,
|
||||
size, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: error while reading data... ERROR %08X\n",
|
||||
tag, __func__, ret);
|
||||
kfree(node->ix2_fm);
|
||||
kfree(node->cx2_fm);
|
||||
kfree(node->ix2_sn);
|
||||
kfree(node->cx2_sn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
logError(0, "%s Read node data ok!\n", tag);
|
||||
|
||||
memcpy(node->ix2_fm, data, node->header.force_node);
|
||||
memcpy(node->ix2_sn, &data[node->header.force_node],
|
||||
node->header.sense_node);
|
||||
memcpy(node->cx2_fm, &data[node->header.force_node +
|
||||
node->header.sense_node],
|
||||
node->header.force_node);
|
||||
memcpy(node->cx2_sn, &data[node->header.force_node * 2 +
|
||||
node->header.sense_node],
|
||||
node->header.sense_node);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform all the steps to read the necessary info for SS Initialization data
|
||||
* from the buffer and store it in a SelfSenseData variable
|
||||
* @param type type of SS Initialization data to read @link load_opt Load Host
|
||||
* Data Option @endlink
|
||||
* @param data pointer to SelfSenseData variable which will contain the SS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readSelfSenseCompensationData(u8 type, SelfSenseData *data)
|
||||
{
|
||||
int ret;
|
||||
u64 address;
|
||||
|
||||
data->ix2_fm = NULL;
|
||||
data->cx2_fm = NULL;
|
||||
data->ix2_sn = NULL;
|
||||
data->cx2_sn = NULL;
|
||||
|
||||
if (!(type == LOAD_CX_SS_TOUCH || type == LOAD_CX_SS_TOUCH_IDLE ||
|
||||
type == LOAD_CX_SS_KEY || type == LOAD_CX_SS_FORCE)) {
|
||||
logError(1,
|
||||
"%s %s: Choose a SS type of compensation data ERROR %08X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = requestCompensationData(type);
|
||||
if (ret < 0) {
|
||||
logError(1,
|
||||
"%s %s: error while requesting data... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_REQU_COMP_DATA);
|
||||
return ret | ERROR_REQU_COMP_DATA;
|
||||
}
|
||||
|
||||
ret = readCompensationDataHeader(type, &(data->header), &address);
|
||||
if (ret < 0) {
|
||||
logError(1,
|
||||
"%s %s: error while reading data header... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_COMP_DATA_HEADER);
|
||||
return ret | ERROR_COMP_DATA_HEADER;
|
||||
}
|
||||
|
||||
ret = readSelfSenseGlobalData(&address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_GLOBAL);
|
||||
return ret | ERROR_COMP_DATA_GLOBAL;
|
||||
}
|
||||
|
||||
ret = readSelfSenseNodeData(address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_NODE);
|
||||
return ret | ERROR_COMP_DATA_NODE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read TOT MS Global Initialization data from the buffer such as number of
|
||||
* force and sense channels
|
||||
* @param address pointer to a variable which contain the address from where
|
||||
* to read the data and will contain the updated address to the next data
|
||||
* @param global pointer to a variable which will contain the TOT MS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readTotMutualSenseGlobalData(u64 *address, TotMutualSenseData *global)
|
||||
{
|
||||
int ret;
|
||||
u8 data[COMP_DATA_GLOBAL];
|
||||
|
||||
logError(0, "%s Address for Global data= %04llX\n", tag, *address);
|
||||
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, *address, data,
|
||||
COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: error while reading info data ERROR %08X\n",
|
||||
tag, __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
logError(0, "%s Global data Read !\n", tag);
|
||||
|
||||
global->header.force_node = data[0];
|
||||
global->header.sense_node = data[1];
|
||||
/* all other bytes are reserved atm */
|
||||
|
||||
logError(0, "%s force_len = %d sense_len = %d\n", tag,
|
||||
global->header.force_node, global->header.sense_node);
|
||||
|
||||
*address += COMP_DATA_GLOBAL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read TOT MS Initialization data for each node from the buffer
|
||||
* @param address a variable which contain the address from where to read the
|
||||
* data
|
||||
* @param node pointer to MutualSenseData variable which will contain the TOT
|
||||
* MS initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readTotMutualSenseNodeData(u64 address, TotMutualSenseData *node)
|
||||
{
|
||||
int ret, i;
|
||||
int size = node->header.force_node * node->header.sense_node;
|
||||
int toRead = size * sizeof(u16);
|
||||
u8 data[toRead];
|
||||
|
||||
logError(0, "%s Address for Node data = %04llX\n", tag, address);
|
||||
|
||||
node->node_data = (short *)kmalloc(size * (sizeof(short)), GFP_KERNEL);
|
||||
|
||||
if (node->node_data == NULL) {
|
||||
logError(1, "%s %s: can not allocate node_data... ERROR %08X",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
logError(0, "%s Node Data to read %d bytes\n", tag, size);
|
||||
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, data,
|
||||
toRead, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while reading node data ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ret);
|
||||
kfree(node->node_data);
|
||||
return ret;
|
||||
}
|
||||
node->node_data_size = size;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
node->node_data[i] = ((short)data[i * 2 + 1]) << 8 | data[i *
|
||||
2];
|
||||
|
||||
logError(0, "%s Read node data OK!\n", tag);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform all the steps to read the necessary info for TOT MS Initialization
|
||||
* data from the buffer and store it in a TotMutualSenseData variable
|
||||
* @param type type of TOT MS Initialization data to read @link load_opt Load
|
||||
* Host Data Option @endlink
|
||||
* @param data pointer to a variable which will contain the TOT MS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readTotMutualSenseCompensationData(u8 type, TotMutualSenseData *data)
|
||||
{
|
||||
int ret;
|
||||
u64 address;
|
||||
|
||||
data->node_data = NULL;
|
||||
|
||||
if (!(type == LOAD_PANEL_CX_TOT_MS_TOUCH || type ==
|
||||
LOAD_PANEL_CX_TOT_MS_LOW_POWER || type ==
|
||||
LOAD_PANEL_CX_TOT_MS_KEY ||
|
||||
type == LOAD_PANEL_CX_TOT_MS_FORCE)) {
|
||||
logError(1,
|
||||
"%s %s: Choose a TOT MS type of compensation data ERROR %08X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = requestCompensationData(type);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_REQU_COMP_DATA);
|
||||
return ret | ERROR_REQU_COMP_DATA;
|
||||
}
|
||||
|
||||
ret = readCompensationDataHeader(type, &(data->header), &address);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_HEADER);
|
||||
return ret | ERROR_COMP_DATA_HEADER;
|
||||
}
|
||||
|
||||
ret = readTotMutualSenseGlobalData(&address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_GLOBAL);
|
||||
return ret | ERROR_COMP_DATA_GLOBAL;
|
||||
}
|
||||
|
||||
ret = readTotMutualSenseNodeData(address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_NODE);
|
||||
return ret | ERROR_COMP_DATA_NODE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read TOT SS Global Initialization data from the buffer such as number of
|
||||
* force and sense channels
|
||||
* @param address pointer to a variable which contain the address from where
|
||||
* to read the data and will contain the updated address to the next data
|
||||
* @param global pointer to a variable which will contain the TOT SS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readTotSelfSenseGlobalData(u64 *address, TotSelfSenseData *global)
|
||||
{
|
||||
int ret;
|
||||
u8 data[COMP_DATA_GLOBAL];
|
||||
|
||||
logError(0, "%s Address for Global data= %04llX\n", tag, *address);
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, *address, data,
|
||||
COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while reading the data... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
logError(0, "%s Global data Read !\n", tag);
|
||||
|
||||
|
||||
global->header.force_node = data[0];
|
||||
global->header.sense_node = data[1];
|
||||
|
||||
|
||||
logError(0, "%s force_len = %d sense_len = %d\n", tag,
|
||||
global->header.force_node, global->header.sense_node);
|
||||
|
||||
|
||||
*address += COMP_DATA_GLOBAL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read TOT SS Global Initialization data from the buffer such as number of
|
||||
* force and sense channels
|
||||
* @param address pointer to a variable which contain the address from where
|
||||
* to read the data and will contain the updated address to the next data
|
||||
* @param node pointer to a variable which will contain the TOT SS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readTotSelfSenseNodeData(u64 address, TotSelfSenseData *node)
|
||||
{
|
||||
int size = node->header.force_node * 2 + node->header.sense_node * 2;
|
||||
int toRead = size * 2; /* *2 2 bytes each node */
|
||||
u8 data[toRead];
|
||||
int ret, i, j = 0;
|
||||
|
||||
node->ix_fm = (u16 *)kmalloc(node->header.force_node * (sizeof(u16)),
|
||||
GFP_KERNEL);
|
||||
if (node->ix_fm == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for ix2_fm... ERROR %08X",
|
||||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
node->cx_fm = (short *)kmalloc(node->header.force_node *
|
||||
(sizeof(short)), GFP_KERNEL);
|
||||
if (node->cx_fm == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for cx2_fm ... ERROR %08X",
|
||||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix_fm);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->ix_sn = (u16 *)kmalloc(node->header.sense_node * (sizeof(u16)),
|
||||
GFP_KERNEL);
|
||||
if (node->ix_sn == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for ix2_sn ERROR %08X",
|
||||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix_fm);
|
||||
kfree(node->cx_fm);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->cx_sn = (short *)kmalloc(node->header.sense_node *
|
||||
(sizeof(short)), GFP_KERNEL);
|
||||
if (node->cx_sn == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for cx2_sn ERROR %08X",
|
||||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix_fm);
|
||||
kfree(node->cx_fm);
|
||||
kfree(node->ix_sn);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
|
||||
logError(0, "%s Address for Node data = %04llX\n", tag, address);
|
||||
|
||||
logError(0, "%s Node Data to read %d bytes\n", tag, size);
|
||||
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, data,
|
||||
toRead, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: error while reading data... ERROR %08X\n",
|
||||
tag, __func__, ret);
|
||||
kfree(node->ix_fm);
|
||||
kfree(node->cx_fm);
|
||||
kfree(node->ix_sn);
|
||||
kfree(node->cx_sn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
logError(0, "%s Read node data ok!\n", tag);
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < node->header.force_node; i++) {
|
||||
node->ix_fm[i] = ((u16)data[j + 1]) << 8 | data[j];
|
||||
j += 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < node->header.sense_node; i++) {
|
||||
node->ix_sn[i] = ((u16)data[j + 1]) << 8 | data[j];
|
||||
j += 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < node->header.force_node; i++) {
|
||||
node->cx_fm[i] = ((short)data[j + 1]) << 8 | data[j];
|
||||
j += 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < node->header.sense_node; i++) {
|
||||
node->cx_sn[i] = ((short)data[j + 1]) << 8 | data[j];
|
||||
j += 2;
|
||||
}
|
||||
|
||||
if (j != toRead)
|
||||
logError(1, "%s %s: parsed a wrong number of bytes %d!=%d\n",
|
||||
tag, __func__, j, toRead);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform all the steps to read the necessary info for TOT SS Initialization
|
||||
* data from the buffer and store it in a TotSelfSenseData variable
|
||||
* @param type type of TOT MS Initialization data to read @link load_opt Load
|
||||
* Host Data Option @endlink
|
||||
* @param data pointer to a variable which will contain the TOT MS
|
||||
* initialization data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readTotSelfSenseCompensationData(u8 type, TotSelfSenseData *data)
|
||||
{
|
||||
int ret;
|
||||
u64 address;
|
||||
|
||||
data->ix_fm = NULL;
|
||||
data->cx_fm = NULL;
|
||||
data->ix_sn = NULL;
|
||||
data->cx_sn = NULL;
|
||||
|
||||
if (!(type == LOAD_PANEL_CX_TOT_SS_TOUCH || type ==
|
||||
LOAD_PANEL_CX_TOT_SS_TOUCH_IDLE || type ==
|
||||
LOAD_PANEL_CX_TOT_SS_KEY ||
|
||||
type == LOAD_PANEL_CX_TOT_SS_FORCE)) {
|
||||
logError(1,
|
||||
"%s %s: Choose a TOT SS type of compensation data ERROR %08X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = requestCompensationData(type);
|
||||
if (ret < 0) {
|
||||
logError(1,
|
||||
"%s %s: error while requesting data... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_REQU_COMP_DATA);
|
||||
return ret | ERROR_REQU_COMP_DATA;
|
||||
}
|
||||
|
||||
ret = readCompensationDataHeader(type, &(data->header), &address);
|
||||
if (ret < 0) {
|
||||
logError(1,
|
||||
"%s %s: error while reading data header... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_COMP_DATA_HEADER);
|
||||
return ret | ERROR_COMP_DATA_HEADER;
|
||||
}
|
||||
|
||||
ret = readTotSelfSenseGlobalData(&address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_GLOBAL);
|
||||
return ret | ERROR_COMP_DATA_GLOBAL;
|
||||
}
|
||||
|
||||
ret = readTotSelfSenseNodeData(address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_COMP_DATA_NODE);
|
||||
return ret | ERROR_COMP_DATA_NODE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
136
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCompensation.h
Normal file
136
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCompensation.h
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS functions for getting Initialization Data **
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsCompensation.h
|
||||
* \brief Contains all the definitions and structs to work with Initialization
|
||||
* Data
|
||||
*/
|
||||
|
||||
#ifndef FTS_COMPENSATION_H
|
||||
#define FTS_COMPENSATION_H
|
||||
|
||||
#include "ftsCore.h"
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
|
||||
|
||||
#define RETRY_COMP_DATA_READ 2 /* /< max number of attempts to read
|
||||
* initialization data */
|
||||
|
||||
|
||||
/* Bytes dimension of Compensation Data Format */
|
||||
|
||||
#define COMP_DATA_HEADER DATA_HEADER /* /< size in bytes of
|
||||
* initialization data header */
|
||||
#define COMP_DATA_GLOBAL (16 - COMP_DATA_HEADER) /* /< size in bytes
|
||||
* of initialization
|
||||
*data general info */
|
||||
|
||||
|
||||
#define HEADER_SIGNATURE 0xA5 /* /< signature used as starting byte of
|
||||
* data loaded in memory */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Struct which contains the general info about Frames and Initialization Data
|
||||
*/
|
||||
typedef struct {
|
||||
int force_node; /* /< Number of Force Channels in the
|
||||
* frame/Initialization data */
|
||||
int sense_node; /* /< Number of Sense Channels in the
|
||||
* frame/Initialization data */
|
||||
int type; /* /< Type of frame/Initialization data */
|
||||
} DataHeader;
|
||||
|
||||
/**
|
||||
* Struct which contains the MS Initialization data
|
||||
*/
|
||||
typedef struct {
|
||||
DataHeader header; /* /< Header */
|
||||
i8 cx1; /* /< Cx1 value (can be negative)) */
|
||||
i8 *node_data; /* /< Pointer to an array of bytes which contains the
|
||||
* CX2 data (can be negative) */
|
||||
int node_data_size; /* /< size of the data */
|
||||
} MutualSenseData;
|
||||
|
||||
|
||||
/**
|
||||
* Struct which contains the SS Initialization data
|
||||
*/
|
||||
typedef struct {
|
||||
DataHeader header; /* /< Header */
|
||||
u8 f_ix1; /* /< IX1 Force */
|
||||
u8 s_ix1; /* /< IX1 Sense */
|
||||
i8 f_cx1; /* /< CX1 Force (can be negative) */
|
||||
i8 s_cx1; /* /< CX1 Sense (can be negative) */
|
||||
u8 f_max_n; /* /< Force MaxN */
|
||||
u8 s_max_n; /* /< Sense MaxN */
|
||||
u8 f_ix0; /* /< IX0 Force */
|
||||
u8 s_ix0; /* /< IX0 Sense */
|
||||
u8 *ix2_fm; /* /< pointer to an array of bytes which contains Force
|
||||
* Ix2 data node */
|
||||
u8 *ix2_sn; /* /< pointer to an array of bytes which contains Sense
|
||||
* Ix2 data node */
|
||||
i8 *cx2_fm; /* /< pointer to an array of bytes which contains Force
|
||||
* Cx2 data node (can be negative) */
|
||||
i8 *cx2_sn; /* /< pointer to an array of bytes which contains Sense
|
||||
* Cx2 data node (can be negative)) */
|
||||
} SelfSenseData;
|
||||
|
||||
/**
|
||||
* Struct which contains the TOT MS Initialization data
|
||||
*/
|
||||
typedef struct {
|
||||
DataHeader header; /* /< Header */
|
||||
short *node_data; /* /< pointer to an array of ushort which
|
||||
* contains TOT MS Initialization data */
|
||||
int node_data_size; /* /< size of data */
|
||||
} TotMutualSenseData;
|
||||
|
||||
/**
|
||||
* Struct which contains the TOT SS Initialization data
|
||||
*/
|
||||
typedef struct {
|
||||
DataHeader header; /* /< Header */
|
||||
|
||||
u16 *ix_fm; /* /< pointer to an array of ushort which contains TOT
|
||||
* SS IX Force data */
|
||||
u16 *ix_sn; /* /< pointer to an array of ushort which contains TOT
|
||||
* SS IX Sense data */
|
||||
short *cx_fm; /* /< pointer to an array of ushort which contains TOT
|
||||
* SS CX Force data (can be negative) */
|
||||
short *cx_sn; /* /< pointer to an array of ushort which contains TOT
|
||||
* SS CX Sense data (can be negative) */
|
||||
} TotSelfSenseData;
|
||||
|
||||
|
||||
|
||||
int requestCompensationData(u8 type);
|
||||
int readCompensationDataHeader(u8 type, DataHeader *header, u64 *address);
|
||||
int readMutualSenseGlobalData(u64 *address, MutualSenseData *global);
|
||||
int readMutualSenseNodeData(u64 address, MutualSenseData *node);
|
||||
int readMutualSenseCompensationData(u8 type, MutualSenseData *data);
|
||||
int readSelfSenseGlobalData(u64 *address, SelfSenseData *global);
|
||||
int readSelfSenseNodeData(u64 address, SelfSenseData *node);
|
||||
int readSelfSenseCompensationData(u8 type, SelfSenseData *data);
|
||||
int readToTMutualSenseGlobalData(u64 *address, TotMutualSenseData *global);
|
||||
int readToTMutualSenseNodeData(u64 address, TotMutualSenseData *node);
|
||||
int readTotMutualSenseCompensationData(u8 type, TotMutualSenseData *data);
|
||||
int readTotSelfSenseGlobalData(u64 *address, TotSelfSenseData *global);
|
||||
int readTotSelfSenseNodeData(u64 address, TotSelfSenseData *node);
|
||||
int readTotSelfSenseCompensationData(u8 type, TotSelfSenseData *data);
|
||||
#endif
|
||||
1155
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCore.c
Normal file
1155
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCore.c
Normal file
File diff suppressed because it is too large
Load diff
219
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCore.h
Normal file
219
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsCore.h
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Core definitions **
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsCore.h
|
||||
* \brief Contains all the definitions and structs of Core functionalities
|
||||
*/
|
||||
|
||||
#ifndef FTS_CORE_H
|
||||
#define FTS_CORE_H
|
||||
|
||||
#include "ftsHardware.h"
|
||||
#include "ftsSoftware.h"
|
||||
#include "../fts.h"
|
||||
|
||||
/* HW DATA */
|
||||
#define GPIO_NOT_DEFINED -1 /* /< value assumed by reset_gpio when
|
||||
* the reset pin of the IC is not
|
||||
* connected */
|
||||
|
||||
|
||||
#define ADDR_SIZE_HW_REG BITS_32 /* /< value of AddrSize for Hw register
|
||||
* in FTI @see AddrSize */
|
||||
|
||||
|
||||
#define DATA_HEADER 4 /* /< size in byte of the header loaded
|
||||
* with the data in the frambuffer */
|
||||
|
||||
/**
|
||||
* Type of CRC errors
|
||||
*/
|
||||
typedef enum {
|
||||
CRC_CODE = 1, /* /< CRC in the code section */
|
||||
CRC_CONFIG = 2, /* /< CRC in the config section */
|
||||
CRC_CX = 3, /* /< CRC in the cx section */
|
||||
CRC_PANEL = 4 /* /< CRC in the panel section */
|
||||
} CRC_Error;
|
||||
|
||||
/* CHIP INFO */
|
||||
/** @defgroup system_info System Info
|
||||
* System Info Data collect the most important informations about hw and fw
|
||||
* @{
|
||||
*/
|
||||
/* Size in bytes of System Info data */
|
||||
#define SYS_INFO_SIZE 216 /* Num bytes of die info */
|
||||
#define DIE_INFO_SIZE 16 /* Num bytes of external release
|
||||
* in config */
|
||||
#define EXTERNAL_RELEASE_INFO_SIZE 8 /* Num bytes of release info in
|
||||
* sys info
|
||||
* (first bytes are external
|
||||
*release) */
|
||||
#define RELEASE_INFO_SIZE (EXTERNAL_RELEASE_INFO_SIZE)
|
||||
/** @}*/
|
||||
|
||||
/* RETRY MECHANISM */
|
||||
#define RETRY_MAX_REQU_DATA 2 /* /< Max number of attemps
|
||||
* performed
|
||||
* when requesting data */
|
||||
#define RETRY_SYSTEM_RESET 3 /* /< Max number of attemps
|
||||
* performed
|
||||
* to reset the IC */
|
||||
|
||||
/** @addtogroup system_info
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Struct which contains fundamental informations about the chip and its
|
||||
*configuration
|
||||
*/
|
||||
typedef struct {
|
||||
u16 u16_apiVer_rev; /* /< API revision version */
|
||||
u8 u8_apiVer_minor; /* /< API minor version */
|
||||
u8 u8_apiVer_major; /* /< API major version */
|
||||
u16 u16_chip0Ver; /* /< Dev0 version */
|
||||
u16 u16_chip0Id; /* /< Dev0 ID */
|
||||
u16 u16_chip1Ver; /* /< Dev1 version */
|
||||
u16 u16_chip1Id; /* /< Dev1 ID */
|
||||
u16 u16_fwVer; /* /< Fw version */
|
||||
u16 u16_svnRev; /* /< SVN Revision */
|
||||
u16 u16_cfgVer; /* /< Config Version */
|
||||
u16 u16_cfgProjectId; /* /< Config Project ID */
|
||||
u16 u16_cxVer; /* /< Cx Version */
|
||||
u16 u16_cxProjectId; /* /< Cx Project ID */
|
||||
u8 u8_cfgAfeVer; /* /< AFE version in Config */
|
||||
u8 u8_cxAfeVer; /* /< AFE version in CX */
|
||||
u8 u8_panelCfgAfeVer; /* /< AFE version in PanelMem */
|
||||
u8 u8_protocol; /* /< Touch Report Protocol */
|
||||
u8 u8_dieInfo[DIE_INFO_SIZE]; /* /< Die information */
|
||||
u8 u8_releaseInfo[RELEASE_INFO_SIZE]; /* /< Release information */
|
||||
u32 u32_fwCrc; /* /< Crc of FW */
|
||||
u32 u32_cfgCrc; /* /< Crc of config */
|
||||
u8 u8_mpFlag; /* /< MP Flag */
|
||||
u8 u8_ssDetScanSet; /* /< Type of Detect Scan Selected */
|
||||
|
||||
u16 u16_scrResX; /* /< X resolution on main screen */
|
||||
u16 u16_scrResY; /* /< Y resolution on main screen */
|
||||
u8 u8_scrTxLen; /* /< Tx length */
|
||||
u8 u8_scrRxLen; /* /< Rx length */
|
||||
u8 u8_keyLen; /* /< Key Len */
|
||||
u8 u8_forceLen; /* /< Force Len */
|
||||
u32 u32_productionTimestamp; /* /< Production Timestamp */
|
||||
|
||||
u16 u16_dbgInfoAddr; /* /< Offset of debug Info structure */
|
||||
|
||||
u16 u16_msTchRawAddr; /* /< Offset of MS touch raw frame */
|
||||
u16 u16_msTchFilterAddr; /* /< Offset of MS touch filter frame */
|
||||
u16 u16_msTchStrenAddr; /* /< Offset of MS touch strength frame */
|
||||
u16 u16_msTchBaselineAddr; /* /< Offset of MS touch baseline frame
|
||||
* */
|
||||
|
||||
u16 u16_ssTchTxRawAddr; /* /< Offset of SS touch force raw frame */
|
||||
u16 u16_ssTchTxFilterAddr; /* /< Offset of SS touch force filter
|
||||
* frame */
|
||||
u16 u16_ssTchTxStrenAddr; /* /< Offset of SS touch force strength
|
||||
* frame */
|
||||
u16 u16_ssTchTxBaselineAddr; /* /< Offset of SS touch force baseline
|
||||
* frame */
|
||||
|
||||
u16 u16_ssTchRxRawAddr; /* /< Offset of SS touch sense raw frame */
|
||||
u16 u16_ssTchRxFilterAddr; /* /< Offset of SS touch sense filter
|
||||
* frame */
|
||||
u16 u16_ssTchRxStrenAddr; /* /< Offset of SS touch sense strength
|
||||
* frame */
|
||||
u16 u16_ssTchRxBaselineAddr; /* /< Offset of SS touch sense baseline
|
||||
* frame */
|
||||
|
||||
u16 u16_keyRawAddr; /* /< Offset of key raw frame */
|
||||
u16 u16_keyFilterAddr; /* /< Offset of key filter frame */
|
||||
u16 u16_keyStrenAddr; /* /< Offset of key strength frame */
|
||||
u16 u16_keyBaselineAddr; /* /< Offset of key baseline frame */
|
||||
|
||||
u16 u16_frcRawAddr; /* /< Offset of force touch raw frame */
|
||||
u16 u16_frcFilterAddr; /* /< Offset of force touch filter frame */
|
||||
u16 u16_frcStrenAddr; /* /< Offset of force touch strength frame */
|
||||
u16 u16_frcBaselineAddr; /* /< Offset of force touch baseline
|
||||
* frame */
|
||||
|
||||
u16 u16_ssHvrTxRawAddr; /* /< Offset of SS hover Force raw frame */
|
||||
u16 u16_ssHvrTxFilterAddr; /* /< Offset of SS hover Force filter
|
||||
* frame */
|
||||
u16 u16_ssHvrTxStrenAddr; /* /< Offset of SS hover Force strength
|
||||
* frame */
|
||||
u16 u16_ssHvrTxBaselineAddr; /* /< Offset of SS hover Force baseline
|
||||
* frame */
|
||||
|
||||
u16 u16_ssHvrRxRawAddr; /* /< Offset of SS hover Sense raw frame */
|
||||
u16 u16_ssHvrRxFilterAddr; /* /< Offset of SS hover Sense filter
|
||||
* frame */
|
||||
u16 u16_ssHvrRxStrenAddr; /* /< Offset of SS hover Sense strength
|
||||
* frame */
|
||||
u16 u16_ssHvrRxBaselineAddr; /* /< Offset of SS hover Sense baseline
|
||||
* frame */
|
||||
|
||||
u16 u16_ssPrxTxRawAddr; /* /< Offset of SS proximity force raw frame */
|
||||
u16 u16_ssPrxTxFilterAddr; /* /< Offset of SS proximity force
|
||||
* filter frame */
|
||||
u16 u16_ssPrxTxStrenAddr; /* /< Offset of SS proximity force
|
||||
* strength frame */
|
||||
u16 u16_ssPrxTxBaselineAddr; /* /< Offset of SS proximity force
|
||||
* baseline frame */
|
||||
|
||||
u16 u16_ssPrxRxRawAddr; /* /< Offset of SS proximity sense raw frame */
|
||||
u16 u16_ssPrxRxFilterAddr; /* /< Offset of SS proximity sense
|
||||
* filter frame */
|
||||
u16 u16_ssPrxRxStrenAddr; /* /< Offset of SS proximity sense
|
||||
* strength frame */
|
||||
u16 u16_ssPrxRxBaselineAddr; /* /< Offset of SS proximity sense
|
||||
* baseline frame */
|
||||
|
||||
u16 u16_ssDetRawAddr; /* /< Offset of SS detect raw frame */
|
||||
u16 u16_ssDetFilterAddr; /* /< Offset of SS detect filter
|
||||
* frame */
|
||||
u16 u16_ssDetStrenAddr; /* /< Offset of SS detect strength
|
||||
* frame */
|
||||
u16 u16_ssDetBaselineAddr; /* /< Offset of SS detect baseline
|
||||
* frame */
|
||||
} SysInfo;
|
||||
|
||||
/** @}*/
|
||||
|
||||
int initCore(struct fts_ts_info *info);
|
||||
void setResetGpio(int gpio);
|
||||
int fts_system_reset(void);
|
||||
int isSystemResettedUp(void);
|
||||
int isSystemResettedDown(void);
|
||||
void setSystemResetedUp(int val);
|
||||
void setSystemResetedDown(int val);
|
||||
int pollForEvent(int *event_to_search, int event_bytes, u8 *readData, int
|
||||
time_to_wait);
|
||||
int checkEcho(u8 *cmd, int size);
|
||||
int setScanMode(u8 mode, u8 settings);
|
||||
int setFeatures(u8 feat, u8 *settings, int size);
|
||||
int defaultSysInfo(int i2cError);
|
||||
int writeSysCmd(u8 sys_cmd, u8 *sett, int size);
|
||||
int readSysInfo(int request);
|
||||
int readConfig(u16 offset, u8 *outBuf, int len);
|
||||
int writeConfig(u16 offset, u8 *data, int len);
|
||||
int fts_disableInterrupt(void);
|
||||
int fts_disableInterruptNoSync(void);
|
||||
int fts_resetDisableIrqCount(void);
|
||||
int fts_enableInterrupt(void);
|
||||
int fts_crc_check(void);
|
||||
int requestSyncFrame(u8 type);
|
||||
int saveMpFlag(u8 mpflag);
|
||||
|
||||
#endif /* FTS_CORE_H */
|
||||
371
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsError.c
Normal file
371
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsError.c
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS error/info kernel log reporting *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsError.c
|
||||
* \brief Contains all the function which handle with Error conditions
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
#include "../fts.h"
|
||||
#include "ftsCore.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsTool.h"
|
||||
#include "ftsCompensation.h"
|
||||
|
||||
|
||||
static ErrorList errors; /* /< private variable which implement the Error
|
||||
* List */
|
||||
|
||||
/**
|
||||
* Print messages in the kernel log
|
||||
* @param force if 1, the log is printed always otherwise only if DEBUG is
|
||||
* defined, the log will be printed
|
||||
* @param msg string containing the message to print
|
||||
* @param ... additional parameters that are used in msg according the format
|
||||
* of printf
|
||||
*/
|
||||
void logError(int force, const char *msg, ...)
|
||||
{
|
||||
if (force == 1
|
||||
#ifdef DEBUG
|
||||
|| 1
|
||||
#endif
|
||||
) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
vprintk(msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an error code is related to an I2C failure
|
||||
* @param error error code to check
|
||||
* @return 1 if the first level error code is I2C related otherwise 0
|
||||
*/
|
||||
int isI2cError(int error)
|
||||
{
|
||||
if (((error & 0x000000FF) >= (ERROR_BUS_R & 0x000000FF)) &&
|
||||
((error & 0x000000FF) <= (ERROR_BUS_O & 0x000000FF)))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dump in the kernel log some debug info in case of FW hang
|
||||
* @param outBuf (optional)pointer to bytes array where to copy the debug info,
|
||||
* if NULL the data will just printed on the kernel log
|
||||
* @param size dimension in bytes of outBuf,
|
||||
* if > ERROR_DUMP_ROW_SIZE*ERROR_DUMP_COL_SIZE, only the first
|
||||
* ERROR_DUMP_ROW_SIZE*ERROR_DUMP_COL_SIZE bytes will be copied
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int dumpErrorInfo(u8 *outBuf, int size)
|
||||
{
|
||||
int ret, i;
|
||||
u8 data[ERROR_DUMP_ROW_SIZE * ERROR_DUMP_COL_SIZE] = { 0 };
|
||||
u32 sign = 0;
|
||||
|
||||
logError(0, "%s %s: Starting dump of error info...\n", tag, __func__);
|
||||
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, ADDR_ERROR_DUMP,
|
||||
data, ERROR_DUMP_ROW_SIZE * ERROR_DUMP_COL_SIZE,
|
||||
DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: reading data ERROR %08X\n", tag, __func__,
|
||||
ret);
|
||||
return ret;
|
||||
} else {
|
||||
if (outBuf != NULL) {
|
||||
sign = size > ERROR_DUMP_ROW_SIZE *
|
||||
ERROR_DUMP_COL_SIZE ? ERROR_DUMP_ROW_SIZE *
|
||||
ERROR_DUMP_COL_SIZE : size;
|
||||
memcpy(outBuf, data, sign);
|
||||
logError(0, "%s %s: error info copied in the buffer!\n",
|
||||
tag, __func__);
|
||||
}
|
||||
logError(1, "%s %s: Error Info =\n", tag, __func__);
|
||||
u8ToU32(data, &sign);
|
||||
if (sign != ERROR_DUMP_SIGNATURE)
|
||||
logError(1,
|
||||
"%s %s: Wrong Error Signature! Data may be invalid!\n",
|
||||
tag, __func__);
|
||||
else
|
||||
logError(1,
|
||||
"%s %s: Error Signature OK! Data are valid!\n",
|
||||
tag,
|
||||
__func__);
|
||||
|
||||
for (i = 0; i < ERROR_DUMP_ROW_SIZE * ERROR_DUMP_COL_SIZE;
|
||||
i++) {
|
||||
if (i % ERROR_DUMP_COL_SIZE == 0)
|
||||
logError(1, KERN_ERR "\n%s %s: %d) ", tag,
|
||||
__func__, i / ERROR_DUMP_COL_SIZE);
|
||||
logError(1, "%02X ", data[i]);
|
||||
}
|
||||
logError(1, "\n");
|
||||
|
||||
logError(0, "%s %s: dump of error info FINISHED!\n", tag,
|
||||
__func__);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implement recovery strategies to be used when an error event is found
|
||||
* while polling the FIFO
|
||||
* @param event error event found during the polling
|
||||
* @param size size of event
|
||||
* @return OK if the error event doesn't require any action or the recovery
|
||||
* strategy doesn't have any impact in the possible procedure that trigger the
|
||||
* error, otherwise return an error code which specify the kind of error
|
||||
* encountered. If ERROR_HANDLER_STOP_PROC the calling function must stop!
|
||||
*/
|
||||
int errorHandler(u8 *event, int size)
|
||||
{
|
||||
int res = OK;
|
||||
struct fts_ts_info *info = NULL;
|
||||
|
||||
if (getDev() != NULL)
|
||||
info = dev_get_drvdata(getDev());
|
||||
|
||||
if (info != NULL && event != NULL && size > 1 && event[0] ==
|
||||
EVT_ID_ERROR) {
|
||||
logError(1, "%s errorHandler: Starting handling...\n", tag);
|
||||
addErrorIntoList(event, size);
|
||||
switch (event[1]) { /* TODO: write an error log for
|
||||
* undefined command subtype 0xBA */
|
||||
case EVT_TYPE_ERROR_ESD: /* esd */
|
||||
res = fts_chip_powercycle(info);
|
||||
if (res < OK)
|
||||
logError(1,
|
||||
"%s errorHandler: Error performing powercycle ERROR %08X\n",
|
||||
tag, res);
|
||||
|
||||
res = fts_system_reset();
|
||||
if (res < OK)
|
||||
logError(1,
|
||||
"%s errorHandler: Cannot reset the device ERROR %08X\n",
|
||||
tag, res);
|
||||
res = (ERROR_HANDLER_STOP_PROC | res);
|
||||
break;
|
||||
|
||||
case EVT_TYPE_ERROR_WATCHDOG: /* watchdog */
|
||||
dumpErrorInfo(NULL, 0);
|
||||
res = fts_system_reset();
|
||||
if (res < OK)
|
||||
logError(1,
|
||||
"%s errorHandler: Cannot reset the device ERROR %08X\n",
|
||||
tag, res);
|
||||
res = (ERROR_HANDLER_STOP_PROC | res);
|
||||
break;
|
||||
|
||||
case EVT_TYPE_ERROR_ITO_FORCETOGND:
|
||||
logError(1, "%s errorHandler: Force Short to GND!\n",
|
||||
tag);
|
||||
break;
|
||||
case EVT_TYPE_ERROR_ITO_SENSETOGND:
|
||||
logError(1, "%s errorHandler: Sense short to GND!\n",
|
||||
tag);
|
||||
break;
|
||||
case EVT_TYPE_ERROR_ITO_FORCETOVDD:
|
||||
logError(1, "%s errorHandler: Force short to VDD!\n",
|
||||
tag);
|
||||
break;
|
||||
case EVT_TYPE_ERROR_ITO_SENSETOVDD:
|
||||
logError(1, "%s errorHandler: Sense short to VDD!\n",
|
||||
tag);
|
||||
break;
|
||||
case EVT_TYPE_ERROR_ITO_FORCE_P2P:
|
||||
logError(1,
|
||||
"%s errorHandler: Force Pin to Pin Short!\n",
|
||||
tag);
|
||||
break;
|
||||
case EVT_TYPE_ERROR_ITO_SENSE_P2P:
|
||||
logError(1,
|
||||
"%s errorHandler: Sense Pin to Pin Short!\n",
|
||||
tag);
|
||||
break;
|
||||
case EVT_TYPE_ERROR_ITO_FORCEOPEN:
|
||||
logError(1, "%s errorHandler: Force Open !\n", tag);
|
||||
break;
|
||||
case EVT_TYPE_ERROR_ITO_SENSEOPEN:
|
||||
logError(1, "%s errorHandler: Sense Open !\n", tag);
|
||||
break;
|
||||
case EVT_TYPE_ERROR_ITO_KEYOPEN:
|
||||
logError(1, "%s errorHandler: Key Open !\n", tag);
|
||||
break;
|
||||
|
||||
default:
|
||||
logError(1, "%s errorHandler: No Action taken!\n", tag);
|
||||
break;
|
||||
}
|
||||
logError(1, "%s errorHandler: handling Finished! res = %08X\n",
|
||||
tag, res);
|
||||
return res;
|
||||
} else {
|
||||
logError(1,
|
||||
"%s errorHandler: event Null or not correct size! ERROR %08X\n",
|
||||
tag, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an error event into the Error List
|
||||
* @param event error event to add
|
||||
* @param size size of event
|
||||
* @return OK
|
||||
*/
|
||||
int addErrorIntoList(u8 *event, int size)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
logError(0, "%s Adding error in to ErrorList...\n", tag);
|
||||
|
||||
memcpy(&errors.list[errors.last_index * FIFO_EVENT_SIZE], event, size);
|
||||
i = FIFO_EVENT_SIZE - size;
|
||||
if (i > 0) {
|
||||
logError(0,
|
||||
"%s Filling last %d bytes of the event with zero...\n",
|
||||
tag, i);
|
||||
memset(&errors.list[errors.last_index * FIFO_EVENT_SIZE + size],
|
||||
0, i);
|
||||
}
|
||||
logError(0, "%s Adding error in to ErrorList... FINISHED!\n", tag);
|
||||
|
||||
errors.count += 1;
|
||||
if (errors.count > FIFO_DEPTH)
|
||||
logError(1,
|
||||
"%s ErrorList is going in overflow... the first %d event(s) were override!\n",
|
||||
tag, errors.count - FIFO_DEPTH);
|
||||
errors.last_index = (errors.last_index + 1) % FIFO_DEPTH;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the Error List setting the count and last_index to 0.
|
||||
* @return OK
|
||||
*/
|
||||
int resetErrorList(void)
|
||||
{
|
||||
errors.count = 0;
|
||||
errors.last_index = 0;
|
||||
memset(errors.list, 0, FIFO_DEPTH * FIFO_EVENT_SIZE);
|
||||
/* if count is not considered is better reset also the list in order to
|
||||
* avoid to read data previously copied into the list */
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of error events copied into the Error List
|
||||
* @return the number of error events into the Error List
|
||||
*/
|
||||
int getErrorListCount(void)
|
||||
{
|
||||
if (errors.count > FIFO_DEPTH)
|
||||
return FIFO_DEPTH;
|
||||
else
|
||||
return errors.count;
|
||||
}
|
||||
|
||||
/* in case of success return the index of the event found */
|
||||
/**
|
||||
* Scroll the Error List looking for the event specified
|
||||
* @param event_to_search event_to_search pointer to an array of int where
|
||||
* each element correspond to a byte of the event to find. If the element
|
||||
* of the array has value -1, the byte of the event, in the same position
|
||||
* of the element is ignored.
|
||||
* @param event_bytes size of event_to_search
|
||||
* @return a value >=0 if the event is found which represent the index of
|
||||
* the Error List where the event is located otherwise an error code
|
||||
*/
|
||||
int pollErrorList(int *event_to_search, int event_bytes)
|
||||
{
|
||||
int i = 0, j = 0, find = 0;
|
||||
int count = getErrorListCount();
|
||||
|
||||
logError(1, "%s Starting to poll ErrorList...\n", tag);
|
||||
while (find != 1 && i < count) {
|
||||
find = 1;
|
||||
for (j = 0; j < event_bytes; j++) {
|
||||
if ((event_to_search[i] != -1) &&
|
||||
((int)errors.list[i * FIFO_EVENT_SIZE + j] !=
|
||||
event_to_search[i])) {
|
||||
find = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (find == 1) {
|
||||
logError(1, "%s Error Found into ErrorList!\n", tag);
|
||||
return i - 1; /* there is i++ at the end of the while */
|
||||
} else {
|
||||
logError(1, "%s Error Not Found into ErrorList! ERROR %08X\n",
|
||||
tag, ERROR_TIMEOUT);
|
||||
return ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Poll the Error List looking for any error types passed in the arguments.
|
||||
* Return at the first match!
|
||||
* @param list pointer to a list of error types to look for
|
||||
* @param size size of list
|
||||
* @return error type found if success or ERROR_TIMEOUT
|
||||
*/
|
||||
int pollForErrorType(u8 *list, int size)
|
||||
{
|
||||
int i = 0, j = 0, find = 0;
|
||||
int count = getErrorListCount();
|
||||
|
||||
logError(1, "%s %s: Starting to poll ErrorList... count = %d\n", tag,
|
||||
__func__, count);
|
||||
while (find != 1 && i < count) {
|
||||
for (j = 0; j < size; j++) {
|
||||
if (list[j] == errors.list[i * FIFO_EVENT_SIZE + 1]) {
|
||||
find = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (find == 1) {
|
||||
logError(1, "%s %s: Error Type %02X into ErrorList!\n", tag,
|
||||
__func__, list[j]);
|
||||
return list[j];
|
||||
} else {
|
||||
logError(1,
|
||||
"%s %s: Error Type Not Found into ErrorList! ERROR %08X\n",
|
||||
tag, __func__, ERROR_TIMEOUT);
|
||||
return ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
236
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsError.h
Normal file
236
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsError.h
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS error/info kernel log reporting *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsError.h
|
||||
* \brief Contains all the definitions and structs which refer to Error
|
||||
* conditions
|
||||
*/
|
||||
|
||||
#ifndef FTS_ERROR_H
|
||||
#define FTS_ERROR_H
|
||||
|
||||
#include "ftsHardware.h"
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
|
||||
/** @defgroup error_codes Error Codes
|
||||
* Error codes that can be reported by the driver functions.
|
||||
* An error code is made up by 4 bytes, each byte indicate a logic error
|
||||
* level.\n
|
||||
* From the LSB to the MSB, the logic level increase going from a low level
|
||||
* error (I2C,TIMEOUT) to an high level error (flashing procedure fail,
|
||||
* production test fail etc)
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* FIRST LEVEL ERROR CODE */
|
||||
/** @defgroup first_level First Level Error Code
|
||||
* @ingroup error_codes
|
||||
* Errors related to low level operation which are not under control of driver,
|
||||
* such as: communication protocol (I2C/SPI), timeout, file operations ...
|
||||
* @{
|
||||
*/
|
||||
#define OK ((int)0x00000000) /* /< No ERROR */
|
||||
#define ERROR_ALLOC ((int)0x80000001) /* /< allocation of
|
||||
* memory failed */
|
||||
#define ERROR_BUS_R ((int)0x80000002) /* /< i2c/spi read
|
||||
* failed */
|
||||
#define ERROR_BUS_W ((int)0x80000003) /* /< i2c/spi write
|
||||
* failed */
|
||||
#define ERROR_BUS_WR ((int)0x80000004) /* /< i2c/spi write/read
|
||||
* failed */
|
||||
#define ERROR_BUS_O ((int)0x80000005) /* /< error during
|
||||
* opening an i2c device
|
||||
*/
|
||||
#define ERROR_OP_NOT_ALLOW ((int)0x80000006) /* /< operation not
|
||||
* allowed */
|
||||
#define ERROR_TIMEOUT ((int)0x80000007) /* /< timeout expired!
|
||||
* exceed the max number
|
||||
* of retries or the max
|
||||
* waiting time */
|
||||
#define ERROR_FILE_NOT_FOUND ((int)0x80000008) /* /< the file that i
|
||||
* want to open is not
|
||||
* found */
|
||||
#define ERROR_FILE_PARSE ((int)0x80000009) /* /< error during
|
||||
* parsing the file */
|
||||
#define ERROR_FILE_READ ((int)0x8000000A) /* /< error during
|
||||
* reading the file */
|
||||
#define ERROR_LABEL_NOT_FOUND ((int)0x8000000B) /* /< label not found */
|
||||
#define ERROR_FW_NO_UPDATE ((int)0x8000000C) /* /< fw in the chip
|
||||
* newer than the one in
|
||||
* the memmh */
|
||||
#define ERROR_FLASH_UNKNOWN ((int)0x8000000D) /* /< flash status busy
|
||||
* or unknown */
|
||||
/** @}*/
|
||||
|
||||
/* SECOND LEVEL ERROR CODE */
|
||||
/** @defgroup second_level Second Level Error Code
|
||||
* @ingroup error_codes
|
||||
* Errors related to simple logic operations in the IC which require one
|
||||
* command or which are part of a more complex procedure
|
||||
* @{
|
||||
*/
|
||||
#define ERROR_DISABLE_INTER ((int)0x80000200) /* /< unable to disable
|
||||
* the interrupt */
|
||||
#define ERROR_ENABLE_INTER ((int)0x80000300) /* /< unable to activate
|
||||
* the interrup */
|
||||
#define ERROR_READ_CONFIG ((int)0x80000400) /* /< failed to read
|
||||
* config memory */
|
||||
#define ERROR_GET_OFFSET ((int)0x80000500) /* /< unable to read an
|
||||
* offset from memory */
|
||||
#define ERROR_GET_FRAME_DATA ((int)0x80000600) /* /< unable to
|
||||
* retrieve the data of
|
||||
* a required frame */
|
||||
#define ERROR_DIFF_DATA_TYPE ((int)0x80000700) /* /< FW answers with
|
||||
* an event that has a
|
||||
* different address
|
||||
* respect the request
|
||||
* done */
|
||||
#define ERROR_WRONG_DATA_SIGN ((int)0x80000800) /* /< the signature of
|
||||
* the host data is not
|
||||
* HEADER_SIGNATURE */
|
||||
#define ERROR_SET_SCAN_MODE_FAIL ((int)0x80000900) /* /< setting the
|
||||
* scanning mode failed
|
||||
* (sense on/off etc...)
|
||||
*/
|
||||
#define ERROR_SET_FEATURE_FAIL ((int)0x80000A00) /* /< setting a
|
||||
* specific feature
|
||||
* failed */
|
||||
#define ERROR_SYSTEM_RESET_FAIL ((int)0x80000B00) /* /< the comand
|
||||
* SYSTEM RESET
|
||||
* failed */
|
||||
#define ERROR_FLASH_NOT_READY ((int)0x80000C00) /* /< flash
|
||||
* status not
|
||||
* ready within
|
||||
* a timeout */
|
||||
#define ERROR_FW_VER_READ ((int)0x80000D00) /* /< unable to read
|
||||
* fw_vers or the
|
||||
* config_id */
|
||||
#define ERROR_GESTURE_ENABLE_FAIL ((int)0x80000E00) /* /< unable to
|
||||
* enable/disable the
|
||||
* gesture */
|
||||
#define ERROR_GESTURE_START_ADD ((int)0x80000F00) /* /< unable to start
|
||||
* add custom gesture */
|
||||
#define ERROR_GESTURE_FINISH_ADD ((int)0x80001000) /* /< unable to finish
|
||||
* to add custom gesture
|
||||
*/
|
||||
#define ERROR_GESTURE_DATA_ADD ((int)0x80001100) /* /< unable to add
|
||||
* custom gesture data
|
||||
* */
|
||||
#define ERROR_GESTURE_REMOVE ((int)0x80001200) /* /< unable to remove
|
||||
* custom gesture data
|
||||
*/
|
||||
#define ERROR_FEATURE_ENABLE_DISABLE ((int)0x80001300) /* /< unable to
|
||||
* enable/disable a
|
||||
* feature mode in the
|
||||
* IC */
|
||||
#define ERROR_NOISE_PARAMETERS ((int)0x80001400) /* /< unable to
|
||||
* set/read noise
|
||||
* parameter in
|
||||
* the IC */
|
||||
#define ERROR_CH_LEN ((int)0x80001500) /* /< unable to read
|
||||
* the force and/or
|
||||
* sense length */
|
||||
/** @}*/
|
||||
|
||||
/* THIRD LEVEL ERROR CODE */
|
||||
/** @defgroup third_level Third Level Error Code
|
||||
* @ingroup error_codes
|
||||
* Errors related to logic operations in the IC which require more
|
||||
*commands/steps or which are part of a more complex procedure
|
||||
* @{
|
||||
*/
|
||||
#define ERROR_REQU_COMP_DATA ((int)0x80010000) /* /< compensation data
|
||||
* request failed */
|
||||
#define ERROR_REQU_DATA ((int)0x80020000) /* /< data request failed */
|
||||
#define ERROR_COMP_DATA_HEADER ((int)0x80030000) /* /< unable to retrieve
|
||||
* compensation data header */
|
||||
#define ERROR_COMP_DATA_GLOBAL ((int)0x80040000) /* /< unable to retrieve the
|
||||
* global compensation data */
|
||||
#define ERROR_COMP_DATA_NODE ((int)0x80050000) /* /< unable to retrieve
|
||||
* the compensation data
|
||||
* for each node */
|
||||
#define ERROR_TEST_CHECK_FAIL ((int)0x80060000) /* /< check of
|
||||
* production limits or
|
||||
* of fw answers failed */
|
||||
#define ERROR_MEMH_READ ((int)0x80070000) /* /< memh reading failed */
|
||||
#define ERROR_FLASH_BURN_FAILED ((int)0x80080000) /* /< flash burn failed */
|
||||
#define ERROR_MS_TUNING ((int)0x80090000) /* /< ms tuning failed */
|
||||
#define ERROR_SS_TUNING ((int)0x800A0000) /* /< ss tuning failed */
|
||||
#define ERROR_LP_TIMER_TUNING ((int)0x800B0000) /* /< lp timer calibration
|
||||
* failed */
|
||||
#define ERROR_SAVE_CX_TUNING ((int)0x800C0000) /* /< save cx data to flash
|
||||
* failed */
|
||||
#define ERROR_HANDLER_STOP_PROC ((int)0x800D0000) /* /< stop the poll of
|
||||
* the FIFO if
|
||||
* particular errors are
|
||||
* found */
|
||||
#define ERROR_CHECK_ECHO_FAIL ((int)0x800E0000) /* /< unable to retrieve
|
||||
* echo event */
|
||||
#define ERROR_GET_FRAME ((int)0x800F0000) /* /< unable to get frame */
|
||||
/** @}*/
|
||||
|
||||
/* FOURTH LEVEL ERROR CODE */
|
||||
/** @defgroup fourth_level Fourth Level Error Code
|
||||
* @ingroup error_codes
|
||||
* Errors related to the highest logic operations in the IC which have an
|
||||
* important impact on the driver flow or which require several commands and
|
||||
* steps to be executed
|
||||
* @{
|
||||
*/
|
||||
#define ERROR_PROD_TEST_DATA ((int)0x81000000) /* /< production
|
||||
* data test failed */
|
||||
#define ERROR_FLASH_PROCEDURE ((int)0x82000000) /* /< fw update
|
||||
* procedure failed */
|
||||
#define ERROR_PROD_TEST_ITO ((int)0x83000000) /* /< production
|
||||
* ito test failed */
|
||||
#define ERROR_PROD_TEST_INITIALIZATION ((int)0x84000000) /* /< production
|
||||
* initialization test
|
||||
* failed */
|
||||
#define ERROR_GET_INIT_STATUS ((int)0x85000000) /* /< mismatch of MS
|
||||
* or SS tuning_version
|
||||
* */
|
||||
/** @}*/
|
||||
|
||||
/** @}*/ /* end of error_commands section */
|
||||
|
||||
/**
|
||||
* Struct which store an ordered list of the errors events encountered during
|
||||
*the polling of a FIFO.
|
||||
* The max number of error events that can be stored is equal to FIFO_DEPTH
|
||||
*/
|
||||
typedef struct {
|
||||
u8 list[FIFO_DEPTH * FIFO_EVENT_SIZE]; /* /< byte array which contains
|
||||
* the series of error events
|
||||
* encountered from the last
|
||||
* reset of the list. */
|
||||
int count; /* /< number of error events stored in the list */
|
||||
int last_index; /* /< index of the list where will be stored the next
|
||||
* error event. Subtract -1 to have the index of the
|
||||
* last error event! */
|
||||
} ErrorList;
|
||||
|
||||
/* #define logError(_l, _msg, ...) pr_err(_msg, ##__VA_ARGS__) */
|
||||
void logError(int force, const char *msg, ...);
|
||||
int isI2cError(int error);
|
||||
int dumpErrorInfo(u8 *outBuf, int size);
|
||||
int errorHandler(u8 *event, int size);
|
||||
int addErrorIntoList(u8 *event, int size);
|
||||
int getErrorListCount(void);
|
||||
int resetErrorList(void);
|
||||
int pollErrorList(int *event_to_search, int event_bytes);
|
||||
int pollForErrorType(u8 *list, int size);
|
||||
#endif
|
||||
1146
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsFlash.c
Normal file
1146
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsFlash.c
Normal file
File diff suppressed because it is too large
Load diff
142
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsFlash.h
Normal file
142
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsFlash.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS API for Flashing the IC *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsFlash.h
|
||||
* \brief Contains all the definitions and structs to handle the FW update
|
||||
*process
|
||||
*/
|
||||
|
||||
#ifndef FTS_FLASH_H
|
||||
#define FTS_FLASH_H
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
/* Flash possible status */
|
||||
#define FLASH_READY 0 /* /< value to indicate that the flash
|
||||
* is ready */
|
||||
#define FLASH_BUSY 1 /* /< value to indicate that the flash
|
||||
* is busy */
|
||||
#define FLASH_UNKNOWN -1 /* /< value to indicate an unknown
|
||||
* status of the flash */
|
||||
|
||||
#define FLASH_STATUS_BYTES 1 /* /< number of bytes to check for read
|
||||
* the flash status */
|
||||
|
||||
|
||||
|
||||
/* Flash timing parameters */
|
||||
#define FLASH_RETRY_COUNT 200 /* /< number of attemps to read the
|
||||
* flash status */
|
||||
#define FLASH_WAIT_BEFORE_RETRY 50 /* /< time to wait in ms between status
|
||||
* readings */
|
||||
|
||||
|
||||
#ifdef FW_H_FILE
|
||||
#define PATH_FILE_FW "NULL"
|
||||
#else
|
||||
#define PATH_FILE_FW "st_fts.ftb" /* /< new FW bin file name */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ALIX
|
||||
#define FLASH_CHUNK (32 * 1024) /* /< Max number of bytes that
|
||||
* the
|
||||
* DMA can burn on the flash in
|
||||
*one shot in FTI */
|
||||
#else
|
||||
#define FLASH_CHUNK (64 * 1024) /* /< Max number of bytes that
|
||||
* the
|
||||
* DMA can burn on the flash in
|
||||
*one shot in FTI */
|
||||
#endif
|
||||
|
||||
|
||||
#define DMA_CHUNK 32 /* /< Max number of bytes that can be
|
||||
* written in I2C to the DMA */
|
||||
|
||||
#define FLASH_ORG_INFO_INDEX 280
|
||||
|
||||
#define FLASH_PAGE_SIZE (4 * 1024) //page size of 4KB
|
||||
|
||||
/**
|
||||
* Define which kind of erase page by page should be performed
|
||||
*/
|
||||
typedef enum {
|
||||
ERASE_ALL = 0, /* /< erase all the pages */
|
||||
SKIP_PANEL_INIT = 1, /* /< skip erase Panel Init Pages */
|
||||
SKIP_PANEL_CX_INIT = 2 /* /< skip erase Panel Init and CX Pages */
|
||||
} ErasePage;
|
||||
|
||||
/** @addtogroup fw_file
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Struct which contains information and data of the FW that should be burnt
|
||||
*into the IC
|
||||
*/
|
||||
typedef struct {
|
||||
u8 *data; /* /< pointer to an array of bytes which represent the
|
||||
* FW data */
|
||||
u16 fw_ver; /* /< FW version of the FW file */
|
||||
u16 config_id; /* /< Config ID of the FW file */
|
||||
u16 cx_ver; /* /< Cx version of the FW file */
|
||||
u8 externalRelease[EXTERNAL_RELEASE_INFO_SIZE]; /* /< External Release
|
||||
* Info of the FW file
|
||||
* */
|
||||
int data_size; /* /< dimension of data (the actual data to be burnt) */
|
||||
u32 sec0_size; /* /< dimension of section 0 (FW) in .ftb file */
|
||||
u32 sec1_size; /* /< dimension of section 1 (Config) in .ftb file */
|
||||
u32 sec2_size; /* /< dimension of section 2 (Cx) in .ftb file */
|
||||
u32 sec3_size; /* /< dimension of section 3 (TBD) in .ftb file */
|
||||
u8 fw_code_size; /* /< size of fw code in pages in
|
||||
.ftb file */
|
||||
u8 panel_config_size;/* /< size of panel area in pages in
|
||||
.ftb file */
|
||||
u8 cx_area_size;/* /< size of cx area in pages in
|
||||
.ftb file */
|
||||
u8 fw_config_size;/* /< size of fw config in pages in
|
||||
.ftb file */
|
||||
u32 code_start_addr; /* start addr for fw code */
|
||||
u32 cx_start_addr; /* start addr for cx area */
|
||||
u32 config_start_addr; /* start addr for config area */
|
||||
} Firmware;
|
||||
|
||||
/** @}*/
|
||||
|
||||
/** @addtogroup flash_command
|
||||
* @{
|
||||
*/
|
||||
|
||||
int wait_for_flash_ready(u8 type);
|
||||
int hold_m3(void);
|
||||
int flash_erase_unlock(void);
|
||||
int flash_full_erase(void);
|
||||
int flash_erase_page_by_page(ErasePage keep_cx, Firmware *fw);
|
||||
int start_flash_dma(void);
|
||||
int fillFlash(u32 address, u8 *data, int size);
|
||||
|
||||
int flash_unlock(void);
|
||||
int getFWdata(const char *pathToFile, u8 **data, int *size);
|
||||
int parseBinFile(u8 *fw_data, int fw_size, Firmware *fw, int keep_cx);
|
||||
int readFwFile(const char *path, Firmware *fw, int keep_cx);
|
||||
int flash_burn(Firmware fw, int force_burn, int keep_cx);
|
||||
int flashProcedure(const char *path, int force, int keep_cx);
|
||||
int flash_enable_uvlo_autopowerdown(void);
|
||||
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
698
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsFrame.c
Normal file
698
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsFrame.c
Normal file
|
|
@ -0,0 +1,698 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS functions for getting frames *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsFrame.c
|
||||
* \brief Contains all the functions to work with frames
|
||||
*/
|
||||
|
||||
#include "ftsCompensation.h"
|
||||
#include "ftsCore.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsFrame.h"
|
||||
#include "ftsHardware.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsTool.h"
|
||||
#include "ftsTime.h"
|
||||
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern SysInfo systemInfo; /* /< forward declaration of the global variable
|
||||
* of containing System Info Data */
|
||||
|
||||
|
||||
/**
|
||||
* Read the channels lengths from the config memory
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int getChannelsLength(void)
|
||||
{
|
||||
int ret;
|
||||
u8 data[2];
|
||||
|
||||
if (data == NULL) {
|
||||
logError(1, "%s getChannelsLength: ERROR %08X\n", tag,
|
||||
ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
ret = readConfig(ADDR_CONFIG_SENSE_LEN, data, 2);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s getChannelsLength: ERROR %08X\n", tag, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
systemInfo.u8_scrRxLen = (int)data[0];
|
||||
systemInfo.u8_scrTxLen = (int)data[1];
|
||||
|
||||
logError(0, "%s Force_len = %d Sense_Len = %d\n", tag,
|
||||
systemInfo.u8_scrTxLen, systemInfo.u8_scrRxLen);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Read and pack the frame data related to the nodes
|
||||
* @param address address in memory when the frame data node start
|
||||
* @param size amount of data to read
|
||||
* @param frame pointer to an array of bytes which will contain the frame node
|
||||
*data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int getFrameData(u16 address, int size, short *frame)
|
||||
{
|
||||
int i, j, ret;
|
||||
u8 *data = (u8 *)kmalloc(size * sizeof(u8), GFP_KERNEL);
|
||||
|
||||
if (data == NULL) {
|
||||
logError(1, "%s getFrameData: ERROR %08X\n", tag, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address, data,
|
||||
size, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s getFrameData: ERROR %08X\n", tag, ERROR_BUS_R);
|
||||
kfree(data);
|
||||
return ERROR_BUS_R;
|
||||
}
|
||||
j = 0;
|
||||
for (i = 0; i < size; i += 2) {
|
||||
frame[j] = (short)((data[i + 1] << 8) + data[i]);
|
||||
j++;
|
||||
}
|
||||
kfree(data);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the number of Sense Channels (Rx)
|
||||
* @return number of Rx channels
|
||||
*/
|
||||
int getSenseLen(void)
|
||||
{
|
||||
if (systemInfo.u8_scrRxLen == 0)
|
||||
getChannelsLength();
|
||||
return systemInfo.u8_scrRxLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of Force Channels (Tx)
|
||||
* @return number of Tx channels
|
||||
*/
|
||||
int getForceLen(void)
|
||||
{
|
||||
if (systemInfo.u8_scrTxLen == 0)
|
||||
getChannelsLength();
|
||||
return systemInfo.u8_scrTxLen;
|
||||
}
|
||||
|
||||
|
||||
/******************** New API **************************/
|
||||
|
||||
/**
|
||||
* Read a MS Frame from frame buffer memory
|
||||
* @param type type of MS frame to read
|
||||
* @param frame pointer to MutualSenseFrame variable which will contain the
|
||||
* data
|
||||
* @return > 0 if success specifying the number of node into the frame or
|
||||
* an error code which specify the type of error
|
||||
*/
|
||||
int getMSFrame3(MSFrameType type, MutualSenseFrame *frame)
|
||||
{
|
||||
u16 offset;
|
||||
int ret, force_len, sense_len;
|
||||
|
||||
force_len = getForceLen();
|
||||
sense_len = getSenseLen();
|
||||
|
||||
frame->node_data = NULL;
|
||||
|
||||
logError(0, "%s %s: Starting to get frame %02X\n", tag, __func__,
|
||||
type);
|
||||
switch (type) {
|
||||
case MS_RAW:
|
||||
offset = systemInfo.u16_msTchRawAddr;
|
||||
goto LOAD_NORM;
|
||||
case MS_FILTER:
|
||||
offset = systemInfo.u16_msTchFilterAddr;
|
||||
|
||||
goto LOAD_NORM;
|
||||
case MS_STRENGTH:
|
||||
offset = systemInfo.u16_msTchStrenAddr;
|
||||
goto LOAD_NORM;
|
||||
case MS_BASELINE:
|
||||
offset = systemInfo.u16_msTchBaselineAddr;
|
||||
LOAD_NORM:
|
||||
if (force_len == 0 || sense_len == 0) {
|
||||
logError(1,
|
||||
"%s %s: number of channels not initialized ERROR %08X\n",
|
||||
tag, __func__, ERROR_CH_LEN);
|
||||
return ERROR_CH_LEN | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MS_KEY_RAW:
|
||||
offset = systemInfo.u16_keyRawAddr;
|
||||
goto LOAD_KEY;
|
||||
case MS_KEY_FILTER:
|
||||
offset = systemInfo.u16_keyFilterAddr;
|
||||
goto LOAD_KEY;
|
||||
case MS_KEY_STRENGTH:
|
||||
offset = systemInfo.u16_keyStrenAddr;
|
||||
goto LOAD_KEY;
|
||||
case MS_KEY_BASELINE:
|
||||
offset = systemInfo.u16_keyBaselineAddr;
|
||||
LOAD_KEY:
|
||||
if (systemInfo.u8_keyLen == 0) {
|
||||
logError(1,
|
||||
"%s %s: number of channels not initialized ERROR %08X\n",
|
||||
tag, __func__, ERROR_CH_LEN);
|
||||
return ERROR_CH_LEN | ERROR_GET_FRAME;
|
||||
}
|
||||
force_len = 1;
|
||||
sense_len = systemInfo.u8_keyLen;
|
||||
break;
|
||||
|
||||
case FRC_RAW:
|
||||
offset = systemInfo.u16_frcRawAddr;
|
||||
goto LOAD_FRC;
|
||||
case FRC_FILTER:
|
||||
offset = systemInfo.u16_frcFilterAddr;
|
||||
goto LOAD_FRC;
|
||||
case FRC_STRENGTH:
|
||||
offset = systemInfo.u16_frcStrenAddr;
|
||||
goto LOAD_FRC;
|
||||
case FRC_BASELINE:
|
||||
offset = systemInfo.u16_frcBaselineAddr;
|
||||
LOAD_FRC:
|
||||
if (force_len == 0) {
|
||||
logError(1,
|
||||
"%s %s: number of channels not initialized ERROR %08X\n",
|
||||
tag, __func__, ERROR_CH_LEN);
|
||||
return ERROR_CH_LEN | ERROR_GET_FRAME;
|
||||
}
|
||||
sense_len = 1;
|
||||
break;
|
||||
default:
|
||||
logError(1, "%s %s: Invalid type ERROR %08X\n", tag, __func__,
|
||||
ERROR_OP_NOT_ALLOW | ERROR_GET_FRAME);
|
||||
return ERROR_OP_NOT_ALLOW | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
frame->node_data_size = ((force_len) * sense_len);
|
||||
frame->header.force_node = force_len;
|
||||
frame->header.sense_node = sense_len;
|
||||
frame->header.type = type;
|
||||
|
||||
logError(0, "%s %s: Force_len = %d Sense_len = %d Offset = %04X\n",
|
||||
tag, __func__, force_len, sense_len, offset);
|
||||
|
||||
frame->node_data = (short *)kmalloc(frame->node_data_size *
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (frame->node_data == NULL) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__, ERROR_ALLOC |
|
||||
ERROR_GET_FRAME);
|
||||
return ERROR_ALLOC | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
ret = getFrameData(offset, frame->node_data_size * BYTES_PER_NODE,
|
||||
(frame->node_data));
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__,
|
||||
ERROR_GET_FRAME_DATA);
|
||||
kfree(frame->node_data);
|
||||
frame->node_data = NULL;
|
||||
return ret | ERROR_GET_FRAME_DATA | ERROR_GET_FRAME;
|
||||
}
|
||||
/* if you want to access one node i,j,
|
||||
* compute the offset like: offset = i*columns + j = > frame[i, j] */
|
||||
|
||||
logError(0, "%s Frame acquired!\n", tag);
|
||||
return frame->node_data_size;
|
||||
/* return the number of data put inside frame */
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a SS Frame from frame buffer
|
||||
* @param type type of SS frame to read
|
||||
* @param frame pointer to SelfSenseFrame variable which will contain the data
|
||||
* @return > 0 if success specifying the number of node into frame or an
|
||||
* error code which specify the type of error
|
||||
*/
|
||||
int getSSFrame3(SSFrameType type, SelfSenseFrame *frame)
|
||||
{
|
||||
u16 offset_force, offset_sense;
|
||||
int ret;
|
||||
|
||||
frame->force_data = NULL;
|
||||
frame->sense_data = NULL;
|
||||
|
||||
frame->header.force_node = getForceLen(); /* use getForce/SenseLen
|
||||
* because introduce a
|
||||
* recover mechanism in
|
||||
* case of len =0 */
|
||||
frame->header.sense_node = getSenseLen();
|
||||
|
||||
if (frame->header.force_node == 0 || frame->header.sense_node == 0) {
|
||||
logError(1,
|
||||
"%s %s: number of channels not initialized ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_CH_LEN);
|
||||
return ERROR_CH_LEN | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
|
||||
logError(0, "%s %s: Starting to get frame %02X\n", tag, __func__,
|
||||
type);
|
||||
switch (type) {
|
||||
case SS_RAW:
|
||||
offset_force = systemInfo.u16_ssTchTxRawAddr;
|
||||
offset_sense = systemInfo.u16_ssTchRxRawAddr;
|
||||
break;
|
||||
case SS_FILTER:
|
||||
offset_force = systemInfo.u16_ssTchTxFilterAddr;
|
||||
offset_sense = systemInfo.u16_ssTchRxFilterAddr;
|
||||
break;
|
||||
case SS_STRENGTH:
|
||||
offset_force = systemInfo.u16_ssTchTxStrenAddr;
|
||||
offset_sense = systemInfo.u16_ssTchRxStrenAddr;
|
||||
break;
|
||||
case SS_BASELINE:
|
||||
offset_force = systemInfo.u16_ssTchTxBaselineAddr;
|
||||
offset_sense = systemInfo.u16_ssTchRxBaselineAddr;
|
||||
break;
|
||||
|
||||
case SS_HVR_RAW:
|
||||
offset_force = systemInfo.u16_ssHvrTxRawAddr;
|
||||
offset_sense = systemInfo.u16_ssHvrRxRawAddr;
|
||||
break;
|
||||
case SS_HVR_FILTER:
|
||||
offset_force = systemInfo.u16_ssHvrTxFilterAddr;
|
||||
offset_sense = systemInfo.u16_ssHvrRxFilterAddr;
|
||||
break;
|
||||
case SS_HVR_STRENGTH:
|
||||
offset_force = systemInfo.u16_ssHvrTxStrenAddr;
|
||||
offset_sense = systemInfo.u16_ssHvrRxStrenAddr;
|
||||
break;
|
||||
case SS_HVR_BASELINE:
|
||||
offset_force = systemInfo.u16_ssHvrTxBaselineAddr;
|
||||
offset_sense = systemInfo.u16_ssHvrRxBaselineAddr;
|
||||
break;
|
||||
|
||||
case SS_PRX_RAW:
|
||||
offset_force = systemInfo.u16_ssPrxTxRawAddr;
|
||||
offset_sense = systemInfo.u16_ssPrxRxRawAddr;
|
||||
break;
|
||||
case SS_PRX_FILTER:
|
||||
offset_force = systemInfo.u16_ssPrxTxFilterAddr;
|
||||
offset_sense = systemInfo.u16_ssPrxRxFilterAddr;
|
||||
break;
|
||||
case SS_PRX_STRENGTH:
|
||||
offset_force = systemInfo.u16_ssPrxTxStrenAddr;
|
||||
offset_sense = systemInfo.u16_ssPrxRxStrenAddr;
|
||||
break;
|
||||
case SS_PRX_BASELINE:
|
||||
offset_force = systemInfo.u16_ssPrxTxBaselineAddr;
|
||||
offset_sense = systemInfo.u16_ssPrxRxBaselineAddr;
|
||||
break;
|
||||
case SS_DETECT_RAW:
|
||||
if (systemInfo.u8_ssDetScanSet == 0) {
|
||||
offset_force = systemInfo.u16_ssDetRawAddr;
|
||||
offset_sense = 0;
|
||||
frame->header.sense_node = 0;
|
||||
} else {
|
||||
offset_sense = systemInfo.u16_ssDetRawAddr;
|
||||
offset_force = 0;
|
||||
frame->header.force_node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_DETECT_FILTER:
|
||||
if (systemInfo.u8_ssDetScanSet == 0) {
|
||||
offset_force = systemInfo.u16_ssDetFilterAddr;
|
||||
offset_sense = 0;
|
||||
frame->header.sense_node = 0;
|
||||
} else {
|
||||
offset_sense = systemInfo.u16_ssDetFilterAddr;
|
||||
offset_force = 0;
|
||||
frame->header.force_node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_DETECT_BASELINE:
|
||||
if (systemInfo.u8_ssDetScanSet == 0) {
|
||||
offset_force = systemInfo.u16_ssDetBaselineAddr;
|
||||
offset_sense = 0;
|
||||
frame->header.sense_node = 0;
|
||||
} else {
|
||||
offset_sense = systemInfo.u16_ssDetBaselineAddr;
|
||||
offset_force = 0;
|
||||
frame->header.force_node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SS_DETECT_STRENGTH:
|
||||
if (systemInfo.u8_ssDetScanSet == 0) {
|
||||
offset_force = systemInfo.u16_ssDetStrenAddr;
|
||||
offset_sense = 0;
|
||||
frame->header.sense_node = 0;
|
||||
} else {
|
||||
offset_sense = systemInfo.u16_ssDetStrenAddr;
|
||||
offset_force = 0;
|
||||
frame->header.force_node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logError(1, "%s %s: Invalid type ERROR %08X\n", tag, __func__,
|
||||
ERROR_OP_NOT_ALLOW | ERROR_GET_FRAME);
|
||||
return ERROR_OP_NOT_ALLOW | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
frame->header.type = type;
|
||||
|
||||
logError(0,
|
||||
"%s %s: Force_len = %d Sense_len = %d Offset_force = %04X Offset_sense = %04X\n",
|
||||
tag, __func__, frame->header.force_node,
|
||||
frame->header.sense_node,
|
||||
offset_force, offset_sense);
|
||||
|
||||
frame->force_data = (short *)kmalloc(frame->header.force_node *
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (frame->force_data == NULL) {
|
||||
logError(1, "%s %s: can not allocate force_data ERROR %08X\n",
|
||||
tag, __func__, ERROR_ALLOC | ERROR_GET_FRAME);
|
||||
return ERROR_ALLOC | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
frame->sense_data = (short *)kmalloc(frame->header.sense_node *
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (frame->sense_data == NULL) {
|
||||
kfree(frame->force_data);
|
||||
frame->force_data = NULL;
|
||||
logError(1, "%s %s: can not allocate sense_data ERROR %08X\n",
|
||||
tag, __func__, ERROR_ALLOC | ERROR_GET_FRAME);
|
||||
return ERROR_ALLOC | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
ret = getFrameData(offset_force, frame->header.force_node *
|
||||
BYTES_PER_NODE, (frame->force_data));
|
||||
if (ret < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while reading force data ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_GET_FRAME_DATA);
|
||||
kfree(frame->force_data);
|
||||
frame->force_data = NULL;
|
||||
kfree(frame->sense_data);
|
||||
frame->sense_data = NULL;
|
||||
return ret | ERROR_GET_FRAME_DATA | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
ret = getFrameData(offset_sense, frame->header.sense_node *
|
||||
BYTES_PER_NODE, (frame->sense_data));
|
||||
if (ret < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while reading sense data ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_GET_FRAME_DATA);
|
||||
kfree(frame->force_data);
|
||||
frame->force_data = NULL;
|
||||
kfree(frame->sense_data);
|
||||
frame->sense_data = NULL;
|
||||
return ret | ERROR_GET_FRAME_DATA | ERROR_GET_FRAME;
|
||||
}
|
||||
/* if you want to access one node i,j, you should compute the offset
|
||||
* like: offset = i*columns + j = > frame[i, j] */
|
||||
|
||||
logError(0, "%s Frame acquired!\n", tag);
|
||||
return frame->header.force_node + frame->header.sense_node;
|
||||
/* return the number of data put inside frame */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read Initialization Data Header and check that the type loaded match with
|
||||
* the one previously requested
|
||||
* @param type type of Initialization data requested @link load_opt Load Host
|
||||
* Data Option @endlink
|
||||
* @param msHeader pointer to DataHeader variable which will contain the header
|
||||
* info for the MS frame
|
||||
* @param ssHeader pointer to DataHeader variable which will contain the header
|
||||
* info for the SS frame
|
||||
* @param address pointer to a variable which will contain the updated address
|
||||
* to the next data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readSyncDataHeader(u8 type, DataHeader *msHeader, DataHeader *ssHeader,
|
||||
u64 *address)
|
||||
{
|
||||
u64 offset = ADDR_FRAMEBUFFER;
|
||||
u8 data[SYNCFRAME_DATA_HEADER];
|
||||
int ret;
|
||||
|
||||
ret = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, offset, data,
|
||||
SYNCFRAME_DATA_HEADER, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) { /* i2c function have already a retry mechanism */
|
||||
logError(1,
|
||||
"%s %s: error while reading data header ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
logError(0, "%s Read Data Header done!\n", tag);
|
||||
|
||||
if (data[0] != HEADER_SIGNATURE) {
|
||||
logError(1,
|
||||
"%s %s: The Header Signature was wrong! %02X != %02X ERROR %08X\n",
|
||||
tag, __func__, data[0], HEADER_SIGNATURE,
|
||||
ERROR_WRONG_DATA_SIGN);
|
||||
return ERROR_WRONG_DATA_SIGN;
|
||||
}
|
||||
|
||||
|
||||
if (data[1] != type) {
|
||||
logError(1, "%s %s: Wrong type found! %02X!=%02X ERROR %08X\n",
|
||||
tag, __func__, data[1], type, ERROR_DIFF_DATA_TYPE);
|
||||
return ERROR_DIFF_DATA_TYPE;
|
||||
}
|
||||
|
||||
logError(0, "%s Type = %02X of SyncFrame data OK!\n", tag, type);
|
||||
|
||||
msHeader->force_node = data[5];
|
||||
msHeader->sense_node = data[6];
|
||||
logError(0, "%s MS Frame force_node = %d, sense_node = %d\n", tag,
|
||||
msHeader->force_node, msHeader->sense_node);
|
||||
|
||||
ssHeader->force_node = data[7];
|
||||
ssHeader->sense_node = data[8];
|
||||
logError(0, "%s SS Frame force_node = %d, sense_node = %d\n", tag,
|
||||
ssHeader->force_node, ssHeader->sense_node);
|
||||
|
||||
*address = offset + SYNCFRAME_DATA_HEADER + data[4];
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a Sync Frame from frame buffer which contain MS and SS data collected
|
||||
*for the same scan
|
||||
* @param type type of Sync frame to read, possible values:
|
||||
* LOAD_SYNC_FRAME_RAW, LOAD_SYNC_FRAME_FILTER, LOAD_SYNC_FRAME_BASELINE,
|
||||
* LOAD_SYNC_FRAME_STRENGTH
|
||||
* @param msFrame pointer to MutualSenseFrame variable which will contain the
|
||||
*MS data
|
||||
* @param ssFrame pointer to SelfSenseFrame variable which will contain the SS
|
||||
*data
|
||||
* @return >0 if success specifying the total number of nodes copied into
|
||||
* msFrame and ssFrame or an error code which specify the type of error
|
||||
*/
|
||||
int getSyncFrame(u8 type, MutualSenseFrame *msFrame, SelfSenseFrame *ssFrame)
|
||||
{
|
||||
int res;
|
||||
u64 address;
|
||||
|
||||
msFrame->node_data = NULL;
|
||||
ssFrame->force_data = NULL;
|
||||
ssFrame->sense_data = NULL;
|
||||
|
||||
logError(0, "%s %s: Starting to get Sync Frame %02X...\n", tag,
|
||||
__func__, type);
|
||||
switch (type) {
|
||||
case LOAD_SYNC_FRAME_RAW:
|
||||
msFrame->header.type = MS_RAW;
|
||||
ssFrame->header.type = SS_RAW;
|
||||
break;
|
||||
|
||||
case LOAD_SYNC_FRAME_FILTER:
|
||||
msFrame->header.type = MS_FILTER;
|
||||
ssFrame->header.type = SS_FILTER;
|
||||
break;
|
||||
|
||||
case LOAD_SYNC_FRAME_BASELINE:
|
||||
msFrame->header.type = MS_BASELINE;
|
||||
ssFrame->header.type = SS_BASELINE;
|
||||
break;
|
||||
|
||||
case LOAD_SYNC_FRAME_STRENGTH:
|
||||
msFrame->header.type = MS_STRENGTH;
|
||||
ssFrame->header.type = SS_STRENGTH;
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR_OP_NOT_ALLOW | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
logError(0, "%s %s: Requesting Sync Frame %02X...\n", tag, __func__,
|
||||
type);
|
||||
res = requestSyncFrame(type);
|
||||
if (res < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while requesting Sync Frame ERROR %08X\n",
|
||||
tag,
|
||||
__func__, res | ERROR_GET_FRAME_DATA);
|
||||
return res | ERROR_GET_FRAME_DATA;
|
||||
}
|
||||
|
||||
res = readSyncDataHeader(type, &(msFrame->header), &(ssFrame->header),
|
||||
&address);
|
||||
if (res < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while reading Sync Frame header... ERROR %08X\n",
|
||||
tag, __func__, res | ERROR_GET_FRAME_DATA);
|
||||
return res | ERROR_GET_FRAME_DATA;
|
||||
}
|
||||
|
||||
msFrame->node_data_size = msFrame->header.force_node *
|
||||
msFrame->header.sense_node;
|
||||
|
||||
msFrame->node_data = (short *)kmalloc(msFrame->node_data_size *
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (msFrame->node_data == NULL) {
|
||||
logError(1,
|
||||
"%s %s: impossible allocate memory for MS frame... ERROR %08X\n",
|
||||
tag, __func__, ERROR_ALLOC | ERROR_GET_FRAME);
|
||||
return ERROR_ALLOC | ERROR_GET_FRAME;
|
||||
}
|
||||
|
||||
logError(0, "%s %s: Getting MS frame at %04llX...\n", tag, __func__,
|
||||
address);
|
||||
res = getFrameData(address, (msFrame->node_data_size) * BYTES_PER_NODE,
|
||||
(msFrame->node_data));
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s: error while getting MS data...ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
res |= ERROR_GET_FRAME_DATA | ERROR_GET_FRAME;
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/* move the offset */
|
||||
address += (msFrame->node_data_size) * BYTES_PER_NODE;
|
||||
|
||||
ssFrame->force_data = (short *)kmalloc(ssFrame->header.force_node *
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (ssFrame->force_data == NULL) {
|
||||
logError(1,
|
||||
"%s %s: impossible allocate memory for SS force frame...ERROR %08X\n",
|
||||
tag, __func__, ERROR_ALLOC | ERROR_GET_FRAME);
|
||||
res = ERROR_ALLOC | ERROR_GET_FRAME;
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
logError(0, "%s %s: Getting SS force frame at %04llX...\n", tag, __func__,
|
||||
address);
|
||||
res = getFrameData(address, (ssFrame->header.force_node) *
|
||||
BYTES_PER_NODE, (ssFrame->force_data));
|
||||
if (res < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while getting SS force data...ERROR %08X\n",
|
||||
tag,
|
||||
__func__, res);
|
||||
res |= ERROR_GET_FRAME_DATA | ERROR_GET_FRAME;
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
/* move the offset */
|
||||
address += (ssFrame->header.force_node) * BYTES_PER_NODE;
|
||||
|
||||
ssFrame->sense_data = (short *)kmalloc(ssFrame->header.sense_node *
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (ssFrame->sense_data == NULL) {
|
||||
logError(1,
|
||||
"%s %s: impossible allocate memory for SS sense frame...ERROR %08X\n",
|
||||
tag, __func__, ERROR_ALLOC | ERROR_GET_FRAME);
|
||||
res = ERROR_ALLOC | ERROR_GET_FRAME;
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
logError(0, "%s %s: Getting SS sense frame at %04llX...\n", tag, __func__,
|
||||
address);
|
||||
res = getFrameData(address, (ssFrame->header.sense_node) *
|
||||
BYTES_PER_NODE, (ssFrame->sense_data));
|
||||
if (res < OK) {
|
||||
logError(1,
|
||||
"%s %s: error while getting SS sense data...ERROR %08X\n",
|
||||
tag,
|
||||
__func__, res);
|
||||
res |= ERROR_GET_FRAME_DATA | ERROR_GET_FRAME;
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
ERROR:
|
||||
if (res < OK) {
|
||||
if (msFrame->node_data != NULL) {
|
||||
kfree(msFrame->node_data);
|
||||
msFrame->node_data = NULL;
|
||||
}
|
||||
|
||||
if (ssFrame->force_data != NULL) {
|
||||
kfree(ssFrame->force_data);
|
||||
ssFrame->force_data = NULL;
|
||||
}
|
||||
|
||||
if (ssFrame->sense_data != NULL) {
|
||||
kfree(ssFrame->sense_data);
|
||||
ssFrame->sense_data = NULL;
|
||||
}
|
||||
logError(0, "Getting Sync Frame FAILED! ERROR %08X!\n", res);
|
||||
} else {
|
||||
logError(0, "Getting Sync Frame FINISHED!\n");
|
||||
res = msFrame->node_data_size + ssFrame->header.force_node +
|
||||
ssFrame->header.sense_node;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
114
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsFrame.h
Normal file
114
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsFrame.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS functions for getting frames *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsFrame.h
|
||||
* \brief Contains all the definitions and structs to work with frames
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FTS_FRAME_H
|
||||
#define FTS_FRAME_H
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsCore.h"
|
||||
|
||||
|
||||
|
||||
/* Number of data bytes for each node */
|
||||
#define BYTES_PER_NODE 2 /* /< number of data bytes for each node */
|
||||
|
||||
|
||||
#define RETRY_FRAME_DATA_READ 2 /* /< max number of attempts to read a
|
||||
* frame */
|
||||
#define SYNCFRAME_DATA_HEADER (DATA_HEADER + 12) /* /< number of bytes of
|
||||
* Sync Frame Header */
|
||||
/**
|
||||
* Possible types of MS frames
|
||||
*/
|
||||
typedef enum {
|
||||
MS_RAW = 0, /* /< Mutual Sense Raw Frame */
|
||||
MS_FILTER = 1, /* /< Mutual Sense Filtered Frame */
|
||||
MS_STRENGTH = 2, /* /< Mutual Sense Strength Frame (Baseline-Raw)
|
||||
* */
|
||||
MS_BASELINE = 3, /* /< Mutual Sense Baseline Frame */
|
||||
MS_KEY_RAW = 4, /* /< Mutual Sense Key Raw Frame */
|
||||
MS_KEY_FILTER = 5, /* /< Mutual Sense Key Filter Frame */
|
||||
MS_KEY_STRENGTH = 6, /* /< Mutual Sense Key Strength Frame
|
||||
* (Baseline-Raw) */
|
||||
MS_KEY_BASELINE = 7, /* /< Mutual Sense Key Baseline Frame */
|
||||
FRC_RAW = 8, /* /< Force Raw Frame */
|
||||
FRC_FILTER = 9, /* /< Force Filtered Frame */
|
||||
FRC_STRENGTH = 10, /* /< Force Strength Frame (Baseline-Raw) */
|
||||
FRC_BASELINE = 11 /* /< Force Baseline Frame */
|
||||
} MSFrameType;
|
||||
|
||||
|
||||
/**
|
||||
* Possible types of SS frames
|
||||
*/
|
||||
typedef enum {
|
||||
SS_RAW = 0, /* /< Self Sense Raw Frame */
|
||||
SS_FILTER = 1, /* /< Self Sense Filtered Frame */
|
||||
SS_STRENGTH = 2, /* /< Self Sense Strength Frame (Baseline-Raw)
|
||||
* */
|
||||
SS_BASELINE = 3, /* /< Self Sense Baseline Frame */
|
||||
SS_HVR_RAW = 4, /* /< Self Sense Hover Raw Frame */
|
||||
SS_HVR_FILTER = 5, /* /< Self Sense Hover Filter Frame */
|
||||
SS_HVR_STRENGTH = 6, /* /< Self Sense Hover Strength Frame
|
||||
* (Baseline-Raw) */
|
||||
SS_HVR_BASELINE = 7, /* /< Self Sense Hover Baseline Frame */
|
||||
SS_PRX_RAW = 8, /* /< Self Sense Proximity Raw Frame */
|
||||
SS_PRX_FILTER = 9, /* /< Self Sense Proximity Filtered Frame */
|
||||
SS_PRX_STRENGTH = 10, /* /< Self Sense Proximity Strength Frame
|
||||
* (Baseline-Raw) */
|
||||
SS_PRX_BASELINE = 11, /* /< Self Sense Proximity Baseline Frame */
|
||||
|
||||
SS_DETECT_RAW = 12, /* /< Self Sense Detect Raw Frame */
|
||||
SS_DETECT_FILTER = 13, /* /< Self Sense Detect Filter Frame */
|
||||
SS_DETECT_STRENGTH = 14, /* /< Self Sense Detect Strength Frame */
|
||||
SS_DETECT_BASELINE = 15 /* /< Self Sense Detect Baseline Frame */
|
||||
} SSFrameType;
|
||||
|
||||
|
||||
/**
|
||||
* Struct which contains the data of a MS Frame
|
||||
*/
|
||||
typedef struct {
|
||||
DataHeader header; /* /< Header which contain basic info of the
|
||||
* frame */
|
||||
short *node_data; /* /< Data of the frame */
|
||||
int node_data_size; /* /< Dimension of the data of the frame */
|
||||
} MutualSenseFrame;
|
||||
|
||||
/**
|
||||
* Struct which contains the data of a SS Frame
|
||||
*/
|
||||
typedef struct {
|
||||
DataHeader header; /* /< Header which contain basic info of the
|
||||
* frame */
|
||||
short *force_data; /* /< Force Channels Data */
|
||||
short *sense_data; /* /< Sense Channels Data */
|
||||
} SelfSenseFrame;
|
||||
|
||||
|
||||
int getChannelsLength(void);
|
||||
int getFrameData(u16 address, int size, short *frame);
|
||||
int getSenseLen(void);
|
||||
int getForceLen(void);
|
||||
int getMSFrame3(MSFrameType type, MutualSenseFrame *frame);
|
||||
int getSSFrame3(SSFrameType type, SelfSenseFrame *frame);
|
||||
int getSyncFrame(u8 type, MutualSenseFrame *msFrame, SelfSenseFrame *ssFrame);
|
||||
#endif
|
||||
405
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsGesture.c
Normal file
405
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsGesture.c
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Gesture Utilities **
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsGesture.c
|
||||
* \brief Contains all the functions and variable to handle the Gesture
|
||||
*Detection features
|
||||
*/
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsCore.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsGesture.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsTime.h"
|
||||
#include "ftsTool.h"
|
||||
|
||||
/* /< store the gesture bitmask which the host want to enable.
|
||||
* If bit set 1 the corresponding gesture will be detected in Gesture Mode */
|
||||
static u8 gesture_mask[GESTURE_MASK_SIZE] = { 0 };
|
||||
/* /< store the x coordinates of the points draw by the user
|
||||
* when a gesture is detected */
|
||||
u16 gesture_coordinates_x[GESTURE_MAX_COORDS_PAIRS_REPORT] = { 0 };
|
||||
/* /< store the y coordinates of the points draw by the user
|
||||
* when a gesture is detected */
|
||||
u16 gesture_coordinates_y[GESTURE_MAX_COORDS_PAIRS_REPORT] = { 0 };
|
||||
/* /< number of coordinates pairs (points) reported with the detected gesture */
|
||||
int gesture_coords_reported = ERROR_OP_NOT_ALLOW;
|
||||
static u8 refreshGestureMask; /* /< flag which indicate if there is
|
||||
* the need to set the gesture mask in the FW */
|
||||
struct mutex gestureMask_mutex; /* /< mutex used to control access on gesture
|
||||
* shared variables */
|
||||
|
||||
/**
|
||||
* Update the gesture mask stored in the driver and have to be used in gesture
|
||||
* mode
|
||||
* @param mask pointer to a byte array which store the gesture mask update
|
||||
* that want to be performed.
|
||||
* @param size dimension in byte of mask. This size can be <=
|
||||
* GESTURE_MASK_SIZE.
|
||||
* If size < GESTURE_MASK_SIZE the bytes of mask are considering continuos
|
||||
* and starting from the less significant byte.
|
||||
* @param en 0 = enable the gestures set in mask, 1 = disable the gestures set
|
||||
*in mask
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int updateGestureMask(u8 *mask, int size, int en)
|
||||
{
|
||||
u8 temp;
|
||||
int i;
|
||||
|
||||
if (mask != NULL) {
|
||||
if (size <= GESTURE_MASK_SIZE) {
|
||||
if (en == FEAT_ENABLE) {
|
||||
mutex_lock(&gestureMask_mutex);
|
||||
logError(0,
|
||||
"%s updateGestureMask: setting gesture mask to enable...\n",
|
||||
tag);
|
||||
if (mask != NULL)
|
||||
for (i = 0; i < size; i++)
|
||||
gesture_mask[i] =
|
||||
gesture_mask[i] |
|
||||
mask[i];
|
||||
/* back up of the gesture enabled */
|
||||
refreshGestureMask = 1;
|
||||
logError(0,
|
||||
"%s updateGestureMask: gesture mask to enable SET!\n",
|
||||
tag);
|
||||
mutex_unlock(&gestureMask_mutex);
|
||||
return OK;
|
||||
} else if (en == FEAT_DISABLE) {
|
||||
mutex_lock(&gestureMask_mutex);
|
||||
logError(0,
|
||||
"%s updateGestureMask: setting gesture mask to disable...\n",
|
||||
tag);
|
||||
for (i = 0; i < size; i++) {
|
||||
temp = gesture_mask[i] ^ mask[i];
|
||||
/* enabled XOR disabled */
|
||||
gesture_mask[i] = temp &
|
||||
gesture_mask[i];
|
||||
/* temp AND enabled
|
||||
* disable the gestures that were
|
||||
* enabled */
|
||||
}
|
||||
logError(0,
|
||||
"%s updateGestureMask: gesture mask to disable SET!\n",
|
||||
tag);
|
||||
refreshGestureMask = 1;
|
||||
mutex_unlock(&gestureMask_mutex);
|
||||
return OK;
|
||||
} else {
|
||||
logError(1,
|
||||
"%s updateGestureMask: Enable parameter Invalid! %d != %d or %d ERROR %08X\n",
|
||||
tag, en, FEAT_DISABLE, FEAT_ENABLE,
|
||||
ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
} else {
|
||||
logError(1,
|
||||
"%s updateGestureMask: Size not valid! %d > %d ERROR %08X\n",
|
||||
tag, size, GESTURE_MASK_SIZE,
|
||||
ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
} else {
|
||||
logError(1, "%s updateGestureMask: Mask NULL! ERROR %08X\n",
|
||||
tag, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable in the FW the gesture mask to be used in gesture mode
|
||||
* @param mask pointer to a byte array which store the gesture mask update
|
||||
* that want to be sent to the FW, if NULL, will be used gesture_mask
|
||||
* set previously without any changes.
|
||||
* @param size dimension in byte of mask. This size can be <=
|
||||
* GESTURE_MASK_SIZE.
|
||||
* If size < GESTURE_MASK_SIZE the bytes of mask are considering continuos and
|
||||
* starting from the less significant byte.
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int enableGesture(u8 *mask, int size)
|
||||
{
|
||||
int i, res;
|
||||
|
||||
logError(0, "%s Trying to enable gesture...\n", tag);
|
||||
|
||||
if (size <= GESTURE_MASK_SIZE) {
|
||||
mutex_lock(&gestureMask_mutex);
|
||||
if (mask != NULL)
|
||||
for (i = 0; i < size; i++)
|
||||
gesture_mask[i] = gesture_mask[i] | mask[i];
|
||||
/* back up of the gesture enabled */
|
||||
|
||||
res = setFeatures(FEAT_SEL_GESTURE, gesture_mask,
|
||||
GESTURE_MASK_SIZE);
|
||||
if (res < OK) {
|
||||
logError(1, "%s enableGesture: ERROR %08X\n", tag,
|
||||
res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
logError(0, "%s enableGesture DONE!\n", tag);
|
||||
res = OK;
|
||||
|
||||
END:
|
||||
mutex_unlock(&gestureMask_mutex);
|
||||
return res;
|
||||
} else {
|
||||
logError(1,
|
||||
"%s enableGesture: Size not valid! %d > %d ERROR %08X\n",
|
||||
tag,
|
||||
size, GESTURE_MASK_SIZE, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable in the FW the gesture mask to be used in gesture mode
|
||||
* @param mask pointer to a byte array which store the gesture mask update that
|
||||
* want to be sent to the FW, if NULL, all the gestures will be disabled.
|
||||
* @param size dimension in byte of mask. This size can be <=
|
||||
* GESTURE_MASK_SIZE.
|
||||
* If size < GESTURE_MASK_SIZE the bytes of mask are considering continuos and
|
||||
* starting from the less significant byte.
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int disableGesture(u8 *mask, int size)
|
||||
{
|
||||
u8 temp;
|
||||
int i, res;
|
||||
u8 *pointer;
|
||||
|
||||
|
||||
logError(0, "%s Trying to disable gesture...\n", tag);
|
||||
|
||||
|
||||
if (size <= GESTURE_MASK_SIZE) {
|
||||
mutex_lock(&gestureMask_mutex);
|
||||
if (mask != NULL) {
|
||||
for (i = 0; i < size; i++) {
|
||||
temp = gesture_mask[i] ^ mask[i];
|
||||
/* enabled mask XOR disabled mask */
|
||||
gesture_mask[i] = temp & gesture_mask[i];
|
||||
/* temp AND enabled
|
||||
* disable the gestures that are specified and
|
||||
* previously enabled */
|
||||
}
|
||||
|
||||
pointer = gesture_mask;
|
||||
} else {
|
||||
i = 0; /* if NULL is passed disable all the possible
|
||||
* gestures */
|
||||
pointer = (u8 *)&i;
|
||||
}
|
||||
|
||||
res = setFeatures(FEAT_SEL_GESTURE, pointer, GESTURE_MASK_SIZE);
|
||||
if (res < OK) {
|
||||
logError(1, "%s disableGesture: ERROR %08X\n", tag,
|
||||
res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
logError(0, "%s disableGesture DONE!\n", tag);
|
||||
|
||||
res = OK;
|
||||
|
||||
END:
|
||||
mutex_unlock(&gestureMask_mutex);
|
||||
return res;
|
||||
} else {
|
||||
logError(1,
|
||||
"%s disableGesture: Size not valid! %d > %d ERROR %08X\n",
|
||||
tag,
|
||||
size, GESTURE_MASK_SIZE, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform all the steps required to put the chip in gesture mode
|
||||
* @param reload if set to 1, before entering in gesture mode it will re-enable
|
||||
* in the FW the last defined gesture mask
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int enterGestureMode(int reload)
|
||||
{
|
||||
int res, ret;
|
||||
|
||||
res = fts_disableInterrupt();
|
||||
if (res < OK) {
|
||||
logError(1, "%s enterGestureMode: ERROR %08X\n", tag, res |
|
||||
ERROR_DISABLE_INTER);
|
||||
return res | ERROR_DISABLE_INTER;
|
||||
}
|
||||
|
||||
if (reload == 1 || refreshGestureMask == 1) {
|
||||
res = enableGesture(NULL, 0);
|
||||
if (res < OK) {
|
||||
logError(1,
|
||||
"%s enterGestureMode: enableGesture ERROR %08X\n",
|
||||
tag,
|
||||
res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
refreshGestureMask = 0;
|
||||
}
|
||||
|
||||
res = setScanMode(SCAN_MODE_LOW_POWER, 0);
|
||||
if (res < OK) {
|
||||
logError(1,
|
||||
"%s enterGestureMode: enter gesture mode ERROR %08X\n",
|
||||
tag,
|
||||
res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
res = OK;
|
||||
END:
|
||||
ret = fts_enableInterrupt();
|
||||
if (ret < OK) {
|
||||
logError(1,
|
||||
"%s enterGestureMode: fts_enableInterrupt ERROR %08X\n",
|
||||
tag,
|
||||
res | ERROR_ENABLE_INTER);
|
||||
res |= ret | ERROR_ENABLE_INTER;
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if one or more Gesture IDs are currently enabled in gesture_mask
|
||||
* @return FEAT_ENABLE if one or more gesture ids are enabled, FEAT_DISABLE if
|
||||
* all the gesture ids are currently disabled
|
||||
*/
|
||||
int isAnyGestureActive(void)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
while (res < (GESTURE_MASK_SIZE - 1) && gesture_mask[res] == 0)
|
||||
/* -1 because in any case the last gesture mask byte will
|
||||
* be evaluated with the following if */
|
||||
res++;
|
||||
|
||||
if (gesture_mask[res] != 0) {
|
||||
logError(0,
|
||||
"%s %s: Active Gestures Found! gesture_mask[%d] = %02X !\n",
|
||||
tag, __func__, res, gesture_mask[res]);
|
||||
return FEAT_ENABLE;
|
||||
} else {
|
||||
logError(0, "%s %s: All Gestures Disabled!\n", tag, __func__);
|
||||
return FEAT_DISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read from the frame buffer the gesture coordinates pairs of the points draw
|
||||
* by an user when a gesture is detected
|
||||
* @param event pointer to a byte array which contains the gesture event
|
||||
* reported
|
||||
* by the fw when a gesture is detected
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int readGestureCoords(u8 *event)
|
||||
{
|
||||
int i = 0;
|
||||
u64 address = 0;
|
||||
int res;
|
||||
|
||||
u8 val[GESTURE_MAX_COORDS_PAIRS_REPORT * 4];
|
||||
|
||||
/* the max coordinates to read are GESTURE_COORDS_REPORT_MAX*4
|
||||
* (because each coordinate is a short(*2) and we have x and y) */
|
||||
|
||||
|
||||
if (event[0] == EVT_ID_USER_REPORT && event[1] ==
|
||||
EVT_TYPE_USER_GESTURE) {
|
||||
address = (event[4] << 8) | event[3]; /* Offset in framebuff */
|
||||
gesture_coords_reported = event[5]; /* number of pairs
|
||||
* coords reported */
|
||||
if (gesture_coords_reported > GESTURE_MAX_COORDS_PAIRS_REPORT) {
|
||||
logError(1,
|
||||
"%s %s: FW reported more than %d points for the gestures! Decreasing to %d\n",
|
||||
tag, __func__, gesture_coords_reported,
|
||||
GESTURE_MAX_COORDS_PAIRS_REPORT);
|
||||
gesture_coords_reported =
|
||||
GESTURE_MAX_COORDS_PAIRS_REPORT;
|
||||
}
|
||||
|
||||
logError(1, "%s %s: Offset: %08llX , coords pairs = %d\n", tag,
|
||||
__func__, address, gesture_coords_reported);
|
||||
|
||||
res = fts_writeReadU8UX(FTS_CMD_FRAMEBUFFER_R, BITS_16, address,
|
||||
val, (gesture_coords_reported * 2 * 2),
|
||||
DUMMY_FRAMEBUFFER);
|
||||
/* *2 because each coord is made by 2 bytes,
|
||||
* *2 because there are x and y */
|
||||
if (res < OK) {
|
||||
logError(1,
|
||||
"%s %s: Cannot read the coordinates! ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
gesture_coords_reported = ERROR_OP_NOT_ALLOW;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* all the points of the gesture are stored in val */
|
||||
for (i = 0; i < gesture_coords_reported; i++) {
|
||||
gesture_coordinates_x[i] = (((u16)val[i * 2 + 1]) &
|
||||
0x0F) << 8 |
|
||||
(((u16)val[i * 2]) & 0xFF);
|
||||
gesture_coordinates_y[i] =
|
||||
(((u16)val[gesture_coords_reported * 2 + i * 2 + 1]) &
|
||||
0x0F) << 8 |
|
||||
(((u16)val[gesture_coords_reported * 2 +
|
||||
i * 2]) & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
logError(1, "%s %s: Reading Gesture Coordinates DONE!\n", tag,
|
||||
__func__);
|
||||
return OK;
|
||||
} else {
|
||||
logError(1,
|
||||
"%s %s: The event passsed as argument is invalid! ERROR %08X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the coordinates of the points stored during the last detected gesture
|
||||
* @param x output parameter which will store the address of the array
|
||||
* containing the x coordinates
|
||||
* @param y output parameter which will store the address of the array
|
||||
* containing the y coordinates
|
||||
* @return the number of points (x,y) stored and therefore the size of the x
|
||||
* and y array returned.
|
||||
*/
|
||||
int getGestureCoords(u16 **x, u16 **y)
|
||||
{
|
||||
*x = gesture_coordinates_x;
|
||||
*y = gesture_coordinates_y;
|
||||
logError(1,
|
||||
"%s %s: Number of gesture coordinates pairs returned = %d\n",
|
||||
tag,
|
||||
__func__, gesture_coords_reported);
|
||||
return gesture_coords_reported;
|
||||
}
|
||||
47
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsGesture.h
Normal file
47
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsGesture.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Gesture Utilities *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsGesture.h
|
||||
* \brief Contains all the macro and prototypes to handle the Gesture Detection
|
||||
* features
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FTS_GESTURE_H_
|
||||
#define FTS_GESTURE_H_
|
||||
|
||||
|
||||
|
||||
|
||||
#include "ftsHardware.h"
|
||||
|
||||
#define GESTURE_MASK_SIZE 4 /* /< number of bytes of the
|
||||
* gesture mask */
|
||||
|
||||
#define GESTURE_MAX_COORDS_PAIRS_REPORT 100 /* /< max number of gestures
|
||||
* coordinates pairs reported */
|
||||
|
||||
|
||||
|
||||
int updateGestureMask(u8 *mask, int size, int en);
|
||||
int disableGesture(u8 *mask, int size);
|
||||
int enableGesture(u8 *mask, int size);
|
||||
int enterGestureMode(int reload);
|
||||
int isAnyGestureActive(void);
|
||||
int readGestureCoords(u8 *event);
|
||||
int getGestureCoords(u16 **x, u16 **y);
|
||||
|
||||
#endif /* ! _GESTURE_H_ */
|
||||
308
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsHardware.h
Normal file
308
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsHardware.h
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* HW related data *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsHardware.h
|
||||
* \brief Contains all the definitions and information related to the IC
|
||||
* from an hardware point of view
|
||||
*/
|
||||
|
||||
#ifndef FTS_HARDWARE_H
|
||||
#define FTS_HARDWARE_H
|
||||
|
||||
|
||||
/* DIGITAL CHIP INFO */
|
||||
//#define ALIX
|
||||
|
||||
#ifdef ALIX
|
||||
#define DCHIP_ID_0 0x36 /* /< LSB chip ID for FTM5 */
|
||||
#define DCHIP_ID_1 0x48 /* /< MSB chip ID for FTM5 */
|
||||
#else
|
||||
#define DCHIP_ID_0 0x36 /* /< LSB chip ID for FTM5 */
|
||||
#define DCHIP_ID_1 0x39 /* /< MSB chip ID for FTM5 */
|
||||
#endif
|
||||
|
||||
|
||||
#define DCHIP_FW_VER_BYTE 2 /* /< number of bytes of the fw
|
||||
* versions */
|
||||
|
||||
/* CHUNKS */
|
||||
#define READ_CHUNK 1024 /* /< chunk dimension of
|
||||
* a single i2c read,
|
||||
* max allowed value is 2kB */
|
||||
#define WRITE_CHUNK 1024 /* /< chunk dimension of
|
||||
* a single i2c write,
|
||||
* max allowed value is 2kB */
|
||||
#define MEMORY_CHUNK 1024 /* /< chunk dimenasion of
|
||||
* a single i2c write on mem,
|
||||
* max allowed value is 2kB */
|
||||
|
||||
/* PROTOCOL INFO */
|
||||
#define I2C_INTERFACE /*/< comment if the chip use SPI bus */
|
||||
#ifdef I2C_INTERFACE
|
||||
#define I2C_SAD 0x49 /* /< slave address of the IC */
|
||||
#else
|
||||
#define SPI4_WIRE /* /< comment if the master is SPI3 wires
|
||||
* (MOSI and MISO share same line) */
|
||||
#define SPI_DELAY_CS 10 /* /< time in usec to wait
|
||||
* before rising the CS */
|
||||
#define SPI_CLOCK_FREQ 7000000 /* /< clock frequency in Hz of
|
||||
* the SPI bus */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define IER_ENABLE 0x41 /* /< value to write in IER_ADDR
|
||||
* to enable the interrupts */
|
||||
#define IER_DISABLE 0x00 /* /< value to write in IER_ADDR
|
||||
* to disable the interrupts */
|
||||
|
||||
/* FLASH COMMAND */
|
||||
/** @defgroup flash_command Flash Commands
|
||||
* All the commands that works with the flash of the IC
|
||||
* @{
|
||||
*/
|
||||
#define FLASH_CMD_UNLOCK 0xF7
|
||||
|
||||
#define FLASH_CMD_READ_REGISTER 0xFA
|
||||
#define FLASH_CMD_WRITE_REGISTER 0xFA
|
||||
|
||||
|
||||
/* FLASH UNLOCK PARAMETER */
|
||||
#define FLASH_UNLOCK_CODE0 0x25
|
||||
#define FLASH_UNLOCK_CODE1 0x20
|
||||
#define FLASH_UNLOCK_CODE2 0x6B
|
||||
#define FLASH_UNLOCK_CODE3 0x00
|
||||
|
||||
|
||||
/* FLASH UVLO ENABLE PARAMETER */
|
||||
#define FLASH_UVLO_ENABLE_CODE0 0x1B
|
||||
#define FLASH_UVLO_ENABLE_CODE1 0x66
|
||||
|
||||
/* FLASH AUTOPOWERDOWN ENABLE PARAMETER */
|
||||
#define FLASH_AUTOPOWERDOWN_ENABLE_CODE0 0x68
|
||||
#define FLASH_AUTOPOWERDOWN_ENABLE_CODE1 0x13
|
||||
|
||||
|
||||
|
||||
/* FLASH ERASE and DMA PARAMETER */
|
||||
#define FLASH_ERASE_START 0x80
|
||||
#define FLASH_ERASE_CODE1 0xC0
|
||||
#define FLASH_DMA_CODE1 0xC0
|
||||
#define FLASH_ERASE_UNLOCK_CODE0 0xDE
|
||||
#define FLASH_ERASE_UNLOCK_CODE1 0x03
|
||||
#define FLASH_ERASE_CODE0 0x6A
|
||||
#define FLASH_DMA_CODE0 0x71
|
||||
#define FLASH_DMA_CONFIG 0x72
|
||||
#define FLASH_NUM_PAGE 32 /* /< number of pages in main
|
||||
* flash */
|
||||
|
||||
#define FLASH_CX_PAGE_START 28 /* /< starting page which
|
||||
* contain Cx data */
|
||||
#define FLASH_CX_PAGE_END 30 /* /< last page which contain Cx
|
||||
* data */
|
||||
#define FLASH_PANEL_PAGE_START 26 /* /< starting page which
|
||||
* contain Panel Init data */
|
||||
#define FLASH_PANEL_PAGE_END 27 /* /< last page which contain
|
||||
* Panel Init data */
|
||||
|
||||
/** @} */
|
||||
|
||||
/* FLASH ADDRESS */
|
||||
|
||||
#define FLASH_ADDR_CODE 0x00000000 /* /< starting address (words)
|
||||
* in the flash of the code in
|
||||
* FTI */
|
||||
#define FLASH_ADDR_CONFIG 0x00007C00 /* /< starting address (words)
|
||||
* in the flash of the config in
|
||||
* FTI */
|
||||
#define FLASH_ADDR_CX 0x00007000 /* /< starting address (words)
|
||||
* in the flash of the Init data
|
||||
* in FTI */
|
||||
|
||||
|
||||
|
||||
/* SIZES FW, CODE, CONFIG, MEMH */
|
||||
/** @defgroup fw_file FW file info
|
||||
* All the info related to the fw file
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define FW_HEADER_SIZE 64 /* /< dimension of the header of the
|
||||
* .fts file */
|
||||
#define FW_HEADER_SIGNATURE 0xAA55AA55 /* /< header signature */
|
||||
#define FW_FTB_VER 0x00000001 /* /< .ftb version */
|
||||
#define FW_BYTES_ALLIGN 4 /* /< allignment of the info */
|
||||
#define FW_BIN_VER_OFFSET 16 /* /< offset of the fw version in the
|
||||
* .ftb file */
|
||||
#define FW_BIN_CONFIG_ID_OFFSET 20 /* /< offset of the config id in the
|
||||
* .ftb file */
|
||||
#define FW_CX_VERSION (16 + 4) /* /< offset of CX version in
|
||||
* the sec2 of FW file */
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/* FIFO */
|
||||
#define FIFO_EVENT_SIZE 8 /* /< number of bytes of one event */
|
||||
#define FIFO_DEPTH 32 /* /< max number of events that the FIFO can
|
||||
* collect before going in overflow in FTM5 */
|
||||
|
||||
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
#define FIFO_CMD_READALL 0x86 /* /< command to read all the events in
|
||||
* the FIFO */
|
||||
#else
|
||||
#define FIFO_CMD_READALL 0x87 /* /< command to read all the events in
|
||||
* the FIFO */
|
||||
#endif
|
||||
#define FIFO_CMD_READONE FIFO_CMD_READALL /* /< commad to read one
|
||||
* event from FIFO */
|
||||
|
||||
|
||||
/* OP CODES FOR MEMORY (based on protocol) */
|
||||
#ifdef I2C_INTERFACE
|
||||
#define FTS_CMD_HW_REG_R 0xFA /* /< command to read an hw register if
|
||||
* FTI */
|
||||
#define FTS_CMD_HW_REG_W 0xFA /* /< command to write an hw register if
|
||||
* FTI */
|
||||
#define FTS_CMD_FRAMEBUFFER_W 0xA6 /* /< command to write the framebuffer if
|
||||
* FTI */
|
||||
#define FTS_CMD_FRAMEBUFFER_R 0xA6 /* /< command to read the framebuffer if
|
||||
* FTI */
|
||||
#define FTS_CMD_CONFIG_R 0xA8 /* /< command to read the config memory
|
||||
* if FTI */
|
||||
#define FTS_CMD_CONFIG_W 0xA8 /* /< command to write the config memory
|
||||
* if FTI */
|
||||
#else
|
||||
#define FTS_CMD_HW_REG_R 0xFB /* /< command to read an hw register if
|
||||
* FTI */
|
||||
#define FTS_CMD_HW_REG_W 0xFA /* /< command to write an hw register if
|
||||
* FTI */
|
||||
#define FTS_CMD_FRAMEBUFFER_W 0xA6 /* /< command to write the framebuffer if
|
||||
* FTI */
|
||||
#define FTS_CMD_FRAMEBUFFER_R 0xA7 /* /< command to read the framebuffer if
|
||||
* FTI */
|
||||
#define FTS_CMD_CONFIG_R 0xA9 /* /< command to read the config memory
|
||||
* if FTI */
|
||||
#define FTS_CMD_CONFIG_W 0xA8 /* /< command to write the config memory
|
||||
* if FTI */
|
||||
#endif
|
||||
|
||||
|
||||
/* DUMMY BYTES DATA */
|
||||
|
||||
#ifndef I2C_INTERFACE
|
||||
#define DUMMY_HW_REG 1 /* /< 1 if the first byte read from HW
|
||||
* register is dummy */
|
||||
#define DUMMY_FRAMEBUFFER 1 /* /< 1 if the first byte read from
|
||||
* Frame buffer is dummy */
|
||||
#define DUMMY_CONFIG 1 /* /< 1 if the first byte read from
|
||||
* Config Memory is dummy */
|
||||
#define DUMMY_FIFO 1 /* /< 1 if the first byte read from FIFO
|
||||
* is dummy */
|
||||
#else
|
||||
#define DUMMY_HW_REG 0 /* /< 1 if the first byte read from HW
|
||||
* register is dummy */
|
||||
#define DUMMY_FRAMEBUFFER 0 /* /< 1 if the first byte read from
|
||||
* Frame buffer is dummy */
|
||||
#define DUMMY_CONFIG 0 /* /< 1 if the first byte read from
|
||||
* Config Memory is dummy */
|
||||
#define DUMMY_FIFO 0 /* /< 1 if the first byte read from FIFO
|
||||
* is dummy */
|
||||
#endif
|
||||
|
||||
|
||||
/** @defgroup hw_adr HW Address
|
||||
* @ingroup address
|
||||
* Important addresses of hardware registers (and sometimes their important
|
||||
*values)
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* IMPORTANT HW ADDRESSES (u64) */
|
||||
#define ADDR_FRAMEBUFFER ((u64)0x0000000000000000) /* /< frame buffer
|
||||
* address in memory */
|
||||
#define ADDR_ERROR_DUMP ((u64)0x000000000000EF80) /* /< start address
|
||||
* dump error log */
|
||||
|
||||
/* SYSTEM RESET INFO */
|
||||
#define ADDR_SYSTEM_RESET ((u64)0x0000000020000024) /* /< address of
|
||||
* System control reg
|
||||
* in FTI */
|
||||
#define SYSTEM_RESET_VALUE 0x81 /* /< value to write in
|
||||
* SYSTEM_RESET_ADDRESS to perform a
|
||||
* system reset in FTM5 */
|
||||
|
||||
|
||||
/* REMAP REGISTER */
|
||||
#define ADDR_BOOT_OPTION ((u64)0x0000000020000025) /* /< address of Boot
|
||||
* option register */
|
||||
|
||||
|
||||
/* INTERRUPT INFO */
|
||||
#define ADDR_IER ((u64)0x0000000020000029) /* /< address of the
|
||||
* Interrupt enable
|
||||
* register in FTMI */
|
||||
|
||||
|
||||
/* Chip ID/Fw Version */
|
||||
#define ADDR_DCHIP_ID ((u64)0x0000000020000000) /* /< chip id address
|
||||
* for FTI */
|
||||
#define ADDR_DCHIP_FW_VER ((u64)0x0000000020000004) /* /< fw version
|
||||
* address for FTI */
|
||||
|
||||
|
||||
/* INTERFACE REGISTER */
|
||||
#define ADDR_ICR ((u64)0x000000002000002D) /* /< address of Device
|
||||
* control register to
|
||||
* set the comunication
|
||||
* protocol (SPI/I2C) */
|
||||
#define SPI4_MASK 0x02 /* /< bit to set spi4 */
|
||||
|
||||
|
||||
/* CRC ADDR */
|
||||
#define ADDR_CRC ((u64)0x0000000020000078) /* /< address of CRC
|
||||
* control register in
|
||||
* FTI */
|
||||
#define CRC_MASK 0x03 /* /< bitmask which reveal if there is a
|
||||
* CRC error in the flash */
|
||||
|
||||
|
||||
|
||||
#define ADDR_CONFIG_OFFSET ((u64)0x0000000000000000) /* /< config address
|
||||
* in memory if FTI */
|
||||
|
||||
|
||||
|
||||
#define ADDR_GPIO_INPUT ((u64)0x0000000020000030) /* /< address of GPIO
|
||||
* input register */
|
||||
#define ADDR_GPIO_DIRECTION ((u64)0x0000000020000032) /* /< address of GPIO
|
||||
* direction register */
|
||||
#define ADDR_GPIO_PULLUP ((u64)0x0000000020000034) /* /< address of GPIO
|
||||
* pullup register */
|
||||
#define ADDR_GPIO_CONFIG_REG0 ((u64)0x000000002000003D) /* /< address of
|
||||
* GPIO config register
|
||||
*/
|
||||
#define ADDR_GPIO_CONFIG_REG2 ((u64)0x000000002000003F) /* /< address of
|
||||
* GPIO config register
|
||||
*/
|
||||
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
||||
#endif
|
||||
745
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsIO.c
Normal file
745
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsIO.c
Normal file
|
|
@ -0,0 +1,745 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* I2C/SPI Communication *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsIO.c
|
||||
* \brief Contains all the functions which handle with the I2C/SPI
|
||||
*communication
|
||||
*/
|
||||
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
static u16 I2CSAD; /* /< slave address of the IC in the i2c bus */
|
||||
#else
|
||||
#include <linux/spi/spidev.h>
|
||||
#endif
|
||||
|
||||
static void *client; /* /< bus client retrived by the OS and
|
||||
* used to execute the bus transfers */
|
||||
|
||||
|
||||
|
||||
#include "ftsCore.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsHardware.h"
|
||||
#include "ftsIO.h"
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the static client variable of the fts_lib library in order
|
||||
* to allow any i2c/spi transaction in the driver (Must be called in the probe)
|
||||
* @param clt pointer to i2c_client or spi_device struct which identify the bus
|
||||
* slave device
|
||||
* @return OK
|
||||
*/
|
||||
int openChannel(void *clt)
|
||||
{
|
||||
client = clt;
|
||||
#ifdef I2C_INTERFACE
|
||||
I2CSAD = ((struct i2c_client *)clt)->addr;
|
||||
logError(1, "%s openChannel: SAD: %02X\n", tag, I2CSAD);
|
||||
#else
|
||||
logError(1, "%s %s: spi_master: flags = %04X !\n", tag, __func__,
|
||||
((struct spi_device *)client)->master->flags);
|
||||
logError(1,
|
||||
"%s %s: spi_device: max_speed = %d chip select = %02X bits_per_words = %d mode = %04X !\n",
|
||||
tag, __func__, ((struct spi_device *)client)->max_speed_hz,
|
||||
((struct spi_device *)client)->chip_select,
|
||||
((struct spi_device *)client)->bits_per_word,
|
||||
((struct spi_device *)client)->mode);
|
||||
logError(1, "%s openChannel: completed!\n", tag);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
/**
|
||||
* Change the I2C slave address which will be used during the transaction
|
||||
* (For Debug Only)
|
||||
* @param sad new slave address id
|
||||
* @return OK
|
||||
*/
|
||||
int changeSAD(u8 sad)
|
||||
{
|
||||
I2CSAD = sad;
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the pointer to the device struct of the IC
|
||||
* @return a the device struct pointer if client was previously set
|
||||
* or NULL in all the other cases
|
||||
*/
|
||||
struct device *getDev(void)
|
||||
{
|
||||
if (client != NULL)
|
||||
return &(getClient()->dev);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
/**
|
||||
* Retrieve the pointer of the i2c_client struct representing the IC as i2c
|
||||
*slave
|
||||
* @return client if it was previously set or NULL in all the other cases
|
||||
*/
|
||||
struct i2c_client *getClient()
|
||||
{
|
||||
if (client != NULL)
|
||||
return (struct i2c_client *)client;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* Retrieve the pointer of the spi_device struct representing the IC as spi
|
||||
*slave
|
||||
* @return client if it was previously set or NULL in all the other cases
|
||||
*/
|
||||
struct spi_device *getClient()
|
||||
{
|
||||
if (client != NULL)
|
||||
return (struct spi_device *)client;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/****************** New I2C API *********************/
|
||||
|
||||
/**
|
||||
* Perform a direct bus read
|
||||
* @param outBuf pointer of a byte array which should contain the byte read
|
||||
*from the IC
|
||||
* @param byteToRead number of bytes to read
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int fts_read(u8 *outBuf, int byteToRead)
|
||||
{
|
||||
int ret = -1;
|
||||
int retry = 0;
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
struct i2c_msg I2CMsg[1];
|
||||
|
||||
I2CMsg[0].addr = (__u16)I2CSAD;
|
||||
I2CMsg[0].flags = (__u16)I2C_M_RD;
|
||||
I2CMsg[0].len = (__u16)byteToRead;
|
||||
I2CMsg[0].buf = (__u8 *)outBuf;
|
||||
#else
|
||||
struct spi_message msg;
|
||||
struct spi_transfer transfer[1] = { { 0 } };
|
||||
|
||||
spi_message_init(&msg);
|
||||
|
||||
transfer[0].len = byteToRead;
|
||||
transfer[0].delay_usecs = SPI_DELAY_CS;
|
||||
transfer[0].tx_buf = NULL;
|
||||
transfer[0].rx_buf = outBuf;
|
||||
spi_message_add_tail(&transfer[0], &msg);
|
||||
#endif
|
||||
|
||||
|
||||
if (client == NULL)
|
||||
return ERROR_BUS_O;
|
||||
while (retry < I2C_RETRY && ret < OK) {
|
||||
#ifdef I2C_INTERFACE
|
||||
ret = i2c_transfer(getClient()->adapter, I2CMsg, 1);
|
||||
#else
|
||||
ret = spi_sync(getClient(), &msg);
|
||||
#endif
|
||||
|
||||
retry++;
|
||||
if (ret < OK)
|
||||
msleep(I2C_WAIT_BEFORE_RETRY);
|
||||
/* logError(1,"%s fts_writeCmd: attempt %d\n", tag, retry); */
|
||||
}
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__, ERROR_BUS_R);
|
||||
return ERROR_BUS_R;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform a bus write followed by a bus read without a stop condition
|
||||
* @param cmd byte array containing the command to write
|
||||
* @param cmdLength size of cmd
|
||||
* @param outBuf pointer of a byte array which should contain the bytes read
|
||||
*from the IC
|
||||
* @param byteToRead number of bytes to read
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int fts_writeRead(u8 *cmd, int cmdLength, u8 *outBuf, int byteToRead)
|
||||
{
|
||||
int ret = -1;
|
||||
int retry = 0;
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
struct i2c_msg I2CMsg[2];
|
||||
|
||||
/* write msg */
|
||||
I2CMsg[0].addr = (__u16)I2CSAD;
|
||||
I2CMsg[0].flags = (__u16)0;
|
||||
I2CMsg[0].len = (__u16)cmdLength;
|
||||
I2CMsg[0].buf = (__u8 *)cmd;
|
||||
|
||||
/* read msg */
|
||||
I2CMsg[1].addr = (__u16)I2CSAD;
|
||||
I2CMsg[1].flags = I2C_M_RD;
|
||||
I2CMsg[1].len = byteToRead;
|
||||
I2CMsg[1].buf = (__u8 *)outBuf;
|
||||
|
||||
#else
|
||||
struct spi_message msg;
|
||||
struct spi_transfer transfer[2] = { { 0 }, { 0 } };
|
||||
|
||||
spi_message_init(&msg);
|
||||
|
||||
transfer[0].len = cmdLength;
|
||||
transfer[0].tx_buf = cmd;
|
||||
transfer[0].rx_buf = NULL;
|
||||
spi_message_add_tail(&transfer[0], &msg);
|
||||
|
||||
transfer[1].len = byteToRead;
|
||||
transfer[1].delay_usecs = SPI_DELAY_CS;
|
||||
transfer[1].tx_buf = NULL;
|
||||
transfer[1].rx_buf = outBuf;
|
||||
spi_message_add_tail(&transfer[1], &msg);
|
||||
|
||||
#endif
|
||||
|
||||
if (client == NULL)
|
||||
return ERROR_BUS_O;
|
||||
|
||||
while (retry < I2C_RETRY && ret < OK) {
|
||||
#ifdef I2C_INTERFACE
|
||||
ret = i2c_transfer(getClient()->adapter, I2CMsg, 2);
|
||||
#else
|
||||
ret = spi_sync(getClient(), &msg);
|
||||
#endif
|
||||
|
||||
retry++;
|
||||
if (ret < OK)
|
||||
msleep(I2C_WAIT_BEFORE_RETRY);
|
||||
}
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__, ERROR_BUS_WR);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform a bus write
|
||||
* @param cmd byte array containing the command to write
|
||||
* @param cmdLength size of cmd
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int fts_write(u8 *cmd, int cmdLength)
|
||||
{
|
||||
int ret = -1;
|
||||
int retry = 0;
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
struct i2c_msg I2CMsg[1];
|
||||
|
||||
I2CMsg[0].addr = (__u16)I2CSAD;
|
||||
I2CMsg[0].flags = (__u16)0;
|
||||
I2CMsg[0].len = (__u16)cmdLength;
|
||||
I2CMsg[0].buf = (__u8 *)cmd;
|
||||
#else
|
||||
struct spi_message msg;
|
||||
struct spi_transfer transfer[1] = { { 0 } };
|
||||
|
||||
spi_message_init(&msg);
|
||||
|
||||
transfer[0].len = cmdLength;
|
||||
transfer[0].delay_usecs = SPI_DELAY_CS;
|
||||
transfer[0].tx_buf = cmd;
|
||||
transfer[0].rx_buf = NULL;
|
||||
spi_message_add_tail(&transfer[0], &msg);
|
||||
#endif
|
||||
|
||||
|
||||
if (client == NULL)
|
||||
return ERROR_BUS_O;
|
||||
while (retry < I2C_RETRY && ret < OK) {
|
||||
#ifdef I2C_INTERFACE
|
||||
ret = i2c_transfer(getClient()->adapter, I2CMsg, 1);
|
||||
#else
|
||||
ret = spi_sync(getClient(), &msg);
|
||||
#endif
|
||||
|
||||
retry++;
|
||||
if (ret < OK)
|
||||
msleep(I2C_WAIT_BEFORE_RETRY);
|
||||
/* logError(1,"%s fts_writeCmd: attempt %d\n", tag, retry); */
|
||||
}
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__, ERROR_BUS_W);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a FW command to the IC and check automatically the echo event
|
||||
* @param cmd byte array containing the command to send
|
||||
* @param cmdLength size of cmd
|
||||
* @return OK if success, or an error code which specify the type of error
|
||||
*/
|
||||
int fts_writeFwCmd(u8 *cmd, int cmdLength)
|
||||
{
|
||||
int ret = -1;
|
||||
int ret2 = -1;
|
||||
int retry = 0;
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
struct i2c_msg I2CMsg[1];
|
||||
|
||||
I2CMsg[0].addr = (__u16)I2CSAD;
|
||||
I2CMsg[0].flags = (__u16)0;
|
||||
I2CMsg[0].len = (__u16)cmdLength;
|
||||
I2CMsg[0].buf = (__u8 *)cmd;
|
||||
#else
|
||||
struct spi_message msg;
|
||||
struct spi_transfer transfer[1] = { { 0 } };
|
||||
|
||||
spi_message_init(&msg);
|
||||
|
||||
transfer[0].len = cmdLength;
|
||||
transfer[0].delay_usecs = SPI_DELAY_CS;
|
||||
transfer[0].tx_buf = cmd;
|
||||
transfer[0].rx_buf = NULL;
|
||||
spi_message_add_tail(&transfer[0], &msg);
|
||||
#endif
|
||||
|
||||
if (client == NULL)
|
||||
return ERROR_BUS_O;
|
||||
resetErrorList();
|
||||
while (retry < I2C_RETRY && (ret < OK || ret2 < OK)) {
|
||||
#ifdef I2C_INTERFACE
|
||||
ret = i2c_transfer(getClient()->adapter, I2CMsg, 1);
|
||||
#else
|
||||
ret = spi_sync(getClient(), &msg);
|
||||
#endif
|
||||
retry++;
|
||||
if (ret >= 0)
|
||||
ret2 = checkEcho(cmd, cmdLength);
|
||||
if (ret < OK || ret2 < OK)
|
||||
msleep(I2C_WAIT_BEFORE_RETRY);
|
||||
/* logError(1,"%s fts_writeCmd: attempt %d\n", tag, retry); */
|
||||
}
|
||||
if (ret < 0) {
|
||||
logError(1, "%s fts_writeFwCmd: ERROR %08X\n", tag,
|
||||
ERROR_BUS_W);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
if (ret2 < OK) {
|
||||
logError(1, "%s fts_writeFwCmd: check echo ERROR %08X\n", tag,
|
||||
ret2);
|
||||
return ret2;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform two bus write and one bus read without any stop condition
|
||||
* In case of FTI this function is not supported and the same sequence
|
||||
* can be achieved calling fts_write followed by an fts_writeRead.
|
||||
* @param writeCmd1 byte array containing the first command to write
|
||||
* @param writeCmdLength size of writeCmd1
|
||||
* @param readCmd1 byte array containing the second command to write
|
||||
* @param readCmdLength size of readCmd1
|
||||
* @param outBuf pointer of a byte array which should contain the bytes read
|
||||
* from the IC
|
||||
* @param byteToRead number of bytes to read
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int fts_writeThenWriteRead(u8 *writeCmd1, int writeCmdLength, u8 *readCmd1, int
|
||||
readCmdLength, u8 *outBuf, int byteToRead)
|
||||
{
|
||||
int ret = -1;
|
||||
int retry = 0;
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
struct i2c_msg I2CMsg[3];
|
||||
|
||||
/* write msg */
|
||||
I2CMsg[0].addr = (__u16)I2CSAD;
|
||||
I2CMsg[0].flags = (__u16)0;
|
||||
I2CMsg[0].len = (__u16)writeCmdLength;
|
||||
I2CMsg[0].buf = (__u8 *)writeCmd1;
|
||||
|
||||
/* write msg */
|
||||
I2CMsg[1].addr = (__u16)I2CSAD;
|
||||
I2CMsg[1].flags = (__u16)0;
|
||||
I2CMsg[1].len = (__u16)readCmdLength;
|
||||
I2CMsg[1].buf = (__u8 *)readCmd1;
|
||||
|
||||
/* read msg */
|
||||
I2CMsg[2].addr = (__u16)I2CSAD;
|
||||
I2CMsg[2].flags = I2C_M_RD;
|
||||
I2CMsg[2].len = byteToRead;
|
||||
I2CMsg[2].buf = (__u8 *)outBuf;
|
||||
#else
|
||||
struct spi_message msg;
|
||||
struct spi_transfer transfer[3] = { { 0 }, { 0 }, { 0 } };
|
||||
|
||||
spi_message_init(&msg);
|
||||
|
||||
transfer[0].len = writeCmdLength;
|
||||
transfer[0].tx_buf = writeCmd1;
|
||||
transfer[0].rx_buf = NULL;
|
||||
spi_message_add_tail(&transfer[0], &msg);
|
||||
|
||||
transfer[1].len = readCmdLength;
|
||||
transfer[1].tx_buf = readCmd1;
|
||||
transfer[1].rx_buf = NULL;
|
||||
spi_message_add_tail(&transfer[1], &msg);
|
||||
|
||||
transfer[2].len = byteToRead;
|
||||
transfer[2].delay_usecs = SPI_DELAY_CS;
|
||||
transfer[2].tx_buf = NULL;
|
||||
transfer[2].rx_buf = outBuf;
|
||||
spi_message_add_tail(&transfer[2], &msg);
|
||||
#endif
|
||||
|
||||
if (client == NULL)
|
||||
return ERROR_BUS_O;
|
||||
while (retry < I2C_RETRY && ret < OK) {
|
||||
#ifdef I2C_INTERFACE
|
||||
ret = i2c_transfer(getClient()->adapter, I2CMsg, 3);
|
||||
#else
|
||||
ret = spi_sync(getClient(), &msg);
|
||||
#endif
|
||||
retry++;
|
||||
if (ret < OK)
|
||||
msleep(I2C_WAIT_BEFORE_RETRY);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__, ERROR_BUS_WR);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Perform a chunked write with one byte op code and 1 to 8 bytes address
|
||||
* @param cmd byte containing the op code to write
|
||||
* @param addrSize address size in byte
|
||||
* @param address the starting address
|
||||
* @param data pointer of a byte array which contain the bytes to write
|
||||
* @param dataSize size of data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
/* this function works only if the address is max 8 bytes */
|
||||
int fts_writeU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *data, int
|
||||
dataSize)
|
||||
{
|
||||
u8 finalCmd[1 + addrSize + WRITE_CHUNK];
|
||||
int remaining = dataSize;
|
||||
int toWrite = 0, i = 0;
|
||||
|
||||
if (addrSize <= sizeof(u64)) {
|
||||
while (remaining > 0) {
|
||||
if (remaining >= WRITE_CHUNK) {
|
||||
toWrite = WRITE_CHUNK;
|
||||
remaining -= WRITE_CHUNK;
|
||||
} else {
|
||||
toWrite = remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
finalCmd[0] = cmd;
|
||||
logError(0, "%s %s: addrSize = %d\n", tag, __func__,
|
||||
addrSize);
|
||||
for (i = 0; i < addrSize; i++) {
|
||||
finalCmd[i + 1] = (u8)((address >> ((addrSize -
|
||||
1 - i) *
|
||||
8)) & 0xFF);
|
||||
logError(1, "%s %s: cmd[%d] = %02X\n", tag,
|
||||
__func__, i + 1, finalCmd[i + 1]);
|
||||
}
|
||||
|
||||
memcpy(&finalCmd[addrSize + 1], data, toWrite);
|
||||
|
||||
if (fts_write(finalCmd, 1 + addrSize + toWrite) < OK) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag,
|
||||
__func__, ERROR_BUS_W);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
|
||||
address += toWrite;
|
||||
|
||||
data += toWrite;
|
||||
}
|
||||
} else
|
||||
logError(1,
|
||||
"%s %s: address size bigger than max allowed %ld... ERROR %08X\n",
|
||||
tag, __func__, sizeof(u64), ERROR_OP_NOT_ALLOW);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a chunked write read with one byte op code and 1 to 8 bytes address
|
||||
* and dummy byte support.
|
||||
* @param cmd byte containing the op code to write
|
||||
* @param addrSize address size in byte
|
||||
* @param address the starting address
|
||||
* @param outBuf pointer of a byte array which contain the bytes to read
|
||||
* @param byteToRead number of bytes to read
|
||||
* @param hasDummyByte if the first byte of each reading is dummy (must be
|
||||
* skipped)
|
||||
* set to 1, otherwise if it is valid set to 0 (or any other value)
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int fts_writeReadU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *outBuf, int
|
||||
byteToRead, int hasDummyByte)
|
||||
{
|
||||
u8 finalCmd[1 + addrSize];
|
||||
u8 buff[READ_CHUNK + 1];/* worst case has dummy byte */
|
||||
int remaining = byteToRead;
|
||||
int toRead = 0, i = 0;
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= READ_CHUNK) {
|
||||
toRead = READ_CHUNK;
|
||||
remaining -= READ_CHUNK;
|
||||
} else {
|
||||
toRead = remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
finalCmd[0] = cmd;
|
||||
for (i = 0; i < addrSize; i++)
|
||||
finalCmd[i + 1] = (u8)((address >> ((addrSize - 1 - i) *
|
||||
8)) & 0xFF);
|
||||
|
||||
if (hasDummyByte == 1) {
|
||||
if (fts_writeRead(finalCmd, 1 + addrSize, buff, toRead +
|
||||
1) < OK) {
|
||||
logError(1,
|
||||
"%s %s: read error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_WR);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
memcpy(outBuf, buff + 1, toRead);
|
||||
} else {
|
||||
if (fts_writeRead(finalCmd, 1 + addrSize, buff,
|
||||
toRead) < OK) {
|
||||
logError(1,
|
||||
"%s %s: read error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_WR);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
memcpy(outBuf, buff, toRead);
|
||||
}
|
||||
|
||||
address += toRead;
|
||||
|
||||
outBuf += toRead;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a chunked write followed by a second write with one byte op code
|
||||
* for each write and 1 to 8 bytes address (the sum of the 2 address size of
|
||||
* the two writes can not exceed 8 bytes)
|
||||
* @param cmd1 byte containing the op code of first write
|
||||
* @param addrSize1 address size in byte of first write
|
||||
* @param cmd2 byte containing the op code of second write
|
||||
* @param addrSize2 address size in byte of second write
|
||||
* @param address the starting address
|
||||
* @param data pointer of a byte array which contain the bytes to write
|
||||
* @param dataSize size of data
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
/* this function works only if the sum of two addresses in the two commands is
|
||||
* max 8 bytes */
|
||||
int fts_writeU8UXthenWriteU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2, AddrSize
|
||||
addrSize2, u64 address, u8 *data, int dataSize)
|
||||
{
|
||||
u8 finalCmd1[1 + addrSize1];
|
||||
u8 finalCmd2[1 + addrSize2 + WRITE_CHUNK];
|
||||
int remaining = dataSize;
|
||||
int toWrite = 0, i = 0;
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= WRITE_CHUNK) {
|
||||
toWrite = WRITE_CHUNK;
|
||||
remaining -= WRITE_CHUNK;
|
||||
} else {
|
||||
toWrite = remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
finalCmd1[0] = cmd1;
|
||||
for (i = 0; i < addrSize1; i++)
|
||||
finalCmd1[i + 1] = (u8)((address >> ((addrSize1 +
|
||||
addrSize2 - 1 -
|
||||
i) * 8)) & 0xFF);
|
||||
|
||||
finalCmd2[0] = cmd2;
|
||||
for (i = addrSize1; i < addrSize1 + addrSize2; i++)
|
||||
finalCmd2[i - addrSize1 + 1] = (u8)((address >>
|
||||
((addrSize1 +
|
||||
addrSize2 - 1 -
|
||||
i) * 8)) & 0xFF);
|
||||
|
||||
memcpy(&finalCmd2[addrSize2 + 1], data, toWrite);
|
||||
|
||||
if (fts_write(finalCmd1, 1 + addrSize1) < OK) {
|
||||
logError(1, "%s %s: first write error... ERROR %08X\n",
|
||||
tag, __func__, ERROR_BUS_W);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
|
||||
if (fts_write(finalCmd2, 1 + addrSize2 + toWrite) < OK) {
|
||||
logError(1,
|
||||
"%s %s: second write error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_W);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
|
||||
address += toWrite;
|
||||
|
||||
data += toWrite;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a chunked write followed by a write read with one byte op code
|
||||
* and 1 to 8 bytes address for each write and dummy byte support.
|
||||
* @param cmd1 byte containing the op code of first write
|
||||
* @param addrSize1 address size in byte of first write
|
||||
* @param cmd2 byte containing the op code of second write read
|
||||
* @param addrSize2 address size in byte of second write read
|
||||
* @param address the starting address
|
||||
* @param outBuf pointer of a byte array which contain the bytes to read
|
||||
* @param byteToRead number of bytes to read
|
||||
* @param hasDummyByte if the first byte of each reading is dummy (must be
|
||||
* skipped) set to 1,
|
||||
* otherwise if it is valid set to 0 (or any other value)
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
/* this function works only if the sum of two addresses in the two commands is
|
||||
* max 8 bytes */
|
||||
int fts_writeU8UXthenWriteReadU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2,
|
||||
AddrSize addrSize2, u64 address, u8 *outBuf,
|
||||
int byteToRead, int hasDummyByte)
|
||||
{
|
||||
u8 finalCmd1[1 + addrSize1];
|
||||
u8 finalCmd2[1 + addrSize2];
|
||||
u8 buff[READ_CHUNK + 1];/* worst case has dummy byte */
|
||||
int remaining = byteToRead;
|
||||
int toRead = 0, i = 0;
|
||||
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= READ_CHUNK) {
|
||||
toRead = READ_CHUNK;
|
||||
remaining -= READ_CHUNK;
|
||||
} else {
|
||||
toRead = remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
|
||||
finalCmd1[0] = cmd1;
|
||||
for (i = 0; i < addrSize1; i++)
|
||||
finalCmd1[i + 1] = (u8)((address >> ((addrSize1 +
|
||||
addrSize2 - 1 -
|
||||
i) * 8)) & 0xFF);
|
||||
/* logError(1, "%s %s: finalCmd1[%d] = %02X\n",
|
||||
* tag, __func__, i+1, finalCmd1[i + 1]); */
|
||||
|
||||
finalCmd2[0] = cmd2;
|
||||
for (i = addrSize1; i < addrSize1 + addrSize2; i++)
|
||||
finalCmd2[i - addrSize1 + 1] = (u8)((address >>
|
||||
((addrSize1 +
|
||||
addrSize2 - 1 -
|
||||
i) * 8)) & 0xFF);
|
||||
|
||||
if (fts_write(finalCmd1, 1 + addrSize1) < OK) {
|
||||
logError(1, "%s %s: first write error... ERROR %08X\n",
|
||||
tag, __func__, ERROR_BUS_W);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
|
||||
if (hasDummyByte == 1) {
|
||||
if (fts_writeRead(finalCmd2, 1 + addrSize2, buff,
|
||||
toRead + 1) < OK) {
|
||||
logError(1,
|
||||
"%s %s: read error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_WR);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
memcpy(outBuf, buff + 1, toRead);
|
||||
} else {
|
||||
if (fts_writeRead(finalCmd2, 1 + addrSize2, buff,
|
||||
toRead) < OK) {
|
||||
logError(1,
|
||||
"%s %s: read error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_WR);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
memcpy(outBuf, buff, toRead);
|
||||
}
|
||||
|
||||
address += toRead;
|
||||
|
||||
outBuf += toRead;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
66
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsIO.h
Normal file
66
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsIO.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* I2C/SPI Communication *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
/*!
|
||||
* \file ftsIO.h
|
||||
* \brief Contains all the definitions and prototypes used and implemented in
|
||||
* ftsIO.c
|
||||
*/
|
||||
|
||||
#ifndef FTS_IO_H
|
||||
#define FTS_IO_H
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
#define I2C_RETRY 3 /* /< number of retry in case of i2c
|
||||
* failure */
|
||||
#define I2C_WAIT_BEFORE_RETRY 2 /* /< wait in ms before retry an i2c
|
||||
* transaction */
|
||||
|
||||
#ifdef I2C_INTERFACE
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
struct i2c_client *getClient(void);
|
||||
#else
|
||||
#include <linux/spi/spi.h>
|
||||
struct spi_device *getClient(void);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int openChannel(void *clt);
|
||||
struct device *getDev(void);
|
||||
|
||||
|
||||
|
||||
/*************** NEW I2C API ****************/
|
||||
#ifdef I2C_INTERFACE
|
||||
int changeSAD(u8 sad);
|
||||
#endif
|
||||
int fts_read(u8 *outBuf, int byteToRead);
|
||||
int fts_writeRead(u8 *cmd, int cmdLength, u8 *outBuf, int byteToRead);
|
||||
int fts_write(u8 *cmd, int cmdLength);
|
||||
int fts_writeFwCmd(u8 *cmd, int cmdLenght);
|
||||
int fts_writeThenWriteRead(u8 *writeCmd1, int writeCmdLength, u8 *readCmd1, int
|
||||
readCmdLength, u8 *outBuf, int byteToRead);
|
||||
int fts_writeU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *data, int
|
||||
dataSize);
|
||||
int fts_writeReadU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *outBuf, int
|
||||
byteToRead, int hasDummyByte);
|
||||
int fts_writeU8UXthenWriteU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2, AddrSize
|
||||
addrSize2, u64 address, u8 *data, int dataSize);
|
||||
int fts_writeU8UXthenWriteReadU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2,
|
||||
AddrSize addrSize2, u64 address, u8 *outBuf,
|
||||
int count, int hasDummyByte);
|
||||
#endif
|
||||
512
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsSoftware.h
Normal file
512
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsSoftware.h
Normal file
|
|
@ -0,0 +1,512 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FW related data *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsSoftware.h
|
||||
* \brief Contains all the definitions and information related to the IC from a
|
||||
*fw/driver point of view
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FTS_SOFTWARE_H
|
||||
#define FTS_SOFTWARE_H
|
||||
#include <linux/types.h>
|
||||
#include "ftsHardware.h"
|
||||
|
||||
|
||||
|
||||
/* unsigned types */
|
||||
typedef uint8_t u8; /* /< basic type that represent one byte (or 8 bits) */
|
||||
typedef uint16_t u16; /* /< basic type that represent 2 bytes (or 16 bits) */
|
||||
typedef uint32_t u32; /* /< basic type that represent 4 bytes (or 32 bits) */
|
||||
typedef uint64_t u64; /* /< basic type that represent 8 bytes (or 64 bits) */
|
||||
|
||||
/* signed type */
|
||||
typedef signed char i8; /* /< basic type that represent one signed byte (or 8
|
||||
* bits) */
|
||||
|
||||
/**
|
||||
* Enumerator which contains all the possible address length expressed in
|
||||
*bytes.
|
||||
*/
|
||||
typedef enum {
|
||||
NO_ADDR = 0,
|
||||
BITS_8 = 1,
|
||||
BITS_16 = 2,
|
||||
BITS_24 = 3,
|
||||
BITS_32 = 4,
|
||||
BITS_40 = 5,
|
||||
BITS_48 = 6,
|
||||
BITS_56 = 7,
|
||||
BITS_64 = 8
|
||||
} AddrSize;
|
||||
|
||||
|
||||
/******************** NEW API *********************/
|
||||
|
||||
/* HOST COMMAND */
|
||||
/** @defgroup host_command Fw Host op codes
|
||||
* Valid op codes for fw commands
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup scan_mode Scan Mode
|
||||
* @ingroup host_command
|
||||
* Set the scanning mode required according to the parameters
|
||||
* @{
|
||||
*/
|
||||
#define FTS_CMD_SCAN_MODE 0xA0 /* /< OP Code to set scan mode */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup feat_sel Feature Select
|
||||
* @ingroup host_command
|
||||
* Set the system defined features to enable/disable according the parameters
|
||||
* @{
|
||||
*/
|
||||
#define FTS_CMD_FEATURE 0xA2 /* /< OP code to set features */
|
||||
/** @} */
|
||||
|
||||
/** @defgroup sys_cmd System Command
|
||||
* @ingroup host_command
|
||||
* Execute a system command to perform core tasks
|
||||
* @{
|
||||
*/
|
||||
#define FTS_CMD_SYSTEM 0xA4 /* /< OP code to write s system command
|
||||
* */
|
||||
/** @} */
|
||||
|
||||
/** @} */ /* end host_command group */
|
||||
|
||||
/* SCAN MODE OPTION (0xA0) */
|
||||
/* Scan mode selection */
|
||||
/** @defgroup scan_opt Scan Mode Option
|
||||
* @ingroup scan_mode
|
||||
* Valid scanning modes and their options
|
||||
* @{
|
||||
*/
|
||||
#define SCAN_MODE_ACTIVE 0x00 /* /< Select the Active scanning mode */
|
||||
#define SCAN_MODE_LOW_POWER 0x01 /* /< Select the low power scanning mode
|
||||
* */
|
||||
#define SCAN_MODE_JIG_1 0x02 /* /< Select the Jig test 1 */
|
||||
#define SCAN_MODE_LOCKED 0x03 /* /< Select the Scan mode which will be
|
||||
* locked */
|
||||
/** @}*/
|
||||
|
||||
/* Active mode option (bitmask) */
|
||||
/** @defgroup active_bitmask Active Mode Bitmask
|
||||
* @ingroup scan_opt
|
||||
* Bitmask to use to enables the specific scanning with the SCAN_MODE_ACTIVE
|
||||
*option
|
||||
* @{
|
||||
*/
|
||||
#define ACTIVE_MULTI_TOUCH 0x01 /* /< Bit 0 MS/SS scan */
|
||||
#define ACTIVE_KEY 0x02 /* /< Bit 1 Key scan */
|
||||
#define ACTIVE_HOVER 0x04 /* /< Bit 2 Hover scan */
|
||||
#define ACTIVE_PROXIMITY 0x08 /* /< Bit 3 Proximity scan */
|
||||
#define ACTIVE_FORCE 0x10 /* /< Bit 4 Force scan */
|
||||
/** @}*/
|
||||
|
||||
|
||||
/* Locked mode option (locked mode) */
|
||||
/** @defgroup locked_opt Locked Mode Option
|
||||
* @ingroup scan_opt
|
||||
* Options to enable and lock specific scanning with the SCAN_MODE_LOCKED
|
||||
*option
|
||||
* @{
|
||||
*/
|
||||
#define LOCKED_ACTIVE 0x00 /* /< Active Scan Mode */
|
||||
#define LOCKED_HOVER 0x01 /* /< Hover Scan Mode */
|
||||
#define LOCKED_IDLE 0x02 /* /< Idle Scan Mode */
|
||||
#define LOCKED_LP_DETECT 0x10 /* /< Low Power SS */
|
||||
#define LOCKED_LP_ACTIVE 0x11 /* /< Low Power MS */
|
||||
/** @}*/
|
||||
|
||||
/* FEATURE SELECT OPTION (0xA2) */
|
||||
/* Feature Selection */
|
||||
/** @defgroup feat_opt Feature Selection Option
|
||||
* @ingroup feat_sel
|
||||
* System defined features that can be enable/disable
|
||||
* @{
|
||||
*/
|
||||
#define FEAT_SEL_GLOVE 0x00 /* /< Glove Mode */
|
||||
#define FEAT_SEL_COVER 0x01 /* /< Cover Mode */
|
||||
#define FEAT_SEL_CHARGER 0x02 /* /< Charger Mode */
|
||||
#define FEAT_SEL_GESTURE 0x03 /* /< Gesture Mode */
|
||||
#define FEAT_SEL_GRIP 0x04 /* /< Grip Detection */
|
||||
#define FEAT_SEL_STYLUS 0x07 /* /< Stylus Mode
|
||||
* (this is a driver define, not
|
||||
* available in FW) */
|
||||
/** @}*/
|
||||
|
||||
/* Feature Settings */
|
||||
#define FEAT_ENABLE 1 /* /< General value to enable a feature
|
||||
* */
|
||||
#define FEAT_DISABLE 0 /* /< General value to disable a feature
|
||||
* */
|
||||
|
||||
|
||||
/* Charger */
|
||||
/** @defgroup charger_opt Charger Mode Option
|
||||
* @ingroup feat_sel
|
||||
* Option for Charger Mode, it is a bitmask where the each bit indicate a
|
||||
*different kind of chager
|
||||
* @{
|
||||
*/
|
||||
#define CHARGER_CABLE 0x01 /* /< normal usb charger */
|
||||
#define CHARGER_WIRLESS 0x02 /* /< wireless charger */
|
||||
/** @}*/
|
||||
|
||||
/* Gestures */
|
||||
/** @defgroup gesture_opt Gesture Mode Option
|
||||
* @ingroup feat_sel
|
||||
* Gesture IDs of the predefined gesture recognized by the fw.
|
||||
* The ID represent also the position of the corresponding bit in the gesture
|
||||
*mask
|
||||
* @{
|
||||
*/
|
||||
#define GEST_ID_UP_1F 0x01 /* /< Bottom to Top line */
|
||||
#define GEST_ID_DOWN_1F 0x02 /* /< Top to bottom line */
|
||||
#define GEST_ID_LEFT_1F 0x03 /* /< Right to left line */
|
||||
#define GEST_ID_RIGHT_1F 0x04 /* /< Left to right line */
|
||||
#define GEST_ID_DBLTAP 0x05 /* /< Double Tap */
|
||||
#define GEST_ID_O 0x06 /* /< 'O' */
|
||||
#define GEST_ID_C 0x07 /* /< 'C' */
|
||||
#define GEST_ID_M 0x08 /* /< 'M' */
|
||||
#define GEST_ID_W 0x09 /* /< 'W' */
|
||||
#define GEST_ID_E 0x0A /* /< 'e' */
|
||||
#define GEST_ID_L 0x0B /* /< 'L' */
|
||||
#define GEST_ID_F 0x0C /* /< 'F' */
|
||||
#define GEST_ID_V 0x0D /* /< 'V' */
|
||||
#define GEST_ID_AT 0x0E /* /< '@' */
|
||||
#define GEST_ID_S 0x0F /* /< 'S' */
|
||||
#define GEST_ID_Z 0x10 /* /< 'Z' */
|
||||
#define GEST_ID_LEFTBRACE 0x11 /* /< '<' */
|
||||
#define GEST_ID_RIGHTBRACE 0x12 /* /< '>' */
|
||||
#define GEST_ID_CARET 0x13 /* /< '^' */
|
||||
/** @}*/
|
||||
|
||||
/* WRYTE SYSTEM COMMAND (0xA4) */
|
||||
/* System command */
|
||||
/** @defgroup sys_opt System Command Option
|
||||
* @ingroup sys_cmd
|
||||
* Valid System Command Parameters
|
||||
* @{
|
||||
*/
|
||||
#define SYS_CMD_SPECIAL 0x00 /* /< Special Commands */
|
||||
#define SYS_CMD_INT 0x01 /* /< FW Interrupt Control */
|
||||
#define SYS_CMD_FORCE_CAL 0x02 /* /< Force Calibration */
|
||||
#define SYS_CMD_CX_TUNING 0x03 /* /< CX initialization */
|
||||
#define SYS_CMD_ITO 0x04 /* /< ITO test */
|
||||
#define SYS_CMD_SAVE_FLASH 0x05 /* /< Saving to flash */
|
||||
#define SYS_CMD_LOAD_DATA 0x06 /* /< Load Host data memory */
|
||||
#define SYS_CMD_SPECIAL_TUNING 0x08 /* /< Perform some special tuning */
|
||||
#define SYS_CMD_MP_FLAG 0x0C /* /< Update value of MP flag in RAM */
|
||||
/** @} */
|
||||
|
||||
/* System command settings */
|
||||
/* Special commands */
|
||||
/** @defgroup sys_special_opt Special Command Option
|
||||
* @ingroup sys_cmd
|
||||
* Valid special command
|
||||
* @{
|
||||
*/
|
||||
#define SPECIAL_SYS_RESET 0x00 /* /< System Reset triggered by the FW */
|
||||
#define SPECIAL_FIFO_FLUSH 0x01 /* /< Flush of the FIFO */
|
||||
#define SPECIAL_PANEL_INIT 0x02 /* /< Panel Initialization */
|
||||
#define SPECIAL_FULL_PANEL_INIT 0x03 /* /< Full panel initialization */
|
||||
/** @} */
|
||||
|
||||
|
||||
/* Force Cal and Cx auto tuning */
|
||||
/** @defgroup forcecal_cx_opt Force Cal and Tuning Option
|
||||
* @ingroup sys_cmd
|
||||
* Valid bitmask for triggering forcecal or performing manual autotune
|
||||
* @{
|
||||
*/
|
||||
#define CAL_MS_TOUCH 0x01 /* /< Mutual Sense Touch */
|
||||
#define CAL_MS_LOW_POWER 0x02 /* /< Mutual Sense Touch in low power
|
||||
* mode */
|
||||
#define CAL_SS_TOUCH 0x04 /* /< Self Sense Touch */
|
||||
#define CAL_SS_IDLE 0x08 /* /< Self Sense Touch in idle mode */
|
||||
#define CAL_MS_KEY 0x10 /* /< Mutual Sense Key */
|
||||
#define CAL_SS_KEY 0x20 /* /< Self Sense Key */
|
||||
#define CAL_MS_FORCE 0x40 /* /< Mutual Sense Force */
|
||||
#define CAL_SS_FORCE 0x80 /* /< Self Sense Force */
|
||||
/** @} */
|
||||
|
||||
/* ITO checks (position of the bit in the mask) */
|
||||
/** @defgroup ito_opt ITO Test Option
|
||||
* @ingroup sys_cmd
|
||||
* Valid option for the ITO test
|
||||
* @{
|
||||
*/
|
||||
#define ITO_FORCE_OPEN 0x00 /* /< Check if some force channels is
|
||||
* open */
|
||||
#define ITO_SENSE_OPEN 0x01 /* /< Check if some sense channels is
|
||||
* open */
|
||||
#define ITO_FORCE_GROUND 0x02 /* /< Check if some force channels is
|
||||
* short to ground */
|
||||
#define ITO_SENSE_GROUND 0x03 /* /< Check if some sense channels is
|
||||
* short to ground */
|
||||
#define ITO_FORCE_VDD 0x04 /* /< Check if some force channels is
|
||||
* short to VDD */
|
||||
#define ITO_SENSE_VDD 0x05 /* /< Check if some sense channels is
|
||||
* short to VDD */
|
||||
#define ITO_FORCE_FORCE 0x06 /* /< Check force to force channels */
|
||||
#define ITO_FORCE_SENSE 0x07 /* /< Check force to sense channels */
|
||||
#define ITO_SENSE_SENSE 0x08 /* /< Check sense to sense channels */
|
||||
#define ITO_KEY_FORCE_OPEN 0x09 /* /< Check if some force channels used
|
||||
* for the key is open */
|
||||
#define ITO_KEY_SENSE_OPEN 0x0A /* /< Check if some sense channels used
|
||||
* for the key is open */
|
||||
/** @}*/
|
||||
|
||||
/* Save flash */
|
||||
/** @defgroup save_opt Save to Flash Option
|
||||
* @ingroup sys_cmd
|
||||
* Valid option for saving data to the Flash
|
||||
* @{
|
||||
*/
|
||||
#define SAVE_FW_CONF 0x01 /* /< Save the confing to the flash */
|
||||
#define SAVE_CX 0x02 /* /< Save the CX to the flash */
|
||||
#define SAVE_PANEL_CONF 0x04 /* /< Save the Panel configuration to the flash
|
||||
* */
|
||||
/** @}*/
|
||||
|
||||
/* Load Data */
|
||||
/** @defgroup load_opt Load Host Data Option
|
||||
* @ingroup sys_cmd
|
||||
* Valid option to ask to the FW to load host data into the memory
|
||||
* @{
|
||||
*/
|
||||
#define LOAD_SYS_INFO 0x01 /* /< Load System Info */
|
||||
#define LOAD_CX_MS_TOUCH 0x10 /* /< Load MS Init Data for
|
||||
* Active Mode */
|
||||
#define LOAD_CX_MS_LOW_POWER 0x11 /* /< Load MS Init Data for Low
|
||||
* Power Mode */
|
||||
#define LOAD_CX_SS_TOUCH 0x12 /* /< Load SS Init Data for
|
||||
* Active Mode */
|
||||
#define LOAD_CX_SS_TOUCH_IDLE 0x13 /* /< Load SS Init Data for Low
|
||||
* Power Mode */
|
||||
#define LOAD_CX_MS_KEY 0x14 /* /< Load MS Init Data for Key
|
||||
* */
|
||||
#define LOAD_CX_SS_KEY 0x15 /* /< Load SS Init Data for Key
|
||||
* */
|
||||
#define LOAD_CX_MS_FORCE 0x16 /* /< Load MS Init Data for
|
||||
* Force */
|
||||
#define LOAD_CX_SS_FORCE 0x17 /* /< Load SS Init Data for
|
||||
* Force */
|
||||
#define LOAD_SYNC_FRAME_RAW 0x30 /* /< Load a Synchronized Raw
|
||||
* Frame */
|
||||
#define LOAD_SYNC_FRAME_FILTER 0x31 /* /< Load a Synchronized Filter
|
||||
* Frame */
|
||||
#define LOAD_SYNC_FRAME_STRENGTH 0x33 /* /< Load a Synchronized
|
||||
* Strength Frame */
|
||||
#define LOAD_SYNC_FRAME_BASELINE 0x32 /* /< Load a Synchronized
|
||||
* Baseline Frame */
|
||||
#define LOAD_PANEL_CX_TOT_MS_TOUCH 0x50 /* /< Load TOT MS Init Data for
|
||||
* Active Mode */
|
||||
#define LOAD_PANEL_CX_TOT_MS_LOW_POWER 0x51 /* /< Load TOT MS Init Data for
|
||||
* Low Power Mode */
|
||||
#define LOAD_PANEL_CX_TOT_SS_TOUCH 0x52 /* /< Load TOT SS Init Data for
|
||||
* Active Mode */
|
||||
#define LOAD_PANEL_CX_TOT_SS_TOUCH_IDLE 0x53 /* /< Load TOT SS Init Data for
|
||||
* Low Power Mode */
|
||||
#define LOAD_PANEL_CX_TOT_MS_KEY 0x54 /* /< Load TOT MS Init Data for
|
||||
* Key */
|
||||
#define LOAD_PANEL_CX_TOT_SS_KEY 0x55 /* /< Load TOT SS Init Data for
|
||||
* Key */
|
||||
#define LOAD_PANEL_CX_TOT_MS_FORCE 0x56 /* /< Load TOT MS Init Data for
|
||||
* Force */
|
||||
#define LOAD_PANEL_CX_TOT_SS_FORCE 0x57 /* /< Load TOT SS Init Data for
|
||||
* Force */
|
||||
/** @}*/
|
||||
|
||||
/* Special Tuning */
|
||||
/** @defgroup spcl_tun_opt Special Tuning Option
|
||||
* @ingroup sys_cmd
|
||||
* Valid special tuning operations which the fw can perform (bitmask)
|
||||
* @{
|
||||
*/
|
||||
#define SPECIAL_TUNING_LP_TIMER 0x01 /* /< Perform LP Timer calibration */
|
||||
#define SPECIAL_TUNING_IOFF 0x02 /* /< Perform Ioff calibration */
|
||||
|
||||
/** @}*/
|
||||
|
||||
/* EVENT ID */
|
||||
/** @defgroup events_group FW Event IDs and Types
|
||||
* Event IDs and Types pushed by the FW into the FIFO
|
||||
* @{
|
||||
*/
|
||||
#define EVT_ID_NOEVENT 0x00 /* /< No Events */
|
||||
#define EVT_ID_CONTROLLER_READY 0x03 /* /< Controller ready, issued after a
|
||||
system reset. */
|
||||
#define EVT_ID_ENTER_POINT 0x13 /* /< Touch enter in the sensing area */
|
||||
#define EVT_ID_MOTION_POINT 0x23 /* /< Touch motion (a specific touch
|
||||
* changed position) */
|
||||
#define EVT_ID_LEAVE_POINT 0x33 /* /< Touch leave the sensing area */
|
||||
#define EVT_ID_STATUS_UPDATE 0x43 /* /< FW report a system condition
|
||||
* change */
|
||||
#define EVT_ID_USER_REPORT 0x53 /* /< User related events triggered
|
||||
* (keys, gestures, proximity etc) */
|
||||
#define EVT_ID_DEBUG 0xE3 /* /< Debug Info */
|
||||
#define EVT_ID_ERROR 0xF3 /* /< Error Event */
|
||||
|
||||
/* /< Max number of unique event IDs supported */
|
||||
#define NUM_EVT_ID (((EVT_ID_ERROR & 0xF0) >> 4)+1)
|
||||
|
||||
/** @}*/
|
||||
|
||||
/* STATUS TYPE */
|
||||
/** @defgroup status_type Status Event Types
|
||||
* @ingroup events_group
|
||||
* Types of EVT_ID_STATUS_UPDATE events
|
||||
* @{
|
||||
*/
|
||||
#define EVT_TYPE_STATUS_ECHO 0x01 /* /< Echo event, contain the
|
||||
* first 5 bytes of the FW
|
||||
* command sent */
|
||||
#define EVT_TYPE_STATUS_FRAME_DROP 0x03 /* /< Some frame was skipped
|
||||
* during the elaboration */
|
||||
#define EVT_TYPE_STATUS_FORCE_CAL 0x05 /* /< Force Calibration has
|
||||
* triggered */
|
||||
#define EVT_TYPE_STATUS_WATER 0x06 /* /< Water Mode */
|
||||
#define EVT_TYPE_STATUS_SS_RAW_SAT 0x07 /* /< Self Sense data saturated
|
||||
* */
|
||||
/** @} */
|
||||
|
||||
/* USER TYPE */
|
||||
/** @defgroup user_type User Event Types
|
||||
* @ingroup events_group
|
||||
* Types of EVT_ID_USER_REPORT events generated by the FW
|
||||
* @{
|
||||
*/
|
||||
#define EVT_TYPE_USER_KEY 0x00 /* /< Keys pressed/relesed event report
|
||||
* */
|
||||
#define EVT_TYPE_USER_PROXIMITY 0x01 /* /< Proximity detection event report
|
||||
* */
|
||||
#define EVT_TYPE_USER_GESTURE 0x02 /* /< Gesture detection event report */
|
||||
/** @}*/
|
||||
|
||||
/* ERROR TYPE */
|
||||
/** @defgroup error_type Error Event Types
|
||||
* @ingroup events_group
|
||||
* Types of EVT_ID_ERROR events reported by the FW
|
||||
* @{
|
||||
*/
|
||||
#define EVT_TYPE_ERROR_HARD_FAULT 0x02 /* /< Hard Fault */
|
||||
#define EVT_TYPE_ERROR_WATCHDOG 0x06 /* /< Watchdog timer expired */
|
||||
|
||||
#define EVT_TYPE_ERROR_CRC_CFG_HEAD 0x20 /* /< CRC error in the Config
|
||||
* Area Header */
|
||||
#define EVT_TYPE_ERROR_CRC_CFG 0x21 /* /< CRC error in the Config
|
||||
* Area */
|
||||
#define EVT_TYPE_ERROR_CRC_PANEL_HEAD 0x22 /* /< CRC error in the Panel
|
||||
* Area Header */
|
||||
#define EVT_TYPE_ERROR_CRC_PANEL 0x23 /* /< CRC error in the Panel
|
||||
* Area */
|
||||
|
||||
#define EVT_TYPE_ERROR_ITO_FORCETOGND 0x60 /* /< Force channel/s short to
|
||||
* ground */
|
||||
#define EVT_TYPE_ERROR_ITO_SENSETOGND 0x61 /* /< Sense channel/s short to
|
||||
* ground */
|
||||
#define EVT_TYPE_ERROR_ITO_FORCETOVDD 0x62 /* /< Force channel/s short to
|
||||
* VDD */
|
||||
#define EVT_TYPE_ERROR_ITO_SENSETOVDD 0x63 /* /< Sense channel/s short to
|
||||
* VDD */
|
||||
#define EVT_TYPE_ERROR_ITO_FORCE_P2P 0x64 /* /< Pin to Pin short Force
|
||||
* channel/s */
|
||||
#define EVT_TYPE_ERROR_ITO_SENSE_P2P 0x65 /* /< Pin to Pin short Sense
|
||||
* channel/s */
|
||||
#define EVT_TYPE_ERROR_ITO_FORCEOPEN 0x66 /* /< Force Panel open */
|
||||
#define EVT_TYPE_ERROR_ITO_SENSEOPEN 0x67 /* /< Sense Panel open */
|
||||
#define EVT_TYPE_ERROR_ITO_KEYOPEN 0x68 /* /< Key open */
|
||||
|
||||
#define EVT_TYPE_ERROR_CRC_CX_HEAD 0xA0 /* /< CRC error in the CX Area
|
||||
* Header */
|
||||
#define EVT_TYPE_ERROR_CRC_CX 0xA1 /* /< CRC error in the CX Area
|
||||
* */
|
||||
#define EVT_TYPE_ERROR_CRC_CX_SUB_HEAD 0xA5 /* /< CRC error in the CX
|
||||
* Subsection Area Header */
|
||||
#define EVT_TYPE_ERROR_CRC_CX_SUB 0xA6 /* /< CRC error in the CX
|
||||
* Subsection Area */
|
||||
|
||||
#define EVT_TYPE_ERROR_ESD 0xF0 /* /< ESD error */
|
||||
/** @}*/
|
||||
|
||||
|
||||
/** @defgroup address Chip Address
|
||||
* Collection of HW and SW Addresses useful to collect different kind of data
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup config_adr SW Address
|
||||
* @ingroup address
|
||||
* Important addresses of data stored into Config memory (and sometimes their
|
||||
*dimensions)
|
||||
* @{
|
||||
*/
|
||||
#define ADDR_CONFIG_ID 0x0010 /* /< Starting Address of the config ID
|
||||
* */
|
||||
#define CONFIG_ID_BYTE 2 /* /< Number of bytes of config ID */
|
||||
#define ADDR_CONFIG_SENSE_LEN 0x0030 /* /< Address where is stored the number
|
||||
* of sense channels */
|
||||
#define ADDR_CONFIG_FORCE_LEN 0x0031 /* /< Address where is stored the number
|
||||
* of force channels */
|
||||
/** @}*/
|
||||
|
||||
/** @}*/
|
||||
|
||||
/** @defgroup mp_flags MP Flags value
|
||||
* @ingroup mp_test
|
||||
* Specify the MP flags value which are written into the flash after performing
|
||||
* a full panel initialization which pass all the tests.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define MP_FLAG_FACTORY 0xA5 /* /< Full Panel Init done in factory */
|
||||
#define MP_FLAG_BOOT 0x5A /* /< Full Panel Init done at boot */
|
||||
#define MP_FLAG_OTHERS 0xFF /* /< Full Panel Init done somewhere
|
||||
* else */
|
||||
|
||||
/** @}*/
|
||||
|
||||
/* ERROR INFO */
|
||||
#define ERROR_DUMP_ROW_SIZE 32 /* /< number of rows of the error memory
|
||||
* */
|
||||
#define ERROR_DUMP_COL_SIZE 4 /* /< number of bytes for each row of
|
||||
* the error memory */
|
||||
#define ERROR_DUMP_SIGNATURE 0xFA5005AF /* /< first row signature of a
|
||||
* proper dump */
|
||||
|
||||
/* Touch Types */
|
||||
#define TOUCH_TYPE_INVALID 0x00 /* /< Invalid touch type */
|
||||
#define TOUCH_TYPE_FINGER 0x01 /* /< Finger touch */
|
||||
#define TOUCH_TYPE_GLOVE 0x02 /* /< Glove touch */
|
||||
#define TOUCH_TYPE_STYLUS 0x03 /* /< Stylus touch */
|
||||
#define TOUCH_TYPE_PALM 0x04 /* /< Palm touch */
|
||||
#define TOUCH_TYPE_HOVER 0x05 /* /< Hovering touch */
|
||||
|
||||
/* Keys code */
|
||||
#define FTS_KEY_0 0x01 /* /< Key 0 bit */
|
||||
#define FTS_KEY_1 0x02 /* /< Key 1 bit */
|
||||
#define FTS_KEY_2 0x04 /* /< Key 2 bit */
|
||||
#define FTS_KEY_3 0x08 /* /< Key 3 bit */
|
||||
#define FTS_KEY_4 0x10 /* /< Key 4 bit */
|
||||
#define FTS_KEY_5 0x20 /* /< Key 5 bit */
|
||||
#define FTS_KEY_6 0x40 /* /< Key 6 bit */
|
||||
#define FTS_KEY_7 0x80 /* /< Key 7 bit */
|
||||
|
||||
#endif
|
||||
7723
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTest.c
Normal file
7723
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTest.c
Normal file
File diff suppressed because it is too large
Load diff
439
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTest.h
Normal file
439
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTest.h
Normal file
|
|
@ -0,0 +1,439 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS API for MP test **
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsTest.h
|
||||
* \brief Contains all the definitions and structs related to the Mass
|
||||
*Production Test
|
||||
*/
|
||||
|
||||
#ifndef FTS_TEST_H
|
||||
#define FTS_TEST_H
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
#ifndef LIMITS_H_FILE
|
||||
/* /< Name of the Production Test Limit File */
|
||||
#define LIMITS_FILE "stm_fts_production_limits.csv"
|
||||
#else
|
||||
#define LIMITS_FILE "NULL"
|
||||
#endif
|
||||
|
||||
#define WAIT_FOR_FRESH_FRAMES 200 /* /< Time in ms to wait after start to
|
||||
* sensing before reading a frame */
|
||||
#define WAIT_AFTER_SENSEOFF 50 /* /< Time in ms to wait after stop
|
||||
* sensing and before reading a frame
|
||||
* from memory */
|
||||
|
||||
#define NO_INIT 0 /* /< No Initialization required during
|
||||
* the MP */
|
||||
|
||||
#define RETRY_INIT_BOOT 3 /* /< number of retry of the
|
||||
* initialization process at boot */
|
||||
|
||||
/** @defgroup mp_test Mass Production Test
|
||||
* Mass production test API.
|
||||
* Mass Production Test (MP) should be executed at least one time in the life
|
||||
* of every device \n
|
||||
* It used to verify that tit is not present any hardware damage and
|
||||
* initialize some value of the chip in order to guarantee the working
|
||||
* performance \n
|
||||
* The MP test is made up by 3 steps:
|
||||
* - ITO test = production_test_ito() \n
|
||||
* - Initialization = production_test_initialization() \n
|
||||
* - Data Test = production_test_data(),
|
||||
* it is possible to select which items test thanks to the TestToDo struct\n
|
||||
* To execute the Data Test it is mandatory load some thresholds that
|
||||
* are stored in the Limit File.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup limit_file Limit File
|
||||
* @ingroup mp_test
|
||||
* Production Test Limit File is a csv which contains thresholds of the data to
|
||||
* test.
|
||||
* This file can be loaded from the file system or stored as a header file
|
||||
* according to the LIMITS_H_FILE define \n
|
||||
* For each selectable test item there can be one or more associated labels
|
||||
* which store the corresponding thresholds \n
|
||||
* @{
|
||||
*/
|
||||
/* LABELS PRODUCTION TEST LIMITS FILE */
|
||||
/** @defgroup test_labels Test Items Labels
|
||||
* @ingroup limit_file
|
||||
* Labels present in the Limit File and associated to the test items of
|
||||
*TestToDo
|
||||
* @{
|
||||
*/
|
||||
#define MS_RAW_MIN_MAX "MS_RAW_DATA_MIN_MAX"
|
||||
#define MS_RAW_EACH_NODE_MIN "MS_RAW_DATA_EACH_MIN"
|
||||
#define MS_RAW_EACH_NODE_MAX "MS_RAW_DATA_EACH_MAX"
|
||||
#define MS_RAW_GAP "MS_RAW_DATA_GAP"
|
||||
#define MS_RAW_ADJH "MS_RAW_DATA_ADJ_HORIZONTAL"
|
||||
#define MS_RAW_ADJV "MS_RAW_DATA_ADJ_VERTICAL"
|
||||
#define MS_RAW_ITO_ADJH "MS_RAW_ITO_DATA_ADJ_HORIZONTAL"
|
||||
#define MS_RAW_ITO_ADJV "MS_RAW_ITO_DATA_ADJ_VERTICAL"
|
||||
#define MS_RAW_LP_MIN_MAX "MS_RAW_LOWPOWER_DATA_MIN_MAX"
|
||||
#define MS_RAW_LP_EACH_NODE_MIN "MS_RAW_LOWPOWER_DATA_EACH_MIN"
|
||||
#define MS_RAW_LP_EACH_NODE_MAX "MS_RAW_LOWPOWER_DATA_EACH_MAX"
|
||||
#define MS_RAW_LP_GAP "MS_RAW_LOWPOWER_DATA_GAP"
|
||||
#define MS_RAW_LP_ADJH "MS_RAW_LOWPOWER_DATA_ADJ_HORIZONTAL"
|
||||
#define MS_RAW_LP_ADJV "MS_RAW_LOWPOWER_DATA_ADJ_VERTICAL"
|
||||
#define MS_RAW_ADJH_GAP "MS_RAW_DATA_ADJ_HORIZONTAL_P2P"
|
||||
#define MS_RAW_ADJV_GAP "MS_RAW_DATA_ADJ_VERTICAL_P2P"
|
||||
#define MS_RAW_ADJ_PEAK "MS_RAW_DATA_ADJ_PEAK"
|
||||
#define MS_CX1_MIN_MAX "MS_TOUCH_ACTIVE_CX1_MIN_MAX"
|
||||
#define MS_CX2_MAP_MIN "MS_TOUCH_ACTIVE_CX2_MIN"
|
||||
#define MS_CX2_MAP_MAX "MS_TOUCH_ACTIVE_CX2_MAX"
|
||||
#define MS_CX2_ADJH_MAP_MAX "MS_TOUCH_ACTIVE_CX2_ADJ_HORIZONTAL"
|
||||
#define MS_CX2_ADJV_MAP_MAX "MS_TOUCH_ACTIVE_CX2_ADJ_VERTICAL"
|
||||
#define MS_TOTAL_CX_MAP_MIN "MS_TOUCH_ACTIVE_TOTAL_CX_MIN"
|
||||
#define MS_TOTAL_CX_MAP_MAX "MS_TOUCH_ACTIVE_TOTAL_CX_MAX"
|
||||
#define MS_TOTAL_CX_ADJH_MAP_MAX "MS_TOUCH_ACTIVE_TOTAL_CX_ADJ_HORIZONTAL"
|
||||
#define MS_TOTAL_CX_ADJV_MAP_MAX "MS_TOUCH_ACTIVE_TOTAL_CX_ADJ_VERTICAL"
|
||||
#define MS_CX1_LP_MIN_MAX "MS_TOUCH_LOWPOWER_CX1_MIN_MAX"
|
||||
#define MS_CX2_LP_MAP_MIN "MS_TOUCH_LOWPOWER_CX2_MIN"
|
||||
#define MS_CX2_LP_MAP_MAX "MS_TOUCH_LOWPOWER_CX2_MAX"
|
||||
#define MS_CX2_ADJH_LP_MAP_MAX "MS_TOUCH_LOWPOWER_CX2_ADJ_HORIZONTAL"
|
||||
#define MS_CX2_ADJV_LP_MAP_MAX "MS_TOUCH_LOWPOWER_CX2_ADJ_VERTICAL"
|
||||
#define MS_TOTAL_CX_LP_MAP_MIN "MS_TOUCH_LOWPOWER_TOTAL_CX_MIN"
|
||||
#define MS_TOTAL_CX_LP_MAP_MAX "MS_TOUCH_LOWPOWER_TOTAL_CX_MAX"
|
||||
#define MS_TOTAL_CX_ADJH_LP_MAP_MAX "MS_TOUCH_LOWPOWER_TOTAL_CX_ADJ_HORIZONTAL"
|
||||
#define MS_TOTAL_CX_ADJV_LP_MAP_MAX "MS_TOUCH_LOWPOWER_TOTAL_CX_ADJ_VERTICAL"
|
||||
#define SS_RAW_FORCE_MIN_MAX "SS_RAW_DATA_FORCE_MIN_MAX"
|
||||
#define SS_RAW_FORCE_EACH_NODE_MIN "SS_RAW_DATA_FORCE_EACH_MIN"
|
||||
#define SS_RAW_FORCE_EACH_NODE_MAX "SS_RAW_DATA_FORCE_EACH_MAX"
|
||||
#define SS_RAW_SENSE_MIN_MAX "SS_RAW_DATA_SENSE_MIN_MAX"
|
||||
#define SS_RAW_SENSE_EACH_NODE_MIN "SS_RAW_DATA_SENSE_EACH_MIN"
|
||||
#define SS_RAW_SENSE_EACH_NODE_MAX "SS_RAW_DATA_SENSE_EACH_MAX"
|
||||
#define SS_RAW_FORCE_GAP "SS_RAW_DATA_FORCE_GAP"
|
||||
#define SS_RAW_SENSE_GAP "SS_RAW_DATA_SENSE_GAP"
|
||||
#define SS_RAW_LP_FORCE_MIN_MAX "SS_RAW_LOWPOWER_DATA_FORCE_MIN_MAX"
|
||||
#define SS_RAW_LP_SENSE_MIN_MAX "SS_RAW_LOWPOWER_DATA_SENSE_MIN_MAX"
|
||||
#define SS_RAW_LP_FORCE_EACH_NODE_MIN "SS_RAW_LOWPOWER_DATA_FORCE_EACH_MIN"
|
||||
#define SS_RAW_LP_FORCE_EACH_NODE_MAX "SS_RAW_LOWPOWER_DATA_FORCE_EACH_MAX"
|
||||
#define SS_RAW_LP_SENSE_MIN_MAX "SS_RAW_LOWPOWER_DATA_SENSE_MIN_MAX"
|
||||
#define SS_RAW_LP_SENSE_EACH_NODE_MIN "SS_RAW_LOWPOWER_DATA_SENSE_EACH_MIN"
|
||||
#define SS_RAW_LP_SENSE_EACH_NODE_MAX "SS_RAW_LOWPOWER_DATA_SENSE_EACH_MAX"
|
||||
#define SS_RAW_LP_FORCE_GAP "SS_RAW_LOWPOWER_DATA_FORCE_GAP"
|
||||
#define SS_RAW_LP_SENSE_GAP "SS_RAW_LOWPOWER_DATA_SENSE_GAP"
|
||||
#define SS_IX1_FORCE_MIN_MAX "SS_TOUCH_ACTIVE_IX1_FORCE_MIN_MAX"
|
||||
#define SS_IX1_SENSE_MIN_MAX "SS_TOUCH_ACTIVE_IX1_SENSE_MIN_MAX"
|
||||
#define SS_CX1_FORCE_MIN_MAX "SS_TOUCH_ACTIVE_CX1_FORCE_MIN_MAX"
|
||||
#define SS_CX1_SENSE_MIN_MAX "SS_TOUCH_ACTIVE_CX1_SENSE_MIN_MAX"
|
||||
#define SS_IX2_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_IX2_FORCE_MIN"
|
||||
#define SS_IX2_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_IX2_FORCE_MAX"
|
||||
#define SS_IX2_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_IX2_SENSE_MIN"
|
||||
#define SS_IX2_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_IX2_SENSE_MAX"
|
||||
#define SS_IX2_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_IX2_ADJ_VERTICAL"
|
||||
#define SS_IX2_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_IX2_ADJ_HORIZONTAL"
|
||||
#define SS_CX2_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_CX2_FORCE_MIN"
|
||||
#define SS_CX2_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_CX2_FORCE_MAX"
|
||||
#define SS_CX2_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_CX2_SENSE_MIN"
|
||||
#define SS_CX2_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_CX2_SENSE_MAX"
|
||||
#define SS_CX2_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_CX2_ADJ_VERTICAL"
|
||||
#define SS_CX2_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_CX2_ADJ_HORIZONTAL"
|
||||
|
||||
|
||||
/* TOTAL SS */
|
||||
#define SS_TOTAL_IX_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_IX_FORCE_MIN"
|
||||
#define SS_TOTAL_IX_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_FORCE_MAX"
|
||||
#define SS_TOTAL_IX_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_IX_SENSE_MIN"
|
||||
#define SS_TOTAL_IX_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_SENSE_MAX"
|
||||
#define SS_TOTAL_IX_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_ADJ_VERTICAL"
|
||||
#define SS_TOTAL_IX_SENSE_ADJH_MAP_MAX \
|
||||
"SS_TOUCH_ACTIVE_TOTAL_IX_ADJ_HORIZONTAL"
|
||||
#define SS_TOTAL_CX_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_CX_FORCE_MIN"
|
||||
#define SS_TOTAL_CX_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_FORCE_MAX"
|
||||
#define SS_TOTAL_CX_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_CX_SENSE_MIN"
|
||||
#define SS_TOTAL_CX_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_SENSE_MAX"
|
||||
#define SS_TOTAL_CX_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_ADJ_VERTICAL"
|
||||
#define SS_TOTAL_CX_SENSE_ADJH_MAP_MAX \
|
||||
"SS_TOUCH_ACTIVE_TOTAL_CX_ADJ_HORIZONTAL"
|
||||
|
||||
/* Idle (LP) version*/
|
||||
#define SS_IX1_LP_FORCE_MIN_MAX "SS_TOUCH_IDLE_IX1_FORCE_MIN_MAX"
|
||||
#define SS_IX1_LP_SENSE_MIN_MAX "SS_TOUCH_IDLE_IX1_SENSE_MIN_MAX"
|
||||
#define SS_CX1_LP_FORCE_MIN_MAX "SS_TOUCH_IDLE_CX1_FORCE_MIN_MAX"
|
||||
#define SS_CX1_LP_SENSE_MIN_MAX "SS_TOUCH_IDLE_CX1_SENSE_MIN_MAX"
|
||||
#define SS_IX2_LP_FORCE_MAP_MIN "SS_TOUCH_IDLE_IX2_FORCE_MIN"
|
||||
#define SS_IX2_LP_FORCE_MAP_MAX "SS_TOUCH_IDLE_IX2_FORCE_MAX"
|
||||
#define SS_IX2_LP_SENSE_MAP_MIN "SS_TOUCH_IDLE_IX2_SENSE_MIN"
|
||||
#define SS_IX2_LP_SENSE_MAP_MAX "SS_TOUCH_IDLE_IX2_SENSE_MAX"
|
||||
#define SS_IX2_LP_FORCE_ADJV_MAP_MAX "SS_TOUCH_IDLE_IX2_ADJ_VERTICAL"
|
||||
#define SS_IX2_LP_SENSE_ADJH_MAP_MAX "SS_TOUCH_IDLE_IX2_ADJ_HORIZONTAL"
|
||||
#define SS_CX2_LP_FORCE_MAP_MIN "SS_TOUCH_IDLE_CX2_FORCE_MIN"
|
||||
#define SS_CX2_LP_FORCE_MAP_MAX "SS_TOUCH_IDLE_CX2_FORCE_MAX"
|
||||
#define SS_CX2_LP_SENSE_MAP_MIN "SS_TOUCH_IDLE_CX2_SENSE_MIN"
|
||||
#define SS_CX2_LP_SENSE_MAP_MAX "SS_TOUCH_IDLE_CX2_SENSE_MAX"
|
||||
#define SS_CX2_LP_FORCE_ADJV_MAP_MAX "SS_TOUCH_IDLE_CX2_ADJ_VERTICAL"
|
||||
#define SS_CX2_LP_SENSE_ADJH_MAP_MAX "SS_TOUCH_IDLE_CX2_ADJ_HORIZONTAL"
|
||||
|
||||
|
||||
/* TOTAL SS */
|
||||
#define SS_TOTAL_IX_LP_FORCE_MAP_MIN "SS_TOUCH_IDLE_TOTAL_IX_FORCE_MIN"
|
||||
#define SS_TOTAL_IX_LP_FORCE_MAP_MAX "SS_TOUCH_IDLE_TOTAL_IX_FORCE_MAX"
|
||||
#define SS_TOTAL_IX_LP_SENSE_MAP_MIN "SS_TOUCH_IDLE_TOTAL_IX_SENSE_MIN"
|
||||
#define SS_TOTAL_IX_LP_SENSE_MAP_MAX "SS_TOUCH_IDLE_TOTAL_IX_SENSE_MAX"
|
||||
#define SS_TOTAL_IX_LP_FORCE_ADJV_MAP_MAX \
|
||||
"SS_TOUCH_IDLE_TOTAL_IX_ADJ_VERTICAL"
|
||||
#define SS_TOTAL_IX_LP_SENSE_ADJH_MAP_MAX \
|
||||
"SS_TOUCH_IDLE_TOTAL_IX_ADJ_HORIZONTAL"
|
||||
#define SS_TOTAL_CX_LP_FORCE_MAP_MIN "SS_TOUCH_IDLE_TOTAL_CX_FORCE_MIN"
|
||||
#define SS_TOTAL_CX_LP_FORCE_MAP_MAX "SS_TOUCH_IDLE_TOTAL_CX_FORCE_MAX"
|
||||
#define SS_TOTAL_CX_LP_SENSE_MAP_MIN "SS_TOUCH_IDLE_TOTAL_CX_SENSE_MIN"
|
||||
#define SS_TOTAL_CX_LP_SENSE_MAP_MAX "SS_TOUCH_IDLE_TOTAL_CX_SENSE_MAX"
|
||||
#define SS_TOTAL_CX_LP_FORCE_ADJV_MAP_MAX \
|
||||
"SS_TOUCH_IDLE_TOTAL_CX_ADJ_VERTICAL"
|
||||
#define SS_TOTAL_CX_LP_SENSE_ADJH_MAP_MAX \
|
||||
"SS_TOUCH_IDLE_TOTAL_CX_ADJ_HORIZONTAL"
|
||||
|
||||
/* KEYS */
|
||||
#define MS_KEY_RAW_MIN_MAX "MS_KEY_RAW_DATA_MIN_MAX"
|
||||
#define MS_KEY_CX1_MIN_MAX "MS_KEY_CX1_MIN_MAX"
|
||||
#define MS_KEY_CX2_MAP_MIN "MS_KEY_CX2_MIN"
|
||||
#define MS_KEY_CX2_MAP_MAX "MS_KEY_CX2_MAX"
|
||||
#define MS_KEY_TOTAL_CX_MAP_MIN "MS_KEY_TOTAL_CX_MIN"
|
||||
#define MS_KEY_TOTAL_CX_MAP_MAX "MS_KEY_TOTAL_CX_MAX"
|
||||
|
||||
/* CONSTANT TOTAL IX */
|
||||
#define SS_IX1_FORCE_W "IX1_FORCE_W"
|
||||
#define SS_IX2_FORCE_W "IX2_FORCE_W"
|
||||
#define SS_IX1_SENSE_W "IX1_SENSE_W"
|
||||
#define SS_IX2_SENSE_W "IX2_SENSE_W"
|
||||
/** @}*/
|
||||
|
||||
|
||||
/**
|
||||
* Struct used to specify which test perform during the Mass Production Test.
|
||||
* For each test item selected in this structure, there should be one or
|
||||
* more labels associated in the Limit file from where load the thresholds
|
||||
*/
|
||||
typedef struct {
|
||||
int MutualRaw; /* /< MS Raw min/Max test */
|
||||
int MutualRawMap; /* /< MS Raw min/Max test for each node */
|
||||
int MutualRawGap; /* /< MS Raw Gap(max-min) test */
|
||||
int MutualRawAdj; /* /< MS Raw Adjacent test */
|
||||
int MutualRawAdjGap; /* /< MS Raw Adjacent Gap (max-min) test */
|
||||
int MutualRawAdjPeak; /* /< MS Raw Adjacent Peak
|
||||
* max(max(adjv),max(adjh)) test */
|
||||
int MutualRawLP; /* /< MS Low Power Raw min/Max test */
|
||||
int MutualRawMapLP; /* /< MS Low Power Raw min/Max test
|
||||
* for each node */
|
||||
int MutualRawGapLP; /* /< MS Low Power Raw Gap(max-min) test */
|
||||
int MutualRawAdjLP; /* /< MS Low Power Raw Adjacent test */
|
||||
int MutualRawAdjITO; /* /< MS Raw Adjacent test during ITO test */
|
||||
|
||||
int MutualCx1; /* /< MS Cx1 min/Max test */
|
||||
int MutualCx2; /* /< MS Cx2 min/Max (for each node) test */
|
||||
int MutualCx2Adj; /* /< MS Vertical and Horizontal Adj Cx2 min/Max
|
||||
* (for each node) test */
|
||||
int MutualCxTotal; /* /< MS Total Cx min/Max (for each node) test
|
||||
* */
|
||||
int MutualCxTotalAdj; /* /< MS Total vertical and Horizontal Adj Cx2
|
||||
* min/Max (for each node) test */
|
||||
|
||||
int MutualCx1LP; /* /< MS LowPower Cx1 min/Max test */
|
||||
int MutualCx2LP; /* /< MS LowPower Cx2 min/Max (for each node) test */
|
||||
int MutualCx2AdjLP; /* /< MS LowPower Vertical and Horizontal Adj Cx2 min/Max
|
||||
* (for each node) test */
|
||||
int MutualCxTotalLP; /* /< MS Total LowPower Cx min/Max (for each node) test
|
||||
* */
|
||||
int MutualCxTotalAdjLP; /* /< MS Total LowPower vertical and Horizontal Adj Cx2
|
||||
* min/Max (for each node) test */
|
||||
|
||||
int MutualKeyRaw; /* /< MS Raw Key min/Max test */
|
||||
int MutualKeyCx1; /* /< MS Cx1 Key min/Max test */
|
||||
int MutualKeyCx2; /* /< MS Cx2 Key min/Max (for each node) test */
|
||||
int MutualKeyCxTotal; /* /< MS Total Cx Key min/Max (for each node)
|
||||
* test */
|
||||
|
||||
int SelfForceRaw; /* /< SS Force Raw min/Max test */
|
||||
int SelfForceRawGap; /* /< SS Force Raw Gap(max-min) test */
|
||||
int SelfForceRawMap; /* /< SS Force Raw min/Max Map test */
|
||||
int SelfForceRawLP; /* /< SS Low Power Force Raw min/Max test */
|
||||
int SelfForceRawGapLP; /* /< SS Low Power Force Raw Gap(max-min)test */
|
||||
int SelfForceRawMapLP; /* /< SS Low Power Force Raw min/Max Map test */
|
||||
|
||||
int SelfForceIx1; /* /< SS Force Ix1 min/Max test */
|
||||
int SelfForceIx2; /* /< SS Force Ix2 min/Max (for each node) test
|
||||
* */
|
||||
int SelfForceIx2Adj; /* /< SS Vertical Adj Force Ix2 min/Max
|
||||
* (for each node) test */
|
||||
int SelfForceIxTotal; /* /< SS Total Force Ix min/Max (for each node)
|
||||
* test */
|
||||
int SelfForceIxTotalAdj; /* /< SS Total Vertical Adj Force Ix
|
||||
* min/Max (for each node) test */
|
||||
int SelfForceCx1; /* /< SS Force Cx1 min/Max test */
|
||||
int SelfForceCx2; /* /< SS Force Cx2 min/Max (for each node) test */
|
||||
int SelfForceCx2Adj; /* /< SS Vertical Adj Force Cx2 min/Max (for
|
||||
* each node) test */
|
||||
int SelfForceCxTotal; /* /< SS Total Force Cx min/Max (for each node)
|
||||
* test */
|
||||
int SelfForceCxTotalAdj; /* /< SS Total Vertical Adj Force Cx
|
||||
* min/Max (for each node) test */
|
||||
|
||||
int SelfForceIx1LP; /* /< SS LP Force Ix1 min/Max test */
|
||||
int SelfForceIx2LP; /* /< SS LP Force Ix2 min/Max (for each node)
|
||||
* test */
|
||||
int SelfForceIx2AdjLP; /* /< SS LP Vertical Adj Force Ix2 min/Max
|
||||
* (for each node) test */
|
||||
int SelfForceIxTotalLP; /* /< SS LP Total Force Ix min/Max
|
||||
* (for each node) test */
|
||||
int SelfForceIxTotalAdjLP; /* /< SS LP Total Vertical Adj Force Ix
|
||||
* min/Max (for each node) test */
|
||||
int SelfForceCx1LP; /* /< SS LP Force Cx1 min/Max test */
|
||||
int SelfForceCx2LP; /* /< SS LP Force Cx2 min/Max (for each node) test */
|
||||
int SelfForceCx2AdjLP; /* /< SS LP Vertical Adj Force Cx2 min/Max (for
|
||||
* each node) test */
|
||||
int SelfForceCxTotalLP; /* /< SS LP Total Force Cx min/Max
|
||||
* (for each node) test */
|
||||
int SelfForceCxTotalAdjLP; /* /< SS LP Total Vertical Adj Force Cx
|
||||
* min/Max (for each node) test */
|
||||
|
||||
int SelfSenseRaw; /* /< SS Sense Raw min/Max test */
|
||||
int SelfSenseRawGap; /* /< SS Sense Raw Gap(max-min) test */
|
||||
int SelfSenseRawMap; /* /< SS Sense Raw min/Max test for each node */
|
||||
int SelfSenseRawLP; /* /< SS Low Power Sense Raw min/Max test */
|
||||
int SelfSenseRawGapLP; /* /< SS Low Power Sense Raw Gap(max-min) test */
|
||||
int SelfSenseRawMapLP; /* /< SS Low Power Sense Raw min/Max test for
|
||||
* each node */
|
||||
|
||||
int SelfSenseIx1; /* /< SS Sense Ix1 min/Max test */
|
||||
int SelfSenseIx2; /* /< SS Sense Ix2 min/Max (for each node) test */
|
||||
int SelfSenseIx2Adj; /* /< SS Horizontal Adj Sense Ix2 min/Max
|
||||
* (for each node) test */
|
||||
int SelfSenseIxTotal; /* /< SS Total Horizontal Sense Ix min/Max
|
||||
* (for each node) test */
|
||||
int SelfSenseIxTotalAdj; /* /< SS Total Horizontal Adj Sense Ix
|
||||
* min/Max (for each node) test */
|
||||
int SelfSenseCx1; /* /< SS Sense Cx1 min/Max test */
|
||||
int SelfSenseCx2; /* /< SS Sense Cx2 min/Max (for each node) test */
|
||||
int SelfSenseCx2Adj; /* /< SS Horizontal Adj Sense Cx2 min/Max
|
||||
* (for each node) test */
|
||||
int SelfSenseCxTotal; /* /< SS Total Sense Cx min/Max (for each node)
|
||||
* test */
|
||||
int SelfSenseCxTotalAdj; /* /< SS Total Horizontal Adj Sense Cx
|
||||
* min/Max (for each node) test */
|
||||
|
||||
int SelfSenseIx1LP; /* /< SS LP Sense Ix1 min/Max test */
|
||||
int SelfSenseIx2LP; /* /< SS LP Sense Ix2 min/Max (for each node)
|
||||
* test */
|
||||
int SelfSenseIx2AdjLP; /* /< SS LP Horizontal Adj Sense Ix2 min/Max
|
||||
* (for each node) test */
|
||||
int SelfSenseIxTotalLP; /* /< SS LP Total Horizontal Sense Ix min/Max
|
||||
* (for each node) test */
|
||||
int SelfSenseIxTotalAdjLP; /* /< SS LP Total Horizontal Adj Sense Ix
|
||||
* min/Max (for each node) test */
|
||||
int SelfSenseCx1LP; /* /< SS LP Sense Cx1 min/Max test */
|
||||
int SelfSenseCx2LP; /* /< SS LP Sense Cx2 min/Max (for each node)
|
||||
* test */
|
||||
int SelfSenseCx2AdjLP; /* /< SS LP Horizontal Adj Sense Cx2 min/Max
|
||||
* (for each node) test */
|
||||
int SelfSenseCxTotalLP; /* /< SS LP Total Sense Cx min/Max
|
||||
* (for each node) test */
|
||||
int SelfSenseCxTotalAdjLP; /* /< SS LP Total Horizontal Adj Sense Cx
|
||||
* min/Max (for each node) test */
|
||||
} TestToDo;
|
||||
|
||||
|
||||
#define MAX_LIMIT_FILE_NAME 100 /* /< max number of chars of the limit file name
|
||||
* */
|
||||
|
||||
/**
|
||||
* Struct which store the data coming from a Production Limit File
|
||||
*/
|
||||
typedef struct {
|
||||
char *data; /* /< pointer to an array of char which contains
|
||||
* the content of the Production Limit File */
|
||||
int size; /* /< size of data */
|
||||
char name[MAX_LIMIT_FILE_NAME]; /* /< identifier of the source from
|
||||
* where the limits data were loaded (if
|
||||
* loaded from a file it will be the
|
||||
* file name, while if loaded from .h
|
||||
* will be "NULL") */
|
||||
} LimitFile;
|
||||
|
||||
|
||||
|
||||
int initTestToDo(void);
|
||||
/**@}*/
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
||||
int computeAdjHoriz(i8 *data, int row, int column, u8 **result);
|
||||
int computeAdjHorizTotal(short *data, int row, int column, u16 **result);
|
||||
int computeAdjVert(i8 *data, int row, int column, u8 **result);
|
||||
int computeAdjVertTotal(short *data, int row, int column, u16 **result);
|
||||
int computeAdjHorizFromU(u8 *data, int row, int column, u8 **result);
|
||||
int computeAdjHorizTotalFromU(u16 *data, int row, int column, u16 **result);
|
||||
int computeAdjVertFromU(u8 *data, int row, int column, u8 **result);
|
||||
int computeAdjVertTotalFromU(u16 *data, int row, int column, u16 **result);
|
||||
int checkLimitsMinMax(short *data, int row, int column, int min, int max);
|
||||
int checkLimitsMap(i8 *data, int row, int column, int *min, int *max);
|
||||
int checkLimitsMapTotal(short *data, int row, int column, int *min, int *max);
|
||||
int checkLimitsMapFromU(u8 *data, int row, int column, int *min, int *max);
|
||||
int checkLimitsMapTotalFromU(u16 *data, int row, int column, int *min,
|
||||
int *max);
|
||||
int checkLimitsMapAdj(u8 *data, int row, int column, int *max);
|
||||
int checkLimitsMapAdjTotal(u16 *data, int row, int column, int *max);
|
||||
int checkLimitsGap(short *data, int row, int column, int threshold);
|
||||
int checkLimitsGapOffsets(short *data, int row, int column, int threshold,
|
||||
int row_start, int column_start, int row_end, int column_end);
|
||||
|
||||
/** @defgroup mp_api MP API
|
||||
* @ingroup mp_test
|
||||
* Functions to execute the MP test.
|
||||
* The parameters of these functions allow to customize their behavior
|
||||
* in order to satisfy different scenarios
|
||||
* @{
|
||||
*/
|
||||
int production_test_ito(char *path_limits, TestToDo *todo);
|
||||
int production_test_initialization(u8 type);
|
||||
int production_test_main(char *pathThresholds, int stop_on_fail, int saveInit,
|
||||
TestToDo *todo, u8 mpflag);
|
||||
int production_test_ms_raw(char *path_limits, int stop_on_fail, TestToDo *todo);
|
||||
int production_test_ms_raw_lp(char *path_limits, int stop_on_fail,
|
||||
TestToDo *todo);
|
||||
int production_test_ms_cx(char *path_limits, int stop_on_fail, TestToDo *todo);
|
||||
int production_test_ms_cx_lp(char *path_limits, int stop_on_fail,
|
||||
TestToDo *todo);
|
||||
int production_test_ss_raw(char *path_limits, int stop_on_fail, TestToDo *todo);
|
||||
int production_test_ss_raw_lp(char *path_limits, int stop_on_fail,
|
||||
TestToDo *todo);
|
||||
int production_test_ss_ix_cx(char *path_limits, int stop_on_fail,
|
||||
TestToDo *todo);
|
||||
int production_test_ss_ix_cx_lp(char *path_limits, int stop_on_fail,
|
||||
TestToDo *todo);
|
||||
int production_test_data(char *path_limits, int stop_on_fail, TestToDo *todo);
|
||||
int production_test_ms_key_cx(char *path_limits, int stop_on_fail,
|
||||
TestToDo *todo);
|
||||
int production_test_ms_key_raw(char *path_limits);
|
||||
/** @}*/
|
||||
|
||||
/**
|
||||
* @addtogroup limit_file
|
||||
* @{
|
||||
*/
|
||||
int parseProductionTestLimits(char *path, LimitFile *file, char *label,
|
||||
int **data, int *row, int *column);
|
||||
int readLine(char *data, char *line, int size, int *n);
|
||||
int getLimitsFile(char *path, LimitFile *file);
|
||||
int freeLimitsFile(LimitFile *file);
|
||||
int freeCurrentLimitsFile(void);
|
||||
/**@}*/
|
||||
|
||||
#endif
|
||||
85
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTime.c
Normal file
85
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTime.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Utility for mesuring/handling the time *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsTime.c
|
||||
* \brief Contains all functions to handle and measure the time in the driver
|
||||
*/
|
||||
|
||||
#include "ftsTime.h"
|
||||
|
||||
|
||||
#include <linux/errno.h>
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
|
||||
/**
|
||||
* Take the starting time and save it in a StopWatch variable
|
||||
* @param w pointer of a StopWatch struct
|
||||
*/
|
||||
void startStopWatch(StopWatch *w)
|
||||
{
|
||||
w->start = current_kernel_time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the stop time and save it in a StopWatch variable
|
||||
* @param w pointer of a StopWatch struct
|
||||
*/
|
||||
void stopStopWatch(StopWatch *w)
|
||||
{
|
||||
w->end = current_kernel_time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the amount of time spent from when the startStopWatch and then
|
||||
* the stopStopWatch were called on the StopWatch variable
|
||||
* @param w pointer of a StopWatch struct
|
||||
* @return amount of time in ms (the return value is meaningless
|
||||
* if the startStopWatch and stopStopWatch were not called before)
|
||||
*/
|
||||
int elapsedMillisecond(StopWatch *w)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = ((w->end.tv_sec - w->start.tv_sec) * 1000) + (w->end.tv_nsec -
|
||||
w->start.tv_nsec)
|
||||
/ 1000000;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the amount of time spent from when the startStopWatch and
|
||||
* then the stopStopWatch were called on the StopWatch variable
|
||||
* @param w pointer of a StopWatch struct
|
||||
* @return amount of time in ns (the return value is meaningless
|
||||
* if the startStopWatch and stopStopWatch were not called before)
|
||||
*/
|
||||
int elapsedNanosecond(StopWatch *w)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = ((w->end.tv_sec - w->start.tv_sec) * 1000000000) +
|
||||
(w->end.tv_nsec - w->start.tv_nsec);
|
||||
return result;
|
||||
}
|
||||
73
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTime.h
Normal file
73
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTime.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Utility for measuring/handling the time *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsTime.h
|
||||
* \brief Contains all the definitions and structs to handle and measure the
|
||||
* time in the driver
|
||||
*/
|
||||
|
||||
#ifndef FTS_TIME_H
|
||||
#define FTS_TIME_H
|
||||
|
||||
|
||||
#include <linux/time.h>
|
||||
|
||||
/* TIMEOUT */
|
||||
/** @defgroup timeouts Timeouts
|
||||
* Definitions of all the Timeout used in several operations
|
||||
* @{
|
||||
*/
|
||||
#define TIMEOUT_RESOLUTION 50
|
||||
/* /< timeout resolution in ms (all timeout should be multiples of this unit) */
|
||||
#define GENERAL_TIMEOUT (15 * TIMEOUT_RESOLUTION)
|
||||
/* /< general timeout in ms */
|
||||
#define RELEASE_INFO_TIMEOUT (2 * TIMEOUT_RESOLUTION)
|
||||
/* /< timeout to request release info in ms */
|
||||
|
||||
|
||||
#define TIMEOUT_REQU_COMP_DATA (4 * TIMEOUT_RESOLUTION)
|
||||
/* /< timeout to request compensation data in ms */
|
||||
#define TIMEOUT_REQU_DATA (8 * TIMEOUT_RESOLUTION)
|
||||
/* /< timeout to request data in ms */
|
||||
#define TIMEOUT_ITO_TEST_RESULT (4 * TIMEOUT_RESOLUTION)
|
||||
/* /< timeout to perform ito test in ms */
|
||||
#define TIMEOUT_INITIALIZATION_TEST_RESULT (5000 * TIMEOUT_RESOLUTION)
|
||||
/* /< timeout to perform initialization test in ms */
|
||||
#define TIEMOUT_ECHO (50 * TIMEOUT_RESOLUTION)
|
||||
/* /< timeout of the echo command,*/
|
||||
#define TIMEOUT_ECHO_FPI (200 * TIMEOUT_RESOLUTION)
|
||||
/* /< timeout of the Full panel Init echo command */
|
||||
#define TIMEOUT_ECHO_SINGLE_ENDED_SPECIAL_AUTOTUNE \
|
||||
(100 * TIMEOUT_RESOLUTION)
|
||||
/* /< timeout of the Single ended special Autotune echo command */
|
||||
/** @}*/
|
||||
|
||||
|
||||
/**
|
||||
* Struct used to measure the time elapsed between a starting and ending point.
|
||||
*/
|
||||
typedef struct {
|
||||
struct timespec start; /* /< store the starting time */
|
||||
struct timespec end; /* /< store the finishing time */
|
||||
} StopWatch;
|
||||
|
||||
|
||||
void startStopWatch(StopWatch *w);
|
||||
void stopStopWatch(StopWatch *w);
|
||||
int elapsedMillisecond(StopWatch *w);
|
||||
int elapsedNanosecond(StopWatch *w);
|
||||
|
||||
#endif
|
||||
715
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTool.c
Normal file
715
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTool.c
Normal file
|
|
@ -0,0 +1,715 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Utility Functions *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsTool.c
|
||||
* \brief Contains all the functions to support common operation inside the
|
||||
*driver
|
||||
*/
|
||||
|
||||
#include "ftsCompensation.h"
|
||||
#include "ftsCore.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsHardware.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsTime.h"
|
||||
#include "ftsTool.h"
|
||||
#include "../fts.h" /* needed for the tag define */
|
||||
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
|
||||
/**
|
||||
* Print an array of byte in a HEX string and attach at the beginning a label.
|
||||
* The function allocate memory that should be free outside the function itself
|
||||
* @param label string to attach at the beginning
|
||||
* @param buff pointer to the byte array that should be printed as HEX string
|
||||
* @param count size of buff
|
||||
* @param result pointer to the array of characters that compose the HEX final
|
||||
* string
|
||||
* @return pointer to the array of characters that compose the HEX string,
|
||||
* (same address of result)
|
||||
* @warning result MUST be allocated outside the function and should be
|
||||
* big enough to contain the data converted as HEX!
|
||||
*/
|
||||
char *printHex(char *label, u8 *buff, int count, u8 *result)
|
||||
{
|
||||
int i, offset;
|
||||
|
||||
offset = strlen(label);
|
||||
strlcpy(result, label, offset+1); /* +1 for terminator char */
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
snprintf(&result[offset], 4, "%02X ", buff[i]);
|
||||
/* this append automatically a null terminator char */
|
||||
offset += 3;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the FIFO from any event
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int flushFIFO(void)
|
||||
{
|
||||
int ret;
|
||||
u8 sett = SPECIAL_FIFO_FLUSH;
|
||||
|
||||
ret = writeSysCmd(SYS_CMD_SPECIAL, &sett, 1); /* flush the FIFO */
|
||||
if (ret < OK) {
|
||||
logError(1, "%s flushFIFO: ERROR %08X\n", tag, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
logError(0, "%s FIFO flushed!\n", tag);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert an array of bytes to an array of u16 taking two bytes at time,
|
||||
* src has LSB first.
|
||||
* @param src pointer to the source byte array
|
||||
* @param src_length size of src
|
||||
* @param dst pointer to the destination array.
|
||||
* @return the final size of dst (half of the source) or ERROR_OP_NOT_ALLOW
|
||||
* if the size of src is not multiple of 2.
|
||||
*/
|
||||
int u8ToU16n(u8 *src, int src_length, u16 *dst)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (src_length % 2 != 0)
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
else {
|
||||
j = 0;
|
||||
dst = (u16 *)kmalloc((src_length / 2) * sizeof(u16),
|
||||
GFP_KERNEL);
|
||||
for (i = 0; i < src_length; i += 2) {
|
||||
dst[j] = ((src[i + 1] & 0x00FF) << 8) + (src[i] &
|
||||
0x00FF);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
return src_length / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array of 2 bytes to a u16, src has LSB first (little endian).
|
||||
* @param src pointer to the source byte array
|
||||
* @param dst pointer to the destination u16.
|
||||
* @return OK
|
||||
*/
|
||||
int u8ToU16(u8 *src, u16 *dst)
|
||||
{
|
||||
*dst = (u16)(((src[1] & 0x00FF) << 8) + (src[0] & 0x00FF));
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array of 2 bytes to a u16, src has MSB first (big endian).
|
||||
* @param src pointer to the source byte array
|
||||
* @param dst pointer to the destination u16.
|
||||
* @return OK
|
||||
*/
|
||||
int u8ToU16_be(u8 *src, u16 *dst)
|
||||
{
|
||||
*dst = (u16)(((src[0] & 0x00FF) << 8) + (src[1] & 0x00FF));
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array of u16 to an array of u8, dst has MSB first (big endian).
|
||||
* @param src pointer to the source array of u16
|
||||
* @param src_length size of src
|
||||
* @param dst pointer to the destination array of u8. This array should be free
|
||||
* when no need anymore
|
||||
* @return size of dst (src size multiply by 2)
|
||||
*/
|
||||
int u16ToU8n_be(u16 *src, int src_length, u8 *dst)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
dst = (u8 *)kmalloc((2 * src_length) * sizeof(u8), GFP_KERNEL);
|
||||
j = 0;
|
||||
for (i = 0; i < src_length; i++) {
|
||||
dst[j] = (u8)(src[i] & 0xFF00) >> 8;
|
||||
dst[j + 1] = (u8)(src[i] & 0x00FF);
|
||||
j += 2;
|
||||
}
|
||||
|
||||
return src_length * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a u16 to an array of 2 u8, dst has MSB first (big endian).
|
||||
* @param src u16 to convert
|
||||
* @param dst pointer to the destination array of 2 u8.
|
||||
* @return OK
|
||||
*/
|
||||
int u16ToU8_be(u16 src, u8 *dst)
|
||||
{
|
||||
dst[0] = (u8)((src & 0xFF00) >> 8);
|
||||
dst[1] = (u8)(src & 0x00FF);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a u16 to an array of 2 u8, dst has LSB first (little endian).
|
||||
* @param src u16 to convert
|
||||
* @param dst pointer to the destination array of 2 u8.
|
||||
* @return OK
|
||||
*/
|
||||
int u16ToU8(u16 src, u8 *dst)
|
||||
{
|
||||
dst[1] = (u8)((src & 0xFF00) >> 8);
|
||||
dst[0] = (u8)(src & 0x00FF);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array of bytes to a u32, src has LSB first (little endian).
|
||||
* @param src array of bytes to convert
|
||||
* @param dst pointer to the destination u32 variable.
|
||||
* @return OK
|
||||
*/
|
||||
int u8ToU32(u8 *src, u32 *dst)
|
||||
{
|
||||
*dst = (u32)(((src[3] & 0xFF) << 24) + ((src[2] & 0xFF) << 16) +
|
||||
((src[1] & 0xFF) << 8) + (src[0] & 0xFF));
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array of bytes to a u32, src has MSB first (big endian).
|
||||
* @param src array of bytes to convert
|
||||
* @param dst pointer to the destination u32 variable.
|
||||
* @return OK
|
||||
*/
|
||||
int u8ToU32_be(u8 *src, u32 *dst)
|
||||
{
|
||||
*dst = (u32)(((src[0] & 0xFF) << 24) + ((src[1] & 0xFF) << 16) +
|
||||
((src[2] & 0xFF) << 8) + (src[3] & 0xFF));
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a u32 to an array of 4 bytes, dst has LSB first (little endian).
|
||||
* @param src u32 value to convert
|
||||
* @param dst pointer to the destination array of 4 bytes.
|
||||
* @return OK
|
||||
*/
|
||||
int u32ToU8(u32 src, u8 *dst)
|
||||
{
|
||||
dst[3] = (u8)((src & 0xFF000000) >> 24);
|
||||
dst[2] = (u8)((src & 0x00FF0000) >> 16);
|
||||
dst[1] = (u8)((src & 0x0000FF00) >> 8);
|
||||
dst[0] = (u8)(src & 0x000000FF);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a u32 to an array of 4 bytes, dst has MSB first (big endian).
|
||||
* @param src u32 value to convert
|
||||
* @param dst pointer to the destination array of 4 bytes.
|
||||
* @return OK
|
||||
*/
|
||||
int u32ToU8_be(u32 src, u8 *dst)
|
||||
{
|
||||
dst[0] = (u8)((src & 0xFF000000) >> 24);
|
||||
dst[1] = (u8)((src & 0x00FF0000) >> 16);
|
||||
dst[2] = (u8)((src & 0x0000FF00) >> 8);
|
||||
dst[3] = (u8)(src & 0x000000FF);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a function passed as argment and retry it defined number of times if
|
||||
*not successfull
|
||||
* @param code pointer to a function which return an int and doesn't have any
|
||||
*parameters
|
||||
* @param wait_before_retry interval of time in ms to wait between one trial
|
||||
*and another one
|
||||
* @param retry_count max number of retry to attemp
|
||||
* @return last return value obtained from the last execution of the code
|
||||
*function
|
||||
*/
|
||||
int attempt_function(int (*code)(void), unsigned long wait_before_retry, int
|
||||
retry_count)
|
||||
{
|
||||
int result;
|
||||
int count = 0;
|
||||
|
||||
do {
|
||||
result = code();
|
||||
count++;
|
||||
msleep(wait_before_retry);
|
||||
} while (count < retry_count && result < 0);
|
||||
|
||||
|
||||
if (count == retry_count)
|
||||
return result | ERROR_TIMEOUT;
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable all the possible sensing mode supported by the FW
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int senseOn(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = setScanMode(SCAN_MODE_ACTIVE, 0xFF); /* enable all */
|
||||
if (ret < OK) {
|
||||
logError(1, "%s senseOn: ERROR %08X\n", tag, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
logError(0, "%s senseOn: SENSE ON\n", tag);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable all the sensing mode
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int senseOff(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = setScanMode(SCAN_MODE_ACTIVE, 0x00);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s senseOff: ERROR %08X\n", tag, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
logError(0, "%s senseOff: SENSE OFF\n", tag);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clean up the IC status executing a system reset and giving
|
||||
* the possibility to re-enabling the sensing
|
||||
* @param enableTouch if 1, re-enable the sensing and the interrupt of the IC
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
*/
|
||||
int cleanUp(int enableTouch)
|
||||
{
|
||||
int res;
|
||||
|
||||
logError(0, "%s cleanUp: system reset...\n", tag);
|
||||
res = fts_system_reset();
|
||||
if (res < OK)
|
||||
return res;
|
||||
if (enableTouch) {
|
||||
logError(0, "%s cleanUp: enabling touches...\n", tag);
|
||||
res = senseOn(); /* already enable everything */
|
||||
if (res < OK)
|
||||
return res;
|
||||
logError(0, "%s cleanUp: enabling interrupts...\n", tag);
|
||||
res = fts_enableInterrupt();
|
||||
if (res < OK)
|
||||
return res;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an array of short in a matrix of short with a defined number of
|
||||
* columns and the resulting number of rows
|
||||
* @param data array of bytes to convert
|
||||
* @param size size of data
|
||||
* @param columns number of columns that the resulting matrix should have.
|
||||
* @return a reference to a matrix of short where for each row there are
|
||||
* columns elements
|
||||
* @warning If size = 0 it will be allocated a matrix 1*1 wich still should
|
||||
* be free
|
||||
*/
|
||||
short **array1dTo2d_short(short *data, int size, int columns)
|
||||
{
|
||||
int i;
|
||||
short **matrix = NULL;
|
||||
if (size == 0) {
|
||||
matrix = (short **)kmalloc(1 *
|
||||
sizeof(short *), GFP_KERNEL);
|
||||
matrix[0] = (short *)kmalloc(0 *
|
||||
sizeof(short), GFP_KERNEL);
|
||||
} else {
|
||||
matrix = (short **)kmalloc(((int)(size / columns)) *
|
||||
sizeof(short *), GFP_KERNEL);
|
||||
|
||||
if (matrix != NULL) {
|
||||
for (i = 0; i < (int)(size / columns); i++)
|
||||
matrix[i] = (short *)kmalloc(columns *
|
||||
sizeof(short), GFP_KERNEL);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
matrix[i / columns][i % columns] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an array of u16 in a matrix of u16 with a defined number of
|
||||
* columns and the resulting number of rows
|
||||
* @param data array of bytes to convert
|
||||
* @param size size of data
|
||||
* @param columns number of columns that the resulting matrix should have.
|
||||
* @return a reference to a matrix of u16 where for each row there are columns
|
||||
* elements
|
||||
* @warning If size = 0 it will be allocated a matrix 1*1 wich still should
|
||||
* be free
|
||||
*/
|
||||
u16 **array1dTo2d_u16(u16 *data, int size, int columns)
|
||||
{
|
||||
int i;
|
||||
u16 **matrix = NULL;
|
||||
|
||||
|
||||
if (size == 0) {
|
||||
matrix = (u16 **)kmalloc(1 *
|
||||
sizeof(u16 *), GFP_KERNEL);
|
||||
matrix[0] = (u16 *)kmalloc(0 *
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
} else {
|
||||
matrix = (u16 **)kmalloc(((int)(size / columns)) *
|
||||
sizeof(u16 *), GFP_KERNEL);
|
||||
|
||||
if (matrix != NULL) {
|
||||
for (i = 0; i < (int)(size / columns); i++)
|
||||
matrix[i] = (u16 *)kmalloc(columns *
|
||||
sizeof(u16), GFP_KERNEL);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
matrix[i / columns][i % columns] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an array of u8 in a matrix of u8 with a defined number of
|
||||
* columns and the resulting number of rows
|
||||
* @param data array of bytes to convert
|
||||
* @param size size of data
|
||||
* @param columns number of columns that the resulting matrix should have.
|
||||
* @return a reference to a matrix of short where for each row there are
|
||||
* columns elements
|
||||
* @warning If size = 0 it will be allocated a matrix 1*1 wich still should
|
||||
* be free
|
||||
*/
|
||||
u8 **array1dTo2d_u8(u8 *data, int size, int columns)
|
||||
{
|
||||
int i;
|
||||
u8 **matrix = NULL;
|
||||
|
||||
|
||||
if (size == 0) {
|
||||
matrix = (u8 **)kmalloc(1 *
|
||||
sizeof(u8 *), GFP_KERNEL);
|
||||
|
||||
matrix[0] = (u8 *)kmalloc(0 *
|
||||
sizeof(u8), GFP_KERNEL);
|
||||
} else {
|
||||
|
||||
matrix = (u8 **)kmalloc(((int)(size / columns)) * sizeof(u8 *),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (matrix != NULL) {
|
||||
for (i = 0; i < (int)(size / columns); i++)
|
||||
matrix[i] = (u8 *)kmalloc(columns * sizeof(u8),
|
||||
GFP_KERNEL);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
matrix[i / columns][i % columns] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an array of i8 in a matrix of i8 with a defined number of
|
||||
* columns and the resulting number of rows
|
||||
* @param data array of bytes to convert
|
||||
* @param size size of data
|
||||
* @param columns number of columns that the resulting matrix should have.
|
||||
* @return a reference to a matrix of short where for each row there are
|
||||
* columns elements
|
||||
* @warning If size = 0 it will be allocated a matrix 1*1 wich still should
|
||||
* be free
|
||||
*/
|
||||
i8 **array1dTo2d_i8(i8 *data, int size, int columns)
|
||||
{
|
||||
int i;
|
||||
i8 **matrix = NULL;
|
||||
|
||||
if (size == 0) {
|
||||
matrix = (i8 **)kmalloc(1 *
|
||||
sizeof(i8 *), GFP_KERNEL);
|
||||
matrix[0] = (i8 *)kmalloc(0 *
|
||||
sizeof(i8), GFP_KERNEL);
|
||||
} else {
|
||||
matrix = (i8 **)kmalloc(((int)(size / columns)) * sizeof(i8 *),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (matrix != NULL) {
|
||||
for (i = 0; i < (int)(size / columns); i++)
|
||||
matrix[i] = (i8 *)kmalloc(columns * sizeof(i8),
|
||||
GFP_KERNEL);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
matrix[i / columns][i % columns] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print in the kernel log a label followed by a matrix of short row x columns
|
||||
*and free its memory
|
||||
* @param label pointer to the string to print before the actual matrix
|
||||
* @param matrix reference to the matrix of short which contain the actual data
|
||||
* @param row number of rows on which the matrix should be print
|
||||
* @param column number of columns for each row
|
||||
*/
|
||||
void print_frame_short(char *label, short **matrix, int row, int column)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
logError(0, "%s %s\n", tag, label);
|
||||
for (i = 0; i < row; i++) {
|
||||
logError(0, "%s ", tag);
|
||||
for (j = 0; j < column; j++)
|
||||
printk("%d ", matrix[i][j]);
|
||||
logError(0, "\n");
|
||||
kfree(matrix[i]);
|
||||
}
|
||||
kfree(matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print in the kernel log a label followed by a matrix of u16 row x columns
|
||||
*and free its memory
|
||||
* @param label pointer to the string to print before the actual matrix
|
||||
* @param matrix reference to the matrix of u16 which contain the actual data
|
||||
* @param row number of rows on which the matrix should be print
|
||||
* @param column number of columns for each row
|
||||
*/
|
||||
void print_frame_u16(char *label, u16 **matrix, int row, int column)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
logError(0, "%s %s\n", tag, label);
|
||||
for (i = 0; i < row; i++) {
|
||||
logError(0, "%s ", tag);
|
||||
for (j = 0; j < column; j++)
|
||||
printk("%d ", matrix[i][j]);
|
||||
logError(0, "\n");
|
||||
kfree(matrix[i]);
|
||||
}
|
||||
kfree(matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print in the kernel log a label followed by a matrix of u8 row x columns and
|
||||
*free its memory
|
||||
* @param label pointer to the string to print before the actual matrix
|
||||
* @param matrix reference to the matrix of u8 which contain the actual data
|
||||
* @param row number of rows on which the matrix should be print
|
||||
* @param column number of columns for each row
|
||||
*/
|
||||
void print_frame_u8(char *label, u8 **matrix, int row, int column)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
logError(0, "%s %s\n", tag, label);
|
||||
for (i = 0; i < row; i++) {
|
||||
logError(0, "%s ", tag);
|
||||
for (j = 0; j < column; j++)
|
||||
printk("%d ", matrix[i][j]);
|
||||
logError(0, "\n");
|
||||
kfree(matrix[i]);
|
||||
}
|
||||
kfree(matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print in the kernel log a label followed by a matrix of i8 row x columns and
|
||||
* free its memory
|
||||
* @param label pointer to the string to print before the actual matrix
|
||||
* @param matrix reference to the matrix of u8 which contain the actual data
|
||||
* @param row number of rows on which the matrix should be print
|
||||
* @param column number of columns for each row
|
||||
*/
|
||||
void print_frame_i8(char *label, i8 **matrix, int row, int column)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
logError(0, "%s %s\n", tag, label);
|
||||
for (i = 0; i < row; i++) {
|
||||
logError(0, "%s ", tag);
|
||||
for (j = 0; j < column; j++)
|
||||
printk("%d ", matrix[i][j]);
|
||||
logError(0, "\n");
|
||||
kfree(matrix[i]);
|
||||
}
|
||||
kfree(matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print in the kernel log a label followed by a matrix of u32 row x columns
|
||||
*and free its memory
|
||||
* @param label pointer to the string to print before the actual matrix
|
||||
* @param matrix reference to the matrix of u32 which contain the actual data
|
||||
* @param row number of rows on which the matrix should be print
|
||||
* @param column number of columns for each row
|
||||
*/
|
||||
void print_frame_u32(char *label, u32 **matrix, int row, int column)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
logError(0, "%s %s\n", tag, label);
|
||||
for (i = 0; i < row; i++) {
|
||||
logError(0, "%s ", tag);
|
||||
for (j = 0; j < column; j++)
|
||||
printk("%d ", matrix[i][j]);
|
||||
logError(0, "\n");
|
||||
kfree(matrix[i]);
|
||||
}
|
||||
kfree(matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print in the kernel log a label followed by a matrix of int row x columns
|
||||
* and free its memory
|
||||
* @param label pointer to the string to print before the actual matrix
|
||||
* @param matrix reference to the matrix of int which contain the actual data
|
||||
* @param row number of rows on which the matrix should be print
|
||||
* @param column number of columns for each row
|
||||
*/
|
||||
void print_frame_int(char *label, int **matrix, int row, int column)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
logError(0, "%s %s\n", tag, label);
|
||||
for (i = 0; i < row; i++) {
|
||||
logError(0, "%s ", tag);
|
||||
for (j = 0; j < column; j++)
|
||||
printk("%d ", matrix[i][j]);
|
||||
logError(0, "\n");
|
||||
kfree(matrix[i]);
|
||||
}
|
||||
kfree(matrix);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an array of bytes to an u64, src has MSB first (big endian).
|
||||
* @param src array of bytes
|
||||
* @param dest pointer to the destination u64.
|
||||
* @param size size of src (can be <= 8)
|
||||
* @return OK if success or ERROR_OP_NOT_ALLOW if size exceed 8
|
||||
*/
|
||||
int u8ToU64_be(u8 *src, u64 *dest, int size)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* u64 temp =0; */
|
||||
if (size > sizeof(u64))
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
else {
|
||||
*dest = 0;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
*dest |= (u64)(src[i]) << ((size - 1 - i) * 8);
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an u64 to an array of bytes, dest has MSB first (big endian).
|
||||
* @param src value of u64
|
||||
* @param dest pointer to the destination array of bytes.
|
||||
* @param size size of src (can be <= 8)
|
||||
* @return OK if success or ERROR_OP_NOT_ALLOW if size exceed 8
|
||||
*/
|
||||
int u64ToU8_be(u64 src, u8 *dest, int size)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (size > sizeof(u64))
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
else
|
||||
for (i = 0; i < size; i++)
|
||||
dest[i] = (u8)((src >> ((size - 1 - i) * 8)) & 0xFF);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********** NEW API *************/
|
||||
|
||||
/**
|
||||
* Convert a value of an id in a bitmask with a 1 in the position of the value
|
||||
*of the id
|
||||
* @param id Value of the ID to convert
|
||||
* @param mask pointer to the bitmask that will be updated with the value of id
|
||||
* @param size dimension in bytes of mask
|
||||
* @return OK if success or ERROR_OP_NOT_ALLOW if size of mask is not enough to
|
||||
*contain ID
|
||||
*/
|
||||
int fromIDtoMask(u8 id, u8 *mask, int size)
|
||||
{
|
||||
if (((int)((id) / 8)) < size) {
|
||||
logError(0, "%s %s: ID = %d Index = %d Position = %d !\n", tag,
|
||||
__func__, id, ((int)((id) / 8)), (id % 8));
|
||||
mask[((int)((id) / 8))] |= 0x01 << (id % 8);
|
||||
return OK;
|
||||
} else {
|
||||
logError(1,
|
||||
"%s %s: Bitmask too small! Impossible contain ID = %d %d>=%d! ERROR %08X\n",
|
||||
tag, __func__, id, ((int)((id) / 8)), size,
|
||||
ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
}
|
||||
59
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTool.h
Normal file
59
drivers/input/touchscreen/stmicro_mmi/fts_lib/ftsTool.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Utility Functions *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file ftsTool.h
|
||||
* \brief Contains all the definitions to support common operations inside the
|
||||
* driver
|
||||
*/
|
||||
|
||||
#ifndef FTS_TOOL_H
|
||||
#define FTS_TOOL_H
|
||||
|
||||
|
||||
char *printHex(char *label, u8 *buff, int count, u8 *result);
|
||||
int u8ToU16(u8 *src, u16 *dst);
|
||||
int u8ToU16_be(u8 *src, u16 *dst);
|
||||
int u8ToU16n(u8 *src, int src_length, u16 *dst);
|
||||
int u16ToU8(u16 src, u8 *dst);
|
||||
int u16ToU8_be(u16 src, u8 *dst);
|
||||
int u16ToU8n_be(u16 *src, int src_length, u8 *dst);
|
||||
int u8ToU32(u8 *src, u32 *dst);
|
||||
int u8ToU32_be(u8 *src, u32 *dst);
|
||||
int u32ToU8(u32 src, u8 *dst);
|
||||
int u32ToU8_be(u32 src, u8 *dst);
|
||||
int u8ToU64_be(u8 *src, u64 *dest, int size);
|
||||
int u64ToU8_be(u64 src, u8 *dest, int size);
|
||||
int attempt_function(int (*code)(void), unsigned long wait_before_retry, int
|
||||
retry_count);
|
||||
int senseOn(void);
|
||||
int senseOff(void);
|
||||
void print_frame_short(char *label, short **matrix, int row, int column);
|
||||
short **array1dTo2d_short(short *data, int size, int columns);
|
||||
void print_frame_u16(char *label, u16 **matrix, int row, int column);
|
||||
u16 **array1dTo2d_u16(u16 *data, int size, int columns);
|
||||
u8 **array1dTo2d_u8(u8 *data, int size, int columns);
|
||||
i8 **array1dTo2d_i8(i8 *data, int size, int columns);
|
||||
void print_frame_u8(char *label, u8 **matrix, int row, int column);
|
||||
void print_frame_i8(char *label, i8 **matrix, int row, int column);
|
||||
void print_frame_u32(char *label, u32 **matrix, int row, int column);
|
||||
void print_frame_int(char *label, int **matrix, int row, int column);
|
||||
int cleanUp(int enableTouch);
|
||||
int flushFIFO(void);
|
||||
|
||||
/* New API */
|
||||
int fromIDtoMask(u8 id, u8 *mask, int size);
|
||||
|
||||
#endif
|
||||
2111
drivers/input/touchscreen/stmicro_mmi/fts_limits.h
Normal file
2111
drivers/input/touchscreen/stmicro_mmi/fts_limits.h
Normal file
File diff suppressed because it is too large
Load diff
3073
drivers/input/touchscreen/stmicro_mmi/fts_proc.c
Normal file
3073
drivers/input/touchscreen/stmicro_mmi/fts_proc.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue