pct1812_mmi: firmware upgrade

Added code to support FW upgrade. This code has not been tested yet

Change-Id: I677f0cc6f722515681608581afc9bff650e8a46d
Signed-off-by: Konstantin Makariev <hcv867@motorola.com>
Reviewed-on: https://gerrit.mot.com/2010238
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:
Konstantin Makariev 2021-07-12 20:22:00 -05:00 • committed by Konstantin Makariev
commit bcc68f6a8a

View file

@ -37,14 +37,35 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include <linux/workqueue.h>
#include <linux/kfifo.h>
#define AREAD (1)
#define AWRITE (0)
#define INVALID_BYTE2 0xebeb
#define INVALID_BYTE 0xeb
#define ADDRESS_FW 0x00
#define ADDRESS_PARAMS 0xe0
#define SUPPORTED_FW_FILE_SIZE 0x0000F000
#define FW_SECTION_SIZE 0x0000E000
#define PCT1812_SECTOR_SIZE (0x1000) // 4K
#define CHUNK_SZ 256
#define FW_ADDR_BASE 0x00
#define PARAM_ADDR_BASE 0xe0
#define POWERUP_CODE 0x02
#define RESET_CODE 0xaa
#define RESUME_CODE 0xbb
#define ENGINEERING_CODE 0xcc
#define SUSPEND_CODE 0x99
#define FRAME_NUM_REG 0x00
@ -55,10 +76,30 @@
#define STATUS_REG 0x71
#define USER_BANK_REG 0x73
#define USER_ADDR_REG 0x74
#define USER_DAA_REG 0x75
#define USER_DATA_REG 0x75
#define SW_RESET_REG 0x7a
#define DEEP_SLEEP_REG 0x7c
#define BANK(a) (a)
#define KEYS_NUM 8
// USER BANK 0
#define VER_LOW_REG 0x7e
#define VER_HIGH_REG 0x7f
// USER BANK 1
#define FLASH_PUP_REG 0x0d
#define KEY1_REG 0x2c
#define KEY2_REG 0x2d
// USER BANK 3
#define FUNCT_CTRL_REG 0x02
#define KEYS_NUM_REG 0x1a
#define KEY_THRES_BASE 0x00
// USER BANK 4
#define FLASH_STATUS_REG 0x1c
#define FLASH_ADDR0_REG 0x24
#define FLASH_ADDR1_REG 0x25
#define FLASH_ADDR2_REG 0x26
#define STAT_BIT_ERR (1 << 0)
#define STAT_BIT_EVENT (1 << 3)
#define STAT_BIT_WDOG (1 << 7)
@ -96,6 +137,17 @@ enum cmds {
CMD_WDOG
};
enum gestures {
GEST_TAP = 2,
GEST_DBL_TAP,
GEST_VERT_SCROLL = 7,
GEST_HORIZ_SCROLL,
GEST_UP_SWIPE = 17,
GEST_DWN_SWIPE,
GEST_LFT_SWIPE,
GEST_RGHT_SWIPE
};
struct pct1812_platform {
int max_x;
int max_y;
@ -133,6 +185,10 @@ struct pct1812_data {
struct pinctrl *ts_pinctrl;
struct pinctrl_state *pinctrl_state_active;
struct pinctrl_state *pinctrl_state_suspend;
unsigned short version;
unsigned char func_ctrl;
unsigned char keys;
};
#if 0
static int inline get_cmd(void)
@ -298,11 +354,11 @@ static int pct1812_parse_dt(struct i2c_client *client)
}
if (of_property_read_string(np, "pct1812,regulator_vio", &pdata->vio)) {
dev_err(dev, "%s: Failed to get VIO name property\n", __func__);
return -EINVAL;
dev_warn(dev, "%s: Failed to get VIO name property\n", __func__);
//return -EINVAL;
}
pdata->irq_gpio = of_get_named_gpio(np, "pct1812,irq_gpio", 0);
pdata->irq_gpio = of_get_named_gpio(np, "pct1812,irq-gpio", 0);
if (gpio_is_valid(pdata->irq_gpio)) {
ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "pct1812,irq");
if (ret) {
@ -315,7 +371,7 @@ static int pct1812_parse_dt(struct i2c_client *client)
return -EINVAL;
}
#if 0
pdata->rst_gpio = of_get_named_gpio(np, "pct1812,rst_gpio", 0);
pdata->rst_gpio = of_get_named_gpio(np, "pct1812,reset-gpio", 0);
if (gpio_is_valid(pdata->rst_gpio)) {
ret = gpio_request_one(pdata->rst_gpio, GPIOF_DIR_OUT, "pct1812,reset");
if (ret) {
@ -337,6 +393,29 @@ static int pct1812_parse_dt(struct i2c_client *client)
}
static int pct1812_read_touch_event(struct pct1812_data *ts)
{
unsigned char gest, gdata[2];
int ret;
ret = pct1812_i2c_read(ts, GEST_TYPE_REG, &gest, sizeof(gest));
if (ret)
return -EIO;
pr_debug("gesture 0x%02x\n", gest);
switch(gest & 0x1f) {
case GEST_HORIZ_SCROLL:
case GEST_VERT_SCROLL:
ret = pct1812_i2c_read(ts, GEST_X0_REG, gdata, sizeof(gdata));
pr_debug("X0: 0x%04x\n", (gdata[1] << 8) | gdata[0]);
break;
case GEST_TAP:
case GEST_DBL_TAP:
case GEST_UP_SWIPE:
case GEST_DWN_SWIPE:
case GEST_LFT_SWIPE:
case GEST_RGHT_SWIPE:
break;
default: return -EINVAL;
}
return 0;
}
@ -364,6 +443,407 @@ static irqreturn_t pct1812_irq_handler(int irq, void *ptr)
return IRQ_HANDLED;
}
static int pct1812_user_access(struct pct1812_data *ts,
unsigned char bank, unsigned char addr,
unsigned char *value, unsigned int size, bool R)
{
unsigned char val;
int ret;
pr_debug("Access %c: b%d:0x%02x val 0x%02x\n",
R ? 'R' : 'W', bank, addr, R ? 0 : *value);
ret = pct1812_i2c_write(ts, USER_BANK_REG, &bank, sizeof(bank));
if (ret)
return -EIO;
ret = pct1812_i2c_write(ts, USER_ADDR_REG, &addr, sizeof(addr));
if (ret)
return -EIO;
if (R) { // read access
if (value)
*value = 0;
ret = pct1812_i2c_read(ts, USER_DATA_REG, &val, sizeof(val));
if (!ret && value)
*value = val;
} else {
ret = pct1812_i2c_write(ts, USER_DATA_REG, value, size);
}
return ret;
}
static int pct1812_get_extinfo(struct pct1812_data *ts)
{
unsigned char val;
unsigned char t_addr;
unsigned short tk1, tk2, version = 0;
int i, ret;
ts->version = INVALID_BYTE2;
ret = pct1812_user_access(ts, BANK(0), VER_LOW_REG, &val, sizeof(val), AREAD);
if (!ret)
version |= val;
ret = pct1812_user_access(ts, BANK(0), VER_HIGH_REG, &val, sizeof(val), AREAD);
if (!ret)
version |= (val << 8);
ts->version = version;
dev_info(ts->dev, "%s: FW version 0x%04x\n", __func__, ts->version);
ts->func_ctrl = INVALID_BYTE;
ret = pct1812_user_access(ts, BANK(3), FUNCT_CTRL_REG, &val, sizeof(val), AREAD);
if (!ret)
ts->func_ctrl = val;
if (ts->func_ctrl != INVALID_BYTE)
dev_info(ts->dev, "%s: Func CTRL 0x%02x\n", __func__, ts->func_ctrl);
ts->keys = INVALID_BYTE;
ret = pct1812_user_access(ts, BANK(3), KEYS_NUM_REG, &val, sizeof(val), AREAD);
if (!ret)
ts->keys = val;
if (ts->keys != INVALID_BYTE)
dev_info(ts->dev, "%s: Keys supported %d\n", __func__, ts->keys);
t_addr = KEY_THRES_BASE;
for (i = 0; i < KEYS_NUM; i++) {
tk1 = 0;
ret = pct1812_user_access(ts, BANK(3), t_addr++, &val, sizeof(val), AREAD);
if (!ret)
tk1 |= val;
ret = pct1812_user_access(ts, BANK(3), t_addr++, &val, sizeof(val), AREAD);
if (!ret)
tk1 |= (val << 8);
tk2 = 0;
ret = pct1812_user_access(ts, BANK(3), t_addr++, &val, sizeof(val), AREAD);
if (!ret)
tk2 |= val;
ret = pct1812_user_access(ts, BANK(3), t_addr++, &val, sizeof(val), AREAD);
if (!ret)
tk2 |= (val << 8);
if (!ret)
pr_debug("Key[%i] THRESHOLD: TK1 = 0x%04x, TK2 = 0x%04x\n", i, tk1, tk2);
}
return ret;
}
static int inline pct1812_engmode(struct pct1812_data *ts, bool on)
{
unsigned char value;
int ret;
value = RESET_CODE;
ret = pct1812_user_access(ts, BANK(1), KEY1_REG, &value, sizeof(value), AWRITE);
if (ret)
return -EIO;
value = on ? ENGINEERING_CODE : RESUME_CODE;
ret = pct1812_user_access(ts, BANK(1), KEY2_REG, &value, sizeof(value), AWRITE);
if (ret)
return -EIO;
pct1812_delay_ms(2);
return 0;
}
static int pct1812_flash_exec(struct pct1812_data *ts,
unsigned char cmd, unsigned char flash_cmd, int cnt)
{
unsigned char lval;
int repetition = 0;
int ret, step = 0;
lval = 0;
ret = pct1812_user_access(ts, BANK(4), 0x2c, &lval, sizeof(lval), AWRITE);
if (ret)
goto error;
step++;
lval = flash_cmd;
ret = pct1812_user_access(ts, BANK(4), 0x20, &lval, sizeof(lval), AWRITE);
if (ret)
goto error;
step++;
lval = cnt & 0xff;
ret = pct1812_user_access(ts, BANK(4), 0x22, &lval, sizeof(lval), AWRITE);
if (ret)
goto error;
step++;
lval = (cnt >> 8) & 0xff;
ret = pct1812_user_access(ts, BANK(4), 0x23, &lval, sizeof(lval), AWRITE);
if (ret)
goto error;
step++;
do_again:
lval = 0;
ret = pct1812_user_access(ts, BANK(4), 0x2c, &lval, sizeof(lval), AREAD);
if (ret)
goto error;
if ((lval & cmd) != 0) {
repetition++;
if (repetition%11)
pr_debug("Still waiting ... %d\n", repetition);
goto do_again;
}
return 0;
error:
dev_err(ts->dev,
"Error exec cmd 0x%02x, flash_cmd 0x%02x, cnt %d (stage %d, reps %d)\n",
__func__, cmd, flash_cmd, cnt, step, repetition);
return -EIO;
}
static int pct1812_flash_status(struct pct1812_data *ts, int idx, int vok)
{
unsigned char status[2];
int ret;
do_again:
ret = pct1812_flash_exec(ts, 0x08, 0x05, 1);
if (ret) {
dev_err(ts->dev, "Error flash cmd\n", __func__);
return -EIO;
}
ret = pct1812_user_access(ts, BANK(4), FLASH_STATUS_REG, status, sizeof(status), AREAD);
if (ret) {
dev_err(ts->dev, "Error reading flash status\n", __func__);
return -EIO;
}
if (status[idx] != vok) {
pct1812_delay_ms(1); // adjust delay if necessary
goto do_again;
}
pr_debug("Flash status ([%d]=%d) OK\n", idx, vok);
return 0;
}
static int pct1812_flash_chunk(struct pct1812_data *ts, unsigned int address)
{
int ret, step = 0;
unsigned char value;
// Flash WriteEnable
ret = pct1812_flash_exec(ts, 0x02, 0x09, 0);
if (ret)
goto error;
step++;
// check status
ret = pct1812_flash_status(ts, 1, 1);
if (ret)
goto error;
step++;
value = (unsigned char)(address & 0xff);
ret = pct1812_user_access(ts, BANK(4), FLASH_ADDR0_REG, &value, sizeof(value), AWRITE);
if (ret)
goto error;
step++;
value = (unsigned char)((address >> 8) & 0xff);
ret = pct1812_user_access(ts, BANK(4), FLASH_ADDR1_REG, &value, sizeof(value), AWRITE);
if (ret)
goto error;
step++;
value = (unsigned char)((address >> 16) & 0xff);
ret = pct1812_user_access(ts, BANK(4), FLASH_ADDR2_REG, &value, sizeof(value), AWRITE);
if (ret)
goto error;
step++;
ret = pct1812_flash_exec(ts, 0x81, 0x02, CHUNK_SZ);
if (ret)
goto error;
step++;
// wait for completion
ret = pct1812_flash_status(ts, 0, 0);
if (ret)
goto error;
return 0;
error:
dev_err(ts->dev, "Error erasing address 0x%06x (stage %d)\n",
__func__, address, step);
return -EIO;
}
static int pct1812_erase_sector(struct pct1812_data *ts, unsigned int address)
{
int ret, step = 0;
unsigned char value;
pr_debug("Erasing sector at address 0x%06x\n", address);
// Flash WriteEnable
ret = pct1812_flash_exec(ts, 0x02, 0x09, 0);
if (ret)
goto error;
step++;
// check status
ret = pct1812_flash_status(ts, 1, 1);
if (ret)
goto error;
step++;
value = (unsigned char)(address & 0xff);
ret = pct1812_user_access(ts, BANK(4), FLASH_ADDR0_REG, &value, sizeof(value), AWRITE);
if (ret)
goto error;
step++;
value = (unsigned char)((address >> 8) & 0xff);
ret = pct1812_user_access(ts, BANK(4), FLASH_ADDR1_REG, &value, sizeof(value), AWRITE);
if (ret)
goto error;
step++;
value = (unsigned char)((address >> 16) & 0xff);
ret = pct1812_user_access(ts, BANK(4), FLASH_ADDR2_REG, &value, sizeof(value), AWRITE);
if (ret)
goto error;
step++;
ret = pct1812_flash_exec(ts, 0x02, 0x20, 3);
if (ret)
goto error;
step++;
// wait for completion
ret = pct1812_flash_status(ts, 0, 0);
if (ret)
goto error;
return 0;
error:
dev_err(ts->dev, "Error erasing address 0x%06x (stage %d)\n",
__func__, address, step);
return -EIO;
}
static int pct1812_flash_section(struct pct1812_data *ts, unsigned char *data,
unsigned int size, unsigned int address)
{
int m, ret;
unsigned int num_of_sectors = size / PCT1812_SECTOR_SIZE;
unsigned int target_num = size / CHUNK_SZ;
unsigned char value;
unsigned char *ptr = data;
for (m = 0; m < num_of_sectors; m++) {
ret = pct1812_erase_sector(ts, address + PCT1812_SECTOR_SIZE * m);
if (ret)
goto error;
pr_debug("Erased sector %d of %d\n", m + 1, num_of_sectors);
}
for (m = 0; m < target_num; m++) {
// Set SRAM select
value = 0x08;
ret = pct1812_user_access(ts, BANK(2), 0x09, &value, sizeof(value), AWRITE);
if (ret)
goto error;
// Set SRAM NSC to 0
value = 0x00;
ret = pct1812_user_access(ts, BANK(2), 0x0a, &value, sizeof(value), AWRITE);
if (ret)
goto error;
// Write data to SRAM port
ret = pct1812_user_access(ts, BANK(2), 0x0b, ptr, CHUNK_SZ, AWRITE);
if (ret)
goto error;
// Set SRAM NSC to 1
value = 0x01;
ret = pct1812_user_access(ts, BANK(2), 0x0a, &value, sizeof(value), AWRITE);
if (ret)
goto error;
// advance data pointer
ptr += CHUNK_SZ;
pr_debug("Flashing chunk @0x%04x\n", address);
// Program Flash from SRAM
ret = pct1812_flash_chunk(ts, address);
if (ret)
goto error;
address += CHUNK_SZ;
}
return 0;
error:
dev_err(ts->dev, "Error flashing chunk %d\n", __func__, m);
return -EIO;
}
/*static*/
int pct1812_fw_update(struct pct1812_data *ts, const char *fname)
{
int ret;
unsigned char value;
unsigned char *fwdata_ptr, *fwparam_ptr;
unsigned int fwdata_size, fwparam_size;
const struct firmware *fw_entry = NULL;
//__pm_stay_awake(&ts->wake_src);
mutex_lock(&ts->cmdlock);
pr_debug("Start of FW reflash process\n");
//fwu_irq_enable(fwu, true);
pr_debug("Requesting firmware %s\n", fname);
ret = request_firmware(&fw_entry, fname, ts->dev);
if (ret) {
dev_err(ts->dev, "%s: Error loading firmware %s\n", __func__, fname);
ret = -EINVAL;
goto exit;
}
// FW file size check
if (fw_entry->size != SUPPORTED_FW_FILE_SIZE) {
dev_err(ts->dev, "%s: Firmware %s file size is WRONG!!!\n", __func__, fname);
ret = -EINVAL;
goto exit;
}
fwdata_size = FW_SECTION_SIZE;
fwdata_ptr = (unsigned char *)fw_entry->data;
fwparam_size = SUPPORTED_FW_FILE_SIZE - FW_SECTION_SIZE;
fwparam_ptr = fwdata_ptr + FW_SECTION_SIZE;
ret = pct1812_engmode(ts, true);
if (ret) {
dev_err(ts->dev, "%s: Error entering flash mode\n", __func__);
goto exit;
}
value = POWERUP_CODE;
ret = pct1812_user_access(ts, BANK(1), FLASH_PUP_REG, &value, sizeof(value), AWRITE);
if (ret) {
dev_err(ts->dev, "%s: Error powering flash controller\n", __func__);
goto exit;
}
ret = pct1812_flash_section(ts, fwdata_ptr, fwdata_size, ADDRESS_FW);
if (ret) {
dev_err(ts->dev, "%s: Flash error!!!\n", __func__);
} else {
ret = pct1812_flash_section(ts, fwparam_ptr, fwparam_size, ADDRESS_PARAMS);
if (ret)
dev_err(ts->dev, "%s: Flash error!!!\n", __func__);
}
exit:
ret = pct1812_engmode(ts, false);
if (ret) {
dev_err(ts->dev, "%s: Error leaving flash mode\n", __func__);
}
mutex_unlock(&ts->cmdlock);
//__pm_relax(&ts->wake_src);
return ret;
}
static int pct1812_wait4ready(struct pct1812_data *ts, unsigned char reg, unsigned char vok)
{
unsigned char status = 0;
@ -375,8 +855,12 @@ static int pct1812_wait4ready(struct pct1812_data *ts, unsigned char reg, unsign
break;
pct1812_delay_ms(CMD_WAIT_DELAY);
}
if (ret == CNT_WAIT_RETRY)
if (retry == CNT_WAIT_RETRY)
ret = -ETIME;
else if (!ret) {
pr_debug("success waiting for %d\n", vok);
}
return (status == vok) ? 0 : ret;
}
@ -409,6 +893,8 @@ static int pct1812_regulator(struct pct1812_data *ts, bool get)
ts->reg_vdd = rvdd;
ts->reg_vio = rvio;
pr_debug("vdd=%p, vio=%p\n", rvdd, rvio);
return 0;
}
@ -433,6 +919,9 @@ static int pct1812_pinctrl_state(struct pct1812_data *info, bool on)
if (error < 0)
dev_err(info->dev, "%s: Failed to select %s\n",
__func__, state_name);
else
pr_debug("set pinctrl state %s\n", state_name);
return error;
}
@ -491,7 +980,7 @@ static int pct1812_power(struct pct1812_data *ts, bool on)
regulator_disable(ts->reg_vio);
}
dev_info(ts->dev,"%s: %s: %s:%s\n", __func__, on ? "on" : "off",
dev_info(ts->dev,"%s: power %s: %s:%s\n", __func__, on ? "ON" : "OFF",
pdata->vdd, regulator_is_enabled(ts->reg_vdd) ? "on" : "off");
if (pdata->vio)
dev_info(ts->dev,"%s: %s: %s:%s\n", __func__, on ? "on" : "off",
@ -509,21 +998,27 @@ static int pct1812_power_mode(struct pct1812_data *ts, enum pwr_modes mode)
static int pct1812_run_cmd(struct pct1812_data *ts, enum cmds command)
{
unsigned char code;
const char *action;
int ret, counter = 0;
switch (command) {
case CMD_RESET:
action = "RESET";
code = RESET_CODE;
break;
case CMD_RESUME:
action = "RESUME";
code = RESUME_CODE;
break;
case CMD_SUSPEND:
action = "SUSPEND";
code = SUSPEND_CODE;
break;
default: return -EINVAL;
}
run_once_again:
pr_debug("command: %s\n", action);
ret = pct1812_i2c_write(ts, SW_RESET_REG, &code, sizeof(code));
if (ret) {
dev_err(ts->dev, "%s: Error sending cmd: %d (%d)\n", __func__, command, ret);
@ -532,6 +1027,7 @@ run_once_again:
if (!counter++)
pct1812_delay_ms(10);
if (code == RESET_CODE) {
action = "RESUME";
code = RESUME_CODE;
goto run_once_again;
}
@ -543,6 +1039,8 @@ static int pct1812_queued_resume(struct pct1812_data *ts)
{
int ret;
pr_debug("enter\n");
if (atomic_cmpxchg(&ts->touch_stopped, 1, 0) == 0)
return 0;
@ -559,18 +1057,21 @@ static void pct1812_work(struct work_struct *work)
struct pct1812_data *ts = container_of(work, struct pct1812_data, worker.work);
unsigned char status = 0;
static unsigned char prev;
const char *action;
int cmd, ret;
while (kfifo_get(&ts->cmd_pipe, &cmd)) {
//cmd = get_cmd();
switch (cmd) {
case CMD_WDOG:
action = "WDOG";
ret = pct1812_i2c_read(ts, FRAME_NUM_REG, &status, sizeof(status));
if (ret || (prev == status)) {
dev_warn(ts->dev, "%s: Possible lockup\n", __func__);
}
break;
case CMD_RECOVER:
action = "RECOVER";
ret = pct1812_run_cmd(ts, CMD_RESET);
if (ret) {
dev_err(ts->dev, "%s: Failed to reset\n", __func__);
@ -581,6 +1082,7 @@ static void pct1812_work(struct work_struct *work)
}
break;
case CMD_RESUME:
action = "RESUME";
ret = pct1812_queued_resume(ts);
if (ret)
dev_err(ts->dev, "%s: Failed to resume\n", __func__);
@ -588,6 +1090,8 @@ static void pct1812_work(struct work_struct *work)
}
}
pr_debug("action: %s\n", action);
pct1812_fifo_cmd_add(ts, CMD_WDOG, WDOG_INTERVAL);
}
#if 0
@ -596,6 +1100,8 @@ static int pct1812_suspend(struct device *dev)
struct pct1812_data *ts = dev_get_drvdata(dev);
int ret;
pr_debug("enter\n");
if (atomic_cmpxchg(&ts->touch_stopped, 0, 1) == 1)
return 0;
@ -658,17 +1164,6 @@ static int pct1812_probe(struct i2c_client *client, const struct i2c_device_id *
i2c_set_clientdata(client, ts);
dev_set_drvdata(&client->dev, ts);
pdata->pinctrl = devm_pinctrl_get(&client->dev);
if (IS_ERR(pdata->pinctrl)) {
dev_warn(&client->dev, "%s: no pinctrl found\n", __func__);
} else {
struct pinctrl_state *state;
state = pinctrl_lookup_state(pdata->pinctrl, "on_state");
if (IS_ERR(state))
dev_err(&client->dev, "%s: could not get active pinstate\n", __func__);
}
mutex_init(&ts->i2c_mutex);
mutex_init(&ts->cmdlock);
mutex_init(&ts->eventlock);
@ -688,6 +1183,8 @@ static int pct1812_probe(struct i2c_client *client, const struct i2c_device_id *
goto error_init;
}
pct1812_get_extinfo(ts);
ret = kfifo_alloc(&ts->cmd_pipe, sizeof(unsigned int)* 10, GFP_KERNEL);
if (ret)
goto error_init;
@ -701,7 +1198,6 @@ static int pct1812_probe(struct i2c_client *client, const struct i2c_device_id *
/* prevent unbalanced irq enable */
ts->irq_enabled = true;
dev_info(&client->dev, "%s: done\n", __func__);
pct1812_fifo_cmd_add(ts, CMD_WDOG, WDOG_INTERVAL);