return get_unaligned_be32(buf) >> 4;
 }
 
-static int elants_i2c_query_fw_id(struct elants_data *ts)
+static int elants_i2c_query_hw_version(struct elants_data *ts)
 {
        struct i2c_client *client = ts->client;
        int error, retry_cnt;
                        error, (int)sizeof(resp), resp);
        }
 
-       dev_err(&client->dev,
-               "Failed to read fw id or fw id is invalid\n");
+       if (error) {
+               dev_err(&client->dev,
+                       "Failed to read fw id: %d\n", error);
+               return error;
+       }
+
+       dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
 
        return -EINVAL;
 }
 static int elants_i2c_initialize(struct elants_data *ts)
 {
        struct i2c_client *client = ts->client;
-       int error, retry_cnt;
+       int error, error2, retry_cnt;
        const u8 hello_packet[] = { 0x55, 0x55, 0x55, 0x55 };
        const u8 recov_packet[] = { 0x55, 0x55, 0x80, 0x80 };
        u8 buf[HEADER_SIZE];
                }
        }
 
+       /* hw version is available even if device in recovery state */
+       error2 = elants_i2c_query_hw_version(ts);
        if (!error)
-               error = elants_i2c_query_fw_id(ts);
+               error = error2;
+
        if (!error)
                error = elants_i2c_query_fw_version(ts);
+       if (!error)
+               error = elants_i2c_query_test_version(ts);
+       if (!error)
+               error = elants_i2c_query_bc_version(ts);
+       if (!error)
+               error = elants_i2c_query_ts_info(ts);
 
-       if (error) {
+       if (error)
                ts->iap_mode = ELAN_IAP_RECOVERY;
-       } else {
-               elants_i2c_query_test_version(ts);
-               elants_i2c_query_bc_version(ts);
-               elants_i2c_query_ts_info(ts);
-       }
 
        return 0;
 }