blob: e8fe81de29116bb4fc4b9dd69ad28fc2a4233d70 [file] [log] [blame]
/*
* FTS Capacitive touch screen controller (FingerTipS)
*
* Copyright (C) 2016-2018, STMicroelectronics Limited.
* 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.
*
* 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/device.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/hrtimer.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/completion.h>
/*#include <linux/wakelock.h>*/
#include <linux/pm_wakeup.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/regulator/consumer.h>
#include "fts.h"
#include "fts_lib/ftsCompensation.h"
#include "fts_lib/ftsIO.h"
#include "fts_lib/ftsError.h"
#include "fts_lib/ftsFrame.h"
#include "fts_lib/ftsFlash.h"
#include "fts_lib/ftsTest.h"
#include "fts_lib/ftsTime.h"
#include "fts_lib/ftsTool.h"
#ifdef DRIVER_TEST
#define MAX_PARAMS 50
/*DEFINE COMMANDS TO TEST*/
#define CMD_READ 0x00
#define CMD_WRITE 0x01
#define CMD_READU16 0x02
#define CMD_READB2 0x03
#define CMD_READB2U16 0x04
#define CMD_POLLFOREVENT 0x05
#define CMD_SYSTEMRESET 0x06
#define CMD_CLEANUP 0x07
#define CMD_GETFORCELEN 0x08
#define CMD_GETSENSELEN 0x09
#define CMD_GETMSFRAME 0x0A
/*#define CMD_GETMSKEYFRAME 0x0B*/
#define CMD_GETSSFRAME 0x0C
#define CMD_REQCOMPDATA 0x0D
#define CMD_READCOMPDATAHEAD 0x0E
#define CMD_READMSCOMPDATA 0x0F
#define CMD_READSSCOMPDATA 0x10
#define CMD_READGNCOMPDATA 0x11
#define CMD_GETFWVER 0x12
#define CMD_FLASHSTATUS 0x13
#define CMD_FLASHUNLOCK 0x14
#define CMD_READFWFILE 0x15
#define CMD_FLASHPROCEDURE 0x16
#define CMD_ITOTEST 0x17
#define CMD_INITTEST 0x18
#define CMD_MSRAWTEST 0x19
#define CMD_MSINITDATATEST 0x1A
#define CMD_SSRAWTEST 0x1B
#define CMD_SSINITDATATEST 0x1C
#define CMD_MAINTEST 0x1D
#define CMD_POWERCYCLE 0x1E
#define CMD_FWWRITE 0x1F
#define CMD_READCHIPINFO 0x20
#define CMD_REQFRAME 0x21
static char tag[8] = "[ FTS ]\0";
static u32 functionToTest[MAX_PARAMS];
static int numberParam;
static ssize_t stm_driver_test_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int n;
char *p = (char *)buf;
int ret;
memset(functionToTest, 0, MAX_PARAMS * sizeof(u32));
for (n = 0; n < (count + 1) / 3 && n < MAX_PARAMS; n++) {
ret = sscanf(p, "%02X ", &functionToTest[n]);
if (ret != 1)
return -EINVAL;
p += 3;
logError(1, "%s functionToTest[%d] = %02X\n", tag, n,
functionToTest[n]);
}
numberParam = n;
logError(1, "%s Number of Parameters = %d\n", tag, numberParam);
return count;
}
static ssize_t stm_driver_test_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
char buff[CMD_STR_LEN] = {0};
int res = -1, j, count;
int size = 6 * 2;
int temp = 0;
int i;
int byteToRead = 0;
u8 *readData = NULL;
u8 *all_strbuff = NULL;
u8 *cmd = NULL;
struct MutualSenseFrame frameMS;
struct SelfSenseFrame frameSS;
struct DataHeader dataHead;
struct MutualSenseData compData;
struct SelfSenseData comData;
struct GeneralData gnData;
u16 address;
u16 fw_version;
u16 config_id;
struct Firmware fw;
/*struct used for defining which test*/
/*perform during the MP test*/
struct TestToDo todoDefault;
struct i2c_client *client = to_i2c_client(dev);
struct fts_ts_info *info = i2c_get_clientdata(client);
fw.data = NULL;
todoDefault.MutualRaw = 1;
todoDefault.MutualRawGap = 1;
todoDefault.MutualCx1 = 0;
todoDefault.MutualCx2 = 1;
todoDefault.MutualCx2Adj = 1;
todoDefault.MutualCxTotal = 0;
todoDefault.MutualCxTotalAdj = 0;
todoDefault.MutualKeyRaw = 0;
todoDefault.MutualKeyCx1 = 0;
todoDefault.MutualKeyCx2 = 0;
todoDefault.MutualKeyCxTotal = 0;
todoDefault.SelfForceRaw = 1;
todoDefault.SelfForceRawGap = 0;
todoDefault.SelfForceIx1 = 0;
todoDefault.SelfForceIx2 = 0;
todoDefault.SelfForceIx2Adj = 0;
todoDefault.SelfForceIxTotal = 1;
todoDefault.SelfForceIxTotalAdj = 0;
todoDefault.SelfForceCx1 = 0;
todoDefault.SelfForceCx2 = 0;
todoDefault.SelfForceCx2Adj = 0;
todoDefault.SelfForceCxTotal = 0;
todoDefault.SelfForceCxTotalAdj = 0;
todoDefault.SelfSenseRaw = 1;
todoDefault.SelfSenseRawGap = 0;
todoDefault.SelfSenseIx1 = 0;
todoDefault.SelfSenseIx2 = 0;
todoDefault.SelfSenseIx2Adj = 0;
todoDefault.SelfSenseIxTotal = 1;
todoDefault.SelfSenseIxTotalAdj = 0;
todoDefault.SelfSenseCx1 = 0;
todoDefault.SelfSenseCx2 = 0;
todoDefault.SelfSenseCx2Adj = 0;
todoDefault.SelfSenseCxTotal = 0;
todoDefault.SelfSenseCxTotalAdj = 0;
if (numberParam < 1) {
logError(1, "%s NO COMMAND SPECIFIED!!! ", tag);
logError(1, "do: 'echo [cmd_code] [args] > stm_fts_cmd' ");
logError(1, "before looking for result!\n");
res = ERROR_OP_NOT_ALLOW;
goto END;
}
res = fts_disableInterrupt();
if (res < 0) {
logError(0, "%s %s: ERROR %08X\n", tag, __func__, res);
res = (res | ERROR_DISABLE_INTER);
goto END;
}
switch (functionToTest[0]) {
case CMD_READ:
if (numberParam != 4) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/**
* need to pass:cmdLength
* cmd[0]cmd[1]…cmd[cmdLength-1]
* byteToRead
*/
temp = (int)functionToTest[1];
if (numberParam == 4 + (temp - 1) && temp != 0) {
cmd = (u8 *)kmalloc_array(temp, sizeof(u8), GFP_KERNEL);
for (i = 0; i < temp; i++)
cmd[i] = functionToTest[i + 2];
byteToRead = functionToTest[i + 2];
readData = (u8 *)kmalloc_array(byteToRead, sizeof(u8),
GFP_KERNEL);
res = fts_readCmd(cmd, temp, readData, byteToRead);
size += (byteToRead * sizeof(u8)) * 2;
kfree(cmd);
} else {
logError(1, "%s Wrong parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
}
break;
case CMD_WRITE:
if (numberParam != 3) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/**
* need to pass:cmdLength
* cmd[0] cmd[1]…cmd[cmdLength-1]
*/
temp = (int)functionToTest[1];
if (numberParam == 3 + (temp - 1) && temp != 0) {
cmd = (u8 *)kmalloc_array(temp, sizeof(u8), GFP_KERNEL);
for (i = 0; i < temp; i++)
cmd[i] = functionToTest[i + 2];
res = fts_writeCmd(cmd, temp);
kfree(cmd);
} else {
logError(1, "%s Wrong parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
}
break;
case CMD_FWWRITE:
if (numberParam != 3) {
logError(1, "%s Wrong number parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/**
* need to pass:cmdLength
* cmd[0] cmd[1]…cmd[cmdLength-1]
*/
temp = (int)functionToTest[1];
if (numberParam == 3 + (temp - 1) && temp != 0) {
cmd = (u8 *)kmalloc_array(temp, sizeof(u8), GFP_KERNEL);
for (i = 0; i < temp; i++)
cmd[i] = functionToTest[i + 2];
res = fts_writeFwCmd(cmd, temp);
kfree(cmd);
} else {
logError(1, "%s Wrong parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
}
break;
case CMD_READU16:
if (numberParam != 6) {
logError(1, "%s Wrong number parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/**
* need to pass: cmd addr[0] addr[1]
* byteToRead hasDummyByte
*/
byteToRead = functionToTest[4];
readData = kmalloc_array(byteToRead,
sizeof(u8), GFP_KERNEL);
res = readCmdU16((u8)functionToTest[1],
(u16)((((u8) functionToTest[2]
& 0x00FF) << 8) + ((u8) functionToTest[3]
& 0x00FF)),
readData,
byteToRead,
functionToTest[5]);
size += (byteToRead * sizeof(u8)) * 2;
break;
case CMD_READB2:
if (numberParam != 4) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*need to pass: addr[0] addr[1] byteToRead*/
byteToRead = functionToTest[3];
readData = kmalloc_array(byteToRead,
sizeof(u8), GFP_KERNEL);
res = readB2((u16)(
(((u8)functionToTest[1] & 0x00FF) << 8)
+ ((u8) functionToTest[2] & 0x00FF)),
readData,
byteToRead);
size += (byteToRead * sizeof(u8)) * 2;
break;
case CMD_READB2U16:
if (numberParam != 4) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*need to pass: addr[0] addr[1] byteToRead*/
byteToRead = functionToTest[3];
readData = (u8 *)kmalloc_array(byteToRead,
sizeof(u8), GFP_KERNEL);
res = readB2U16((u16)((((u8)functionToTest[1]
& 0x00FF) << 8) + ((u8)functionToTest[2]
& 0x00FF)), readData, byteToRead);
size += (byteToRead * sizeof(u8)) * 2;
break;
case CMD_POLLFOREVENT:
if (numberParam < 5) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/**
* need to pass: eventLength event[0] event[1]
* … event[eventLength-1] timeTowait
*/
temp = (int)functionToTest[1];
if (numberParam == 5 + (temp - 1) && temp != 0) {
readData = (u8 *)kmalloc_array(FIFO_EVENT_SIZE,
sizeof(u8), GFP_KERNEL);
res = pollForEvent((int *)&functionToTest[2],
temp,
readData,
((functionToTest[temp + 2] & 0x00FF) << 8)
+ (functionToTest[temp + 3] & 0x00FF));
//pollForEvent return the number of error found
if (res >= OK)
res = OK;
size += (FIFO_EVENT_SIZE * sizeof(u8)) * 2;
byteToRead = FIFO_EVENT_SIZE;
} else {
logError(1, "%s Wrong parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
}
break;
case CMD_SYSTEMRESET:
res = fts_system_reset();
break;
case CMD_READCHIPINFO:
if (numberParam != 2) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*need to pass: doRequest */
res = readChipInfo(functionToTest[1]);
break;
/* TOUCH ENABLE/DISABLE */
case CMD_CLEANUP:
if (numberParam != 2) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/* need to pass: enableTouch*/
res = cleanUp(functionToTest[1]);
break;
case CMD_GETFORCELEN:
/*read number Tx channels */
temp = getForceLen();
if (temp < OK)
res = temp;
else {
size += (1 * sizeof(u8)) * 2;
res = OK;
}
break;
case CMD_GETSENSELEN:
/* read number Rx channels */
temp = getSenseLen();
if (temp < OK)
res = temp;
else {
size += (1 * sizeof(u8)) * 2;
res = OK;
}
break;
case CMD_REQFRAME:
/* request a frame */
if (numberParam != 3) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
logError(0, "%s Requesting Frame\n", tag);
res = requestFrame((u16)((((u8)functionToTest[1] & 0x00FF) << 8)
+ ((u8)functionToTest[2] & 0x00FF)));
if (res < OK) {
logError(0, "%s Err requesting frame ERROR:%02X\n",
tag, res);
} else {
logError(0, "%s Requesting Frame Finished!\n", tag);
}
break;
case CMD_GETMSFRAME:
if (numberParam != 3) {
logError(1, "%s Wrong number of param!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
logError(0, "%s Get 1 MS Frame\n", tag);
flushFIFO();
/**
* delete the events related to some
* touch (allow to call this function
* while touching the sreen without
* having a flooding of the FIFO)
*/
res = getMSFrame2((u16)((((u8)functionToTest[1] & 0x00FF) << 8)
+ ((u8)functionToTest[2] & 0x00FF)), &frameMS);
if (res < 0) {
logError(0, "%s Err while taking MS frame:%02X\n",
tag, res);
} else {
logError(0, "%s:frame size is %d words\n", tag, res);
size = (res * sizeof(short) + 8) * 2;
/*set res to OK because if getMSFrame is*/
/*successful res = number of words read*/
res = OK;
print_frame_short("MS frame =",
array1dTo2d_short(frameMS.node_data,
frameMS.node_data_size,
frameMS.header.sense_node),
frameMS.header.force_node,
frameMS.header.sense_node);
}
break;
/*read self raw*/
case CMD_GETSSFRAME:
if (numberParam != 3) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
logError(0, "%s Get 1 SS Frame\n", tag);
flushFIFO();
/**
* delete the events related to some
* touch (allow to call this function
* while touching the sreen without
* having a flooding of the FIFO)
*/
res = getSSFrame2((u16)((((u8)functionToTest[1] & 0x00FF) << 8)
+ ((u8)functionToTest[2] & 0x00FF)), &frameSS);
if (res < OK) {
logError(0,
"%s Error while taking the SS frame... ERROR %02X\n",
tag, res);
} else {
logError(0, "%s The frame size is %d words\n",
tag, res);
size = (res * sizeof(short) + 8) * 2 + 1;
/*set res to OK because if getMSFrame is*/
/*successful res = number of words read*/
res = OK;
print_frame_short("SS force frame =",
array1dTo2d_short(frameSS.force_data,
frameSS.header.force_node, 1),
frameSS.header.force_node,
1);
print_frame_short("SS sense frame =",
array1dTo2d_short(frameSS.sense_data,
frameSS.header.sense_node,
frameSS.header.sense_node),
1,
frameSS.header.sense_node);
}
break;
case CMD_REQCOMPDATA:
/*request comp data*/
if (numberParam != 3) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
logError(0, "%s Requesting Compensation Data\n", tag);
res = requestCompensationData((u16)
((((u8)functionToTest[1] & 0x00FF) << 8)
+ ((u8)functionToTest[2] & 0x00FF)));
if (res < OK) {
logError(0,
"%s Error requesting compensation data ERROR %02X\n",
tag, res);
} else {
logError(0,
"%s Requesting Compensation Data Finished!\n",
tag);
}
break;
case CMD_READCOMPDATAHEAD:
/*read comp data header*/
if (numberParam != 3) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
logError(0, "%s Requesting Compensation Data\n", tag);
res = requestCompensationData(
(u16) ((((u8)functionToTest[1] & 0x00FF) << 8)
+ ((u8)functionToTest[2] & 0x00FF)));
if (res < OK) {
logError(0, "%s Error requesting:%02X\n", tag, res);
} else {
logError(0,
"%s Requesting Compensation Data Finished!\n", tag);
res = readCompensationDataHeader(
(u16)((((u8)functionToTest[1] & 0x00FF) << 8)
+((u8)functionToTest[2] & 0x00FF)),
&dataHead,
&address);
if (res < OK) {
logError(0, "%s Read Header ERROR:%02X\n",
tag, res);
} else {
logError(0, "%s Read Header OK!\n", tag);
size += (2 * sizeof(u8)) * 2;
}
}
break;
case CMD_READMSCOMPDATA:
if (numberParam != 3) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*read mutual comp data */
logError(0, "%s Get MS Compensation Data\n", tag);
res = readMutualSenseCompensationData(
(u16)((((u8)functionToTest[1] & 0x00FF) << 8)
+ ((u8)functionToTest[2] & 0x00FF)),
&compData);
if (res < OK) {
logError(0, "%s Error reading MS compe data:%02X\n",
tag, res);
} else {
logError(0, "%s MS Compensa Reading Finished!\n",
tag);
size = ((compData.node_data_size + 9) * sizeof(u8)) * 2;
print_frame_u8("MS Data (Cx2) = ",
array1dTo2d_u8(compData.node_data,
compData.node_data_size,
compData.header.sense_node),
compData.header.force_node,
compData.header.sense_node);
}
break;
case CMD_READSSCOMPDATA:
if (numberParam != 3) {
logError(1, "%sWrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*read self comp data*/
logError(0, "%s Get SS Compensation Data...\n", tag);
res = readSelfSenseCompensationData((u16)
((((u8)functionToTest[1] & 0x00FF) << 8)
+ ((u8)functionToTest[2] & 0x00FF)),
&comData);
if (res < OK) {
logError(0, "%s Error reading SS Compensa data %02X\n",
tag, res);
} else {
logError(0, "%s SS Compensa Reading Finished!\n", tag);
size = comData.header.force_node
+ comData.header.sense_node;
size = (size * 2 + 12) * sizeof(u8) * 2;
print_frame_u8("SS Data Ix2_fm = ",
array1dTo2d_u8(comData.ix2_fm,
comData.header.force_node,
comData.header.force_node),
1,
comData.header.force_node);
print_frame_u8("SS Data Cx2_fm = ",
array1dTo2d_u8(comData.cx2_fm,
comData.header.force_node,
comData.header.force_node),
1,
comData.header.force_node);
print_frame_u8("SS Data Ix2_sn = ",
array1dTo2d_u8(comData.ix2_sn,
comData.header.sense_node,
comData.header.sense_node),
1,
comData.header.sense_node);
print_frame_u8("SS Data Cx2_sn = ",
array1dTo2d_u8(comData.cx2_sn,
comData.header.sense_node,
comData.header.sense_node),
1,
comData.header.sense_node);
}
break;
case CMD_READGNCOMPDATA:
if (numberParam != 3) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*read self comp data */
logError(0, "%s Get General Compensation Data...\n", tag);
res = readGeneralCompensationData((u16)
((((u8)functionToTest[1]
& 0x00FF) << 8) + ((u8)functionToTest[2]
& 0x00FF)), &gnData);
if (res < OK) {
logError(0,
"%s Reading General compensa data ERROR %02X\n",
tag, res);
} else {
logError(0, "%s:General compensa Reading Finished!\n",
tag);
size = (14) * sizeof(u8) * 2;
}
break;
case CMD_GETFWVER:
res = getFirmwareVersion(&fw_version, &config_id);
if (res < OK) {
logError(1, "%s Reading firmware version ERROR %02X\n",
tag, res);
} else {
logError(0, "%s getFirmware Version Finished!\n", tag);
size += (4) * sizeof(u8) * 2;
}
break;
#ifdef FTM3_CHIP
case CMD_FLASHSTATUS:
res = flash_status();
/*return 0 = flash ready, 1 = flash busy, <0 error*/
if (res < OK) {
logError(1, "%s Reading flash status ERROR %02X\n",
tag, res);
} else {
logError(0, "%s Flash Status: %d\n", tag, res);
size += (1 * sizeof(u8)) * 2;
/*need to store the value for further display */
temp = res;
/*set res =ok for returning code*/
res = OK;
}
break;
#endif
case CMD_FLASHUNLOCK:
res = flash_unlock();
if (res < OK) {
logError(1, "%s:Impossible Unlock Flash ERROR %02X\n",
tag, res);
} else {
logError(0, "%s Flash Unlock OK!\n", tag);
}
break;
case CMD_READFWFILE:
if (numberParam != 2) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*read fw file */
logError(0, "%s Reading FW File...\n", tag);
res = readFwFile(PATH_FILE_FW, &fw, functionToTest[1]);
if (res < OK) {
logError(0, "%s Error reading FW File:%02X\n",
tag, res);
} else {
logError(0, "%s Read FW File Finished!\n", tag);
}
kfree(fw.data);
break;
case CMD_FLASHPROCEDURE:
if (numberParam != 3) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*flashing procedure*/
logError(0, "%s Starting Flashing Procedure\n", tag);
res = flashProcedure(PATH_FILE_FW,
functionToTest[1], functionToTest[2]);
if (res < OK) {
logError(0, "%s During flash procedure ERROR %02X",
tag, res);
} else {
logError(0, "%s Flash Procedure Finished!\n", tag);
}
break;
/*ITO TEST*/
case CMD_ITOTEST:
res = production_test_ito();
break;
/*Initialization*/
case CMD_INITTEST:
if (numberParam != 2) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*need to specify if if save value on Flash*/
if (functionToTest[1] == 0x01)
res = production_test_initialization();
else
res = production_test_split_initialization(false);
break;
case CMD_MSRAWTEST:
if (numberParam != 2) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/* MS Raw DATA TEST*/
/* need to specify if stopOnFail */
res = production_test_ms_raw(LIMITS_FILE, functionToTest[1],
&todoDefault);
break;
case CMD_MSINITDATATEST:
/*MS CX DATA TEST*/
if (numberParam != 2) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*need to specify if stopOnFail*/
res = production_test_ms_cx(LIMITS_FILE, functionToTest[1],
&todoDefault);
break;
case CMD_SSRAWTEST:
/*SS RAW DATA TEST*/
if (numberParam != 2) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*need to specify if stopOnFail*/
res = production_test_ss_raw(LIMITS_FILE, functionToTest[1],
&todoDefault);
break;
case CMD_SSINITDATATEST:
/*SS IX CX DATA TEST*/
if (numberParam != 2) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*need to specify if stopOnFail*/
res = production_test_ss_ix_cx(LIMITS_FILE, functionToTest[1],
&todoDefault);
break;
case CMD_MAINTEST:
/*PRODUCTION TEST*/
if (numberParam != 3) {
logError(1, "%s Wrong number of parameters!\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
/*need to specify if stopOnFail and saveInit*/
res = production_test_main(LIMITS_FILE, functionToTest[1],
functionToTest[2], &todoDefault, INIT_FIELD);
break;
case CMD_POWERCYCLE:
res = fts_chip_powercycle(info);
break;
default:
logError(1, "%s COMMAND ID NOT VALID!!\n", tag);
logError(1, "%s Inset a value between 00 and 1E.\n", tag);
res = ERROR_OP_NOT_ALLOW;
break;
}
END:
/**
* here start the reporting phase,
* assembling the data to send in the file node
*/
all_strbuff = kmalloc(size, GFP_KERNEL);
memset(all_strbuff, 0, size);
snprintf(buff, sizeof(buff), "%02X", 0xAA);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%08X", res);
strlcat(all_strbuff, buff, size);
if (res >= OK) {
/*all the other cases are already*/
/*fine printing only the res.*/
switch (functionToTest[0]) {
case CMD_READ:
case CMD_READU16:
case CMD_READB2:
case CMD_READB2U16:
case CMD_POLLFOREVENT:
for (j = 0; j < byteToRead; j++) {
snprintf(buff, sizeof(buff), "%02X",
readData[j]);
strlcat(all_strbuff, buff, size);
}
break;
case CMD_GETFORCELEN:
case CMD_GETSENSELEN:
case CMD_FLASHSTATUS:
snprintf(buff, sizeof(buff), "%02X", (u8)temp);
strlcat(all_strbuff, buff, size);
break;
case CMD_GETMSFRAME:
snprintf(buff, sizeof(buff), "%02X",
(u8) frameMS.header.force_node);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
(u8)frameMS.header.sense_node);
strlcat(all_strbuff, buff, size);
for (j = 0; j < frameMS.node_data_size; j++) {
snprintf(buff, sizeof(buff), "%04X",
frameMS.node_data[j]);
strlcat(all_strbuff, buff, size);
}
kfree(frameMS.node_data);
break;
case CMD_GETSSFRAME:
snprintf(buff, sizeof(buff), "%02X",
(u8) frameSS.header.force_node);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
(u8)frameSS.header.sense_node);
strlcat(all_strbuff, buff, size);
/* Copying self raw data Force */
for (j = 0; j < frameSS.header.force_node; j++) {
snprintf(buff, sizeof(buff), "%04X",
frameSS.force_data[j]);
strlcat(all_strbuff, buff, size);
}
/* Copying self raw data Sense */
for (j = 0; j < frameSS.header.sense_node; j++) {
snprintf(buff, sizeof(buff), "%04X",
frameSS.sense_data[j]);
strlcat(all_strbuff, buff, size);
}
kfree(frameSS.force_data);
kfree(frameSS.sense_data);
break;
case CMD_READMSCOMPDATA:
snprintf(buff, sizeof(buff), "%02X",
(u8)compData.header.force_node);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
(u8)compData.header.sense_node);
strlcat(all_strbuff, buff, size);
/* Cpying CX1 value */
snprintf(buff, sizeof(buff), "%02X",
compData.cx1);
strlcat(all_strbuff, buff, size);
/* Copying CX2 values */
for (j = 0; j < compData.node_data_size; j++) {
snprintf(buff, sizeof(buff), "%02X",
*(compData.node_data + j));
strlcat(all_strbuff, buff, size);
}
kfree(compData.node_data);
break;
case CMD_READSSCOMPDATA:
snprintf(buff, sizeof(buff), "%02X",
comData.header.force_node);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
comData.header.sense_node);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X", comData.f_ix1);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X", comData.s_ix1);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X", comData.f_cx1);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X", comData.s_cx1);
strlcat(all_strbuff, buff, size);
/* Copying IX2 Force */
for (j = 0; j < comData.header.force_node; j++) {
snprintf(buff, sizeof(buff), "%02X",
comData.ix2_fm[j]);
strlcat(all_strbuff, buff, size);
}
/* Copying IX2 Sense*/
for (j = 0; j < comData.header.sense_node; j++) {
snprintf(buff, sizeof(buff), "%02X",
comData.ix2_sn[j]);
strlcat(all_strbuff, buff, size);
}
/* Copying CX2 Force */
for (j = 0; j < comData.header.force_node; j++) {
snprintf(buff, sizeof(buff), "%02X",
comData.cx2_fm[j]);
strlcat(all_strbuff, buff, size);
}
/* Copying CX2 Sense */
for (j = 0; j < comData.header.sense_node; j++) {
snprintf(buff, sizeof(buff), "%02X",
comData.cx2_sn[j]);
strlcat(all_strbuff, buff, size);
}
kfree(comData.ix2_fm);
kfree(comData.ix2_sn);
kfree(comData.cx2_fm);
kfree(comData.cx2_sn);
break;
case CMD_READGNCOMPDATA:
snprintf(buff, sizeof(buff), "%02X",
gnData.header.force_node);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
gnData.header.sense_node);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
gnData.ftsd_lp_timer_cal0);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
gnData.ftsd_lp_timer_cal1);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
gnData.ftsd_lp_timer_cal2);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
gnData.ftsd_lp_timer_cal3);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
gnData.ftsa_lp_timer_cal0);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
gnData.ftsa_lp_timer_cal1);
strlcat(all_strbuff, buff, size);
break;
case CMD_GETFWVER:
snprintf(buff, sizeof(buff), "%04X", fw_version);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%04X", config_id);
strlcat(all_strbuff, buff, size);
break;
case CMD_READCOMPDATAHEAD:
snprintf(buff, sizeof(buff), "%02X",
dataHead.force_node);
strlcat(all_strbuff, buff, size);
snprintf(buff, sizeof(buff), "%02X",
dataHead.sense_node);
strlcat(all_strbuff, buff, size);
break;
default:
break;
}
}
snprintf(buff, sizeof(buff), "%02X", 0xBB);
strlcat(all_strbuff, buff, size);
count = snprintf(buf, TSP_BUF_SIZE, "%s\n", all_strbuff);
numberParam = 0;
/**
* need to reset the number of parameters
* in order to wait the next command,
* comment if you want to repeat
* the last command sent just doing a cat
*/
kfree(readData);
kfree(all_strbuff);
return count;
}
static DEVICE_ATTR(stm_driver_test, 0664, stm_driver_test_show,
stm_driver_test_store);
static struct attribute *test_cmd_attributes[] = {
&dev_attr_stm_driver_test.attr,
NULL,
};
struct attribute_group test_cmd_attr_group = {
.attrs = test_cmd_attributes,
};
#endif