diff options
| author | Shantanu Jain <shjain@codeaurora.org> | 2013-11-19 09:52:24 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-10-20 04:46:27 -0700 |
| commit | 52bf9de85b71d0cd8b3a355e5d991997be21ee7a (patch) | |
| tree | 48db6b0d71161cd64eaa125bd5c7f45c3932ea69 | |
| parent | 0647a86f8f6a329bac516bfa9ef28b5822ff4b1c (diff) | |
input: touchscreen: Add firmware upgrade via sysfs entry
Add sysfs entry for firmware upgrade support in Goodix
driver.
Change-Id: If71d4020223547e0db425c9fd37819c6166efcab
Signed-off-by: Shantanu Jain <shjain@codeaurora.org>
| -rw-r--r-- | drivers/input/touchscreen/gt9xx/gt9xx.c | 80 | ||||
| -rw-r--r-- | drivers/input/touchscreen/gt9xx/gt9xx.h | 5 |
2 files changed, 70 insertions, 15 deletions
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c index c870df328923..9c506efb679d 100644 --- a/drivers/input/touchscreen/gt9xx/gt9xx.c +++ b/drivers/input/touchscreen/gt9xx/gt9xx.c @@ -1523,12 +1523,63 @@ static ssize_t gtp_fw_name_store(struct device *dev, return size; } +static ssize_t gtp_fw_upgrade_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct goodix_ts_data *ts = dev_get_drvdata(dev); + + return snprintf(buf, 2, "%d\n", ts->fw_loading); +} + +static ssize_t gtp_fw_upgrade_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct goodix_ts_data *ts = dev_get_drvdata(dev); + unsigned long val; + int ret; + + if (size > 2) + return -EINVAL; + + ret = kstrtoul(buf, 10, &val); + if (ret != 0) + return ret; + + if (ts->gtp_is_suspend) { + dev_err(&ts->client->dev, + "Can't start fw upgrade. Device is in suspend state"); + return -EBUSY; + } + + mutex_lock(&ts->input_dev->mutex); + if (!ts->fw_loading && val) { + disable_irq(ts->client->irq); + ts->fw_loading = true; + if (config_enabled(CONFIG_GT9XX_TOUCHPANEL_UPDATE)) { + ret = gup_update_proc(NULL); + if (ret == FAIL) + dev_err(&ts->client->dev, + "Fail to update GTP firmware\n"); + } + ts->fw_loading = false; + enable_irq(ts->client->irq); + } + mutex_unlock(&ts->input_dev->mutex); + + return size; +} + static DEVICE_ATTR(fw_name, (S_IRUGO | S_IWUSR | S_IWGRP), gtp_fw_name_show, gtp_fw_name_store); +static DEVICE_ATTR(fw_upgrade, (S_IRUGO | S_IWUSR | S_IWGRP), + gtp_fw_upgrade_show, + gtp_fw_upgrade_store); static struct attribute *gtp_attrs[] = { &dev_attr_fw_name.attr, + &dev_attr_fw_upgrade.attr, NULL }; @@ -1861,9 +1912,7 @@ static int goodix_ts_probe(struct i2c_client *client, return -EINVAL; } -#if GTP_ESD_PROTECT i2c_connect_client = client; -#endif if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "GTP I2C not supported\n"); @@ -1915,18 +1964,17 @@ static int goodix_ts_probe(struct i2c_client *client, strlcpy(ts->fw_name, pdata->fw_name, strlen(pdata->fw_name) + 1); -#ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE - ret = gup_init_update_proc(ts); - if (ret < 0) { - dev_err(&client->dev, - "GTP Create firmware update thread error.\n"); - goto exit_power_off; + if (config_enabled(CONFIG_GT9XX_TOUCHPANEL_UPDATE)) { + ret = gup_init_update_proc(ts); + if (ret < 0) { + dev_err(&client->dev, + "GTP Create firmware update thread error\n"); + goto exit_power_off; + } } -#endif - ret = gtp_init_panel(ts); if (ret < 0) { - dev_err(&client->dev, "GTP init panel failed.\n"); + dev_err(&client->dev, "GTP init panel failed\n"); ts->abs_x_max = GTP_MAX_WIDTH; ts->abs_y_max = GTP_MAX_HEIGHT; ts->int_trigger_type = GTP_INT_TRIGGER; @@ -1934,7 +1982,7 @@ static int goodix_ts_probe(struct i2c_client *client, ret = gtp_request_input_dev(ts); if (ret) { - dev_err(&client->dev, "GTP request input dev failed.\n"); + dev_err(&client->dev, "GTP request input dev failed\n"); goto exit_free_inputdev; } input_set_drvdata(ts->input_dev, ts); @@ -2117,6 +2165,14 @@ static int goodix_ts_suspend(struct device *dev) } mutex_lock(&ts->lock); + + if (ts->fw_loading) { + dev_info(&ts->client->dev, + "Fw upgrade in progress, can't go to suspend."); + mutex_unlock(&ts->lock); + return 0; + } + #if GTP_ESD_PROTECT gtp_esd_switch(ts->client, SWITCH_OFF); #endif diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h index 31b078ba4688..36d09755b1af 100644 --- a/drivers/input/touchscreen/gt9xx/gt9xx.h +++ b/drivers/input/touchscreen/gt9xx/gt9xx.h @@ -89,6 +89,7 @@ struct goodix_ts_data { u8 fw_error; bool power_on; struct mutex lock; + bool fw_loading; struct regulator *avdd; struct regulator *vdd; struct regulator *vcc_i2c; @@ -213,11 +214,9 @@ s32 init_wr_node(struct i2c_client *client); void uninit_wr_node(void); #endif -#ifdef CONFIG_GT9XX_TOUCHPANEL_UPDATE -extern u8 gup_init_update_proc(struct goodix_ts_data *ts); +u8 gup_init_update_proc(struct goodix_ts_data *ts); s32 gup_enter_update_mode(struct i2c_client *client); void gup_leave_update_mode(struct i2c_client *client); s32 gup_update_proc(void *dir); extern struct i2c_client *i2c_connect_client; -#endif #endif /* _GOODIX_GT9XX_H_ */ |
