Input: elants - refactor elants_i2c_execute_command()
authorMichał Mirosław <mirq-linux@rere.qmqm.pl>
Mon, 18 May 2020 03:41:05 +0000 (20:41 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 18 May 2020 04:11:34 +0000 (21:11 -0700)
Apply some DRY-ing to elants_i2c_execute_command() callers.  This pulls
polling and error printk()s into a single function.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Link: https://lore.kernel.org/r/6c576f688b385235c65b461410a917080d27e825.1587923061.git.mirq-linux@rere.qmqm.pl
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/touchscreen/elants_i2c.c

index ccaef40315560e7eac174078d5f118095efc8a3d..233cb1085bbdd0f93469e2b405bb109f189d39ca 100644 (file)
@@ -192,7 +192,8 @@ static int elants_i2c_read(struct i2c_client *client, void *data, size_t size)
 
 static int elants_i2c_execute_command(struct i2c_client *client,
                                      const u8 *cmd, size_t cmd_size,
-                                     u8 *resp, size_t resp_size)
+                                     u8 *resp, size_t resp_size,
+                                     int retries, const char *cmd_name)
 {
        struct i2c_msg msgs[2];
        int ret;
@@ -212,30 +213,55 @@ static int elants_i2c_execute_command(struct i2c_client *client,
                break;
 
        default:
-               dev_err(&client->dev, "%s: invalid command %*ph\n",
-                       __func__, (int)cmd_size, cmd);
+               dev_err(&client->dev, "(%s): invalid command: %*ph\n",
+                       cmd_name, (int)cmd_size, cmd);
                return -EINVAL;
        }
 
-       msgs[0].addr = client->addr;
-       msgs[0].flags = client->flags & I2C_M_TEN;
-       msgs[0].len = cmd_size;
-       msgs[0].buf = (u8 *)cmd;
+       for (;;) {
+               msgs[0].addr = client->addr;
+               msgs[0].flags = client->flags & I2C_M_TEN;
+               msgs[0].len = cmd_size;
+               msgs[0].buf = (u8 *)cmd;
+
+               msgs[1].addr = client->addr;
+               msgs[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
+               msgs[1].flags |= I2C_M_RD;
+               msgs[1].len = resp_size;
+               msgs[1].buf = resp;
+
+               ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+               if (ret < 0) {
+                       if (--retries > 0) {
+                               dev_dbg(&client->dev,
+                                       "(%s) I2C transfer failed: %pe (retrying)\n",
+                                       cmd_name, ERR_PTR(ret));
+                               continue;
+                       }
 
-       msgs[1].addr = client->addr;
-       msgs[1].flags = client->flags & I2C_M_TEN;
-       msgs[1].flags |= I2C_M_RD;
-       msgs[1].len = resp_size;
-       msgs[1].buf = resp;
+                       dev_err(&client->dev,
+                               "(%s) I2C transfer failed: %pe\n",
+                               cmd_name, ERR_PTR(ret));
+                       return ret;
+               }
 
-       ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-       if (ret < 0)
-               return ret;
+               if (ret != ARRAY_SIZE(msgs) ||
+                   resp[FW_HDR_TYPE] != expected_response) {
+                       if (--retries > 0) {
+                               dev_dbg(&client->dev,
+                                       "(%s) unexpected response: %*ph (retrying)\n",
+                                       cmd_name, ret, resp);
+                               continue;
+                       }
 
-       if (ret != ARRAY_SIZE(msgs) || resp[FW_HDR_TYPE] != expected_response)
-               return -EIO;
+                       dev_err(&client->dev,
+                               "(%s) unexpected response: %*ph\n",
+                               cmd_name, ret, resp);
+                       return -EIO;
+               }
 
-       return 0;
+               return 0;
+       }
 }
 
 static int elants_i2c_calibrate(struct elants_data *ts)
@@ -308,27 +334,21 @@ static u16 elants_i2c_parse_version(u8 *buf)
 static int elants_i2c_query_hw_version(struct elants_data *ts)
 {
        struct i2c_client *client = ts->client;
-       int error, retry_cnt;
+       int retry_cnt = MAX_RETRIES;
        const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 };
        u8 resp[HEADER_SIZE];
+       int error;
 
-       for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
+       while (retry_cnt--) {
                error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-                                                  resp, sizeof(resp));
-               if (!error) {
-                       ts->hw_version = elants_i2c_parse_version(resp);
-                       if (ts->hw_version != 0xffff)
-                               return 0;
-               }
-
-               dev_dbg(&client->dev, "read fw id error=%d, buf=%*phC\n",
-                       error, (int)sizeof(resp), resp);
-       }
+                                                  resp, sizeof(resp), 1,
+                                                  "read fw id");
+               if (error)
+                       return error;
 
-       if (error) {
-               dev_err(&client->dev,
-                       "Failed to read fw id: %d\n", error);
-               return error;
+               ts->hw_version = elants_i2c_parse_version(resp);
+               if (ts->hw_version != 0xffff)
+                       return 0;
        }
 
        dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
@@ -339,26 +359,27 @@ static int elants_i2c_query_hw_version(struct elants_data *ts)
 static int elants_i2c_query_fw_version(struct elants_data *ts)
 {
        struct i2c_client *client = ts->client;
-       int error, retry_cnt;
+       int retry_cnt = MAX_RETRIES;
        const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 };
        u8 resp[HEADER_SIZE];
+       int error;
 
-       for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
+       while (retry_cnt--) {
                error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-                                                  resp, sizeof(resp));
-               if (!error) {
-                       ts->fw_version = elants_i2c_parse_version(resp);
-                       if (ts->fw_version != 0x0000 &&
-                           ts->fw_version != 0xffff)
-                               return 0;
-               }
+                                                  resp, sizeof(resp), 1,
+                                                  "read fw version");
+               if (error)
+                       return error;
+
+               ts->fw_version = elants_i2c_parse_version(resp);
+               if (ts->fw_version != 0x0000 && ts->fw_version != 0xffff)
+                       return 0;
 
-               dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n",
-                       error, (int)sizeof(resp), resp);
+               dev_dbg(&client->dev, "(read fw version) resp %*phC\n",
+                       (int)sizeof(resp), resp);
        }
 
-       dev_err(&client->dev,
-               "Failed to read fw version or fw version is invalid\n");
+       dev_err(&client->dev, "Invalid fw ver: %#04x\n", ts->fw_version);
 
        return -EINVAL;
 }
@@ -366,30 +387,24 @@ static int elants_i2c_query_fw_version(struct elants_data *ts)
 static int elants_i2c_query_test_version(struct elants_data *ts)
 {
        struct i2c_client *client = ts->client;
-       int error, retry_cnt;
+       int error;
        u16 version;
        const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 };
        u8 resp[HEADER_SIZE];
 
-       for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
-               error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-                                                  resp, sizeof(resp));
-               if (!error) {
-                       version = elants_i2c_parse_version(resp);
-                       ts->test_version = version >> 8;
-                       ts->solution_version = version & 0xff;
-
-                       return 0;
-               }
-
-               dev_dbg(&client->dev,
-                       "read test version error rc=%d, buf=%*phC\n",
-                       error, (int)sizeof(resp), resp);
+       error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
+                                          resp, sizeof(resp), MAX_RETRIES,
+                                          "read test version");
+       if (error) {
+               dev_err(&client->dev, "Failed to read test version\n");
+               return error;
        }
 
-       dev_err(&client->dev, "Failed to read test version\n");
+       version = elants_i2c_parse_version(resp);
+       ts->test_version = version >> 8;
+       ts->solution_version = version & 0xff;
 
-       return -EINVAL;
+       return 0;
 }
 
 static int elants_i2c_query_bc_version(struct elants_data *ts)
@@ -401,13 +416,10 @@ static int elants_i2c_query_bc_version(struct elants_data *ts)
        int error;
 
        error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-                                          resp, sizeof(resp));
-       if (error) {
-               dev_err(&client->dev,
-                       "read BC version error=%d, buf=%*phC\n",
-                       error, (int)sizeof(resp), resp);
+                                          resp, sizeof(resp), 1,
+                                          "read BC version");
+       if (error)
                return error;
-       }
 
        version = elants_i2c_parse_version(resp);
        ts->bc_version = version >> 8;
@@ -439,12 +451,10 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
        error = elants_i2c_execute_command(client,
                                           get_resolution_cmd,
                                           sizeof(get_resolution_cmd),
-                                          resp, sizeof(resp));
-       if (error) {
-               dev_err(&client->dev, "get resolution command failed: %d\n",
-                       error);
+                                          resp, sizeof(resp), 1,
+                                          "get resolution");
+       if (error)
                return error;
-       }
 
        rows = resp[2] + resp[6] + resp[10];
        cols = resp[3] + resp[7] + resp[11];
@@ -452,36 +462,29 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
        /* Process mm_to_pixel information */
        error = elants_i2c_execute_command(client,
                                           get_osr_cmd, sizeof(get_osr_cmd),
-                                          resp, sizeof(resp));
-       if (error) {
-               dev_err(&client->dev, "get osr command failed: %d\n",
-                       error);
+                                          resp, sizeof(resp), 1, "get osr");
+       if (error)
                return error;
-       }
 
        osr = resp[3];
 
        error = elants_i2c_execute_command(client,
                                           get_physical_scan_cmd,
                                           sizeof(get_physical_scan_cmd),
-                                          resp, sizeof(resp));
-       if (error) {
-               dev_err(&client->dev, "get physical scan command failed: %d\n",
-                       error);
+                                          resp, sizeof(resp), 1,
+                                          "get physical scan");
+       if (error)
                return error;
-       }
 
        phy_x = get_unaligned_be16(&resp[2]);
 
        error = elants_i2c_execute_command(client,
                                           get_physical_drive_cmd,
                                           sizeof(get_physical_drive_cmd),
-                                          resp, sizeof(resp));
-       if (error) {
-               dev_err(&client->dev, "get physical drive command failed: %d\n",
-                       error);
+                                          resp, sizeof(resp), 1,
+                                          "get physical drive");
+       if (error)
                return error;
-       }
 
        phy_y = get_unaligned_be16(&resp[2]);
 
@@ -636,11 +639,10 @@ static int elants_i2c_validate_remark_id(struct elants_data *ts,
 
        /* Compare TS Remark ID and FW Remark ID */
        error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-                                       resp, sizeof(resp));
-       if (error) {
-               dev_err(&client->dev, "failed to query Remark ID: %d\n", error);
+                                          resp, sizeof(resp),
+                                          1, "read Remark ID");
+       if (error)
                return error;
-       }
 
        ts_remark_id = get_unaligned_be16(&resp[3]);
 
@@ -1075,16 +1077,12 @@ static ssize_t show_calibration_count(struct device *dev,
        int error;
 
        error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
-                                               resp, sizeof(resp));
-       if (error) {
-               dev_err(&client->dev,
-                       "read ReK status error=%d, buf=%*phC\n",
-                       error, (int)sizeof(resp), resp);
+                                          resp, sizeof(resp), 1,
+                                          "read ReK status");
+       if (error)
                return sprintf(buf, "%d\n", error);
-       }
 
        rek_count = get_unaligned_be16(&resp[2]);
-
        return sprintf(buf, "0x%04x\n", rek_count);
 }