mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
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:
parent
67a83c3bef
commit
bcc68f6a8a
1 changed files with 515 additions and 19 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue