summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMao Li <maol@codeaurora.org>2014-04-08 19:58:04 +0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-08-21 21:41:58 -0700
commit405643a77ee764fa0dddacaa9dc4b50b76794c5f (patch)
tree767b59c78164799a9b7015060648fd8f7ebc3537
parentfa14a65666673b967f88b33f744c87f40a76256d (diff)
input: ft5x06_ts: check vendor id before upgrade FT firmware
Upgrade the firmware only if same vendor id is found both in existing fw and new fw to be upgraded. This patch is propagated from 3.18 kernel 'commit dba19fc86781 ("input: ft5x06_ts: check vendor id before upgrade FT firmware")' Change-Id: Idfc50da45891a1475ac6b35d80c7d725607cbf81 Signed-off-by: Mao Li <maol@codeaurora.org>
-rw-r--r--drivers/input/touchscreen/ft5x06_ts.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
index 010da1bdcce1..0f74e10a0bbc 100644
--- a/drivers/input/touchscreen/ft5x06_ts.c
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -65,6 +65,7 @@
#define FT_REG_ID 0xA3
#define FT_REG_PMODE 0xA5
#define FT_REG_FW_VER 0xA6
+#define FT_REG_FW_VENDOR_ID 0xA8
#define FT_REG_POINT_RATE 0x88
#define FT_REG_THGROUP 0x80
#define FT_REG_ECC 0xCC
@@ -115,6 +116,7 @@
#define FT_FW_FILE_MAJ_VER(x) ((x)->data[(x)->size - 2])
#define FT_FW_FILE_MIN_VER(x) 0
#define FT_FW_FILE_SUB_MIN_VER(x) 0
+#define FT_FW_FILE_VENDOR_ID(x) ((x)->data[(x)->size - 1])
#define FT_FW_FILE_MAJ_VER_FT6X36(x) ((x)->data[0x10a])
#define FT_FW_FILE_VENDOR_ID_FT6X36(x) ((x)->data[0x108])
@@ -213,6 +215,7 @@ struct ft5x06_ts_data {
u8 *tch_data;
u32 tch_data_len;
u8 fw_ver[3];
+ u8 fw_vendor_id;
#if defined(CONFIG_FB)
struct notifier_block fb_notif;
#elif defined(CONFIG_HAS_EARLYSUSPEND)
@@ -295,6 +298,18 @@ static int ft5x0x_read_reg(struct i2c_client *client, u8 addr, u8 *val)
return ft5x06_i2c_read(client, &addr, 1, val, 1);
}
+static void ft5x06_update_fw_vendor_id(struct ft5x06_ts_data *data)
+{
+ struct i2c_client *client = data->client;
+ u8 reg_addr;
+ int err;
+
+ reg_addr = FT_REG_FW_VENDOR_ID;
+ err = ft5x06_i2c_read(client, &reg_addr, 1, &data->fw_vendor_id, 1);
+ if (err < 0)
+ dev_err(&client->dev, "fw vendor id read failed");
+}
+
static void ft5x06_update_fw_ver(struct ft5x06_ts_data *data)
{
struct i2c_client *client = data->client;
@@ -903,7 +918,7 @@ static int ft5x06_fw_upgrade(struct device *dev, bool force)
struct ft5x06_ts_data *data = dev_get_drvdata(dev);
const struct firmware *fw = NULL;
int rc;
- u8 fw_file_maj, fw_file_min, fw_file_sub_min;
+ u8 fw_file_maj, fw_file_min, fw_file_sub_min, fw_file_vendor_id;
bool fw_upgrade = false;
if (data->suspended) {
@@ -933,6 +948,7 @@ static int ft5x06_fw_upgrade(struct device *dev, bool force)
}
fw_file_min = FT_FW_FILE_MIN_VER(fw);
fw_file_sub_min = FT_FW_FILE_SUB_MIN_VER(fw);
+ fw_file_vendor_id = FT_FW_FILE_VENDOR_ID(fw);
dev_info(dev, "Current firmware: %d.%d.%d", data->fw_ver[0],
data->fw_ver[1], data->fw_ver[2]);
@@ -941,7 +957,8 @@ static int ft5x06_fw_upgrade(struct device *dev, bool force)
if (force)
fw_upgrade = true;
- else if (data->fw_ver[0] < fw_file_maj)
+ else if ((data->fw_ver[0] < fw_file_maj) &&
+ data->fw_vendor_id == fw_file_vendor_id)
fw_upgrade = true;
if (!fw_upgrade) {
@@ -1661,6 +1678,7 @@ static int ft5x06_ts_probe(struct i2c_client *client,
dev_dbg(&client->dev, "touch threshold = %d\n", reg_value * 4);
ft5x06_update_fw_ver(data);
+ ft5x06_update_fw_vendor_id(data);
FT_STORE_TS_INFO(data->ts_info, data->family_id, data->pdata->name,
data->pdata->num_max_touches, data->pdata->group_id,