Input: goodix - restore config on resume if necessary
authorHans de Goede <hdegoede@redhat.com>
Tue, 24 Mar 2020 18:34:11 +0000 (11:34 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 24 Mar 2020 22:07:58 +0000 (15:07 -0700)
Some devices, e.g the Trekstor Primetab S11B, lose there config over
a suspend/resume cycle (likely the controller loses power during suspend).

This commit reads back the config version on resume and if matches the
expected config version it resets the controller and resends the config
we read back and saved at probe time.

BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20200307121505.3707-11-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/touchscreen/goodix.c

index 958a5d65e374407c3b67c0e390bd4547d79e882a..7811500ba3b55b8eb88b7409a173eaafbe176c0a 100644 (file)
@@ -1268,6 +1268,7 @@ static int __maybe_unused goodix_resume(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct goodix_ts_data *ts = i2c_get_clientdata(client);
+       u8 config_ver;
        int error;
 
        if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
@@ -1289,6 +1290,27 @@ static int __maybe_unused goodix_resume(struct device *dev)
        if (error)
                return error;
 
+       error = goodix_i2c_read(ts->client, ts->chip->config_addr,
+                               &config_ver, 1);
+       if (error)
+               dev_warn(dev, "Error reading config version: %d, resetting controller\n",
+                        error);
+       else if (config_ver != ts->config[0])
+               dev_info(dev, "Config version mismatch %d != %d, resetting controller\n",
+                        config_ver, ts->config[0]);
+
+       if (error != 0 || config_ver != ts->config[0]) {
+               error = goodix_reset(ts);
+               if (error) {
+                       dev_err(dev, "Controller reset failed.\n");
+                       return error;
+               }
+
+               error = goodix_send_cfg(ts, ts->config, ts->chip->config_len);
+               if (error)
+                       return error;
+       }
+
        error = goodix_request_irq(ts);
        if (error)
                return error;