input: touchscreen: Add fw_name sysfs entry in Goodix driver
Add fw_name sysfs entry in Goodix driver. This entry allows
user to read and write firmware name from sysfs.
CRs-fixed: 555332
Change-Id: I69585d757f1a6dc40834a99ee67c872bf6f3ea13
Signed-off-by: Shantanu Jain <shjain@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
index fdba7c2..af35e77 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
@@ -50,6 +50,7 @@
to provide that.
- goodix,cfg-data5 : Touch screen controller config data group 5. Ask vendor
to provide that.
+ - goodix,fw-name : Touch screen controller firmware file name.
Example:
i2c@f9927000 {
goodix@5d {
@@ -84,5 +85,6 @@
20 21 22 24 26 28 29 2A FF FF
FF FF FF FF FF FF FF 22 22 22
22 22 22 FF 07 01];
+ goodix,fw_name = "gtp_fw.bin";
};
};
diff --git a/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi b/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
index 66f5095..76bd262 100755
--- a/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd-skuf.dtsi
@@ -124,6 +124,7 @@
20 21 22 24 26 28 29 2A FF FF
FF FF FF FF FF FF FF FF FF FF
FF FF FF FF 3E 01];
+ goodix,fw_name = "gtp_fw.bin";
};
};
};
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index 8b08ac9..a7b6d05 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -1055,9 +1055,7 @@
dev_info(&client->dev, "Goodix Product ID = %s\n", product_id);
- if (!IS_ERR(ts->pdata->product_id))
- ret = strcmp(product_id, ts->pdata->product_id);
-
+ ret = strcmp(product_id, ts->pdata->product_id);
if (ret != 0)
return -EINVAL;
@@ -1473,6 +1471,50 @@
return 0;
}
+static ssize_t gtp_fw_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct goodix_ts_data *ts = dev_get_drvdata(dev);
+
+ if (!strlen(ts->fw_name))
+ return snprintf(buf, GTP_FW_NAME_MAXSIZE - 1,
+ "No fw name has been given.");
+ else
+ return snprintf(buf, GTP_FW_NAME_MAXSIZE - 1,
+ "%s\n", ts->fw_name);
+}
+
+static ssize_t gtp_fw_name_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct goodix_ts_data *ts = dev_get_drvdata(dev);
+
+ if (size > GTP_FW_NAME_MAXSIZE - 1) {
+ dev_err(dev, "FW name size exceeds the limit.");
+ return -EINVAL;
+ }
+
+ strlcpy(ts->fw_name, buf, size);
+ if (ts->fw_name[size-1] == '\n')
+ ts->fw_name[size-1] = '\0';
+
+ return size;
+}
+
+static DEVICE_ATTR(fw_name, (S_IRUGO | S_IWUSR | S_IWGRP),
+ gtp_fw_name_show,
+ gtp_fw_name_store);
+
+static struct attribute *gtp_attrs[] = {
+ &dev_attr_fw_name.attr,
+ NULL
+};
+
+static const struct attribute_group gtp_attr_grp = {
+ .attrs = gtp_attrs,
+};
+
static int goodix_ts_get_dt_coords(struct device *dev, char *name,
struct goodix_ts_platform_data *pdata)
{
@@ -1549,8 +1591,17 @@
rc = of_property_read_string(np, "goodix,product-id",
&pdata->product_id);
- if (rc < 0 || strlen(pdata->product_id) > GTP_PRODUCT_ID_MAXSIZE)
- return rc;
+ if (rc && (rc != -EINVAL)) {
+ dev_err(dev, "Failed to parse product_id.");
+ return -EINVAL;
+ }
+
+ rc = of_property_read_string(np, "goodix,fw_name",
+ &pdata->fw_name);
+ if (rc && (rc != -EINVAL)) {
+ dev_err(dev, "Failed to parse firmware name.\n");
+ return -EINVAL;
+ }
prop = of_find_property(np, "goodix,button-map", NULL);
if (prop) {
@@ -1689,12 +1740,16 @@
goto exit_free_io_port;
}
+ if (pdata->fw_name)
+ strlcpy(ts->fw_name, pdata->fw_name,
+ strlen(pdata->fw_name) + 1);
+
#if GTP_AUTO_UPDATE
ret = gup_init_update_proc(ts);
if (ret < 0) {
dev_err(&client->dev,
"GTP Create firmware update thread error.\n");
- goto exit_free_io_port;
+ goto exit_power_off;
}
#endif
@@ -1711,6 +1766,7 @@
dev_err(&client->dev, "GTP request input dev failed.\n");
goto exit_free_inputdev;
}
+ input_set_drvdata(ts->input_dev, ts);
#if defined(CONFIG_FB)
ts->fb_notif.notifier_call = fb_notifier_callback;
@@ -1754,6 +1810,12 @@
#if GTP_ESD_PROTECT
gtp_esd_switch(client, SWITCH_ON);
#endif
+ ret = sysfs_create_group(&client->dev.kobj, >p_attr_grp);
+ if (ret < 0) {
+ dev_err(&client->dev, "sys file creation failed.\n");
+ goto exit_free_irq;
+ }
+
init_done = true;
return 0;
exit_free_irq:
@@ -1806,6 +1868,8 @@
{
struct goodix_ts_data *ts = i2c_get_clientdata(client);
+ sysfs_remove_group(&ts->input_dev->dev.kobj, >p_attr_grp);
+
#if defined(CONFIG_FB)
if (fb_unregister_client(&ts->fb_notif))
dev_err(&client->dev,
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h
index 1fdbfa3..5256c7f 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.h
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.h
@@ -46,12 +46,15 @@
#endif
#define GOODIX_MAX_CFG_GROUP 6
+#define GTP_FW_NAME_MAXSIZE 50
+
struct goodix_ts_platform_data {
int irq_gpio;
u32 irq_gpio_flags;
int reset_gpio;
u32 reset_gpio_flags;
const char *product_id;
+ const char *fw_name;
u32 x_max;
u32 y_max;
u32 x_min;
@@ -73,6 +76,7 @@
struct hrtimer timer;
struct workqueue_struct *goodix_wq;
struct work_struct work;
+ char fw_name[GTP_FW_NAME_MAXSIZE];
s32 irq_is_disabled;
s32 use_irq;
u16 abs_x_max;