Input: ili210x - probe even if no resolution information
authorMarek Vasut <marex@denx.de>
Sat, 6 May 2023 18:40:03 +0000 (11:40 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 6 May 2023 18:45:31 +0000 (11:45 -0700)
Probe the touch controller driver even if resolution information is not
available. This can happen e.g. in case the touch controller suffered a
failed firmware update and is stuck in bootloader mode.

Signed-off-by: Marek Vasut <marex@denx.de>
Link: https://lore.kernel.org/r/20230217025200.203833-1-marex@denx.de
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/touchscreen/ili210x.c

index 4897faf..ee4e739 100644 (file)
@@ -370,22 +370,33 @@ static int ili251x_firmware_update_resolution(struct device *dev)
 
        /* The firmware update blob might have changed the resolution. */
        error = priv->chip->read_reg(client, REG_PANEL_INFO, &rs, sizeof(rs));
-       if (error)
-               return error;
+       if (!error) {
+               resx = le16_to_cpup((__le16 *)rs);
+               resy = le16_to_cpup((__le16 *)(rs + 2));
 
-       resx = le16_to_cpup((__le16 *)rs);
-       resy = le16_to_cpup((__le16 *)(rs + 2));
+               /* The value reported by the firmware is invalid. */
+               if (!resx || resx == 0xffff || !resy || resy == 0xffff)
+                       error = -EINVAL;
+       }
 
-       /* The value reported by the firmware is invalid. */
-       if (!resx || resx == 0xffff || !resy || resy == 0xffff)
-               return -EINVAL;
+       /*
+        * In case of error, the firmware might be stuck in bootloader mode,
+        * e.g. after a failed firmware update. Set maximum resolution, but
+        * do not fail to probe, so the user can re-trigger the firmware
+        * update and recover the touch controller.
+        */
+       if (error) {
+               dev_warn(dev, "Invalid resolution reported by controller.\n");
+               resx = 16384;
+               resy = 16384;
+       }
 
        input_abs_set_max(priv->input, ABS_X, resx - 1);
        input_abs_set_max(priv->input, ABS_Y, resy - 1);
        input_abs_set_max(priv->input, ABS_MT_POSITION_X, resx - 1);
        input_abs_set_max(priv->input, ABS_MT_POSITION_Y, resy - 1);
 
-       return 0;
+       return error;
 }
 
 static ssize_t ili251x_firmware_update_firmware_version(struct device *dev)
@@ -977,11 +988,10 @@ static int ili210x_i2c_probe(struct i2c_client *client)
        if (priv->chip->has_pressure_reg)
                input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xa, 0, 0);
        error = ili251x_firmware_update_cached_state(dev);
-       if (error) {
-               dev_err(dev, "Unable to cache firmware information, err: %d\n",
-                       error);
-               return error;
-       }
+       if (error)
+               dev_warn(dev, "Unable to cache firmware information, err: %d\n",
+                        error);
+
        touchscreen_parse_properties(input, true, &priv->prop);
 
        error = input_mt_init_slots(input, priv->chip->max_touches,