mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 06:09:23 -04:00
fts: support touchscreen class
Make initial driver's code buildable in MMI products. Added initial support for touchscreen class. Change-Id: Iabe4b047b8fbe7f1d1c4f0991ff9b261e4dbf673 Signed-off-by: Konstantin Makariev <hcv867@motorola.com> Reviewed-on: https://gerrit.mot.com/1682834 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Igor Kovalenko <igork@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
d9b9cd7244
commit
9d501e96ea
16 changed files with 452 additions and 69 deletions
12
drivers/input/touchscreen/stmicro_mmi/Android.mk
Normal file
12
drivers/input/touchscreen/stmicro_mmi/Android.mk
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
DLKM_DIR := motorola/kernel/modules
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
ifneq ($(findstring touchscreen_mmi.ko,$(BOARD_VENDOR_KERNEL_MODULES)),)
|
||||
KERNEL_CFLAGS += CONFIG_INPUT_TOUCHSCREEN_MMI=y
|
||||
endif
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := stmicro_mmi.ko
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||
include $(DLKM_DIR)/AndroidKernelModule.mk
|
||||
22
drivers/input/touchscreen/stmicro_mmi/Kbuild
Normal file
22
drivers/input/touchscreen/stmicro_mmi/Kbuild
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# add -Wall to try to catch everything we canss
|
||||
# EXTRA_CFLAGS += -Wallss
|
||||
EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/include \
|
||||
-I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/stmicro_mmi
|
||||
|
||||
obj-m := stmicro_mmi.o
|
||||
stmicro_mmi-objs := fts.o fts_proc.o
|
||||
stmicro_mmi-objs += fts_lib/ftsCompensation.o
|
||||
stmicro_mmi-objs += fts_lib/ftsCore.o
|
||||
stmicro_mmi-objs += fts_lib/ftsError.o
|
||||
stmicro_mmi-objs += fts_lib/ftsFlash.o
|
||||
stmicro_mmi-objs += fts_lib/ftsFrame.o
|
||||
stmicro_mmi-objs += fts_lib/ftsGesture.o
|
||||
stmicro_mmi-objs += fts_lib/ftsIO.o
|
||||
stmicro_mmi-objs += fts_lib/ftsTest.o
|
||||
stmicro_mmi-objs += fts_lib/ftsTime.o
|
||||
stmicro_mmi-objs += fts_lib/ftsTool.o
|
||||
|
||||
ifneq ($(filter m y,$(CONFIG_INPUT_TOUCHSCREEN_MMI)),)
|
||||
EXTRA_CFLAGS += -DCONFIG_INPUT_TOUCHSCREEN_MMI
|
||||
stmicro_mmi-objs += fts_mmi_class.o
|
||||
endif
|
||||
13
drivers/input/touchscreen/stmicro_mmi/Kconfig
Normal file
13
drivers/input/touchscreen/stmicro_mmi/Kconfig
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# STmicro TOUCH driver configuration
|
||||
#
|
||||
|
||||
config TOUCHSCREEN_FTS_TS
|
||||
tristate "STmicro Touchscreen"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y here if you want support for FTS touchscreen controllers.
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called stmicro_mmi.
|
||||
|
|
@ -1,6 +1,10 @@
|
|||
#
|
||||
# Makefile for the touchscreen drivers.
|
||||
#
|
||||
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
|
||||
|
||||
obj-y += fts.o fts_proc.o fts_lib/
|
||||
all:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
|
||||
|
||||
modules_install:
|
||||
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
#include "fts_lib/ftsTime.h"
|
||||
#include "fts_lib/ftsTool.h"
|
||||
|
||||
|
||||
#include "fts_mmi.h"
|
||||
|
||||
/**
|
||||
* Event handler installer helpers
|
||||
|
|
@ -2823,6 +2823,7 @@ int fts_fw_update(struct fts_ts_info *info)
|
|||
int crc_status = 0;
|
||||
int error = 0;
|
||||
int init_type = NO_INIT;
|
||||
const char *firmware_name;
|
||||
|
||||
#if defined(PRE_SAVED_METHOD) || defined (COMPUTE_INIT_METHOD)
|
||||
int keep_cx = 1;
|
||||
|
|
@ -2844,15 +2845,20 @@ int fts_fw_update(struct fts_ts_info *info)
|
|||
"%s %s: NO CRC Error or Impossible to read CRC register!\n",
|
||||
tag, __func__);
|
||||
}
|
||||
/* support arbitrary firmware file */
|
||||
if (info->fw_file)
|
||||
firmware_name = info->fw_file;
|
||||
else
|
||||
firmware_name = PATH_FILE_FW;
|
||||
|
||||
retval = flashProcedure(PATH_FILE_FW, crc_status, keep_cx);
|
||||
retval = flashProcedure(firmware_name, crc_status, keep_cx);
|
||||
if ((retval & 0xFF000000) == ERROR_FLASH_PROCEDURE) {
|
||||
logError(1,
|
||||
"%s %s: firmware update failed and retry! ERROR %08X\n",
|
||||
tag,
|
||||
__func__, retval);
|
||||
fts_chip_powercycle(info); /* power reset */
|
||||
retval1 = flashProcedure(PATH_FILE_FW, crc_status, keep_cx);
|
||||
retval1 = flashProcedure(firmware_name, crc_status, keep_cx);
|
||||
if ((retval1 & 0xFF000000) == ERROR_FLASH_PROCEDURE) {
|
||||
logError(1,
|
||||
"%s %s: firmware update failed again! ERROR %08X\n",
|
||||
|
|
@ -3448,29 +3454,33 @@ static int fts_mode_handler(struct fts_ts_info *info, int force)
|
|||
return res;
|
||||
}
|
||||
|
||||
void fts_resume_func(struct fts_ts_info *info)
|
||||
{
|
||||
__pm_wakeup_event(&info->wakesrc, jiffies_to_msecs(HZ));
|
||||
info->resume_bit = 1;
|
||||
fts_system_reset();
|
||||
release_all_touches(info);
|
||||
fts_mode_handler(info, 0);
|
||||
info->sensor_sleep = false;
|
||||
fts_enableInterrupt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume work function which perform a system reset, clean all the touches
|
||||
*from the linux input system and prepare the ground for enabling the sensing
|
||||
*/
|
||||
static void fts_resume_work(struct work_struct *work)
|
||||
static void inline fts_resume_work(struct work_struct *work)
|
||||
{
|
||||
struct fts_ts_info *info;
|
||||
|
||||
|
||||
info = container_of(work, struct fts_ts_info, resume_work);
|
||||
fts_resume_func(container_of(work, struct fts_ts_info, resume_work));
|
||||
}
|
||||
|
||||
void fts_suspend_func(struct fts_ts_info *info)
|
||||
{
|
||||
__pm_wakeup_event(&info->wakesrc, jiffies_to_msecs(HZ));
|
||||
|
||||
info->resume_bit = 1;
|
||||
|
||||
fts_system_reset();
|
||||
|
||||
release_all_touches(info);
|
||||
|
||||
info->resume_bit = 0;
|
||||
fts_mode_handler(info, 0);
|
||||
|
||||
info->sensor_sleep = false;
|
||||
|
||||
release_all_touches(info);
|
||||
info->sensor_sleep = true;
|
||||
fts_enableInterrupt();
|
||||
}
|
||||
|
||||
|
|
@ -3478,23 +3488,9 @@ static void fts_resume_work(struct work_struct *work)
|
|||
* Suspend work function which clean all the touches from Linux input system
|
||||
*and prepare the ground to disabling the sensing or enter in gesture mode
|
||||
*/
|
||||
static void fts_suspend_work(struct work_struct *work)
|
||||
static void inline fts_suspend_work(struct work_struct *work)
|
||||
{
|
||||
struct fts_ts_info *info;
|
||||
|
||||
info = container_of(work, struct fts_ts_info, suspend_work);
|
||||
|
||||
__pm_wakeup_event(&info->wakesrc, jiffies_to_msecs(HZ));
|
||||
|
||||
info->resume_bit = 0;
|
||||
|
||||
fts_mode_handler(info, 0);
|
||||
|
||||
release_all_touches(info);
|
||||
|
||||
info->sensor_sleep = true;
|
||||
|
||||
fts_enableInterrupt();
|
||||
fts_suspend_func(container_of(work, struct fts_ts_info, suspend_work));
|
||||
}
|
||||
/** @}*/
|
||||
|
||||
|
|
@ -4050,6 +4046,9 @@ static int fts_probe(struct spi_device *client)
|
|||
goto ProbeErrorExit_6;
|
||||
}
|
||||
|
||||
/* register touchscreen class if provisioned */
|
||||
fts_mmi_init(info, true);
|
||||
|
||||
#if defined(FW_UPDATE_ON_PROBE) && defined(FW_H_FILE)
|
||||
logError(1, "%s FW Update and Sensing Initialization:\n", tag);
|
||||
error = fts_fw_update(info);
|
||||
|
|
@ -4097,6 +4096,8 @@ static int fts_probe(struct spi_device *client)
|
|||
|
||||
|
||||
ProbeErrorExit_7:
|
||||
fts_mmi_init(info, false);
|
||||
|
||||
#ifdef FW_UPDATE_ON_PROBE
|
||||
fb_unregister_client(&info->notifier);
|
||||
#endif
|
||||
|
|
@ -4169,6 +4170,8 @@ static int fts_remove(struct spi_device *client)
|
|||
fts_enable_reg(info, false);
|
||||
fts_get_reg(info, false);
|
||||
|
||||
fts_mmi_init(info, false);
|
||||
|
||||
/* free all */
|
||||
kfree(info);
|
||||
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ struct fts_hw_platform_data {
|
|||
* Forward declaration
|
||||
*/
|
||||
struct fts_ts_info;
|
||||
struct fts_sys_info;
|
||||
extern char tag[8]; /* /< forward the definition of the label used
|
||||
* to print the log in the kernel log */
|
||||
|
||||
|
|
@ -340,8 +341,10 @@ struct fts_ts_info {
|
|||
* when allowed */
|
||||
int grip_enabled; /* /< if set, the grip mode mode will be enabled
|
||||
* when allowed */
|
||||
};
|
||||
|
||||
struct fts_sys_info *sysinfo;
|
||||
const char *fw_file;
|
||||
};
|
||||
|
||||
|
||||
int fts_chip_powercycle(struct fts_ts_info *info);
|
||||
|
|
|
|||
|
|
@ -326,12 +326,13 @@ int readSelfSenseGlobalData(u64 *address, SelfSenseData *global)
|
|||
int readSelfSenseNodeData(u64 address, SelfSenseData *node)
|
||||
{
|
||||
int size = node->header.force_node * 2 + node->header.sense_node * 2;
|
||||
u8 data[size];
|
||||
u8 *data = NULL;
|
||||
int ret;
|
||||
|
||||
data = (u8 *)kzalloc(size, GFP_KERNEL);
|
||||
node->ix2_fm = (u8 *)kmalloc(node->header.force_node * (sizeof(u8)),
|
||||
GFP_KERNEL);
|
||||
if (node->ix2_fm == NULL) {
|
||||
if (node->ix2_fm == NULL || data == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for ix2_fm... ERROR %08X",
|
||||
tag,
|
||||
|
|
@ -347,6 +348,7 @@ int readSelfSenseNodeData(u64 address, SelfSenseData *node)
|
|||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix2_fm);
|
||||
kfree(data);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->ix2_sn = (u8 *)kmalloc(node->header.sense_node * (sizeof(u8)),
|
||||
|
|
@ -358,6 +360,7 @@ int readSelfSenseNodeData(u64 address, SelfSenseData *node)
|
|||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix2_fm);
|
||||
kfree(node->cx2_fm);
|
||||
kfree(data);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->cx2_sn = (i8 *)kmalloc(node->header.sense_node * (sizeof(i8)),
|
||||
|
|
@ -370,6 +373,7 @@ int readSelfSenseNodeData(u64 address, SelfSenseData *node)
|
|||
kfree(node->ix2_fm);
|
||||
kfree(node->cx2_fm);
|
||||
kfree(node->ix2_sn);
|
||||
kfree(data);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
|
|
@ -387,6 +391,7 @@ int readSelfSenseNodeData(u64 address, SelfSenseData *node)
|
|||
kfree(node->cx2_fm);
|
||||
kfree(node->ix2_sn);
|
||||
kfree(node->cx2_sn);
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -401,6 +406,7 @@ int readSelfSenseNodeData(u64 address, SelfSenseData *node)
|
|||
memcpy(node->cx2_sn, &data[node->header.force_node * 2 +
|
||||
node->header.sense_node],
|
||||
node->header.sense_node);
|
||||
kfree(data);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -517,13 +523,13 @@ 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];
|
||||
u8 *data;
|
||||
|
||||
logError(0, "%s Address for Node data = %04llX\n", tag, address);
|
||||
|
||||
data = (u8 *)kzalloc(toRead, GFP_KERNEL);
|
||||
node->node_data = (short *)kmalloc(size * (sizeof(short)), GFP_KERNEL);
|
||||
|
||||
if (node->node_data == NULL) {
|
||||
if (node->node_data == NULL || data == NULL) {
|
||||
logError(1, "%s %s: can not allocate node_data... ERROR %08X",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
|
|
@ -539,6 +545,7 @@ int readTotMutualSenseNodeData(u64 address, TotMutualSenseData *node)
|
|||
tag,
|
||||
__func__, ret);
|
||||
kfree(node->node_data);
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
node->node_data_size = size;
|
||||
|
|
@ -548,6 +555,7 @@ int readTotMutualSenseNodeData(u64 address, TotMutualSenseData *node)
|
|||
2];
|
||||
|
||||
logError(0, "%s Read node data OK!\n", tag);
|
||||
kfree(data);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
|
@ -663,12 +671,13 @@ 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];
|
||||
u8 *data;
|
||||
int ret, i, j = 0;
|
||||
|
||||
data = (u8 *)kzalloc(toRead, GFP_KERNEL);
|
||||
node->ix_fm = (u16 *)kmalloc(node->header.force_node * (sizeof(u16)),
|
||||
GFP_KERNEL);
|
||||
if (node->ix_fm == NULL) {
|
||||
if (node->ix_fm == NULL || data == NULL) {
|
||||
logError(1,
|
||||
"%s %s: can not allocate memory for ix2_fm... ERROR %08X",
|
||||
tag,
|
||||
|
|
@ -684,6 +693,7 @@ int readTotSelfSenseNodeData(u64 address, TotSelfSenseData *node)
|
|||
tag,
|
||||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix_fm);
|
||||
kfree(data);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->ix_sn = (u16 *)kmalloc(node->header.sense_node * (sizeof(u16)),
|
||||
|
|
@ -695,6 +705,7 @@ int readTotSelfSenseNodeData(u64 address, TotSelfSenseData *node)
|
|||
__func__, ERROR_ALLOC);
|
||||
kfree(node->ix_fm);
|
||||
kfree(node->cx_fm);
|
||||
kfree(data);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->cx_sn = (short *)kmalloc(node->header.sense_node *
|
||||
|
|
@ -707,6 +718,7 @@ int readTotSelfSenseNodeData(u64 address, TotSelfSenseData *node)
|
|||
kfree(node->ix_fm);
|
||||
kfree(node->cx_fm);
|
||||
kfree(node->ix_sn);
|
||||
kfree(data);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
|
|
@ -724,6 +736,7 @@ int readTotSelfSenseNodeData(u64 address, TotSelfSenseData *node)
|
|||
kfree(node->cx_fm);
|
||||
kfree(node->ix_sn);
|
||||
kfree(node->cx_sn);
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -753,6 +766,7 @@ int readTotSelfSenseNodeData(u64 address, TotSelfSenseData *node)
|
|||
if (j != toRead)
|
||||
logError(1, "%s %s: parsed a wrong number of bytes %d!=%d\n",
|
||||
tag, __func__, j, toRead);
|
||||
kfree(data);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ int initCore(struct fts_ts_info *info)
|
|||
{
|
||||
int ret = OK;
|
||||
|
||||
info->sysinfo = &systemInfo;
|
||||
|
||||
logError(0, "%s %s: Initialization of the Core...\n", tag, __func__);
|
||||
ret |= openChannel(info->client);
|
||||
ret |= resetErrorList();
|
||||
|
|
@ -406,10 +408,14 @@ int setScanMode(u8 mode, u8 settings)
|
|||
*/
|
||||
int setFeatures(u8 feat, u8 *settings, int size)
|
||||
{
|
||||
u8 cmd[2 + size];
|
||||
u8 *cmd;
|
||||
int i = 0;
|
||||
int ret;
|
||||
|
||||
cmd = (u8 *)kzalloc(2 + size, GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return ret | ERROR_SET_FEATURE_FAIL;
|
||||
|
||||
logError(0, "%s %s: Setting feature: feat = %02X !\n", tag, __func__,
|
||||
feat);
|
||||
cmd[0] = FTS_CMD_FEATURE;
|
||||
|
|
@ -429,6 +435,7 @@ int setFeatures(u8 feat, u8 *settings, int size)
|
|||
return ret | ERROR_SET_FEATURE_FAIL;
|
||||
}
|
||||
logError(0, "%s %s: Setting feature OK!\n", tag, __func__);
|
||||
kfree(cmd);
|
||||
return OK;
|
||||
}
|
||||
/** @}*/
|
||||
|
|
@ -448,9 +455,13 @@ int setFeatures(u8 feat, u8 *settings, int size)
|
|||
*/
|
||||
int writeSysCmd(u8 sys_cmd, u8 *sett, int size)
|
||||
{
|
||||
u8 cmd[2 + size];
|
||||
u8 *cmd;
|
||||
int ret;
|
||||
|
||||
cmd = (u8 *)kzalloc(2 + size, GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return ret | ERROR_SET_FEATURE_FAIL;
|
||||
|
||||
cmd[0] = FTS_CMD_SYSTEM;
|
||||
cmd[1] = sys_cmd;
|
||||
|
||||
|
|
@ -470,6 +481,7 @@ int writeSysCmd(u8 sys_cmd, u8 *sett, int size)
|
|||
else {
|
||||
logError(1, "%s %s: No setting argument! ERROR %08X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
kfree(cmd);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
}
|
||||
|
|
@ -478,6 +490,7 @@ int writeSysCmd(u8 sys_cmd, u8 *sett, int size)
|
|||
|
||||
else
|
||||
logError(0, "%s %s: FINISHED!\n", tag, __func__);
|
||||
kfree(cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -925,6 +938,11 @@ int fts_resetDisableIrqCount(void)
|
|||
return OK;
|
||||
}
|
||||
|
||||
int fts_is_InterruptEnabled(void)
|
||||
{
|
||||
return !disable_irq_count ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the interrupt so the ISR of the driver can be called
|
||||
* @return OK if success or an error code which specify the type of error
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ typedef enum {
|
|||
* Struct which contains fundamental informations about the chip and its
|
||||
*configuration
|
||||
*/
|
||||
typedef struct {
|
||||
struct fts_sys_info {
|
||||
u16 u16_apiVer_rev; /* /< API revision version */
|
||||
u8 u8_apiVer_minor; /* /< API minor version */
|
||||
u8 u8_apiVer_major; /* /< API major version */
|
||||
|
|
@ -187,7 +187,9 @@ typedef struct {
|
|||
* frame */
|
||||
u16 u16_ssDetBaselineAddr; /* /< Offset of SS detect baseline
|
||||
* frame */
|
||||
} SysInfo;
|
||||
};
|
||||
|
||||
typedef struct fts_sys_info SysInfo;
|
||||
|
||||
/** @}*/
|
||||
|
||||
|
|
@ -212,6 +214,7 @@ int fts_disableInterrupt(void);
|
|||
int fts_disableInterruptNoSync(void);
|
||||
int fts_resetDisableIrqCount(void);
|
||||
int fts_enableInterrupt(void);
|
||||
int fts_is_InterruptEnabled(void);
|
||||
int fts_crc_check(void);
|
||||
int requestSyncFrame(u8 type);
|
||||
int saveMpFlag(u8 mpflag);
|
||||
|
|
|
|||
|
|
@ -503,9 +503,9 @@ int parseBinFile(u8 *fw_data, int fw_size, Firmware *fwData, int keep_cx)
|
|||
fwData->fw_code_size, fwData->panel_config_size,
|
||||
fwData->cx_area_size, fwData->fw_config_size);
|
||||
|
||||
if((fwData->fw_code_size == 0) ||
|
||||
if((fwData->fw_code_size == 0) ||
|
||||
(fwData->panel_config_size == 0) ||
|
||||
(fwData->cx_area_size == 0) ||
|
||||
(fwData->cx_area_size == 0) ||
|
||||
(fwData->fw_config_size == 0))
|
||||
{
|
||||
logError(0, "%s Using default flash Address\n", tag);
|
||||
|
|
|
|||
|
|
@ -102,13 +102,13 @@ typedef struct {
|
|||
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
|
||||
u8 fw_code_size; /* /< size of fw code in pages in
|
||||
.ftb file */
|
||||
u8 panel_config_size;/* /< size of panel area in pages in
|
||||
u8 panel_config_size;/* /< size of panel area in pages in
|
||||
.ftb file */
|
||||
u8 cx_area_size;/* /< size of cx area in pages in
|
||||
u8 cx_area_size;/* /< size of cx area in pages in
|
||||
.ftb file */
|
||||
u8 fw_config_size;/* /< size of fw config in pages in
|
||||
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 */
|
||||
|
|
|
|||
|
|
@ -476,10 +476,14 @@ int fts_writeThenWriteRead(u8 *writeCmd1, int writeCmdLength, u8 *readCmd1, int
|
|||
int fts_writeU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *data, int
|
||||
dataSize)
|
||||
{
|
||||
u8 finalCmd[1 + addrSize + WRITE_CHUNK];
|
||||
u8 *finalCmd;
|
||||
int remaining = dataSize;
|
||||
int toWrite = 0, i = 0;
|
||||
|
||||
finalCmd = (u8 *)kzalloc(1 + addrSize + WRITE_CHUNK, GFP_KERNEL);
|
||||
if (!finalCmd)
|
||||
return ERROR_ALLOC;
|
||||
|
||||
if (addrSize <= sizeof(u64)) {
|
||||
while (remaining > 0) {
|
||||
if (remaining >= WRITE_CHUNK) {
|
||||
|
|
@ -506,6 +510,7 @@ int fts_writeU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *data, int
|
|||
if (fts_write(finalCmd, 1 + addrSize + toWrite) < OK) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag,
|
||||
__func__, ERROR_BUS_W);
|
||||
kfree(finalCmd);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
|
||||
|
|
@ -517,7 +522,7 @@ int fts_writeU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *data, int
|
|||
logError(1,
|
||||
"%s %s: address size bigger than max allowed %ld... ERROR %08X\n",
|
||||
tag, __func__, sizeof(u64), ERROR_OP_NOT_ALLOW);
|
||||
|
||||
kfree(finalCmd);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -537,11 +542,15 @@ int fts_writeU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *data, int
|
|||
int fts_writeReadU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *outBuf, int
|
||||
byteToRead, int hasDummyByte)
|
||||
{
|
||||
u8 finalCmd[1 + addrSize];
|
||||
u8 *finalCmd;
|
||||
u8 buff[READ_CHUNK + 1];/* worst case has dummy byte */
|
||||
int remaining = byteToRead;
|
||||
int toRead = 0, i = 0;
|
||||
|
||||
finalCmd = (u8 *)kzalloc(1 + addrSize, GFP_KERNEL);
|
||||
if (!finalCmd)
|
||||
return ERROR_ALLOC;
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= READ_CHUNK) {
|
||||
toRead = READ_CHUNK;
|
||||
|
|
@ -563,6 +572,7 @@ int fts_writeReadU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *outBuf, int
|
|||
"%s %s: read error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_WR);
|
||||
kfree(finalCmd);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
memcpy(outBuf, buff + 1, toRead);
|
||||
|
|
@ -573,6 +583,7 @@ int fts_writeReadU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *outBuf, int
|
|||
"%s %s: read error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_WR);
|
||||
kfree(finalCmd);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
memcpy(outBuf, buff, toRead);
|
||||
|
|
@ -582,7 +593,7 @@ int fts_writeReadU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *outBuf, int
|
|||
|
||||
outBuf += toRead;
|
||||
}
|
||||
|
||||
kfree(finalCmd);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -604,11 +615,21 @@ int fts_writeReadU8UX(u8 cmd, AddrSize addrSize, u64 address, u8 *outBuf, int
|
|||
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];
|
||||
u8 *finalCmd1;
|
||||
u8 *finalCmd2;
|
||||
int remaining = dataSize;
|
||||
int toWrite = 0, i = 0;
|
||||
|
||||
finalCmd1 = (u8 *)kzalloc(1 + addrSize1, GFP_KERNEL);
|
||||
if (!finalCmd1)
|
||||
return ERROR_ALLOC;
|
||||
|
||||
finalCmd2 = (u8 *)kzalloc(1 + addrSize2 + WRITE_CHUNK, GFP_KERNEL);
|
||||
if (!finalCmd2) {
|
||||
kfree(finalCmd1);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= WRITE_CHUNK) {
|
||||
toWrite = WRITE_CHUNK;
|
||||
|
|
@ -636,6 +657,8 @@ int fts_writeU8UXthenWriteU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2, AddrSize
|
|||
if (fts_write(finalCmd1, 1 + addrSize1) < OK) {
|
||||
logError(1, "%s %s: first write error... ERROR %08X\n",
|
||||
tag, __func__, ERROR_BUS_W);
|
||||
kfree(finalCmd1);
|
||||
kfree(finalCmd2);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
|
||||
|
|
@ -644,6 +667,8 @@ int fts_writeU8UXthenWriteU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2, AddrSize
|
|||
"%s %s: second write error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_W);
|
||||
kfree(finalCmd1);
|
||||
kfree(finalCmd2);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
|
||||
|
|
@ -651,7 +676,8 @@ int fts_writeU8UXthenWriteU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2, AddrSize
|
|||
|
||||
data += toWrite;
|
||||
}
|
||||
|
||||
kfree(finalCmd1);
|
||||
kfree(finalCmd2);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -676,12 +702,21 @@ 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 *finalCmd1;
|
||||
u8 *finalCmd2;
|
||||
u8 buff[READ_CHUNK + 1];/* worst case has dummy byte */
|
||||
int remaining = byteToRead;
|
||||
int toRead = 0, i = 0;
|
||||
|
||||
finalCmd1 = (u8 *)kzalloc(1 + addrSize1, GFP_KERNEL);
|
||||
if (!finalCmd1)
|
||||
return ERROR_ALLOC;
|
||||
|
||||
finalCmd2 = (u8 *)kzalloc(1 + addrSize2, GFP_KERNEL);
|
||||
if (!finalCmd2) {
|
||||
kfree(finalCmd1);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= READ_CHUNK) {
|
||||
|
|
@ -711,6 +746,8 @@ int fts_writeU8UXthenWriteReadU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2,
|
|||
if (fts_write(finalCmd1, 1 + addrSize1) < OK) {
|
||||
logError(1, "%s %s: first write error... ERROR %08X\n",
|
||||
tag, __func__, ERROR_BUS_W);
|
||||
kfree(finalCmd1);
|
||||
kfree(finalCmd2);
|
||||
return ERROR_BUS_W;
|
||||
}
|
||||
|
||||
|
|
@ -721,6 +758,8 @@ int fts_writeU8UXthenWriteReadU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2,
|
|||
"%s %s: read error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_WR);
|
||||
kfree(finalCmd1);
|
||||
kfree(finalCmd2);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
memcpy(outBuf, buff + 1, toRead);
|
||||
|
|
@ -731,6 +770,8 @@ int fts_writeU8UXthenWriteReadU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2,
|
|||
"%s %s: read error... ERROR %08X\n",
|
||||
tag,
|
||||
__func__, ERROR_BUS_WR);
|
||||
kfree(finalCmd1);
|
||||
kfree(finalCmd2);
|
||||
return ERROR_BUS_WR;
|
||||
}
|
||||
memcpy(outBuf, buff, toRead);
|
||||
|
|
@ -740,6 +781,7 @@ int fts_writeU8UXthenWriteReadU8UX(u8 cmd1, AddrSize addrSize1, u8 cmd2,
|
|||
|
||||
outBuf += toRead;
|
||||
}
|
||||
|
||||
kfree(finalCmd1);
|
||||
kfree(finalCmd2);
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@
|
|||
|
||||
|
||||
/* 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) */
|
||||
#define u8 uint8_t /* /< basic type that represent one byte (or 8 bits) */
|
||||
#define u16 uint16_t /* /< basic type that represent 2 bytes (or 16 bits) */
|
||||
#define u32 uint32_t /* /< basic type that represent 4 bytes (or 32 bits) */
|
||||
#define u64 uint64_t /* /< basic type that represent 8 bytes (or 64 bits) */
|
||||
|
||||
/* signed type */
|
||||
typedef signed char i8; /* /< basic type that represent one signed byte (or 8
|
||||
|
|
|
|||
17
drivers/input/touchscreen/stmicro_mmi/fts_mmi.h
Normal file
17
drivers/input/touchscreen/stmicro_mmi/fts_mmi.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef _FTS_MMI_H_
|
||||
#define _FTS_MMI_H_
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/touchscreen_mmi.h>
|
||||
|
||||
struct fts_ts_info;
|
||||
|
||||
#ifdef CONFIG_INPUT_TOUCHSCREEN_MMI
|
||||
int fts_mmi_init(struct fts_ts_info *info, bool enable);
|
||||
#else
|
||||
static int inline fts_mmi_init(struct fts_ts_info *info, bool enable)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
217
drivers/input/touchscreen/stmicro_mmi/fts_mmi_class.c
Normal file
217
drivers/input/touchscreen/stmicro_mmi/fts_mmi_class.c
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Motorola Mobility LLC
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include "fts.h"
|
||||
#include "fts_mmi.h"
|
||||
#include "fts_lib/ftsCore.h"
|
||||
|
||||
extern void fts_resume_func(struct fts_ts_info *info);
|
||||
extern void fts_suspend_func(struct fts_ts_info *info);
|
||||
extern int fts_fw_update(struct fts_ts_info *info);
|
||||
|
||||
#define ASSERT_PTR(p) if (p == NULL) { \
|
||||
dev_err(dev, "Failed to get driver data"); \
|
||||
return -ENODEV; \
|
||||
}
|
||||
|
||||
static int fts_mmi_get_class_entry_name(struct device *dev, void *cdata) {
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
ASSERT_PTR(ts);
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "primary");
|
||||
}
|
||||
|
||||
static int fts_mmi_get_vendor(struct device *dev, void *cdata) {
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "stmicro");
|
||||
}
|
||||
|
||||
static int fts_mmi_get_productinfo(struct device *dev, void *cdata) {
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
char buffer[64];
|
||||
ssize_t blen = 0;
|
||||
ASSERT_PTR(ts);
|
||||
blen += scnprintf(buffer+blen, sizeof(buffer)-blen, "%02x%02x%02x%02x",
|
||||
ts->sysinfo->u8_dieInfo[0], ts->sysinfo->u8_dieInfo[1],
|
||||
ts->sysinfo->u8_dieInfo[2], ts->sysinfo->u8_dieInfo[3]);
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_INFO_LEN, "%s", buffer);
|
||||
}
|
||||
|
||||
static int fts_mmi_get_build_id(struct device *dev, void *cdata) {
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
char buffer[64];
|
||||
ssize_t blen = 0;
|
||||
ASSERT_PTR(ts);
|
||||
blen += scnprintf(buffer+blen, sizeof(buffer)-blen, "%08x%02x",
|
||||
ts->sysinfo->u16_cfgVer, ts->sysinfo->u8_cfgAfeVer);
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, "%s", buffer);
|
||||
}
|
||||
|
||||
static int fts_mmi_get_config_id(struct device *dev, void *cdata) {
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
char buffer[64];
|
||||
ssize_t blen = 0;
|
||||
ASSERT_PTR(ts);
|
||||
blen += scnprintf(buffer+blen, sizeof(buffer)-blen, "%02x%02x%02x%02x",
|
||||
ts->sysinfo->u8_releaseInfo[0], ts->sysinfo->u8_releaseInfo[1],
|
||||
ts->sysinfo->u8_releaseInfo[2], ts->sysinfo->u8_releaseInfo[3]);
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, "%s", buffer);
|
||||
}
|
||||
|
||||
static int fts_mmi_get_bus_type(struct device *dev, void *idata) {
|
||||
TO_INT(idata) = TOUCHSCREEN_MMI_BUS_TYPE_I2C;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_mmi_get_irq_status(struct device *dev, void *idata) {
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
ASSERT_PTR(ts);
|
||||
TO_INT(idata) = gpio_get_value(ts->board->irq_gpio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_mmi_get_drv_irq(struct device *dev, void *idata) {
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
ASSERT_PTR(ts);
|
||||
TO_INT(idata) = fts_is_InterruptEnabled();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_mmi_get_poweron(struct device *dev, void *idata)
|
||||
{
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
ASSERT_PTR(ts);
|
||||
//TO_INT(idata) = (atomic_read(&ts->touch_stopped) == 0 && ts->flash_enabled) ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_mmi_get_flashprog(struct device *dev, void *idata)
|
||||
{
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
|
||||
ASSERT_PTR(ts);
|
||||
//TO_INT(idata) = ts->in_bootloader ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_mmi_drv_irq(struct device *dev, int state)
|
||||
{
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
ASSERT_PTR(ts);
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
switch (state) {
|
||||
case 0: /* Disable irq */
|
||||
fts_disableInterrupt();
|
||||
break;
|
||||
case 1: /* Enable irq */
|
||||
fts_enableInterrupt();
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "%s: invalid value\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_mmi_reset(struct device *dev, int type)
|
||||
{
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
ASSERT_PTR(ts);
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
return fts_system_reset();
|
||||
}
|
||||
|
||||
static int fts_mmi_panel_state(struct device *dev,
|
||||
enum ts_mmi_pm_mode from, enum ts_mmi_pm_mode to)
|
||||
{
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
ASSERT_PTR(ts);
|
||||
dev_dbg(dev, "%s: panel state change: %d->%d\n", __func__, from, to);
|
||||
switch (to) {
|
||||
case TS_MMI_PM_GESTURE:
|
||||
case TS_MMI_PM_DEEPSLEEP:
|
||||
fts_suspend_func(ts);
|
||||
break;
|
||||
case TS_MMI_PM_ACTIVE:
|
||||
break;
|
||||
default:
|
||||
dev_warn(dev, "invalid panel state %d\n", to);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_mmi_post_resume(struct device *dev)
|
||||
{
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
ASSERT_PTR(ts);
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
fts_resume_func(ts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fts_mmi_fw_update(struct device *dev, char *fwname)
|
||||
{
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
ASSERT_PTR(ts);
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
ts->fw_file = fwname;
|
||||
ret = fts_fw_update(ts);
|
||||
ts->fw_file = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fts_mmi_charger_mode(struct device *dev, int mode)
|
||||
{
|
||||
struct fts_ts_info *ts = dev_get_drvdata(dev);
|
||||
ASSERT_PTR(ts);
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ts_mmi_methods fts_mmi_methods = {
|
||||
.get_vendor = fts_mmi_get_vendor,
|
||||
.get_productinfo = fts_mmi_get_productinfo,
|
||||
.get_build_id = fts_mmi_get_build_id,
|
||||
.get_config_id = fts_mmi_get_config_id,
|
||||
.get_bus_type = fts_mmi_get_bus_type,
|
||||
.get_irq_status = fts_mmi_get_irq_status,
|
||||
.get_drv_irq = fts_mmi_get_drv_irq,
|
||||
.get_poweron = fts_mmi_get_poweron,
|
||||
.get_flashprog = fts_mmi_get_flashprog,
|
||||
.get_class_entry_name = fts_mmi_get_class_entry_name,
|
||||
/* SET methods */
|
||||
.reset = fts_mmi_reset,
|
||||
.drv_irq = fts_mmi_drv_irq,
|
||||
.charger_mode = fts_mmi_charger_mode,
|
||||
/* Firmware */
|
||||
.firmware_update = fts_mmi_fw_update,
|
||||
/* vendor specific attribute group */
|
||||
/* PM callback */
|
||||
.panel_state = fts_mmi_panel_state,
|
||||
.post_resume = fts_mmi_post_resume,
|
||||
};
|
||||
|
||||
int fts_mmi_init(struct fts_ts_info *ts, bool enable)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (enable) {
|
||||
ret = ts_mmi_dev_register(ts->dev, &fts_mmi_methods);
|
||||
if (ret)
|
||||
dev_err(ts->dev, "Failed to register ts mmi\n");
|
||||
} else
|
||||
ts_mmi_dev_unregister(ts->dev);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -637,7 +637,7 @@ static ssize_t fts_driver_test_write(struct file *file, const char __user *buf,
|
|||
int numberParam = 0;
|
||||
struct fts_ts_info *info = dev_get_drvdata(getDev());
|
||||
char *p = NULL;
|
||||
char pbuf[count];
|
||||
char *pbuf = NULL;
|
||||
char path[100] = { 0 };
|
||||
int res = -1, j, index = 0;
|
||||
int size = 6;
|
||||
|
|
@ -645,8 +645,8 @@ static ssize_t fts_driver_test_write(struct file *file, const char __user *buf,
|
|||
u16 byteToRead = 0;
|
||||
u32 fileSize = 0;
|
||||
u8 *readData = NULL;
|
||||
u8 cmd[count]; /* worst case needs count bytes */
|
||||
u32 funcToTest[((count + 1) / 3)];
|
||||
u8 *cmd = NULL;
|
||||
u32 *funcToTest = NULL;
|
||||
u64 addr = 0;
|
||||
MutualSenseFrame frameMS;
|
||||
SelfSenseFrame frameSS;
|
||||
|
|
@ -666,6 +666,14 @@ static ssize_t fts_driver_test_write(struct file *file, const char __user *buf,
|
|||
mess.action = 0;
|
||||
mess.msg_size = 0;
|
||||
|
||||
pbuf = (char *)kzalloc(count + 1, GFP_KERNEL);
|
||||
cmd = (u8 *)kzalloc(count, GFP_KERNEL);
|
||||
funcToTest = (u32 *)kzalloc((int)((count + 1)/3), GFP_KERNEL);
|
||||
if (!pbuf || !cmd || !funcToTest) {
|
||||
res = ERROR_ALLOC;
|
||||
goto END;
|
||||
}
|
||||
|
||||
/*for(temp = 0; temp<count; temp++){
|
||||
* logError(0,"%s p[%d] = %02X\n",tag, temp, p[temp]);
|
||||
* }*/
|
||||
|
|
@ -3004,6 +3012,13 @@ ERROR:
|
|||
if (readData != NULL)
|
||||
kfree(readData);
|
||||
|
||||
if (pbuf)
|
||||
kfree(pbuf);
|
||||
if (cmd)
|
||||
kfree(cmd);
|
||||
if (funcToTest)
|
||||
kfree(funcToTest);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue