CHROMIUM: Input: atmel_mxt_ts - Disregard matrix size for config update check
authorBenson Leung <bleung@chromium.org>
Tue, 26 Mar 2013 00:21:56 +0000 (17:21 -0700)
committerChromeBot <chrome-bot@google.com>
Tue, 26 Mar 2013 04:55:28 +0000 (21:55 -0700)
The config update's header check function compares  the x size and y size bytes
in the raw config file with the corresponding bytes from the device.
Unfortunately, these bytes may be changed by changing T46 byte 1, so they
should not be treated as an immutable quality of the device.

We've run into several situations where a firmware update or an invalid
config update blows away the correct value in the device's registers,
and the driver refuses to update to restore the correct register config.

This change skips over the check of the x size and y size, and skips over
the info block crc check in case the size is different, as the crc comparison
with the device's info block crc will also fail.

Signed-off-by: Benson Leung <bleung@chromium.org>
BUG=chrome-os-partner:18386
TEST=Follow the steps below to write an incorrect value into the XYMode reg:
cd /sys/bus/i2c/devices/1-004b
echo "2e000100" > object
echo 1 > backupnv
echo "06000001" > object
shutdown -P now
Boot the system again.

With this fix, the trackpad should be functional, and the following should
be in /var/log/messages:
chromeos-touch-config-update[285]-atmel_mxt_tp: Device config checksum : a9ffd4
chromeos-touch-config-update[285]-atmel_mxt_tp: New config checksum : a84914

atmel_mxt_ts 1-004b: Using config file maxtouch-tp.cfg (size = 1102)
atmel_mxt_ts 1-004b: Config File: Version = OBP_RAW V1
atmel_mxt_ts 1-004b: Config File: Chip ID = 82 01 10 aa 13 0b 16
atmel_mxt_ts 1-004b: Matrix Xsize and Ysize mismatch. Updating.
atmel_mxt_ts 1-004b: Chip Info: 82 01 10 aa 10 0e 16
atmel_mxt_ts 1-004b: Config File: Config CRC = 56506a

Followed by the normal config update output, then confirmation the update worked:
chromeos-touch-config-update[285]-atmel_mxt_tp: Try #1: Checking new device csum a84914
chromeos-touch-config-update[285]-atmel_mxt_tp: Config update succeeded

Change-Id: I22046b6709bfbfc38e9105543cae9d5ff5e6e183
Reviewed-on: https://gerrit.chromium.org/gerrit/46471
Reviewed-by: Yufeng Shen <miletus@chromium.org>
Tested-by: Benson Leung <bleung@chromium.org>
Commit-Queue: Benson Leung <bleung@chromium.org>

drivers/input/touchscreen/atmel_mxt_ts.c

index 5e40f6d..a3476ae 100644 (file)
@@ -1381,8 +1381,6 @@ static int mxt_cfg_verify_hdr(struct mxt_data *data, char **config)
            info.variant_id != data->info.variant_id ||
            info.version != data->info.version ||
            info.build != data->info.build ||
-           info.matrix_xsize != data->info.matrix_xsize ||
-           info.matrix_ysize != data->info.matrix_ysize ||
            info.object_num != data->info.object_num) {
                dev_err(dev, "Invalid config file: Chip ID info mismatch\n");
                dev_err(dev, "Chip Info: %02x %02x %02x %02x %02x %02x %02x\n",
@@ -1399,6 +1397,25 @@ static int mxt_cfg_verify_hdr(struct mxt_data *data, char **config)
                dev_err(dev, "Invalid config file: No Info Block CRC\n");
                return -EINVAL;
        }
+
+       if (info.matrix_xsize != data->info.matrix_xsize ||
+           info.matrix_ysize != data->info.matrix_ysize) {
+               /*
+                * Matrix xsize and ysize depend on the state of T46 byte 1
+                * for the XY Mode. A mismatch is possible due to
+                * a corrupted register set. The config update should proceed
+                * to correct the problem. In this condition, the info block
+                * CRC check should be skipped.
+                */
+               dev_info(dev, "Matrix Xsize and Ysize mismatch. Updating.\n");
+               dev_info(dev, "Chip Info: %02x %02x %02x %02x %02x %02x %02x\n",
+                        data->info.family_id, data->info.variant_id,
+                        data->info.version, data->info.build,
+                        data->info.matrix_xsize, data->info.matrix_ysize,
+                        data->info.object_num);
+               goto config_crc;
+       }
+
        ret = sscanf(token, "%x", &crc);
        dev_info(dev, "Config File: Info Block CRC = %06x\n", crc);
        if (ret != 1 || crc != data->info_csum) {
@@ -1406,6 +1423,7 @@ static int mxt_cfg_verify_hdr(struct mxt_data *data, char **config)
                return -EINVAL;
        }
 
+config_crc:
        /* 4) Config CRC */
        /*
         * Parse but don't verify against current config;