OSDN Git Service

input: touchscreen: Add fw_name sysfs entry in Goodix driver
authorShantanu Jain <shjain@codeaurora.org>
Tue, 8 Oct 2013 08:32:40 +0000 (14:02 +0530)
committerGerrit - the friendly Code Review server <code-review@localhost>
Tue, 20 Sep 2016 11:25:22 +0000 (04:25 -0700)
Add fw_name sysfs entry in Goodix driver. This entry allows
user to read and write firmware name from sysfs.

Change-Id: I69585d757f1a6dc40834a99ee67c872bf6f3ea13
Signed-off-by: Shantanu Jain <shjain@codeaurora.org>
Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
drivers/input/touchscreen/gt9xx/gt9xx.c
drivers/input/touchscreen/gt9xx/gt9xx.h

index 4de2294..9c9f59c 100644 (file)
@@ -55,6 +55,7 @@ Optional properties:
                                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 {
@@ -89,5 +90,6 @@ i2c@f9927000 {
                                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";
                };
 };
index ba31da2..b285dcd 100644 (file)
@@ -1031,9 +1031,7 @@ static int gtp_check_product_id(struct i2c_client *client)
 
        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;
 
@@ -1466,6 +1464,50 @@ static int goodix_power_deinit(struct goodix_ts_data *ts)
        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)
 {
@@ -1542,8 +1584,17 @@ static int goodix_parse_dt(struct device *dev,
 
        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) {
@@ -1677,12 +1728,16 @@ static int goodix_ts_probe(struct i2c_client *client,
                goto exit_power_off;
        }
 
+       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
 
@@ -1699,6 +1754,7 @@ static int goodix_ts_probe(struct i2c_client *client,
                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;
@@ -1742,6 +1798,12 @@ static int goodix_ts_probe(struct i2c_client *client,
 #if GTP_ESD_PROTECT
        gtp_esd_switch(client, SWITCH_ON);
 #endif
+       ret = sysfs_create_group(&client->dev.kobj, &gtp_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:
@@ -1793,6 +1855,8 @@ static int goodix_ts_remove(struct i2c_client *client)
 {
        struct goodix_ts_data *ts = i2c_get_clientdata(client);
 
+       sysfs_remove_group(&ts->input_dev->dev.kobj, &gtp_attr_grp);
+
 #if defined(CONFIG_FB)
        if (fb_unregister_client(&ts->fb_notif))
                dev_err(&client->dev,
index e721a45..b1b62e2 100644 (file)
 #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;
@@ -70,6 +73,7 @@ struct goodix_ts_data {
        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;